# Extracting Iocs From Malware Samples

> 从恶意软件样本中提取攻陷指标（IoC），包括文件哈希、网络指标（IP、域名、URL）、 主机痕迹（文件路径、注册表键、互斥锁）以及行为模式，用于威胁情报共享和检测规则创建。 适用于 IoC 提取、威胁指标采集、恶意软件指标收集或从样本构建检测内容等请求场景。

- Skill: `killvxk/extracting-iocs-from-malware-samples` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add killvxk/extracting-iocs-from-malware-samples`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/extracting-iocs-from-malware-samples/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/extracting-iocs-from-malware-samples

---


# 从恶意软件样本中提取 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

计算哈希并识别文件元数据指标：

```bash
# 生成所有标准哈希
md5sum malware_sample.exe
sha1sum malware_sample.exe
sha256sum malware_sample.exe

# 生成用于相似性匹配的 ssdeep 模糊哈希
ssdeep malware_sample.exe

# 生成 PE 文件的 imphash（导入哈希）
python3 -c "
import pefile
pe = pefile.PE('malware_sample.exe')
print(f'Imphash: {pe.get_imphash()}')
"

# 生成 TLSH（趋势微局部敏感哈希）
python3 -c "
import tlsh
with open('malware_sample.exe', 'rb') as f:
    h = tlsh.hash(f.read())
print(f'TLSH: {h}')
"

# 整理文件元数据 IoC
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 和沙箱报告中提取网络指标：

```python
# 从字符串中提取网络 IoC
import re

with open("malware_sample.exe", "rb") as f:
    data = f.read()

# 提取 ASCII 和 Unicode 字符串
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 地址（排除私有地址段，用于 C2 指标）
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 and octets[1] == 168):
            ips.add(ip)

# 域名
domain_pattern = re.compile(r'\b[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z]{2,})+\b')
domains = set()
for s in all_strings:
    for d in domain_pattern.findall(s):
        if not d.endswith(('.dll', '.exe', '.sys', '.com.au')):
            domains.add(d)

# URL
url_pattern = re.compile(r'https?://[^\s<>"{}|\\^`\[\]]+')
urls = set()
for s in all_strings:
    for u in url_pattern.findall(s):
        urls.add(u)

print("NETWORK IOCs:")
print(f"  IPs:     {ips}")
print(f"  Domains: {domains}")
print(f"  URLs:    {urls}")
```

### 步骤 3：提取基于主机的 IoC

识别文件路径、注册表键、互斥锁和服务：

```python
# 从沙箱报告中提取基于主机的 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"]["summary"].get("mutexes", []):
    if mutex not in ["Local\\!IETld!Mutex", "RasPbFile"]:  # 过滤已知 Windows 互斥锁
        print(f"  [MUTEX] {mutex}")

# 创建的服务
print("\nServices:")
for svc in report["behavior"]["summary"].get("started_services", []):
    print(f"  [SERVICE] {svc}")
```

### 步骤 4：从 PCAP 中提取网络 IoC

解析网络捕获文件以获取更多指标：

```bash
# 从 PCAP 中提取 DNS 查询
tshark -r capture.pcap -T fields -e dns.qry.name -Y "dns.flags.response == 0" | sort -u

# 提取 HTTP 主机和 URL
tshark -r capture.pcap -T fields -e http.host -e http.request.uri -Y "http.request" | sort -u

# 提取 TLS 服务器名称（SNI）
tshark -r capture.pcap -T fields -e tls.handshake.extensions_server_name -Y "tls.handshake.type == 1" | sort -u

# 提取 JA3 哈希
tshark -r capture.pcap -T fields -e tls.handshake.ja3 -Y "tls.handshake.type == 1" | sort -u

# 提取唯一目标 IP
tshark -r capture.pcap -T fields -e ip.dst -Y "ip.src == 10.0.2.15" | sort -u

# 提取 User-Agent 字符串
tshark -r capture.pcap -T fields -e http.user_agent -Y "http.user_agent" | sort -u
```

### 步骤 5：去活化并验证 IoC

对指标进行去活化处理以安全共享，并与威胁情报进行验证：

```python
# 对 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(".", "[.]")

# 通过 VirusTotal 验证 IoC
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"]

# 验证每个 IoC
for ip in ips:
    detections = check_vt_ip(ip)
    print(f"  {defang_ip(ip)} - VT: {detections} 次检测")
```

### 步骤 6：以标准格式导出 IoC

生成结构化 IoC 输出以用于共享和摄取：

```python
# 导出为 STIX 2.1 包
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"]
))

# IP 指标
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))

# 导出为 CSV 供 SIEM 摄取
import csv
with open("iocs.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["type", "value", "context", "confidence"])
    writer.writerow(["sha256", sha256_hash, "malware_sample", "high"])
    for ip in ips:
        writer.writerow(["ipv4", ip, "c2_server", "high"])
    for domain in domains:
        writer.writerow(["domain", domain, "c2_domain", "high"])
    for url in urls:
        writer.writerow(["url", url, "c2_url", "high"])
```

## 核心概念

| 术语 | 定义 |
|------|------|
| **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 沙箱报告。

**方法**：
1. 计算勒索软件二进制文件及任何投放文件的所有哈希（MD5、SHA-1、SHA-256、imphash、ssdeep）
2. 从二进制文件字符串中提取网络 IoC（硬编码的 C2 地址）
3. 解析 PCAP 中的 DNS 查询、HTTP 请求和 TLS SNI 字段
4. 从沙箱报告中提取主机 IoC（文件路径、注册表键、互斥锁、勒索信文件名）
5. 通过 VirusTotal 验证所有网络 IoC 以确认恶意状态并检查已知关联
6. 对所有指标进行去活化处理，并整理为 STIX 2.1 格式用于共享，以及 CSV 格式用于 SIEM 摄取
7. 提交到 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 检测规则
```

