| name | performing-malware-hash-enrichment-with-virustotal |
| description | Enrich malware file hashes (MD5, SHA-1, SHA-256) using the VirusTotal API v3 to retrieve multi-engine detection rates, sandbox behavioral analysis, YARA rule matches, related indicators, and community threat intelligence. Use during SOC triage, incident response, or threat intelligence workflows to validate whether a file hash is malicious and gather context for IOC enrichment. |
| domain | cybersecurity |
| subdomain | threat-intelligence |
| tags | ["virustotal","malware-analysis","hash-enrichment","ioc","threat-intelligence","triage","api","detection"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
| nist_csf | ["ID.RA-01","ID.RA-05","DE.CM-01","DE.AE-02"] |
| mitre_attack | ["T1591","T1592","T1593","T1589","T1027"] |
Performing Malware Hash Enrichment with VirusTotal
Overview
VirusTotal is the world's largest crowdsourced malware corpus, scanning files with 70+ antivirus engines and providing behavioral analysis, YARA rule matches, network indicators, and community intelligence. This skill covers using the VirusTotal API v3 to enrich file hashes (MD5, SHA-1, SHA-256) with detection verdicts, sandbox reports, related indicators, and contextual intelligence for SOC triage, incident response, and threat intelligence enrichment workflows.
When to Use
- When conducting security assessments that involve performing malware hash enrichment with virustotal
- When following incident response procedures for related security events
- When performing scheduled security testing or auditing activities
- When validating security controls through hands-on testing
Prerequisites
- Python 3.9+ with
vt-py (official VirusTotal Python client) or requests
- VirusTotal API key (free tier: 4 requests/minute, 500/day; premium for higher limits)
- Understanding of file hash types: MD5, SHA-1, SHA-256
- Familiarity with AV detection naming conventions
- STIX 2.1 knowledge for IOC representation
Key Concepts
VirusTotal API v3
The API provides RESTful endpoints for file reports (/files/{hash}), URL scanning, domain reports, IP address intelligence, and advanced hunting with VirusTotal Intelligence (VTI). Each file report includes detection results from 70+ AV engines, behavioral analysis from sandboxes, YARA rule matches, sigma rule matches, file metadata (PE headers, imports, sections), network indicators (contacted IPs, domains, URLs), and community votes and comments.
Hash Enrichment Workflow
The typical enrichment flow is: receive hash from alert/EDR -> query VT API -> parse detection ratio -> extract behavioral indicators -> correlate with existing intelligence -> make triage decision. The API returns a last_analysis_stats object with malicious, suspicious, undetected, and harmless counts.
Pivoting from Hashes
VirusTotal enables pivoting from a single hash to related intelligence: similar files (ITW/in-the-wild samples), contacted domains and IPs (C2 infrastructure), dropped files, embedded URLs, YARA rule matches, and threat actor attribution through crowdsourced intelligence.
Workflow
Step 1: Query VirusTotal for Hash Report
import vt
json
hashlib
datetime datetime
:
():
.client = vt.Client(api_key)
():
:
file_obj = .client.get_object()
stats = file_obj.last_analysis_stats
report = {
: file_hash,
: file_obj.sha256,
: file_obj.sha1,
: file_obj.md5,
: (file_obj, , ),
: (file_obj, , ),
: ((file_obj, , )),
: ((file_obj, , )),
: {
: stats.get(, ),
: stats.get(, ),
: stats.get(, ),
: stats.get(, ),
},
: ,
: (file_obj, , {}),
: (file_obj, , []),
: (file_obj, , []),
}
total_engines = (stats.values())
mal_count = stats.get(, )
report[] = (
mal_count > total_engines *
mal_count > total_engines *
mal_count > total_engines *
mal_count >
)
(
)
report
vt.error.APIError e:
()
():
:
behaviors = .client.get_object()
behavior_data = {
: [],
: [],
: [],
: [],
: [],
: [],
: [],
}
sandbox (behaviors, , []):
attrs = sandbox.get(, {})
behavior_data[].extend(
attrs.get(, []))
behavior_data[].extend(
[f.get(, ) f attrs.get(, [])])
behavior_data[].extend(
[r.get(, ) r attrs.get(, [])])
behavior_data[].extend(
[d.get(, ) d attrs.get(, [])])
behavior_data[].extend(
attrs.get(, []))
behavior_data
Exception e:
()
{}
():
.client.close()
enricher = VTEnricher()
report = enricher.enrich_hash()
(json.dumps(report, indent=, default=))
enricher.close()