When to use / when not to use
- Use: when you have a sample hash / domain / IP and want to look up known malicious background ("what is this sample" "which family"); sandbox report interpretation; family/group correlation; MISP event correlation; intelligence into reports
- Use: after analysis is complete, use intelligence to validate conclusions (clues from [[re-malware]] / [[re-forensics]] need external corroboration)
- Don't use: if you only want to run behavioral analysis—that goes to [[re-sandbox]] / [[re-behavior]]; sandbox lookup is only one intelligence method
- Don't use: pure offline environment with no external network (can only do static local matching); no VT results ≠ clean (see pitfall 1)
Tool preparation
This skill is mainly for lookup/interpretation and does not run samples; dynamic execution uploaded to a sandbox must be within [[re-sandbox]] (default highest sandbox principle, see [[re-analyze/platform-tips]]).
VirusTotal (core lookup, web + API)
- Web: https://www.virustotal.com/ — look up hash/domain/IP, no installation
- API key: https://www.virustotal.com/gui/my-apikey generated; store in environment variable
VT_API_KEY(export VT_API_KEY=..., on Windows usesetx) - Verify:
[ -n "$VT_API_KEY" ] && echo ok; requests with key return JSON (401/403 means key invalid or quota exhausted) - Privacy note: before looking up private samples, confirm the data policy—VT is shared intelligence, uploading will disclose to third parties; for internal samples ask about ownership/permissions first (see pitfall 2)
curl — API requests
- Linux:
apt install curl/dnf install curl/pacman -S curl(mostly built in) - macOS: built in
- Windows/WSL: Windows 10+ has curl.exe built in; WSL uses Linux package
- Verify:
curl --version
Any.run / hybrid-analysis (sandbox reports, web)
- Any.run: https://any.run/ register to look up/submit (web interactive sandbox, has public report library)
- hybrid-analysis: https://www.hybrid-analysis.com/ register to look up/submit (API free quota)
- No installation; before uploading samples also confirm the data public policy
MISP (optional, team self-hosted intelligence library)
- Deploy (Linux):
docker run -d --name misp -p 8080:80 harvarditsecurity/misp(community image; for formal deployment follow official docs) - Verify: open in browser https://localhost:8080 and log in (default account admin@admin.test / admin)
- If there is no existing MISP instance, skip this part and do not block lookup
jq (optional, parse API JSON)
- Linux:
apt install jq/dnf install jq/pacman -S jq - macOS:
brew install jq - Windows:
winget install jqlang.jq - Verify:
jq --version
Operation steps
Execute in order; run steps 1-3 for each clue (hash/domain/IP), record results and lookup time (evidence).
-
Hash/domain/IP lookup (VT):
curl -s --request GET \ --url "https://www.virustotal.com/api/v3/search?query=<sha256_or_domain_or_ip>" \ -H "x-apikey: $VT_API_KEY" | jq '.data[0].attributes | {last_analysis_stats, names, tags, popular_threat_category}'- The web can also look it up: on the hash page see detection count (
last_analysis_statsmalicious count), vendor hits, tags, popular_threat_category - On the domain/IP page see resolution records, historical detections, associated samples; no detections found does not directly mean clean (see pitfall 1)
- Privacy option: to upload/look up private objects use VT's private API (enterprise edition) or first confirm the data public risk (see pitfall 2)
- The web can also look it up: on the hash page see detection count (
-
Sandbox report interpretation (Any.run / hybrid-analysis):
- Lookup: search the same hash in Any.run/hybrid-analysis, find public reports; submitting a new sample for execution must be within an isolated [[re-sandbox]] environment (network isolation INetSim/fake DNS, see [[re-analyze/platform-tips]] highest principle)
- hybrid-analysis API (the key is generated on the API key page of the personal profile, request header
api-key):curl -s -H "api-key: $HA_API_KEY" \ "https://hybrid-analysis.com/api/v2/search/hash?hash=<sha256>" | jq '{sha256s, verdicts: [.reports[].verdict]}' - Any.run has an API (api.any.run, the key is generated in the profile), for endpoints and authentication refer to the official documentation; when no key is configured, web-based queries are equally usable
- Interpret three parts:
- Behavior: the process tree that was started (whether there is injection/hollowing), persistence actions (Run keys/scheduled tasks/services), file operations (where written, where deleted)
- Network: callback domains/IPs/ports, DNS resolution, request URLs (compare with the capture in [[re-behavior]])
- File operations: files dropped and hashes (artifacts written to disk by the dropper, go into [[re-ioc]])
- Record the report number and screenshot timestamp as evidence; reports cannot be fully trusted (see Pitfall 3)
-
Family/group association (VT graph, tag):
curl -s --request GET \ --url "https://www.virustotal.com/api/v3/files/<sha256>/graphs" \ -H "x-apikey: $VT_API_KEY" | jq '.data[].type' | sort -u- Endpoint note: the association graph endpoint is
/graphs(plural) —/graphis the path from the API v2 era, and v3 returns 404 - Associations on the VT hash page: other samples hit by the same C2 domain/same signature/same mutex,
popular_threat_category(such as "trojan.agent") and the family tag - tags and graph assign the sample to a family — when writing the report, note the basis (which vendors assigned it, what attributes the association relies on)
- For family names, prefer agreement across multiple vendors; single-vendor naming is only for reference
- Endpoint note: the association graph endpoint is
-
MISP event association (if an instance is available):
# 查询事件的属性(hash/域名/IP)——POST + JSON body curl -s --request POST "https://<misp>/events/restSearch" \ -H "Authorization: <MISP_API_KEY>" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ --data-binary '{"returnFormat":"json","value":"<sha256>"}' | jq '.response[]?.Event | {info, date, orgc}'- body must be raw JSON (
--data-urlencodewill URL-encode it, and MISP cannot parse the value);valuepass a string - The response looks like
{"response": [{"Event": {...}}]}— jq uses.response[]?.Eventto expand; response structures differ across MISP versions (see [[gotchas]]) - A hit indicates the organization has already flagged that sample/infrastructure — cite the event ID as internal evidence
- If there is no instance, skip it; this step does not block the conclusion
- body must be raw JSON (
-
Intelligence goes into the report (connects with [[re-ioc]]):
- Summary: one line per lead — type (hash/domain/IP), VT detection count, family/classification, associated samples, source (report number/event ID), query time
- Intelligence goes directly into the [[re-ioc]] report: IOC list (externally confirmed malicious indicators + confidence), the basis for the family determination in the summary section, and external intelligence supporting evidence in the conclusion section
- Writing only conclusions without sources is as good as not investigating (evidence chain requirement, see Pitfall 4)
Cross-domain joint
- [[re-forensics]]: step 4 of this gateway workflow — this skill is the intelligence correlation step
- [[re-malware]]: use this skill before step 6 of malicious sample analysis to corroborate the family/determination; static intelligence for anti-sandbox samples especially depends on this skill
- [[re-behavior]]: the baseline for interpreting the sandbox report in step 2 comes from behavior analysis artifacts (process/network/file comparison)
- [[re-ioc]]: the intelligence summary from step 5 goes into the IOC list and the report (connects)
- [[re-sandbox]]: this skill's dynamic execution must be within it (default sandbox highest principle, see [[re-analyze/platform-tips]])
- Return to [[re-analyze]]: write the intelligence summary into the final report according to the RE_REPORT preference
Common pitfalls and traps
- No VT result for a private sample ≠ clean: Phenomenon—querying a certain hash returns a detection count of 0 or a "not found" error, and based on that it is judged harmless; Cause—VT only has the public repository, so private/unpublished samples not being found is the norm (it may also be that new samples have not yet been included); Countermeasure—for no result, only mark "no record found" and note the query time, use actual behavioral evidence from [[re-behavior]] / [[re-mem-forensics]] to draw conclusions; after cross-checking across multiple channels (Any.run/hybrid-analysis/MISP), then determine the nature
- Uploading private samples leaks intelligence: Phenomenon—after internal samples/customer samples are uploaded to VT/Any.run, they become publicly available, triggering confidentiality issues; Cause—sandboxes and VT share data by default (public reports); Countermeasure—before uploading, confirm the data policy: use VT's private API (enterprise) or desensitize first (remove PII before uploading), choose private analysis for any.run/hybrid-analysis (if available), and if unsure, first ask the owner
- Sandbox reports cannot be fully trusted (anti-sandbox samples): Phenomenon—the sandbox report shows "no malicious behavior/process exited", but in the actual environment a callback is detected; Cause—after the sample detects sandbox characteristics (VM hardware, debugger, network environment), it sleeps/takes the normal branch, and the report is a false negative; Countermeasure—cross-validate with real-environment results from [[re-behavior]] and memory remnants from [[re-mem-forensics]]; anti-sandbox samples rely on deep static analysis ([[re-binary-core]]) and memory clues
- API quota/rate limiting: Phenomenon—VT free key requests return 403/429, or batch queries get rate-limited midway; Cause—free keys have a daily quota and per-minute rate limit, and a batch script without intervals will inevitably trigger it; Countermeasure—sleep inside the script loop (e.g., 15 seconds), use
/searchfor batch aggregation, and when the quota is exhausted switch to web queries or wait for reset; use jq to extract only the needed fields to reduce the number of requests - Hash false positives require multiple confirmations: Phenomenon—a certain vendor marks a benign file as malicious (hash false positive), or the hash matches but the sample content does not match (a renamed/reassembled old hash); Cause—a single vendor's signature granularity is coarse, VT aggregate statistics are not weighted, and the original hash is not strongly bound to and verified against the file content; Countermeasure—for a "malicious" determination, look at multi-vendor consensus + family labels + behavioral evidence, and do not trust a single vendor; before querying, first recompute the local file's sha256 and check it against the query value (to prevent querying the wrong hash)
- For endpoint quick reference and operation sequences, see [[commands]]; for API version and data quality pitfalls, see [[gotchas]]