Malware IOC extraction is the process of analyzing malicious software to identify actionable indicators of compromise including file hashes, network indicators (C2 domains, IP addresses, URLs), regist
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Malware IOC extraction is the process of analyzing malicious software to identify actionable indicators of compromise including file hashes, network indicators (C2 domains, IP addresses, URLs), regist
Malware IOC extraction is the process of analyzing malicious software to identify actionable indicators of compromise including file hashes, network indicators (C2 domains, IP addresses, URLs), registry modifications, mutex names, embedded strings, and behavioral artifacts. This skill covers static analysis with PE parsing and string extraction, dynamic analysis with sandbox detonation, automated IOC extraction using tools like YARA, and formatting results as STIX 2.1 indicators for sharing.
When to Use
When conducting security assessments that involve performing malware ioc extraction
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 pefile, yara-python, oletools, stix2 libraries
Access to malware analysis sandbox (Cuckoo, CAPE, Any.Run, Joe Sandbox)
VirusTotal API key for enrichment
Isolated analysis environment (VM or container)
Understanding of PE file format, common packing techniques
Familiarity with YARA rule syntax
Key Concepts
Static Analysis IOCs
File Hashes: MD5, SHA-1, SHA-256 of the sample and any dropped files
Import Hash (imphash): Hash of imported function table, groups malware families
Rich Header Hash: PE rich header hash for compiler fingerprinting
PE Metadata: Compilation timestamp, section names, resources, digital signatures
Embedded Artifacts: PDB paths, version info, certificate details
Dynamic Analysis IOCs
Network Activity: DNS queries, HTTP requests, TCP/UDP connections, SSL certificates
File System: Created/modified/deleted files and directories
Registry: Created/modified registry keys and values
Process: Spawned processes, injected processes, service creation
Behavioral: API calls, mutex creation, scheduled tasks, persistence mechanisms
YARA Rules
YARA is a pattern-matching tool for identifying and classifying malware. Rules consist of strings (text, hex, regex) and conditions that define matching logic. Rules can detect malware families, packers, exploit kits, and specific campaign tools.
Workflow
Step 1: Static Analysis - PE Parsing and Hash Generation
import pefile
import hashlib
import os
defanalyze_pe(filepath):
"""Extract IOCs from a PE file through static analysis."""
iocs = {"hashes": {}, "pe_info": {}, "strings": [], "imports": []}
# Calculate file hasheswithopen(filepath, "rb") as f:
data = f.read()
iocs["hashes"]["md5"] = hashlib.md5(data).hexdigest()
iocs["hashes"]["sha1"] = hashlib.sha1(data).hexdigest()
iocs["hashes"]["sha256"] = hashlib.sha256(data).hexdigest()
iocs["hashes"]["file_size"] = len(data)
# Parse PE headerstry:
pe = pefile.PE(filepath)
iocs["hashes"]["imphash"] = pe.get_imphash()
iocs["pe_info"]["compilation_time"] = str(pe.FILE_HEADER.TimeDateStamp)
iocs["pe_info"]["machine_type"] = hex(pe.FILE_HEADER.Machine)
iocs["pe_info"]["subsystem"] = pe.OPTIONAL_HEADER.Subsystem
# Extract sections
iocs["pe_info"]["sections"] = []
for section in pe.sections:
iocs["pe_info"]["sections"].append({
"name": section.Name.decode("utf-8", errors="ignore").strip("\x00"),
"virtual_size": section.Misc_VirtualSize,
"raw_size": section.SizeOfRawData,
"entropy": section.get_entropy(),
"md5": section.get_hash_md5(),
})
# Extract importsifhasattr(pe, "DIRECTORY_ENTRY_IMPORT"):
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll_name = entry.dll.decode("utf-8", errors="ignore")
functions = [
imp.name.decode("utf-8", errors="ignore")
for imp in entry.imports
if imp.name
]
iocs["imports"].append({"dll": dll_name, "functions": functions})
# Check for suspicious characteristics
iocs["pe_info"]["is_dll"] = pe.is_dll()
iocs["pe_info"]["is_driver"] = pe.is_driver()
iocs["pe_info"]["is_exe"] = pe.is_exe()
# Version infoifhasattr(pe, "VS_VERSIONINFO"):
for entry in pe.FileInfo:
for st in entry:
for item in st.entries.items():
key = item[0].decode("utf-8", errors="ignore")
val = item[1].decode("utf-8", errors="ignore")
iocs["pe_info"][f"version_{key}"] = val
pe.close()
except pefile.PEFormatError as e:
iocs["pe_info"]["error"] = str(e)
return iocs
Step 2: String Extraction and IOC Pattern Matching
import re
defextract_ioc_strings(filepath):
"""Extract IOC-relevant strings from binary file."""
patterns = {
"ipv4": re.compile(
r"\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}"r"(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b"
),
"domain": re.compile(
r"\b(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+"r"(?:com|net|org|io|ru|cn|tk|xyz|top|info|biz|cc|ws|pw)\b"
),
"url": re.compile(
r"https?://[^\s\"'<>]{5,200}"
),
"email": re.compile(
r"\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b"
),
"registry": re.compile(
r"(?:HKEY_[A-Z_]+|HKLM|HKCU|HKU|HKCR|HKCC)"r"\\[\\a-zA-Z0-9_ .{}-]+"
),
"filepath_windows": re.compile(
r"[A-Z]:\\(?:[^\\/:*?\"<>|\r\n]+\\)*[^\\/:*?\"<>|\r\n]+"
),
"mutex": re.compile(
r"(?:Global\\|Local\\)[a-zA-Z0-9_\-{}.]{4,}"
),
"useragent": re.compile(
r"Mozilla/[45]\.0[^\"']{10,200}"
),
"bitcoin": re.compile(
r"\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b"
),
"pdb_path": re.compile(
r"[A-Z]:\\[^\"]{5,200}\.pdb"
),
}
withopen(filepath, "rb") as f:
data = f.read()
# Extract ASCII strings (min length 4)
ascii_strings = re.findall(rb"[\x20-\x7e]{4,}", data)
# Extract Unicode strings
unicode_strings = re.findall(
rb"(?:[\x20-\x7e]\x00){4,}", data
)
all_strings = [s.decode("ascii", errors="ignore") for s in ascii_strings]
all_strings += [
s.decode("utf-16-le", errors="ignore") for s in unicode_strings
]
extracted = {category: set() for category in patterns}
for string in all_strings:
for category, pattern in patterns.items():
matches = pattern.findall(string)
formatchin matches:
extracted[category].add(match)
# Convert sets to sorted listsreturn {k: sorted(v) for k, v in extracted.items() if v}