Display Table of Threat Actor Indicators

Display threat actor indicators in a structured table format

This is a query example for the Table of Indicators for Threat Actors (limit 10k) widget in the CrowdStrike Intel Indicators: Actors dashboard of the crowdstrike/intel-indicators package.

Query

flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result
logscale
actors[0]=*
| split(actors)
| actors=* type=* malicious_confidence=*
| table([last_updated, malicious_confidence, actors, type, indicator], sortby=last_updated, limit=10000)
| "Last Updated" := rename(last_updated)
| "Malicious Confidence" := rename(malicious_confidence)
| "Actor" := rename(actors)
| "Indicator Type" := rename(type)
| "Indicator" := rename(indicator)

Introduction

This widget is used to create a structured table view of threat actor indicators, including their confidence levels, types, and last update timestamps.

In this widget, the table() function is used to organize threat actor indicators into columns, while split() handles array fields, and rename() provides user-friendly column headers.

Example incoming data might look like this:

@timestamp#error#repo#type@error@error_msg@error_msg[0]@error_msg[1]@event_parsed@id@ingesttimestamp@rawstring@timestamp.nanos@timezone_markeractors[0]actors[1]deleteddomain_types[0]idindicatorip_address_types[0]kill_chains[0]labels[0].created_onlabels[0].last_valid_onlabels[0].namelabels[1].created_onlabels[1].last_valid_onlabels[1].namelabels[2].created_onlabels[2].last_valid_onlabels[2].namelabels[3].created_onlabels[3].last_valid_onlabels[3].namelabels[4].created_onlabels[4].last_valid_onlabels[4].namelabels[5].created_onlabels[5].last_valid_onlabels[5].namelast_updatedmalicious_confidencemalware_families[0]published_datethreat_types[0]threat_types[1]type
2026-01-15T14:42:01 auto-dashboard-queriesCS_Intel_Indicators     VAq2qyZrM0xlcuqUmqUNchHO_2_204_17684881212026-01-15T14:42:01{"_marker":"1596041942bdd628471893b18bec97d0b4d6edd659","actors":["APT29"],"deleted":false,"domain_types":[],"id":"domain_malicious-site.com","indicator":"192.168.2.143","ip_address_types":["C2"],"kill_chains":["C2"],"labels":[{"created_on":"2026-01-15T14:42:01.002Z","last_valid_on":"2026-01-15T14:42:01.002Z","name":"Malware/Qakbot"},{"created_on":"2026-01-15T14:42:01.002Z","last_valid_on":"2026-01-15T14:42:01.002Z","name":"ThreatType/Criminal"},{"created_on":"2026-01-15T14:42:01.002Z","last_valid_on":"2026-01-15T14:42:01.002Z","name":"Status/Inactive"}],"last_updated":"2026-01-15T14:42:01.002Z","malicious_confidence":"high","malware_families":["Qakbot"],"published_date":"2026-01-15T14:42:01.002Z","relations":[],"reports":[],"targets":[],"threat_types":["Malware"],"type":"ip","vulnerabilities":[]} 32b5b8ff1be8633d9978fa0c3b5ae4da0Z1596041942bdd628471893b18bec97d0b4d6edd659APT29 false domain_malicious-site.com192.168.2.143C2C22026-01-15T14:42:01.002Z2026-01-15T14:42:01.002ZMalware/Qakbot2026-01-15T14:42:01.002Z2026-01-15T14:42:01.002ZThreatType/Criminal2026-01-15T14:42:01.002Z2026-01-15T14:42:01.002ZStatus/Inactive         2026-01-15T14:42:01.002ZhighQakbot2026-01-15T14:42:01.002ZMalware ip
2026-01-15T14:42:01 auto-dashboard-queriesCS_Intel_Indicators     VAq2qyZrM0xlcuqUmqUNchHO_2_205_17684881212026-01-15T14:42:02{"_marker":"1596041943aef739582904c29cfd08e1c5e7fee760","actors":["Lazarus Group","Fancy Bear"],"deleted":false,"domain_types":["DGA"],"id":"domain_evil-host.net","indicator":"malicious-domain.com","ip_address_types":[],"kill_chains":["Reconnaissance"],"labels":[{"created_on":"2026-01-15T14:42:01.793Z","last_valid_on":"2026-01-15T14:42:01.793Z","name":"Malware/Emotet"},{"created_on":"2026-01-15T14:42:01.793Z","last_valid_on":"2026-01-15T14:42:01.793Z","name":"DomainType/DGA"},{"created_on":"2026-01-15T14:42:01.793Z","last_valid_on":"2026-01-15T14:42:01.793Z","name":"ThreatType/Banking"},{"created_on":"2026-01-15T14:42:01.793Z","last_valid_on":"2026-01-15T14:42:01.793Z","name":"Status/Active"}],"last_updated":"2026-01-15T14:42:01.793Z","malicious_confidence":"medium","malware_families":["Emotet"],"published_date":"2026-01-15T14:42:01.793Z","relations":[],"reports":[],"targets":[],"threat_types":["Ransomeware","Phishing"],"type":"domain","vulnerabilities":[]} 32b5b8ff1be8633d9978fa0c3b5ae4da0Z1596041943aef739582904c29cfd08e1c5e7fee760Lazarus GroupFancy BearfalseDGAdomain_evil-host.netmalicious-domain.com Reconnaissance2026-01-15T14:42:01.793Z2026-01-15T14:42:01.793ZMalware/Emotet2026-01-15T14:42:01.793Z2026-01-15T14:42:01.793ZDomainType/DGA2026-01-15T14:42:01.793Z2026-01-15T14:42:01.793ZThreatType/Banking2026-01-15T14:42:01.793Z2026-01-15T14:42:01.793ZStatus/Active      2026-01-15T14:42:01.793ZmediumEmotet2026-01-15T14:42:01.793ZRansomewarePhishingdomain
2026-01-15T14:42:02 auto-dashboard-queriesCS_Intel_Indicators     VAq2qyZrM0xlcuqUmqUNchHO_2_206_17684881222026-01-15T14:42:02{"_marker":"1596041944bcf840693015d30dge19f2d6f8gff871","actors":[],"deleted":false,"domain_types":["Phishing"],"id":"domain_phishing-portal.org","indicator":"evil-site.net","ip_address_types":[],"kill_chains":["Weaponization"],"labels":[{"created_on":"2026-01-15T14:42:02.362Z","last_valid_on":"2026-01-15T14:42:02.362Z","name":"Malware/TrickBot"},{"created_on":"2026-01-15T14:42:02.362Z","last_valid_on":"2026-01-15T14:42:02.362Z","name":"DomainType/Phishing"},{"created_on":"2026-01-15T14:42:02.362Z","last_valid_on":"2026-01-15T14:42:02.362Z","name":"ThreatType/Ransomware"},{"created_on":"2026-01-15T14:42:02.362Z","last_valid_on":"2026-01-15T14:42:02.362Z","name":"Status/Historic"},{"created_on":"2026-01-15T14:42:02.362Z","last_valid_on":"2026-01-15T14:42:02.362Z","name":"KillChain/C2"},{"created_on":"2026-01-15T14:42:02.362Z","last_valid_on":"2026-01-15T14:42:02.362Z","name":"MaliciousConfidence/High"}],"last_updated":"2026-01-15T14:42:02.362Z","malicious_confidence":"low","malware_families":["TrickBot"],"published_date":"2026-01-15T14:42:02.362Z","relations":[],"reports":[],"targets":[],"threat_types":["Malware"],"type":"domain","vulnerabilities":[]} 32b5b8ff1be8633d9978fa0c3b5ae4da0Z1596041944bcf840693015d30dge19f2d6f8gff871  falsePhishingdomain_phishing-portal.orgevil-site.net Weaponization2026-01-15T14:42:02.362Z2026-01-15T14:42:02.362ZMalware/TrickBot2026-01-15T14:42:02.362Z2026-01-15T14:42:02.362ZDomainType/Phishing2026-01-15T14:42:02.362Z2026-01-15T14:42:02.362ZThreatType/Ransomware2026-01-15T14:42:02.362Z2026-01-15T14:42:02.362ZStatus/Historic2026-01-15T14:42:02.362Z2026-01-15T14:42:02.362ZKillChain/C22026-01-15T14:42:02.362Z2026-01-15T14:42:02.362ZMaliciousConfidence/High2026-01-15T14:42:02.362ZlowTrickBot2026-01-15T14:42:02.362ZMalware domain
2026-01-15T14:42:03trueauto-dashboard-queriesCS_Intel_IndicatorstrueCould not parse json for field=@rawstring msg=Could not handle input. reason=Could not parse JSON | Error finding timestamp. Unknown field: "last_updated"Could not parse json for field=@rawstring msg=Could not handle input. reason=Could not parse JSONError finding timestamp. Unknown field: "last_updated"falseDny5CTK5iIJyunQyWbcL4fEA_2_67_17684881232026-01-15T14:42:03{ "_marker": "1596041945cda951704126e41ehf20a3e7a9haa982", "actors": [], "deleted": true, "domain_types": [ "C2" ], "id": "ip_192.168.1.100", "indicator": "phishing-portal.org", "ip_address_types": [], "kill_chains": [ "Delivery" ], "labels": [ { "created_on": 1710340124, "last_valid_on": 1710343724, "name": "Malware/Dridex" }, { "created_on": 1710347324, "last_valid_on": 1710350924, "name": "DomainType/C2" }, { "created_on": 1710354524, "last_valid_on": 1710358124, "name": "ThreatType/APT" }, { "created_on": 1710361724, "last_valid_on": 1710365324, "name": "Status/Confirmed" }, { "created_on": 1710368924, "last_valid_on": 1710372524, "name": "KillChain/Reconnaissance" }, { "created_on": 1710376124, "last_valid_on": 1710379724, "name": "MaliciousConfidence/Medium" }, { "created_on": 1710383324, "last_valid_on": 1710386924, "name": "ThreatType/Espionage" }, { "created_on": 1710390524, "last_valid_on": 1710394124, "name": "Status/Suspected" } ], "last_updated": "2026-01-15T14:42:02.922Z", "malicious_confidence": "Critical", "malware_families": [ "Dridex" "Zeus" "Ryuk" ], "published_date": "2026-01-15T14:42:02.922Z", "relations": [], "reports": [], "targets": [], "threat_types": [ "Ransomeware", "Malware" ], "type": "IP Address", "vulnerabilities": [] } 32b5b8ff1be8633d9978fa0c3b5ae4da0Z                                  
2026-01-15T14:42:03 auto-dashboard-queriesCS_Intel_Indicators     VAq2qyZrM0xlcuqUmqUNchHO_2_207_17684881232026-01-15T14:42:04{"_marker":"1596041946deb062815237f52fhg31b4f8b0ibb093","actors":["Cozy Bear"],"deleted":false,"domain_types":[],"id":"ip_10.0.0.50","indicator":"192.168.0.87","ip_address_types":["Proxy"],"kill_chains":["Exploitation"],"labels":[{"created_on":"2026-01-15T14:42:03.489Z","last_valid_on":"2026-01-15T14:42:03.489Z","name":"Malware/Zeus"},{"created_on":"2026-01-15T14:42:03.489Z","last_valid_on":"2026-01-15T14:42:03.489Z","name":"ThreatType/Malware"},{"created_on":"2026-01-15T14:42:03.489Z","last_valid_on":"2026-01-15T14:42:03.489Z","name":"Status/FalsePositive"}],"last_updated":"2026-01-15T14:42:03.489Z","malicious_confidence":"high","malware_families":["Conti"],"published_date":"2026-01-15T14:42:03.489Z","relations":[],"reports":[],"targets":[],"threat_types":["Ransomeware"],"type":"ip","vulnerabilities":[]} 32b5b8ff1be8633d9978fa0c3b5ae4da0Z1596041946deb062815237f52fhg31b4f8b0ibb093Cozy Bear false ip_10.0.0.50192.168.0.87ProxyExploitation2026-01-15T14:42:03.489Z2026-01-15T14:42:03.489ZMalware/Zeus2026-01-15T14:42:03.489Z2026-01-15T14:42:03.489ZThreatType/Malware2026-01-15T14:42:03.489Z2026-01-15T14:42:03.489ZStatus/FalsePositive         2026-01-15T14:42:03.489ZhighConti2026-01-15T14:42:03.489ZRansomeware ip

