Skip to content
Merged
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
40 changes: 24 additions & 16 deletions external-import/google-ti-feeds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The **Google Threat Intelligence (GTI) Feeds Connector** ingests threat intellig
| Collection | Config toggle | Enabled by default | Main OpenCTI entity | Related OpenCTI entity(s) produced |
|-------------------|--------------------------------|--------------------|---------------------|------------------------------------------------------------------------------------------------------------------------------------|
| Reports | `GTI_IMPORT_REPORTS` | ✅ Yes | Report | Location, Sector, Malware, Tool, Intrusion-Set, Attack-Pattern, Vulnerability, Indicator, Observable (Domain, File, IP, URL), Note |
| Campaigns | `GTI_IMPORT_CAMPAIGNS` | ❌ No | Campaign | Location, Sector, Intrusion-Set, Malware, Attack-Pattern, Vulnerabilities, Tool |
| Campaigns | `GTI_IMPORT_CAMPAIGNS` | ❌ No | Campaign | Location, Sector, Intrusion-Set, Malware, Attack-Pattern, Vulnerabilities, Tool, Indicator, Observable (Domain, File, IP, URL) |
| Threat Actors | `GTI_IMPORT_THREAT_ACTORS` | ❌ No | Intrusion-Set | Location, Sector, Attack-Pattern, Malware, Vulnerabilities, Tool |
| Malware Families | `GTI_IMPORT_MALWARE_FAMILIES` | ❌ No | Malware | Location, Sector, Intrusion-Set, Attack-Pattern, Vulnerabilities |
| Software Toolkits | `GTI_IMPORT_SOFTWARE_TOOLKITS` | ❌ No | Tool | Location, Sector, Malware, Attack-Pattern |
Expand Down Expand Up @@ -108,21 +108,25 @@ Fetches Google TI **[Campaigns](https://gtidocs.virustotal.com/reference/campaig

The connector calls **`GET /collections`** with a filter on `collection_type:campaign` and `last_modification_date` to retrieve only campaigns modified since the last successful execution. The date is persisted in the connector state as `campaign_next_cursor_start_date`; on first run, it is calculated from `GTI_CAMPAIGN_IMPORT_START_DATE`.

For each campaign returned, the connector fetches related sub-entities by calling **`GET /collections/{campaign_id}/{subentity_type}`** for: `malware_families`, `threat_actors`, `attack_techniques`, `vulnerabilities`, and `software_toolkits`.
For each campaign returned, the connector fetches related sub-entities by calling **`GET /collections/{campaign_id}/{subentity_type}`** for: `malware_families`, `threat_actors`, `attack_techniques`, `vulnerabilities`, `domains`, `files`, `urls`, `ip_addresses`, and `software_toolkits`.

All sub-entities are converted to STIX 2.1 objects and linked to the parent Campaign entity.

> **Note:** Relationships between a campaign and reports are not fetched here. These links are established when the `reports` collection is imported — reports fetch `campaigns` as one of their sub-entities, which creates the link in OpenCTI.

#### Sub-entities mapping

| Sub-entity type | OpenCTI entity produced |
|-----------------------|-------------------------|
| `malware_families` | Malware |
| `threat_actors` | Intrusion-Set |
| `attack_techniques` | Attack-Pattern |
| `vulnerabilities` | Vulnerability |
| `software_toolkits` | Tool |
| Sub-entity type | OpenCTI entity produced |
|-----------------------|--------------------------------------------|
| `malware_families` | Malware |
| `threat_actors` | Intrusion-Set |
| `attack_techniques` | Attack-Pattern |
| `vulnerabilities` | Vulnerability |
| `domains` | Domain-Name observable + Indicator |
| `files` | File observable + Indicator |
| `urls` | URL observable + Indicator |
| `ip_addresses` | IPv4-Addr/IPv6-Addr observable + Indicator |
| `software_toolkits` | Tool |


#### Configurable filters
Expand Down Expand Up @@ -475,13 +479,17 @@ These are **direct attributes** of the GTI Campaign object, but they are modeled

These relationships are **only produced when the Campaigns collection is enabled**, as they require fetching additional sub-entities via dedicated API calls.

| GTI Concept | STIX Source Object | STIX Relationship | STIX Target Object |
|--------------------------|--------------------|---------------------|--------------------|
| `threat_actors` | Campaign | `attributed-to` | Intrusion-Set |
| `malware_families` | Campaign | `uses` | Malware |
| `software_toolkits` | Campaign | `uses` | Tool |
| `attack_techniques` | Campaign | `uses` | Attack-Pattern |
| `vulnerabilities` | Campaign | `targets` | Vulnerability |
| GTI Concept | STIX Source Object | STIX Relationship | STIX Target Object |
|--------------------------|--------------------|---------------------|------------------------------------|
| `threat_actors` | Campaign | `attributed-to` | Intrusion-Set |
| `malware_families` | Campaign | `uses` | Malware |
| `software_toolkits` | Campaign | `uses` | Tool |
| `attack_techniques` | Campaign | `uses` | Attack-Pattern |
| `vulnerabilities` | Campaign | `targets` | Vulnerability |
| `domains` | Indicator | `related-to` | Campaign (Domain-Name + Indicator) |
| `files` | Indicator | `related-to` | Campaign (File + Indicator) |
| `urls` | Indicator | `related-to` | Campaign (URL + Indicator) |
| `ip_addresses` | Indicator | `related-to` | Campaign (IPv4/IPv6 + Indicator) |

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ async def run(self, initial_state: dict[str, Any] | None) -> None:
"attack_techniques",
"vulnerabilities",
"threat_actors",
# "reports",
# "domains",
# "files",
# "urls",
# "ip_addresses",
"domains",
"files",
"urls",
"ip_addresses",
Comment thread
ncarenton marked this conversation as resolved.
"software_toolkits",
# "reports",
]
try:
async for gti_campaigns in self.client_api.fetch_campaigns(initial_state):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,28 @@
"domains_count": 1,
"malware_roles": [],
"field_sources": [],
"recent_activity_summary": [7, 7, 7, 14, 3, 2, 7, 6, 3, 6, 4, 3, 3, 5],
"targeted_regions": ["US", "AU", "BE", "CA"],
"recent_activity_summary": [
7,
7,
7,
14,
3,
2,
7,
6,
3,
6,
4,
3,
3,
5
],
"targeted_regions": [
"US",
"AU",
"BE",
"CA"
],
"targeted_regions_hierarchy": [
{
"region": "Oceania",
Expand Down Expand Up @@ -229,10 +249,10 @@
],
"campaign_type": "GLOBAL",
"counters": {
"files": 0,
"files": 1,
"domains": 1,
"ip_addresses": 27,
"urls": 0,
"urls": 1,
"iocs": 28,
"subscribers": 1,
"attack_techniques": 106
Expand All @@ -255,7 +275,9 @@
"workarounds": [],
"first_seen": 1692648309,
"private": true,
"alt_names": ["GLOBAL.24.007"],
"alt_names": [
"GLOBAL.24.007"
],
"vendor_fix_references": [],
"threat_scape": [],
"recent_activity_relative_change": 0.14925373134328357,
Expand Down
24 changes: 16 additions & 8 deletions external-import/google-ti-feeds/tests/custom/test_orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,22 +358,30 @@ def expected_campaign_log_messages() -> list[str]:
"Fetched 1 attack_techniques relationships from API - {'prefix': '[BaseFetcher]'}",
"Fetched 1 vulnerabilities relationships from API - {'prefix': '[BaseFetcher]'}",
"Fetched 1 threat_actors relationships from API - {'prefix': '[BaseFetcher]'}",
"Fetched 1 domains relationships from API - {'prefix': '[BaseFetcher]'}",
"Fetched 1 files relationships from API - {'prefix': '[BaseFetcher]'}",
"Fetched 1 urls relationships from API - {'prefix': '[BaseFetcher]'}",
"Fetched 1 ip_addresses relationships from API - {'prefix': '[BaseFetcher]'}",
"Fetched 1 software_toolkits relationships from API - {'prefix': '[BaseFetcher]'}",
"Found relationships - {'prefix': '[OrchestratorCampaign]', 'current': 1, 'total': 1, 'relationships': 'malware_families: 1, attack_techniques: 1, vulnerabilities: 1, threat_actors: 1, software_toolkits: 1'}",
"Found relationships - {'prefix': '[OrchestratorCampaign]', 'current': 1, 'total': 1, 'relationships': 'malware_families: 1, attack_techniques: 1, vulnerabilities: 1, threat_actors: 1, domains: 1, files: 1, urls: 1, ip_addresses: 1, software_toolkits: 1'}",
"Using ID-only approach for attack techniques (quota optimization) - {'prefix': '[OrchestratorCampaign]', 'attack_technique_count': 1}",
"Converted entities to STIX format - {'prefix': '[GenericConverter]', 'count': 34, 'entity_type': 'malware families'}",
"Converted entities to STIX format - {'prefix': '[GenericConverter]', 'count': 53, 'entity_type': 'vulnerabilities'}",
"Converted entities to STIX format - {'prefix': '[GenericConverter]', 'count': 54, 'entity_type': 'threat actors'}",
"Converted entities to STIX format - {'prefix': '[GenericConverter]', 'count': 5, 'entity_type': 'domains'}",
"Converted entities to STIX format - {'prefix': '[GenericConverter]', 'count': 5, 'entity_type': 'files'}",
"Converted entities to STIX format - {'prefix': '[GenericConverter]', 'count': 5, 'entity_type': 'URLs'}",
"Converted entities to STIX format - {'prefix': '[GenericConverter]', 'count': 5, 'entity_type': 'IP addresses'}",
"Converted entities to STIX format - {'prefix': '[GenericConverter]', 'count': 2, 'entity_type': 'software toolkits'}",
"Converted entities to STIX format - {'prefix': '[GenericConverter]', 'count': 2, 'entity_type': 'attack techniques'}",
"Converted to STIX entities - {'prefix': '[OrchestratorCampaign]', 'current': 1, 'total': 1, 'entities_count': 176, 'entities_summary': 'location: 23, identity: 34, campaign: 1, relationship: 86, malware: 1, vulnerability: 1, software: 24, note: 3, intrusion-set: 1, tool: 1, attack-pattern: 1'}",
"Adding items to batch processor - {'prefix': '[GenericBatchProcessor]', 'count': 176, 'display_name': 'STIX objects'}",
"Successfully added items - {'prefix': '[GenericBatchProcessor]', 'added_count': 176, 'total_count': 176, 'display_name': 'STIX objects'}",
"Flushing remaining items - {'prefix': '[GenericBatchProcessor]', 'count': 178, 'display_name': 'STIX objects'}",
"Processing batch - {'prefix': '[GenericBatchProcessor]', 'batch_num': 1, 'batch_size': 178, 'display_name': 'STIX objects', 'total_processed': 178}",
"Converted to STIX entities - {'prefix': '[OrchestratorCampaign]', 'current': 1, 'total': 1, 'entities_count': 196, 'entities_summary': 'location: 23, identity: 34, campaign: 1, relationship: 98, malware: 1, vulnerability: 1, software: 24, note: 3, intrusion-set: 1, domain-name: 1, indicator: 4, file: 1, url: 1, ipv4-addr: 1, tool: 1, attack-pattern: 1'}",
"Adding items to batch processor - {'prefix': '[GenericBatchProcessor]', 'count': 196, 'display_name': 'STIX objects'}",
"Successfully added items - {'prefix': '[GenericBatchProcessor]', 'added_count': 196, 'total_count': 196, 'display_name': 'STIX objects'}",
"Flushing remaining items - {'prefix': '[GenericBatchProcessor]', 'count': 198, 'display_name': 'STIX objects'}",
"Processing batch - {'prefix': '[GenericBatchProcessor]', 'batch_num': 1, 'batch_size': 198, 'display_name': 'STIX objects', 'total_processed': 198}",
"Sent batch to OpenCTI - {'prefix': '[GenericBatchProcessor]', 'batch_num': 1}",
"Batch completed successfully - {'prefix': '[GenericBatchProcessor]', 'work_id': None, 'total_count': 178, 'type_summary': 'identity: 35, marking-definition: 1, location: 23, campaign: 1, relationship: 86, malware: 1, vulnerability: 1, software: 24, note: 3, intrusion-set: 1, tool: 1, attack-pattern: 1'}",
"Successfully processed batch #1. Total STIX objects sent: 178 - {'prefix': '[GenericBatchProcessor]', 'batch_num': 1, 'total_items_sent': 178}",
"Batch completed successfully - {'prefix': '[GenericBatchProcessor]', 'work_id': None, 'total_count': 198, 'type_summary': 'identity: 35, marking-definition: 1, location: 23, campaign: 1, relationship: 98, malware: 1, vulnerability: 1, software: 24, note: 3, intrusion-set: 1, domain-name: 1, indicator: 4, file: 1, url: 1, ipv4-addr: 1, tool: 1, attack-pattern: 1'}",
"Successfully processed batch #1. Total STIX objects sent: 198 - {'prefix': '[GenericBatchProcessor]', 'batch_num': 1, 'total_items_sent': 198}",
"State update: Setting next_cursor_date - {'prefix': '[GenericBatchProcessor]', 'latest_date': '2025-07-30T22:01:05+00:00'}",
]

Expand Down
Loading