Files matching known malicious hashes from abuse.ch’s recent threat feed may indicate the presence of recently active malware, as these hashes are often associated with new or evolving threats. SOC teams should proactively hunt for these files in Azure Sentinel to identify and mitigate potential compromise from emerging threats before they cause significant damage.
KQL Query
let MaxAge = ago(1d);
let AbuseFeed = materialize (
(externaldata(report:string)
[@"https://bazaar.abuse.ch/export/csv/recent/"]
with (format = "txt"))
| where report !startswith '#'
| extend report = trim("\"", report)
| extend report = parse_csv(report)
| extend FirstSeenUtc = tostring(report[0])
| project FirstSeenUtc = todatetime(FirstSeenUtc)
,SHA256 = trim('[ "]+',tostring(report[1]))
, MD5 = trim('[ "]+',tostring(report[2]))
, SHA1 = trim('[ "]+',tostring(report[3]))
, Reporter = trim('[ "]+',tostring(report[4]))
, FileName = trim('[ "]+',tostring(report[5]))
, FileType = trim('[ "]+',tostring(report[6]))
, MimeType = trim('[ "]+',tostring(report[7]))
, Signer = iff(report[8] == 'n/a', '', trim('[ "]+',tostring(report[8])))
, ClamAV = iff(report[9] == 'n/a', '', trim('[ "]+',tostring(report[9])))
, VTPercent = iff(report[10] == 'n/a', 0.0, todouble(report[10]))
, ImpHash = iff(report[11] == 'n/a', '', trim('[ "]+',tostring(report[11])))
, SSDeep = iff(report[12] == 'n/a', '', trim('[ "]+',tostring(report[12])))
, TLSH = iff(report[13] == 'n/a', '', trim('[ "]+',tostring(report[13])))
);
union (
AbuseFeed
| join (
DeviceProcessEvents
| where Timestamp > MaxAge
) on SHA256
), (
AbuseFeed
| join (
DeviceFileEvents
| where Timestamp > MaxAge
) on SHA256
), (
AbuseFeed
| join (
DeviceImageLoadEvents
| where Timestamp > MaxAge
| where isnotempty(SHA256)
) on SHA256
)
id: 2bcdf59a-679d-4585-93e7-f14d674de205
name: Abuse.ch Recent Threat Feed
description: |
This query will hunt for files matching the current abuse.ch recent threat feed based on Sha256. Currently the query is set up to analyze the last day worth of events, but this is configurable using the MaxAge variable.
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceProcessEvents
- DeviceFileEvents
- DeviceImageLoadEvents
tactics:
- Execution
- Persistence
- Privilege escalation
- Credential Access
- Discovery
- Impact
- Exploit
- Malware, component
- Ransomware
query: |
let MaxAge = ago(1d);
let AbuseFeed = materialize (
(externaldata(report:string)
[@"https://bazaar.abuse.ch/export/csv/recent/"]
with (format = "txt"))
| where report !startswith '#'
| extend report = trim("\"", report)
| extend report = parse_csv(report)
| extend FirstSeenUtc = tostring(report[0])
| project FirstSeenUtc = todatetime(FirstSeenUtc)
,SHA256 = trim('[ "]+',tostring(report[1]))
, MD5 = trim('[ "]+',tostring(report[2]))
, SHA1 = trim('[ "]+',tostring(report[3]))
, Reporter = trim('[ "]+',tostring(report[4]))
, FileName = trim('[ "]+',tostring(report[5]))
, FileType = trim('[ "]+',tostring(report[6]))
, MimeType = trim('[ "]+',tostring(report[7]))
, Signer = iff(report[8] == 'n/a', '', trim('[ "]+',tostring(report[8])))
, ClamAV = iff(report[9] == 'n/a', '', trim('[ "]+',tostring(report[9])))
, VTPercent = iff(report[10] == 'n/a', 0.0, todouble(report[10]))
, ImpHash = iff(report[11] == 'n/a', '', trim('[ "]+',tostring(report[11])))
, SSDeep = iff(report[12] == 'n/a', '', trim('[ "]+',tostring(report[12])))
, TLSH = iff(report[13] == 'n/a', '', trim('[ "]+',tostring(report[13])))
);
union (
AbuseFeed
| join (
DeviceProcessEvents
| where Timestamp > MaxAge
) on SHA256
), (
AbuseFeed
| join (
DeviceFileEvents
| where Timestamp > MaxAge
) on SHA256
), (
AbuseFeed
| join (
DeviceImageLoadEvents
| where Timestamp > MaxAge
| where isnotempty(SHA256)
) on SHA256
)
version: 1.0.0
| Sentinel Table | Notes |
|---|---|
DeviceFileEvents | Ensure this data connector is enabled |
DeviceImageLoadEvents | Ensure this data connector is enabled |
DeviceProcessEvents | Ensure this data connector is enabled |
Scenario: Legitimate file integrity monitoring tool using abuse.ch feed
Description: A security tool like OSSEC or Tripwire may use the abuse.ch threat feed as part of its signature database to detect known malicious files.
Filter/Exclusion: Exclude files that are known to be part of the threat feed and are used by legitimate security tools. Use a filter like:
file_hash NOT IN (SELECT hash FROM known_threat_feed_hashes)
Scenario: Scheduled system update or patching job
Description: A Windows Update or Linux package manager (e.g., apt, yum) might download files that match hashes in the abuse.ch feed during a scheduled update.
Filter/Exclusion: Exclude files associated with known update mechanisms. Use a filter like:
process.name IN ('wuauclt.exe', 'update.exe', 'apt', 'yum')
Scenario: Internal malware analysis lab using known malicious samples
Description: A sandboxing tool like Cuckoo Sandbox or Joe Sandbox may use known malicious files from the abuse.ch feed for analysis.
Filter/Exclusion: Exclude files that are flagged as part of a malware analysis lab. Use a filter like:
process.name IN ('cuckoo', 'joe', 'sandbox') OR file_hash IN (SELECT hash FROM lab_hashes)
Scenario: Backup or restore process using known malicious hashes
Description: A backup tool like Veeam or Commvault might include files from the abuse.ch feed during a restore operation if they were previously flagged as malicious.
Filter/Exclusion: Exclude files associated with backup/restore operations. Use a filter like: