mcpField
E
extracting-iocs-from-malware-samples

extracting-iocs-from-malware-samples

github.com/mukul975セキュリティ35.2k70 回インストール8 週間前に更新
リポジトリ

extracting-iocs-from-malware-samples について

マルウェアサンプル、PCAP、サンドボックスレポートから侵害指標を抽出、検証、無害化し、整理する分析スキルです。検知コンテンツの作成や構造化された脅威インテリジェンスの共有に携わるセキュリティチーム向けです。

主な機能

  1. 01ファイル・ネットワーク・ホスト指標の抽出
  2. 02PCAPネットワークデータの解析
  3. 03指標の無害化と検証
  4. 04構造化STIX指標の出力
  5. 05サンプル間の指標の関連付け

活用シーン

  1. 01分析サンプルからブロックリストを作成
  2. 02YARAまたはネットワーク検知ルールの作成
  3. 03SIEM取り込み用の指標を準備
  4. 04MISPを通じた脅威インテリジェンス共有

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill extracting-iocs-from-malware-samples

インストール後、Claude Code で/extracting-iocs-from-malware-samplesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
scripts/
agent.py

詳細

マルウェアサンプルからの IOC 抽出

使用する場面

  • マルウェアの分析(静的または動的)が完了し、防御チーム向けに実用的なインジケーターを抽出する必要がある場合
  • 分析済みサンプルからファイアウォール、プロキシ、DNS シンクホール用のブロックリストを作成する場合
  • マルウェアのアーティファクトから YARA ルール、Snort/Suricata シグネチャ、または SIEM 検知コンテンツを作成する場合
  • 脅威インテリジェンス共有プラットフォーム(MISP、OTX、ThreatConnect)に情報を提供する場合
  • 複数のサンプルにわたって IOC を関連付け、マルウェアキャンペーンを追跡する場合

使用しないでください 検証されていない情報源から得た IOC には、検証を行わずに使用しないでください。ブロックリストの誤検知は、正当な業務に支障をきたす可能性があります。

前提条件

  • iocextract、pefile、yara-python ライブラリをインストールした Python 3.8 以降
  • 完了したマルウェア分析レポート(静的解析、動的解析、またはリバースエンジニアリング)
  • 分析で作成した PCAP ファイル、メモリダンプ、またはサンドボックスレポートへのアクセス
  • 構造化された IOC 共有のための MISP インスタンスまたは STIX/TAXII サーバー
  • IOC のエンリッチメントと検証のための VirusTotal API キー
  • 難読化されたインジケーターをデコードするための CyberChef

ワークフロー

ステップ 1:ファイルベースの IOC を抽出する

ハッシュを計算し、ファイルのメタデータに関するインジケーターを特定します。

# Generate all standard hashes
md5sum malware_sample.exe
sha1sum malware_sample.exe
sha256sum malware_sample.exe

# Generate ssdeep fuzzy hash for similarity matching
ssdeep malware_sample.exe

# Generate imphash (import hash) for PE files
python3 -c "
import pefile
pe = pefile.PE('malware_sample.exe')
print(f'Imphash: {pe.get_imphash()}')
"

# Generate TLSH (Trend Micro Locality Sensitive Hash)
python3 -c "
import tlsh
with open('malware_sample.exe', 'rb') as f:
    h = tlsh.hash(f.read())
print(f'TLSH: {h}')
"

# Compile file metadata IOCs
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、サンドボックスレポートからネットワークインジケーターを取得します。

# Extract network IOCs from strings
import re

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

# Extract ASCII and Unicode strings
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 addresses (excluding private ranges for C2 indicators)
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):
        # Filter out private/reserved ranges
        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 names
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)

# URLs
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 を抽出する

ファイルパス、レジストリキー、ミューテックス、サービスを特定します。

# Extract host-based IOCs from sandbox report
import json

with open("cuckoo_report.json") as f:
    report = json.load(f)

print("HOST IOCs:")

# File paths created or modified
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}")

# Registry keys for persistence
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}")

# Mutexes (unique to malware family)
print("\nMutexes:")
for mutex in report["behavior"]["summary"].get("mutexes", []):
    if mutex not in ["Local\\!IETld!Mutex", "RasPbFile"]:  # Filter known Windows mutexes
        print(f"  [MUTEX] {mutex}")

# Created services
print("\nServices:")
for svc in report["behavior"]["summary"].get("started_services", []):
    print(f"  [SERVICE] {svc}")
ステップ 4:PCAP からネットワーク IOC を抽出する

ネットワークキャプチャを解析し、追加のインジケーターを抽出します。

# Extract DNS queries from PCAP
tshark -r capture.pcap -T fields -e dns.qry.name -Y "dns.flags.response == 0" | sort -u

# Extract HTTP hosts and URLs
tshark -r capture.pcap -T fields -e http.host -e http.request.uri -Y "http.request" | sort -u

# Extract TLS server names (SNI)
tshark -r capture.pcap -T fields -e tls.handshake.extensions_server_name -Y "tls.handshake.type == 1" | sort -u

# Extract JA3 hashes
tshark -r capture.pcap -T fields -e tls.handshake.ja3 -Y "tls.handshake.type == 1" | sort -u

# Extract unique destination IPs
tshark -r capture.pcap -T fields -e ip.dst -Y "ip.src == 10.0.2.15" | sort -u

# Extract User-Agent strings
tshark -r capture.pcap -T fields -e http.user_agent -Y "http.user_agent" | sort -u
ステップ 5:IOC を無害化して検証する

安全に共有できるようインジケーターを無害化し、脅威インテリジェンスと照合して検証します。

# Defang IOCs for safe sharing
def defang_ip(ip):
    return ip.replace(".", "[.]")

def defang_url(url):
    return url.replace("http", "hxxp").replace(".", "[.]")

def defang_domain(domain):
    return domain.replace(".", "[.]")

# Validate IOCs against VirusTotal
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"]

# Validate each IOC
for ip in ips:
    detections = check_vt_ip(ip)
    print(f"  {defang_ip(ip)} - VT: {detections} detections")
ステップ 6:標準形式で IOC をエクスポートする

共有や取り込みに使用する、構造化された IOC 出力を生成します。

# Export as STIX 2.1 bundle
from stix2 import Indicator, Bundle, Malware, Relationship
import datetime

indicators = []

# File hash indicator
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 indicator
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"]
    ))

# Domain indicator
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))

# Export as CSV for SIEM ingestion
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、ドメイン、ファイルパス、レジストリキーなどがあります
無害化IOC が誤って有効化されないように変更すること(例:レポートで安全に共有できるよう、URL や IP のドットを [.] に置き換える)
ImphashPE ファイルのインポートテーブル関数の MD5 ハッシュ。同じマルウェアファミリーのサンプルは、多くの場合、同じ imphash を共有します
STIX/TAXIIStructured Threat Information Expression / Trusted Automated Exchange。脅威インテリジェンスをエンコードして伝送するための標準です
JA3/JA3SClientHello/ServerHello パラメーターに基づく TLS クライアント/サーバーのフィンガープリント。TLS の実装に基づいて特定のマルウェアファミリーを識別します
ファジーハッシュ(ssdeep)わずかな変更が加えられたファイルも識別できる、コンテキストに応じた分割ハッシュ方式です。マルウェアの亜種の検出に役立ちます
MISPMalware Information Sharing Platform。IOC の収集、保存、共有を行うためのオープンソース脅威インテリジェンスプラットフォームです

ツールとシステム

  • iocextract(Python):テキストから IP、URL、ドメイン、ハッシュ、YARA ルールを抽出する、自動 IOC 抽出ライブラリです
  • MISP:構造化された IOC の管理と配布を行う、オープンソースの脅威インテリジェンス共有プラットフォームです
  • CyberChef:エンコードされた 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. すべてのネットワーク IOC を VirusTotal で検証し、悪意のあるものか確認するとともに、既知の関連情報を調べます
  6. すべてのインジケーターをデファングし、共有用の STIX 2.1 形式と SIEM 取り込み用の CSV にまとめます
  7. 組織内およびコミュニティで共有するため、MISP イベントに登録します

落とし穴:

  • コンテキストを検証せずに、正規の CDN やクラウドサービスの IP アドレスを含めてしまうこと(例:ホスティングに使われた AWS の IP は、それ自体が悪意のあるものではありません)
  • レポート内の URL や IP をデファングしないために、誤ってクリックしたり DNS 名前解決が発生したりすること
  • パックされたバイナリから文字列を抽出すること(パックされたサンプルから得た IOC は信頼性が低いため、先にアンパックします)
  • ドロップされたファイルのハッシュを含め忘れること(最初のドロッパーと最終ペイロードは別々の IOC です)

出力形式

IOC EXTRACTION REPORT
======================
Sample:           ransomware.exe
Analysis Date:    2025-09-15
Analyst:          [Name]

FILE INDICATORS
SHA-256:          e3b0c44298fc1c149afbf4c8996fb924...
SHA-1:            da39a3ee5e6b4b0d3255bfef95601890afd80709
MD5:              d41d8cd98f00b204e9800998ecf8427e
Imphash:          a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
ssdeep:           3072:kJh3bN7fY+aUkJh3bN7fY+aU:kJh3R7aUkJh3R7aU

NETWORK INDICATORS
C2 IPs:           185.220.101[.]42, 91.215.85[.]17
C2 Domains:       update.malicious[.]com, backup.evil[.]net
C2 URLs:          hxxps://update.malicious[.]com/gate.php
                  hxxps://backup.evil[.]net/gate.php
JA3 Hash:         a0e9f5d64349fb13191bc781f81f42e1
User-Agent:       Mozilla/5.0 (compatible; MSIE 10.0)

HOST INDICATORS
File Paths:       C:\Users\Public\svchost.exe
                  C:\Users\%USER%\AppData\Local\Temp\payload.dll
                  C:\Users\%USER%\Desktop\README_DECRYPT.txt
Registry Keys:    HKCU\Software\Microsoft\Windows\CurrentVersion\Run\WindowsUpdate
Mutexes:          Global\CryptLocker_2025_Q3
Services:         FakeWindowsUpdate

CONFIDENCE ASSESSMENT
High Confidence:  SHA-256, C2 IPs (validated via VT), Mutexes
Medium Confidence: Domains (could be compromised legitimate sites)
Low Confidence:   User-Agent (common string, high false positive risk)

EXPORT FILES
stix_bundle.json  - STIX 2.1 format for TIP ingestion
iocs.csv          - Flat CSV for SIEM blocklist import
yara_rule.yar     - YARA detection rule

コメント