reversing-network-protocols について
reversing-network-protocolsは、未文書化のバイナリネットワークプロトコルを調べるセキュリティ研究者や実装者向けのスキルです。通信キャプチャとクライアントコードの分析を組み合わせ、デコード、リプレイ、ファジングに使うパーサーの作成を支援します。
主な機能
- 01複数メッセージの比較によるフレーミングとフィールドの特定
- 02クライアントのシリアライズ・解析コードの調査
- 03Fridaによる暗号化前後のデータフック
- 04Wireshark、Kaitai Struct、scapy用パーサーの作成
- 05検証を繰り返してプロトコルモデルを改善
活用シーン
- 01仕様が公開されていないTCP・UDPプロトコルの調査
- 02Wiresharkが生データとして表示する通信の解析
- 03プロトコルパーサーやWiresharkディセクターの作成
- 04許可を得たテストでのメッセージ再生やファジング
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trilwu/ secskills --skill reversing-network-protocolsインストール後、Claude Code で/reversing-network-protocolsを入力して読み込まれたか確認します。
詳細
ネットワークプロトコルのリバースエンジニアリング
文書化されていないバイナリプロトコルを、ワイヤ上とクライアント側の両面から同時にリバースエンジニアリングします。ワイヤ上では実際に流れるバイト列を確認でき、クライアント側ではそのバイト列を生成したコードを確認できます。どちらか一方だけでは不十分です。キャプチャからは「何が」変化するのかが分かり、クライアントからは「なぜ」変化するのかが分かります。最終的な成果物は、プロトコルのデコード、リプレイ、さらにはファジングにも使えるほど正確なパーサーです。
使用する場面
- 公開仕様のない独自またはカスタムの TCP/UDP プロトコル
- 該当するディセクタがなく、Wireshark に生の
Dataバイト列として表示されるトラフィック - キャプチャとクライアントのバイナリから解読する必要がある、ゲーム、IoT、産業用、または C2 プロトコル
- プロトコルの解析やリプレイに使う、Wireshark ディセクタ、Kaitai Struct 仕様、または scapy レイヤーの作成
使用しない場面
- 既知の構造化プロトコル — 特に Protobuf や gRPC の場合は
attacking-grpc-protobufを使用します。標準プロトコルにはすでにディセクタがあります。 - 防御目的の PCAP 調査 — 脅威ハンティング、IOC 抽出、インシデントのトリアージには
analyzing-network-trafficを使用します。 - クライアントのバイナリ自体のリバースエンジニアリング(逆アセンブル、逆コンパイル)には
analyzing-binariesを使用します。プロトコル解析のために行い、その結果をここで構造化します。 - プロトコルが暗号化されていると判明した後に、暗号方式を特定したり突破したりする場合は
reviewing-cryptographyを使用します。
両面から取り組む
キャプチャからは、多くのメッセージを比較して構造を明らかにします。
- フレーミング — メッセージの終端を判定する方法です。長さプレフィックス(メッセージ間でペイロードサイズを記録するフィールド)、区切り文字、または固定サイズのレコードがあります。長さフィールドの特定が、通常は最初の突破口になります。
- 定数とマジックナンバー — すべてのメッセージで同一のバイト列は、ヘッダー、バージョンフィールド、またはタイプタグを示します。
- オペコード/メッセージタイプ — メッセージの形式の違いと対応する小さなフィールドです。このフィールドに基づいてキャプチャをグループ化します。
- カウンターとシーケンス番号 — 単調に増加するフィールドです。
- チェックサム — ペイロードに応じて予測不能に変化する末尾のフィールドです。メッセージ本体に対して CRC の各種バリエーションを試します。
- TLV — パターンが分かると、多くのカスタムプロトコルはタイプ・長さ・値の三つ組になっています。
- エンディアン — 既知の長さから確認します。260 バイトのメッセージは
04 01と01 04のどちらを含みますか?
クライアントからは、キャプチャだけでは分からないことを明らかにします。
- バイナリをリバースエンジニアリングして(
analyzing- binaries)、シリアライズ/解析コードを見つけ、メッセージの構築方法と処理方法を読み取ります。 - Frida を使って
send/recv(またはアプリのソケットラッパー)にフックを仕掛け、暗号化の前と復号の後のバッファをキャプチャします。暗号を突破せずに暗号化プロトコルを読み取るには、この方法が有効です。 - プロトコルが暗号化されている場合は、平文側にフックを仕掛けます。クライアント外で操作する必要がある場合に限り、
reviewing-cryptographyを使って暗号方式と鍵の扱いを特定します。
パーサーを作成する
復元した構造を実行可能な形にします。パーサーは、プロトコルを理解したことの証明であると同時に、その後の作業すべてに使えるツールだからです。
- Wireshark ディセクタ(Lua)を使ってライブキャプチャをフィールドごとにデコードします。仮説をより多くのトラフィックで検証する最速の方法です。
- Kaitai Struct を使ってバイナリ形式を宣言的に記述し、複数の言語向けにパーサーを生成します。
- リプレイやファジング用のメッセージの解析と作成の両方に、scapy のカスタムレイヤーを使います。
反復します。ひとまとまりのメッセージをデコードし、解析できないメッセージを見つけたら、仕様を改善します。不正なメッセージが見つかった場合、ノイズではなく、モデルに誤りがあるということです。
次のステップ
動作するパーサーがあれば、セキュリティ作業に取り組めます。リプレイして、サーバーがシーケンス、セッション、認証を検証しているかテストします。ファズして、個々のフィールド(長さ、タイプタグ、件数)に不正な値を与え、パーサーのバグを見つけます。また、プロトコルレベルの認証について、ノンス、セッショントークン、MAC が実際にリプレイや改ざんを防いでいるのか、それとも単なる飾りなのかを検討します。
避けるべき合理化
- 「Wireshark では生データとして表示されるので、見るものがありません。」 ディセクターが一致しなかっただけです。これは行き止まりではなく、出発点です。メッセージを比較してフレーミングやフィールドを見つけるか、ディセクターを書きましょう。
- 「暗号化されているので、リバースエンジニアリングできません。」 クライアントの send/recv にフックを仕掛け、暗号化前の平文を読み取りましょう。プロトコルを理解するために、暗号を解読する必要があることはほとんどありません。
- 「16 進数をざっと見ればいいでしょう。」 構造は、多数のメッセージを比較することで見えてきます。長さを示すフィールドや、種類を選択するバイトなどです。メッセージを 1 つだけ見ても、こうした情報は隠れたままです。
- 「パーサーはほぼ動くし、メッセージが 1 つ失敗しても、これで十分でしょう。」 失敗するメッセージこそ、モデルを修正する反例です。追究しましょう。そこに本当の構造があります。
- 「リプレイしても害はありません。」 ライブサービスに対するリプレイは、そのサービスに作用します。許可が必要なテストとして扱い、リプレイしたメッセージを送信する前に、どのような動作を引き起こすかを検討しましょう。
参考資料
analyzing-binaries— クライアントをリバースエンジニアリングして、シリアライズコードを読み取るattacking-grpc-protobuf— プロトコルが独自仕様ではなく Protobuf/gRPC の場合analyzing-network-traffic— 防御目的の PCAP 調査であり、プロトコルのリバースエンジニアリングではないreviewing-cryptography— プロトコルの暗号方式を特定し、評価する