Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions external-import/crowdstrike/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ There are a number of configuration options, which are set either in `docker-com
| Client ID | crowdstrike.client_id | `CROWDSTRIKE_CLIENT_ID` | | Yes | CrowdStrike API Client ID. |
| Client Secret | crowdstrike.client_secret | `CROWDSTRIKE_CLIENT_SECRET` | | Yes | CrowdStrike API Client Secret. |
| TLP | crowdstrike.tlp | `CROWDSTRIKE_TLP` | amber+strict | No | TLP marking for imported data. |
| Create Observables | crowdstrike.create_observables | `CROWDSTRIKE_CREATE_OBSERVABLES` | true | No | Create observables from indicators. |
| Create Observables | crowdstrike.create_observables | `CROWDSTRIKE_CREATE_OBSERVABLES` | true | No | Create observables from indicators and from optional report IOC extraction. |
| Create Indicators | crowdstrike.create_indicators | `CROWDSTRIKE_CREATE_INDICATORS` | true | No | Create indicators. |
| Scopes | crowdstrike.scopes | `CROWDSTRIKE_SCOPES` | actor,report,indicator,yara_master | No | Comma-separated list of data types to import. |
| MITRE ATT&CK Version | crowdstrike.attack_version | `CROWDSTRIKE_ATTACK_VERSION` | 17.1 | No | MITRE ATT&CK Enterprise version used to resolve label-derived ATT&CK techniques to canonical MITRE IDs. Should match the version imported by the MITRE ATT&CK external import connector. |
Expand All @@ -94,7 +94,7 @@ There are a number of configuration options, which are set either in `docker-com
| Report Target Industries | crowdstrike.report_target_industries | `CROWDSTRIKE_REPORT_TARGET_INDUSTRIES` | | No | Filter reports by target industry. |
| Report Guess Malware | crowdstrike.report_guess_malware | `CROWDSTRIKE_REPORT_GUESS_MALWARE` | false | No | Use report tags to guess malware. |
| Report Guess Relations | crowdstrike.report_guess_relations | `CROWDSTRIKE_REPORT_GUESS_RELATIONS` | false | No | Auto-create relationships between entities. |
| Report Extract IOCs | crowdstrike.report_extract_iocs | `CROWDSTRIKE_REPORT_EXTRACT_IOCS` | | No | Comma-separated list of IOC types to extract from report text as Observables. Supported: `ipv4`, `ipv6`, `domain`, `url`, `md5`, `sha1`, `sha256`. Empty to disable. |
| Report Extract IOCs | crowdstrike.report_extract_iocs | `CROWDSTRIKE_REPORT_EXTRACT_IOCS` | | No | Comma-separated list of IOC types to extract from report text as Observables. Supported: `ipv4`, `ipv6`, `domain`, `url`, `md5`, `sha1`, `sha256`. Empty to disable. Requires `CROWDSTRIKE_CREATE_OBSERVABLES=true`. |
| Indicator Start Timestamp | crowdstrike.indicator_start_timestamp | `CROWDSTRIKE_INDICATOR_START_TIMESTAMP` | (30 days ago) | No | Unix timestamp. Empty = 30 days ago. 0 = ALL indicators. |
| Indicator Exclude Types | crowdstrike.indicator_exclude_types | `CROWDSTRIKE_INDICATOR_EXCLUDE_TYPES` | hash_ion,hash_md5,hash_sha1,password,username | No | Comma-separated indicator types to exclude. |
| Default Score | crowdstrike.default_x_opencti_score | `CROWDSTRIKE_DEFAULT_X_OPENCTI_SCORE` | 50 | No | Default x_opencti_score for indicators. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Below is an exhaustive enumeration of all configurable parameters available, eac
| CONNECTOR_DURATION_PERIOD | `string` | | Format: [`duration`](https://json-schema.org/understanding-json-schema/reference/string#built-in-formats) | | `"PT1H"` | ISO8601 Duration format starting with 'P' for Period (e.g., 'PT30M' for 30 minutes). |
| CROWDSTRIKE_BASE_URL | `string` | | Format: [`uri`](https://json-schema.org/understanding-json-schema/reference/string#built-in-formats) | | `"https://api.crowdstrike.com/"` | CrowdStrike API base URL. |
| CROWDSTRIKE_TLP | `string` | | `red` `amber+strict` `amber` `green` `clear` `white` | | `"amber+strict"` | Default Traffic Light Protocol (TLP) marking for imported data. |
| CROWDSTRIKE_CREATE_OBSERVABLES | `boolean` | | boolean | | `true` | Whether to create observables in OpenCTI. |
| CROWDSTRIKE_CREATE_OBSERVABLES | `boolean` | | boolean | | `true` | Whether to create observables in OpenCTI (indicator-derived observables and report IOC extraction observables). |
| CROWDSTRIKE_CREATE_INDICATORS | `boolean` | | boolean | | `true` | Whether to create indicators in OpenCTI. |
| CROWDSTRIKE_SCOPES | `array` | | string | | `["actor", "report", "indicator", "malware", "yara_master", "snort_suricata_master"]` | Comma-separated list of scopes to enable. Available: actor, report, indicator, malware, vulnerability, yara_master, snort_suricata_master. |
| CROWDSTRIKE_ATTACK_VERSION | `string` | | string | | `"17.1"` | MITRE ATT&CK Enterprise version to use for technique ID resolution (e.g., 17.1). Should match the version imported by the MITRE ATT&CK external import connector. |
Expand All @@ -31,7 +31,7 @@ Below is an exhaustive enumeration of all configurable parameters available, eac
| CROWDSTRIKE_REPORT_TARGET_INDUSTRIES | `array` | | string | | `[]` | Comma-separated list of target industries to filter reports. |
| CROWDSTRIKE_REPORT_GUESS_MALWARE | `boolean` | | boolean | | `false` | Whether to use report tags to guess related malware. |
| CROWDSTRIKE_REPORT_GUESS_RELATIONS | `boolean` | | boolean | | `false` | Whether to automatically guess and create relationships in reports. |
| CROWDSTRIKE_REPORT_EXTRACT_IOCS | `array` | | string | | `[]` | Comma-separated list of IOC types to extract from report text content via regex. Extracted IOCs are created as Observables (not Indicators) and linked to the report. Supported types: ipv4, ipv6, domain, url, md5, sha1, sha256. Leave empty to disable. |
| CROWDSTRIKE_REPORT_EXTRACT_IOCS | `array` | | string | | `[]` | Comma-separated list of IOC types to extract from report text content via regex. Extracted IOCs are created as Observables (not Indicators) and linked to the report. Supported types: ipv4, ipv6, domain, url, md5, sha1, sha256. Leave empty to disable. Requires CROWDSTRIKE_CREATE_OBSERVABLES=true. |
| CROWDSTRIKE_INDICATOR_START_TIMESTAMP | `integer` | | integer | | | Unix timestamp from which to start importing indicators. Default is 30 days ago. BEWARE: 0 means ALL indicators! |
| CROWDSTRIKE_INDICATOR_EXCLUDE_TYPES | `array` | | string | | `["hash_ion", "hash_md5", "hash_sha1", "password", "username"]` | Comma-separated list of indicator types to exclude from import. |
| CROWDSTRIKE_INDICATOR_IP_MAX_AGE | `string` | | Format: [`duration`](https://json-schema.org/understanding-json-schema/reference/string#built-in-formats) | | `null` | ISO8601 Duration format starting with 'P' for Period (e.g., 'P90D' for 90 days). Covers both IPv4 and IPv6. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,9 @@ def _create_report_bundle(

def _extract_iocs_from_report(self, report) -> list[_Observable]:
"""Extract IOCs from report text content and create STIX observables."""
if not self.indicator_config.get("create_observables", True):
return []

if not self.report_extract_iocs:
return []

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,54 @@ def test_report_with_iocs_in_description_produces_observables(
assert "ipv4-addr" in bundle_types
assert "domain-name" in bundle_types
assert "file" in bundle_types # SHA-256 creates a File observable


def _build_importer_for_ioc_extraction(
author_identity: Identity, tlp_marking: MarkingDefinition, create_observables: bool
) -> ReportImporter:
importer = ReportImporter.__new__(ReportImporter)
importer.author = author_identity
importer.tlp_marking = tlp_marking
importer.indicator_config = {"create_observables": create_observables}
importer.report_extract_iocs = ["ipv4", "domain", "sha256"]
importer._info = lambda *args, **kwargs: None
importer._warning = lambda *args, **kwargs: None
return importer


def test_extract_iocs_respects_create_observables_disabled(
author_identity, tlp_marking
):
importer = _build_importer_for_ioc_extraction(
author_identity, tlp_marking, create_observables=False
)

report = {
"description": (
"45.33.32.156 evil.example.com "
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
)
}

observables = importer._extract_iocs_from_report(report)
assert observables == []


def test_extract_iocs_when_create_observables_enabled(author_identity, tlp_marking):
importer = _build_importer_for_ioc_extraction(
author_identity, tlp_marking, create_observables=True
)

report = {
"description": (
"45.33.32.156 evil.example.com "
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
)
}

observables = importer._extract_iocs_from_report(report)
observable_types = {observable.type for observable in observables}

assert "ipv4-addr" in observable_types
assert "domain-name" in observable_types
assert "file" in observable_types