Step-by-Step

  1. Starting with the source repository events.

  2. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result style 1 fill:#ff0000,stroke-width:4px,stroke:#000;
    logscale
    actors[0]=*

    Filters events to include only those that have a value in the actors[0] field.

  3. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result style 2 fill:#ff0000,stroke-width:4px,stroke:#000;
    logscale
    | split(actors)

    Splits the array values in the actors field into separate events. Each value from the array creates a new event, with the array value placed in the field name specified in the split function.

  4. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result style 3 fill:#ff0000,stroke-width:4px,stroke:#000;
    logscale
    | actors=* type=* malicious_confidence=*

    Filters to ensure presence of required fields: actors, type, and malicious_confidence.

  5. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result style 4 fill:#ff0000,stroke-width:4px,stroke:#000;
    logscale
    | table([last_updated, malicious_confidence, actors, type, indicator], sortby=last_updated, limit=10000)

    Creates a table with specified columns, sorted by last_updated field, limited to 10,000 rows. The table() function organizes the data into columns in the specified order.

  6. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result style 5 fill:#ff0000,stroke-width:4px,stroke:#000;
    logscale
    | "Last Updated" := rename(last_updated)

    Renames the last_updated field to Last Updated for better readability.

  7. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result style 6 fill:#ff0000,stroke-width:4px,stroke:#000;
    logscale
    | "Malicious Confidence" := rename(malicious_confidence)

    Renames the malicious_confidence field to Malicious Confidence for better readability.

  8. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result style 7 fill:#ff0000,stroke-width:4px,stroke:#000;
    logscale
    | "Actor" := rename(actors)

    Renames the actors field to Actor for better readability.

  9. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result style 8 fill:#ff0000,stroke-width:4px,stroke:#000;
    logscale
    | "Indicator Type" := rename(type)

    Renames the type field to Indicator Type for better readability.

  10. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 1[/Filter/] 2[\Add Field/] 3[/Filter/] 4{{Aggregate}} 5["Expression"] 6["Expression"] 7["Expression"] 8["Expression"] 9["Expression"] result{{Result Set}} repo --> 1 1 --> 2 2 --> 3 3 --> 4 4 --> 5 5 --> 6 6 --> 7 7 --> 8 8 --> 9 9 --> result style 9 fill:#ff0000,stroke-width:4px,stroke:#000;
    logscale
    | "Indicator" := rename(indicator)

    Renames the indicator field to Indicator for better readability.

  11. Event Result set.

Summary and Results

The widget is used to present threat actor indicators in a clear, tabular format with sorted and renamed columns for better readability.

This widget is useful to analyze threat actor indicators, their associated confidence levels, and track when they were last updated in a structured format.

Sample output from the incoming example data:

ActorIndicatorIndicator TypeLast UpdatedMalicious Confidence
APT41command-control.xyzdomain2026-01-15T14:42:04.258Zmedium
Cozy Bear192.168.0.87ip2026-01-15T14:42:03.489Zhigh
Lazarus Groupmalicious-domain.comdomain2026-01-15T14:42:01.793Zmedium
Fancy Bearmalicious-domain.comdomain2026-01-15T14:42:01.793Zmedium
APT29192.168.2.143ip2026-01-15T14:42:01.002Zhigh

The output is sorted by the Last Updated timestamp in descending order, showing the most recent indicators first, and each row represents a unique combination of actor and indicator.