protocol-reverse-engineering について
セキュリティ研究者やエンジニア向けの、未公開ネットワークプロトコルを調査するためのガイドです。通信の取得から識別、解析、再生、ファジング、文書化までを扱います。
主な機能
- 01Wiresharkとtcpdumpによる通信取得
- 02tsharkとScapyによるパケット解析
- 03プロトコルの署名とフィールドの特定
- 04ネットワーク通信のファジングと再生
- 05プロトコル形式の文書化
活用シーン
- 01セキュリティ研究での通信調査
- 02プロトコル相互運用の問題のデバッグ
- 03未公開バイナリプロトコルの構造把握
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ wshobson/ agents --skill protocol-reverse-engineeringインストール後、Claude Code で/protocol-reverse-engineeringを入力して読み込まれたか確認します。
同梱ファイルreferences/binary-encryption-analysis.mdreferences/protocol-documentation.md
詳細
プロトコルのリバースエンジニアリング
セキュリティ研究、相互運用性、デバッグのために、ネットワークプロトコルをキャプチャ、分析、文書化する包括的な手法です。
トラフィックのキャプチャ
Wireshark によるキャプチャ
# Capture on specific interface
wireshark -i eth0 -k
# Capture with filter
wireshark -i eth0 -k -f "port 443"
# Capture to file
tshark -i eth0 -w capture.pcap
# Ring buffer capture (rotate files)
tshark -i eth0 -b filesize:100000 -b files:10 -w capture.pcap
tcpdump によるキャプチャ
# Basic capture
tcpdump -i eth0 -w capture.pcap
# With filter
tcpdump -i eth0 port 8080 -w capture.pcap
# Capture specific bytes
tcpdump -i eth0 -s 0 -w capture.pcap # Full packet
# Real-time display
tcpdump -i eth0 -X port 80
中間者キャプチャ
# mitmproxy for HTTP/HTTPS
mitmproxy --mode transparent -p 8080
# SSL/TLS interception
mitmproxy --mode transparent --ssl-insecure
# Dump to file
mitmdump -w traffic.mitm
# Burp Suite
# Configure browser proxy to 127.0.0.1:8080
プロトコル分析
Wireshark による分析
# Display filters
tcp.port == 8080
http.request.method == "POST"
ip.addr == 192.168.1.1
tcp.flags.syn == 1 && tcp.flags.ack == 0
frame contains "password"
# Following streams
Right-click > Follow > TCP Stream
Right-click > Follow > HTTP Stream
# Export objects
File > Export Objects > HTTP
# Decryption
Edit > Preferences > Protocols > TLS
- (Pre)-Master-Secret log filename
- RSA keys list
tshark による分析
# Extract specific fields
tshark -r capture.pcap -T fields -e ip.src -e ip.dst -e tcp.port
# Statistics
tshark -r capture.pcap -q -z conv,tcp
tshark -r capture.pcap -q -z endpoints,ip
# Filter and extract
tshark -r capture.pcap -Y "http" -T json > http_traffic.json
# Protocol hierarchy
tshark -r capture.pcap -q -z io,phs
カスタム分析に Scapy を使用
from scapy.all import *
# Read pcap
packets = rdpcap("capture.pcap")
# Analyze packets
for pkt in packets:
if pkt.haslayer(TCP):
print(f"Src: {pkt[IP].src}:{pkt[TCP].sport}")
print(f"Dst: {pkt[IP].dst}:{pkt[TCP].dport}")
if pkt.haslayer(Raw):
print(f"Data: {pkt[Raw].load[:50]}")
# Filter packets
http_packets = [p for p in packets if p.haslayer(TCP)
and (p[TCP].sport == 80 or p[TCP].dport == 80)]
# Create custom packets
pkt = IP(dst="target")/TCP(dport=80)/Raw(load="GET / HTTP/1.1\r\n")
send(pkt)
プロトコルの識別
一般的なプロトコルシグネチャ
HTTP - "HTTP/1." or "GET " or "POST " at start
TLS/SSL - 0x16 0x03 (record layer)
DNS - UDP port 53, specific header format
SMB - 0xFF 0x53 0x4D 0x42 ("SMB" signature)
SSH - "SSH-2.0" banner
FTP - "220 " response, "USER " command
SMTP - "220 " banner, "EHLO" command
MySQL - 0x00 length prefix, protocol version
PostgreSQL - 0x00 0x00 0x00 startup length
Redis - "*" RESP array prefix
MongoDB - BSON documents with specific header
プロトコルヘッダーのパターン
+--------+--------+--------+--------+
| Magic number / Signature |
+--------+--------+--------+--------+
| Version | Flags |
+--------+--------+--------+--------+
| Length | Message Type |
+--------+--------+--------+--------+
| Sequence Number / Session ID |
+--------+--------+--------+--------+
| Payload... |
+--------+--------+--------+--------+
バイナリプロトコルや暗号化の分析を行う前に、パーサー、構造の識別、TLS の手法をお読みください。
プロトコルを文書化したり、ディセクターを作成したりする前に、仕様テンプレートと Lua の例をお読みください。
アクティブテスト
Boofuzz によるファジング
from boofuzz import *
def main():
session = Session(
target=Target(
connection=TCPSocketConnection("target", 8888)
)
)
# Define protocol structure
s_initialize("HELLO")
s_static(b"\x50\x52\x4f\x54") # Magic
s_word(1, name="version") # Version
s_word(0x01, name="type") # Type (HELLO)
s_size("payload", length=4) # Length field
s_block_start("payload")
s_dword(0x12345678, name="client_id")
s_word(0, name="flags")
s_block_end()
session.connect(s_get("HELLO"))
session.fuzz()
if __name__ == "__main__":
main()
再生と変更
from scapy.all import *
# Replay captured traffic
packets = rdpcap("capture.pcap")
for pkt in packets:
if pkt.haslayer(TCP) and pkt[TCP].dport == 8888:
send(pkt)
# Modify and replay
for pkt in packets:
if pkt.haslayer(Raw):
# Modify payload
original = pkt[Raw].load
modified = original.replace(b"client", b"CLIENT")
pkt[Raw].load = modified
# Recalculate checksums
del pkt[IP].chksum
del pkt[TCP].chksum
send(pkt)
ベストプラクティス
分析ワークフロー
- トラフィックをキャプチャする:複数のセッションで、さまざまなシナリオを試します
- 境界を特定する:メッセージの開始/終了マーカーを特定します
- 構造を把握する:固定ヘッダーと可変ペイロードを特定します
- フィールドを特定する:複数のサンプルを比較します
- 形式を文書化する:仕様を作成します
- 理解を検証する:パーサー/ジェネレーターを実装します
- エッジケースをテストする:ファジングや境界条件を試します
注目すべき一般的なパターン
- メッセージの開始位置にあるマジックナンバー/シグネチャ
- 互換性を確保するためのバージョンフィールド
- 長さフィールド(可変データの前に配置されることがよくあります)
- メッセージの識別に使われるタイプ/オペコードフィールド
- 順序付けに使われるシーケンス番号
- 完全性を確認するためのチェックサム/CRC
- タイミングを示すタイムスタンプ
- セッション/接続識別子
コメント
Markdown 対応