| name | extracting-iocs-from-malware-samples |
| description | 从恶意软件样本中提取攻陷指标(IoC),包括文件哈希、网络指标(IP、域名、URL)、 主机痕迹(文件路径、注册表键、互斥锁)以及行为模式,用于威胁情报共享和检测规则创建。 适用于 IoC 提取、威胁指标采集、恶意软件指标收集或从样本构建检测内容等请求场景。
|
| domain | cybersecurity |
| subdomain | malware-analysis |
| tags | ["malware","IOC-extraction","threat-intelligence","indicators","detection"] |
| version | 1.0.0 |
| author | mahipal |
| license | Apache-2.0 |
从恶意软件样本中提取 IoC
适用场景
- 恶意软件分析(静态或动态)完成后,需要为防御团队提取可操作的指标
- 从已分析的样本中为防火墙、代理和 DNS 黑洞构建封锁列表
- 从恶意软件痕迹中创建 YARA 规则、Snort/Suricata 签名或 SIEM 检测内容
- 向威胁情报共享平台(MISP、OTX、ThreatConnect)贡献数据
- 通过关联多个样本间的 IoC 来追踪恶意软件活动
不适用于未经验证来源的 IoC——在未经验证的情况下直接使用可能导致封锁列表中的误报,进而干扰合法业务运营。
前置条件
- Python 3.8+,安装
iocextract、pefile、yara-python 库
- 已完成的恶意软件分析报告(静态分析、动态分析或逆向工程)
- 分析所用的 PCAP 文件、内存转储或沙箱报告
- MISP 实例或 STIX/TAXII 服务器,用于结构化 IoC 共享
- VirusTotal API 密钥,用于 IoC 丰富化和验证
- CyberChef,用于解码混淆的指标
工作流程
步骤 1:提取基于文件的 IoC
计算哈希并识别文件元数据指标:
md5sum malware_sample.exe
sha1sum malware_sample.exe
sha256sum malware_sample.exe
ssdeep malware_sample.exe
python3 -c "
import pefile
pe = pefile.PE('malware_sample.exe')
print(f'Imphash: {pe.get_imphash()}')
"
python3 -c "
import tlsh
with open('malware_sample.exe', 'rb') as f:
h = tlsh.hash(f.read())
print(f'TLSH: {h}')
"
python3 << 'PYEOF'
import pefile
import os
import hashlib
import datetime
pe = pefile.PE("malware_sample.exe")
print("FILE IOCs:")
with open("malware_sample.exe", "rb") as f:
data = f.read()
print(f" MD5: {hashlib.md5(data).hexdigest()}")
print(f" SHA-1: {hashlib.sha1(data).hexdigest()}")
print(f" SHA-256: {hashlib.sha256(data).hexdigest()}")
print(f" File Size: {len(data)} bytes")
ts = pe.FILE_HEADER.TimeDateStamp
print(f" Compile: {datetime.datetime.utcfromtimestamp(ts)} UTC")
print(f" Imphash: {pe.get_imphash()}")
PYEOF
步骤 2:提取网络 IoC
从字符串、PCAP 和沙箱报告中提取网络指标:
import re
with open("malware_sample.exe", "rb") as f:
data = f.read()
ascii_strings = re.findall(b'[ -~]{4,}', data)
unicode_strings = re.findall(b'(?:[ -~]\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]
ip_pattern = re.compile(r'\b(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\b')
ips = set()
for s in all_strings:
for ip in ip_pattern.findall(s):
octets = [int(o) for o in ip.split('.')]
if octets[0] not in [10, 127, 0] and not (octets[0] == 172 and 16 <= octets[1] <= 31) and not (octets[0] == 192 octets[] == ):
ips.add(ip)
domain_pattern = re.()
domains = ()
s all_strings:
d domain_pattern.findall(s):
d.endswith((, , , )):
domains.add(d)
url_pattern = re.()
urls = ()
s all_strings:
u url_pattern.findall(s):
urls.add(u)
()
()
()
()
步骤 3:提取基于主机的 IoC
识别文件路径、注册表键、互斥锁和服务:
import json
with open("cuckoo_report.json") as f:
report = json.load(f)
print("HOST IOCs:")
print("\nFile Paths:")
for f in report["behavior"]["summary"].get("files", []):
if any(p in f.lower() for p in ["temp", "appdata", "system32", "programdata"]):
print(f" [DROPPED] {f}")
print("\nRegistry Keys:")
for key in report["behavior"]["summary"].get("write_keys", []):
if any(p in key.lower() for p in ["run", "service", "startup", "shell"]):
print(f" [PERSIST] {key}")
print("\nMutexes:")
for mutex in report["behavior"][].get(, []):
mutex [, ]:
()
()
svc report[][].get(, []):
()
步骤 4:从 PCAP 中提取网络 IoC
解析网络捕获文件以获取更多指标:
tshark -r capture.pcap -T fields -e dns.qry.name -Y "dns.flags.response == 0" | sort -u
tshark -r capture.pcap -T fields -e http.host -e http.request.uri -Y "http.request" | sort -u
tshark -r capture.pcap -T fields -e tls.handshake.extensions_server_name -Y "tls.handshake.type == 1" | sort -u
tshark -r capture.pcap -T fields -e tls.handshake.ja3 -Y "tls.handshake.type == 1" | sort -u
tshark -r capture.pcap -T fields -e ip.dst -Y "ip.src == 10.0.2.15" | sort -u
tshark -r capture.pcap -T fields -e http.user_agent -Y "http.user_agent" | sort -u
步骤 5:去活化并验证 IoC
对指标进行去活化处理以安全共享,并与威胁情报进行验证:
def defang_ip(ip):
return ip.replace(".", "[.]")
def defang_url(url):
return url.replace("http", "hxxp").replace(".", "[.]")
def defang_domain(domain):
return domain.replace(".", "[.]")
import requests
VT_API_KEY = "your_api_key"
def check_vt_ip(ip):
resp = requests.get(f"https://www.virustotal.com/api/v3/ip_addresses/{ip}",
headers={"x-apikey": VT_API_KEY})
data = resp.json()
stats = data["data"]["attributes"]["last_analysis_stats"]
return stats["malicious"]
def check_vt_domain(domain):
resp = requests.get(f"https://www.virustotal.com/api/v3/domains/{domain}",
headers={"x-apikey": VT_API_KEY})
data = resp.json()
stats = data["data"]["attributes"]["last_analysis_stats"]
return stats["malicious"]
for ip ips:
detections = check_vt_ip(ip)
()
步骤 6:以标准格式导出 IoC
生成结构化 IoC 输出以用于共享和摄取:
from stix2 import Indicator, Bundle, Malware, Relationship
import datetime
indicators = []
indicators.append(Indicator(
name="Malware SHA-256 Hash",
pattern=f"[file:hashes.'SHA-256' = '{sha256_hash}']",
pattern_type="stix",
valid_from=datetime.datetime.now(datetime.timezone.utc),
labels=["malicious-activity"]
))
for ip in ips:
indicators.append(Indicator(
name=f"C2 IP Address {ip}",
pattern=f"[ipv4-addr:value = '{ip}']",
pattern_type="stix",
valid_from=datetime.datetime.now(datetime.timezone.utc),
labels=["malicious-activity"]
))
for domain in domains:
indicators.append(Indicator(
name=f"C2 Domain {domain}",
pattern=f"[domain-name:value = '{domain}']",
pattern_type="stix",
valid_from=datetime.datetime.now(datetime.timezone.utc),
labels=["malicious-activity"]
))
bundle = Bundle(objects=indicators)
with open("iocs_stix.json", "w") as f:
f.write(bundle.serialize(pretty=True))
import csv
with open("iocs.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow([, , , ])
writer.writerow([, sha256_hash, , ])
ip ips:
writer.writerow([, ip, , ])
domain domains:
writer.writerow([, domain, , ])
url urls:
writer.writerow([, url, , ])
核心概念
| 术语 | 定义 |
|---|
| IoC(攻陷指标) | 在网络或系统中观察到的取证痕迹,表明潜在入侵:哈希、IP、域名、文件路径、注册表键 |
| 去活化(Defanging) | 修改 IoC 以防止意外触发(如在报告中将 URL 和 IP 的点号替换为 [.] 以安全共享) |
| Imphash | PE 文件导入表函数的 MD5 哈希;同一恶意软件家族的样本通常共享相同的 imphash |
| STIX/TAXII | 结构化威胁信息表达 / 可信自动化交换;用于编码和传输威胁情报的标准 |
| JA3/JA3S | 基于 ClientHello/ServerHello 参数的 TLS 客户端/服务器指纹;通过 TLS 实现方式识别特定恶意软件家族 |
| 模糊哈希(ssdeep) | 上下文触发的分段哈希算法,即使文件有细微修改也能识别相似文件;适用于检测恶意软件变种 |
| MISP | 恶意软件信息共享平台;用于收集、存储和共享 IoC 的开源威胁情报平台 |
工具与系统
- iocextract(Python):自动化 IoC 提取库,支持从文本中提取 IP、URL、域名、哈希和 YARA 规则
- MISP:开源威胁情报共享平台,用于结构化 IoC 管理和分发
- CyberChef:基于 Web 的工具,用于解码、解密和转换数据,适合解混淆编码的 IoC
- tshark:命令行网络协议分析器,用于从 PCAP 文件中提取网络 IoC
- VirusTotal:在线服务,用于通过社区检测结果和威胁情报验证和丰富化 IoC
常见场景
场景:从勒索软件样本构建完整的 IoC 包
背景:一起勒索软件事件需要快速提取 IoC 以在全企业范围内封锁,同时完整调查仍在继续。有多个数据源可用:样本二进制文件、网络监控的 PCAP 文件和 Cuckoo 沙箱报告。
方法:
- 计算勒索软件二进制文件及任何投放文件的所有哈希(MD5、SHA-1、SHA-256、imphash、ssdeep)
- 从二进制文件字符串中提取网络 IoC(硬编码的 C2 地址)
- 解析 PCAP 中的 DNS 查询、HTTP 请求和 TLS SNI 字段
- 从沙箱报告中提取主机 IoC(文件路径、注册表键、互斥锁、勒索信文件名)
- 通过 VirusTotal 验证所有网络 IoC 以确认恶意状态并检查已知关联
- 对所有指标进行去活化处理,并整理为 STIX 2.1 格式用于共享,以及 CSV 格式用于 SIEM 摄取
- 提交到 MISP 事件以供组织内和社区共享
注意事项:
- 不要在未验证上下文的情况下包含合法 CDN 或云服务 IP(如用于托管而非本质恶意的 AWS IP)
- 报告中不要忘记对 URL 和 IP 进行去活化,以避免意外点击或 DNS 解析
- 不要从加壳二进制文件中直接提取字符串(加壳样本的 IoC 不可靠;应先解包)
- 不要忘记包含投放文件的哈希(初始投放器和最终载荷是独立的 IoC)
输出格式
IoC 提取报告
======================
样本: ransomware.exe
分析日期: 2025-09-15
分析人员: [姓名]
文件指标
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
SHA-1: da39a3ee5e6b4b0d3255bfef95601890afd80709
MD5: d41d8cd98f00b204e9800998ecf8427e
Imphash: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
ssdeep: 3072:kJh3bN7fY+aUkJh3bN7fY+aU:kJh3R7aUkJh3R7aU
网络指标
C2 IP: 185.220.101[.]42, 91.215.85[.]17
C2 域名: update.malicious[.]com, backup.evil[.]net
C2 URL: hxxps://update.malicious[.]com/gate.php
hxxps://backup.evil[.]net/gate.php
JA3 哈希: a0e9f5d64349fb13191bc781f81f42e1
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0)
主机指标
文件路径: C:\Users\Public\svchost.exe
C:\Users\%USER%\AppData\Local\Temp\payload.dll
C:\Users\%USER%\Desktop\README_DECRYPT.txt
注册表键: HKCU\Software\Microsoft\Windows\CurrentVersion\Run\WindowsUpdate
互斥锁: Global\CryptLocker_2025_Q3
服务: FakeWindowsUpdate
置信度评估
高置信度: SHA-256、C2 IP(VT 已验证)、互斥锁
中置信度: 域名(可能是被攻陷的合法站点)
低置信度: User-Agent(常见字符串,误报风险高)
导出文件
stix_bundle.json - STIX 2.1 格式,供 TIP 摄取
iocs.csv - CSV 格式,供 SIEM 封锁列表导入
yara_rule.yar - YARA 检测规则