When to use / when not to use
- Use: produce an IOC list after analysis is complete (hash/domain/IP/path/mutex); write YARA rules for sample detection; produce an analysis report following the standard structure
- Use: when behavioral evidence needs to be organized into reproducible, shareable conclusions
- Don't use: when behavioral/static analysis has not yet been completed (the raw IOC material is in the [[re-behavior]] / [[re-triage]] outputs)
- Don't use: when the user only wants a one-sentence conclusion (still recommended to at least provide IOCs and evidence paths)
Tool preparation
This skill is mainly static processing (writing rules/scanning files) and does not run samples; running samples is only done within [[re-sandbox]] (the sandbox-first principle by default, see [[re-analyze/platform-tips]]).
yara —— rule engine
- Linux:
apt install yara/dnf install yara/pacman -S yara - macOS:
brew install yara - Windows/WSL:
pip install yara-python(Python version, cross-platform fallback) - Verify:
yara --version;Python:python -c "import yara; print(yara.__version__)"
pefile —— PE structure parsing (for writing PE characteristics)
- All platforms:
pip install pefile - Verify:
python -c "import pefile; print(pefile.__version__)"
VT / grep.app queries (optional)
- VirusTotal: web page https://www.virustotal.com/ to query hash/domain; API key environment variable:
Verify: a request with a key returns JSON (401 means the key is invalid)curl -s --request GET \ --url "https://www.virustotal.com/api/v3/search?query=<sha256>" \ -H "x-apikey: $VT_API_KEY" | python3 -m json.tool - grep.app: web page https://grep.app/ to search for characteristic strings in public code, no installation
- Note: confirm the data policy before uploading private samples to VT; grep.app queries are only for string/characteristic reference
sha256sum / md5sum (IOC hashes)
- Installation and verification see [[re-triage]] Tool preparation (coreutils / Get-FileHash)
Operation steps
Execute in order, record the result of each step.
-
Extract IOCs (categorized by source):
- File level:
sha256sum sample.exe(sha256 primary, md5 supplementary only); unpacked artifacts and dropper-dropped files each count as one - Network level: domains, IPs, ports in behavior logs ([[re-behavior]] step 4) and INetSim records; hardcoded URLs found in config/memory (
strings sample | grep -iE 'http|https') - System level: file paths (persistence locations, drop paths), mutex names (CreateMutex parameters, look up with [[re-ghidra]] / [[re-ida]] or record via procmon)
- Record source evidence for each IOC type (log file path + line number/timestamp) for report citation
- Deduplicate + label confidence (from behavioral evidence > static strings only)
- File level:
-
YARA rule writing (feature selection + scoring):
- Feature selection criteria: uniqueness (only appears in that family/sample), stability (does not change easily with versions), distinguishability (avoid common library strings)
- Common feature types: strings (URL/domain/mutex/machine code), PE structure (section names, imports), byte patterns (
{ 4D 5A 90 00 }or$a = { E8 ?? ?? ?? ?? }wildcards) - Scoring (annotate in comments, hit threshold reference): score each feature by information content —— unique long string +2, common API name +0.5, short byte pattern +1; 1/3 of the total score serves as the hit threshold reference, with verification as the final authority
- Example:
rule Win32_FamilyX_Dropper { meta: description = "FamilyX dropper 检测" author = "analyst" score = 4 strings: $url = "http://c2.example.org" ascii wide $mutex = "Global\\FamilyX_mutex" ascii wide $pe = { 4D 5A 90 00 } condition: uint16(0) == 0x5A4D and (2 of them) } - Rule name naming convention: platform_family_type (e.g.
Win32_FamilyX_Dropper)
-
Report structure(write in five sections):
- Summary: one-sentence conclusion (what the sample is, whether it is judged malicious, main behavior)
- Behavior: process/persistence/file/network behavior of [[re-behavior]] + ATT&CK mapping table
- Evidence: artifact path + sha256 for each step (sample, logs, memory dumps, rule files) — the key to reproducibility
- IOC: categorized list from step 1 + confidence
- Conclusion: remediation recommendations (kill/remove / block domains and IPs / patch recommendations)
- Format determined by [[re-analyze]]'s RE_REPORT preference (brief/full)
-
Rule validation (yara scan of samples):
yara rule.yar sample.exe # 命中 → 规则有效 yara -s rule.yar sample.exe # 显示命中的特征串,与样本实际内容核对 yara rule.yar benign_samples/* # 误报测试: 已知良性样本目录应 0 命中- Positive control: after a hit,
yara -sverify the matched string is indeed a malicious characteristic - Negative control: a directory of benign samples must not be hit; a hit means a false positive, go back to step 2 to adjust the features
- Full-library verification: add the rule to the local rule set, rescan all analyzed samples, and confirm there is no regression
- Positive control: after a hit,
Cross-domain combination
- [[re-malware]]: workflow step 6 — this skill is the wrap-up of malware sample analysis (IOC and report)
- [[re-behavior]]: the IOC raw material from step 1 (network-level/system-level IOC) comes from behavior analysis artifacts
- [[re-protocol]]: C2 domains/IPs/protocol fingerprints go into the IOC list and YARA features
- [[re-anti-analysis]]: unpacking artifacts, packer fingerprints, and packing behavior can also serve as YARA feature sources
- Reports and rules are passed back to [[re-analyze]] (per RE_REPORT) and shared with the team
Common pitfalls and traps
- Features chosen too broadly → false positives: symptom — the rule hits a large number of unrelated files (e.g., only wrote a
http://or a common library string); cause — the feature is not unique, with no scoring and validation step; countermeasure — in step 2 select features by uniqueness and score them, and in step 4 you must do a benign-sample negative control; on a false positive, go back and revise - Writing only hashes and no behavioral features: symptom — hash IOCs all become ineffective against new samples/variants; cause — a hash covers only a single sample and cannot generalize to the family; countermeasure — besides hashes, provide at least YARA rules or behavioral features (mutexes/domains/byte patterns), and use rule conditions with
2 of theminstead of a single feature - Report lacks evidence paths and is not reproducible: symptom — the report's conclusions cannot be traced (no log/sample paths and hashes); cause — evidence was not archived or not written into the report; countermeasure — the evidence section of the step 3 report must give path + sha256 item by item, with IOCs and behaviors corresponding to their sources one by one
- Poor atom quality in feature strings → slow scans and false positives: symptom — after the rule is written, full-library scans are extremely slow or hit a large number of unrelated files; cause — YARA uses 4-byte substrings for Aho-Corasick prefiltering, and single-byte patterns or patterns starting with 0x00/0xFF/0x90 force a massive number of verifications; countermeasure — use
yr debug atoms(YARA-X) to check atoms, anchor regexes to literals (/mshta\.exe http:\/\/.../instead of/http:/), order conditions from cheap to expensive (filesize → magic → strings), "if you can use uint32, don't load a module" - Single-sample rules are fragile: symptom — the rule only hits the current sample, and all variants of the same family are missed; cause — writing rules based on a single sample and writing features against the encryption layer (pre-unpacking content); countermeasure — collect 3+ variants before writing; for packed samples with entropy >7, unpack first, or write rules against the packer's structural features (section names, opaque predicates) rather than the encryption layer; use yarGen for candidate strings
--excludegood/ FLOSS generated, for regression use YARA-CI / VT retrohunt - Incomplete metadata is unmaintainable: Symptom—after a rule enters the enterprise rule repository, it cannot be audited (unknown author, what it looks for, what it references, which hash); Cause—missing author/date/reference/hash metadata and naming conventions; Countermeasure—the meta section must include description (starting with "Detects"), author, date, reference, hash; for naming use
MAL_/HKTL_/SUSP_and other prefixes + platform/family/variant/date (e.g.MAL_Win_Emotet_Loader_Jan25) for allloop not bound to filesize → scanning large files explodes: Symptom—the rule is very fast on small samples, but hangs/times out when scanning files of tens of MB; Cause—thefor all i in (1..#a)loop's iteration limit is bound to the number of feature hits, and on large files#acan reach thousands; writing it asfor all i in (1..filesize)makes the iteration scale directly with file size; Countermeasure—always add a filesize bound to loop conditions first (filesize < 100KB and for all i in (1..#a): ...), then add the feature conditions- Uniform repeated strings → scan directly reports "too many matches": Symptom—
yarascan reportsstring ... caused too many matcheserror, and the rule cannot run; Cause—the feature string is long repeated/uniform content (e.g."2222...", wide-character space padding), and the number of hits during the prefiltering stage explodes, triggering YARA's protection limit; Countermeasure—avoid using content made of stacked repeated characters as a feature, and instead use hex patterns with wildcards or strings containing multiple variable bytes to ensure atoms are distinguishable (check together with the existing atom pitfalls)