
Pig(Packet intruder generator の略)は、Linux パケットクラフティングツールです。
Pig を使用して、IDS/IPS などをテストできます。
Pig は、すぐに使用できる既知の攻撃シグネチャを多数提供しており、要件に応じてより具体的なものを追加してコレクションを拡張できます。
現時点では、TCP、UDP、ICMP に基づくトランスポート層を持つ IPv4 シグネチャを作成できます。
また、Ethernet フレームからパケットを構築するだけでなく、ARP プロトコルに基づくシグネチャも作成できます。
もし私の SPRING 2016 号の 2600 記事からここにたどり着いたなら、この小さな Pig はその後も進化し続けているので、以下のドキュメントセクションを読み進めてください。
とても簡単です:
[email protected]:~/src# git clone https://github.com/rafael-santiago/pig pig
[email protected]:~/src# cd pig
[email protected]:~/src/pig# git submodule update --init
pig をビルドするには、Hefesto を使用する必要があります。Hefesto をシステム上で動作させる手順を実行した後、pig の src というサブディレクトリに移動し、次のコマンドを実行します:
[email protected]:~/src/pig/src# hefesto
このコマンドの後、src/bin パスに pig バイナリが見つかるはずです。バイナリは src/bin から相対的に使用するか、インストールすることができます。
何らかの理由でビルドに問題がある場合は、BUILD.md にある注意事項を読んでみてください。
インストールするには、src サブディレクトリ内で次のコマンドを実行します:
[email protected]:~/src/pig/src# hefesto --install
アンインストールするには、src サブディレクトリ内で次のコマンドを実行します:
[email protected]:~/src/pig/src# hefesto --uninstall
Pigsty ファイル は、一連のパケットシグネチャを定義するプレーンテキストファイルです。従うべき特定の構文があります。pigsty ファイルの例を見てみましょう:
[ signature = "Hello",
ip.version = 4,
ip.ihl = 5,
ip.tos = 0,
ip.src = 192.30.70.10,
ip.dst = 192.30.70.3,
ip.protocol = 17,
udp.dst = 1008,
udp.src = 32000,
udp.payload = "Hello!!" ]
基本的に、すべてのシグネチャデータは角括弧 [ ... ] で囲む必要があります。
この領域内では、情報は field = data の形式で指定します。
コンピュータネットワークの経験があれば、表1 にリストされているフィールドの大部分が強い意味を持つことは間違いありません。これらのフィールドを使用して、さらにシグネチャを作成する必要があります。
表1: pig シグネチャフィールド。
シグネチャを作成する際、すべてのデータを指定する必要はありません。パケットの最も関連する部分のみを指定すると、残りの部分はデフォルト値で埋められます。チェックサム は 常に 再計算されます。
ヒント: pigsty サブディレクトリを見てください。多くのシグネチャファイルが見つかり、新しいものを定義するのが非常に簡単であることがわかります。
はい、可能です。この機能を使用するには、ip address タイプのフィールドに 表2 にリストされている値を指定するだけです。
表2: 地理的領域別IP。
| 使用する値 | 意味 |
|---|
任意の ip address タイプのフィールドで、値として user-defined-ip を使用する必要があります。この場合、コマンドラインオプション --targets を使用する必要があることに注意してください。詳細については、pigの使用 セクションを参照してください。
自身の環境を超えて関連性があると思われる pigsty ファイル を作成した場合は、これらの有用なファイルを含めるためにプルリクエストを開いてください。よろしくお願いします!
Pig の使用法は非常に簡単で、以下の4つの基本オプションを指定する必要があります:
--signatures--gateway--net-mask--lo-iface各オプションについて詳しく知りたいですか?では、見ていきましょう:
--signatures は、pigsty ファイル へのファイルパスのリストを受け取ります。--gateway は、ゲートウェイアドレスを指定する場所です。pig は イーサネットフレーム も生成 (または少なくとも生成しようと試みる) ことに注意してください。そのため、レイヤ1 データを正しく構成するためには、ゲートウェイアドレスがかなり重要です。--net-mask は、ルーティングの問題のためにネットワークマスクを指定する必要があります。--lo-iface は、生成されたパケットを「排出する」ために使用するローカルネットワークインターフェースの名前を指定する場所です。--no-gateway は、パケットをネットワークの外部に送信しないことを示します。DDos ベースのトラフィックを生成すると仮定しましょう:
[email protected]:~# pig --signatures=pigsty/ddos.pigsty\
> --gateway=10.0.2.2\
> --net-mask=255.255.255.0 --lo-iface=eth0
今度は、すべてをめちゃくちゃにしたいとします:
[email protected]:~# pig --signatures=pigsty/ddos.pigsty,pigsty/attackresponses.pigsty,\
> pigsty/badtraffic.pigsty,pigsty/backdoors.pigsty\
> --gateway=10.0.2.2 --net-mask=255.255.255.0 --lo-iface=eth0
これには --timeout=<ミリ秒> オプションを使用します。
--no-echo オプションを使用します。
--targets オプションを使用します。正確なIP、IPマスク、CIDR に基づくリストを指定できます。
次の例を見てください:
[email protected]:~# pig --signatures=pigsty/local-mess.pigsty\
> --targets=192.30.70.3,192.30.70.*,192.30.70.0/9\
> --gateway=10.0.2.2\
> --net-mask=255.255.255.0\
> --lo-iface=eth0
これは、ロードされたシグネチャが現在のネットワークの外部にデータを送信しない場合に便利です。これを指定するには、オプション --no-gateway を使用する必要があります。--no-gateway オプションを使用すると、パケットが現在のセグメントの外部に流れないため、ゲートウェイアドレスを指定する必要はありません。その結果、ネットワークマスクを指定することも無関係になります。
例:
[email protected]:~# pig --signatures=pigsty/local_traffic.pigsty --no-gateway --lo-iface=eth2
上記のサンプルでは、イーサネットフレームはもはや pig の責任ではありません。このため、pig は --gateway と --net-mask オプションの欠如について文句を言いません。
--no-gateway オプションは、ARP トラフィックを生成する必要がある場合に非常に便利です。ARP spoofing with pig を説明する別のドキュメントも参照してください。
おそらく、1つのシグネチャのみを送信し、その後何が起こったかを確認するために呼び出し元に戻る必要があるかもしれません。この種の要件は、このアプリケーションを システムテスト や ユニットテスト のサポートとして使用する場合によくあります。そのため、これを行う必要がある場合は、オプション --single-test を使用してみてください:
[email protected]:~# pig --signature=pigsty/syn-scan.pigsty --targets=127.0.0.1 --single-test\
> --gateway=10.0.2.2 --net-mask=255.255.255.0 --lo-iface=eth0
このコマンドを実行すると、pig はファイル syn-scan.pigsty から1つのシグネチャのみを選択し、それを送信して終了します。処理中にエラーが発生した場合、pig は終了コード 1 で終了し、それ以外の場合は終了コード 0 で終了します。
基本的な pig の動作モードは、事前に定義されたタイムアウトを尊重しながら、大量のパケットをネットワークに吐き出す無制限の ループ です。
オプション --loop=<モード> を使用して、ロードされたパケットを送信するための pig のトラバース方法を定義できます。現時点では、モードは2つあります: random (デフォルト) と sequential です。
sequential モードは、ロードされたパケットシグネチャリストの末尾に達すると、シグネチャを再度反復します。
サブタスクは、パケットクラフティングに関連する便利なマイナーなタスクで、クラフティングセッションを支援するために pig に同梱されています。これらのタスクは、オプション --sub-task=<タスク名> を使用してアクセスできます。
実質的にサブプログラムであるため、サブタスクには独自の特性があり、それらの詳細はそれぞれのマニュアルに記載されています。表3 を参照してください。
表3: pig サブタスク。
現時点では、トランスポート層に UDP または TCP を持つ IPv4 ベースのパケットを構築できます。また、ARP パケットも構築できます。
ただし、Ethernet フレームからパケットを構築することもできます。これの良い点は、Ethernet のペイロードの上に事実上何でも構築できる可能性があることです。
例えば、現在の pig は IPv6 の組み立てをサポートしていませんが、生の Ethernet ベースの pigsty を使用して構築することができます。次の例を見てください:
[ eth.hwdst = "5C:AC:4C:AA:F5:B5",
eth.hwsrc = "08:95:2A:AD:D6:4F",
eth.type = 0x86DD,
eth.payload = "\x60\x00\x00\x00\x00\x20\x3a\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x0a\x95\x2a\xff\xfe\xad\xd6\x4f\xfe\x80\x00\x00\x00\x00\x00\x00\x55\x51\x00\xc2\x18\x0f\xdb\x46\x88\x00\x32\x01\xe0\x00\x00\x00\xfe\x80\x00\x00\x00\x00\x00\x00\x0a\x95\x2a\xff\xfe\xad\xd6\x4f\x02\x01\x08\x95\x2a\xad\xd6\x4f",
signature = "IPv6 from Sparta" ]
Ethernet pigsty 内に宛先および送信元 MAC アドレスを含めることはオプションであることを考慮すると、plush field を使用しなくても作業を完了できます。
これは、環境内で新しいプロトコルやその他の異常で面白いものをテストする必要がある場合に便利です。この生の方法で、pig はあなたにとって有用であり続けることができます。
次のデータを "oink.pigsty" として保存します:
[ signature = "oink",
ip.version = 4,
ip.ihl = 5,
ip.tos = 0,
ip.src = 127.0.0.1,
ip.dst = user-defined-ip,
ip.protocol = 17,
udp.dst = 1008,
udp.src = 32000,
udp.payload = "Oink!!\n" ]
別の tty で、netcat を UDP モード で実行し、ポート 1008 で接続をリッスンします:
[email protected]:~# nc -u -l -p 1008
次に、"oink.pigsty" を使用して pig を実行し、ターゲットとして ループバック を指定します:
[email protected]:~# pig --signatures=oink.pigsty --targets=127.0.0.1\
> --gateway=10.0.2.2 --net-mask=255.255.255.0 --lo-iface=eth0
netcat は複数の oink を受信し始めるはずです... そして、はい、おめでとうございます! pig がシステム上で動作しています! ;)
インターフェースを流れるこれらの UDP パケット についての詳細を知るために、ネットワークをスニッフィングしてみてください...
楽しんでください!
| フィールド | 意味 | プロトコル | データ型 | 定義例 |
|---|
signature | シグネチャ名 | - | 文字列 | signature = "Udp flood" |
eth.hwdst | Ethernet 宛先MAC | Ethernet | MAC | eth.hwdst = "00:de:ad:be:ef:00" |
eth.hwsrc | Ethernet 送信元MAC | Ethernet | MAC | eth.hwsrc = "00:de:ad:be:ef:00" |
eth.type | Ether タイプ | Ethernet | 数値 | eth.type = 0x0800 |
eth.payload | Ethernet ペイロード | Ethernet | 文字列 | eth.payload = "f\x00ob\x04r" |
ip.version | IP バージョン | IP | 数値 | ip.version = 4 |
ip.ihl | インターネットヘッダ長 | IP | 数値 | ip.ihl = 5 |
ip.tos | サービス種別 | IP | 数値 | ip.tos = 0 |
ip.tlen | 総長 | IP | 数値 | ip.tlen = 20 |
ip.id | パケットID | IP | 数値 | ip.id = 0xbeef |
ip.flags | IP フラグ | IP | 数値 | ip.flags = 4 |
ip.offset | フラグメントオフセット | IP | 数値 | ip.offset = 0 |
ip.ttl | 生存時間 (TTL) | IP | 数値 | ip.ttl = 64 |
ip.protocol | プロトコル | IP | 数値 | ip.protocol = 6 |
ip.checksum | チェックサム | IP | 数値 | ip.checksum = 0 |
ip.src | 送信元アドレス | IP | IPアドレス | ip.src = 192.30.70.3 |
ip.dst | 宛先アドレス | IP | IPアドレス | ip.dst = 192.30.70.3 |
ip.payload | IP 生ペイロード | IP | 文字列 | ip.payload = "\x01\x02" |
tcp.src | 送信元ポート | TCP | 数値 | tcp.src = 80 |
tcp.dst | 宛先ポート | TCP | 数値 | tcp.dst = 21 |
tcp.seqno | シーケンス番号 | TCP | 数値 | tcp.seqno = 10202 |
tcp.ackno | 確認応答番号 | TCP | 数値 | tcp.ackno = 10200 |
tcp.size | TCP 長 | TCP | 数値 | tcp.size = 4 |
tcp.reserv | TCP 予約フィールド | TCP | 数値 | tcp.reserv = 0 |
tcp.urg | TCP URG フラグ | TCP | ビット | tcp.urg = 0 |
tcp.ack | TCP ACK フラグ | TCP | ビット | tcp.ack = 1 |
tcp.psh | TCP PSH フラグ | TCP | ビット | tcp.psh = 0 |
tcp.rst | TCP RST フラグ | TCP | ビット | tcp.rst = 0 |
tcp.syn | TCP SYN フラグ | TCP | ビット | tcp.syn = 0 |
tcp.fin | TCP FIN フラグ | TCP | ビット | tcp.fin = 0 |
tcp.wsize | TCP ウィンドウサイズ | TCP | 数値 | tcp.wsize = 0 |
tcp.checksum | チェックサム | TCP | 数値 | tcp.checksum = 0 |
tcp.urgp | 緊急ポインタ | TCP | 数値 | tcp.urgp = 0 |
tcp.payload | ペイロード | TCP | 文字列 | tcp.payload = "\x01abc" |
udp.src | 送信元ポート | UDP | 数値 | udp.src = 53 |
udp.dst | 宛先ポート | UDP | 数値 | udp.dst = 7 |
udp.size | UDP 長 | UDP | 数値 | udp.size = 8 |
udp.checksum | チェックサム | UDP | 数値 | udp.checksum = 0 |
udp.payload | ペイロード | UDP | 数値 | udp.payload = "boo!" |
icmp.type | ICMP タイプ | ICMP | 数値 | icmp.type = 0 |
icmp.code | ICMP コード | ICMP | 数値 | icmp.code = 0 |
icmp.checksum | チェックサム | ICMP | 数値 | icmp.checksum = 0 |
icmp.payload | ペイロード | ICMP | 文字列 | icmp.payload = "ping!" |
arp.hwtype | ARP ハードウェアタイプ | ARP | 数値 | arp.hwtype = 0x1 |
arp.ptype | ARP プロトコルタイプ | ARP | 数値 | arp.ptype = 0x0800 |
arp.hwlen | ARP ハードウェア長 | ARP | 数値 | arp.hwlen = 6 |
arp.opcode | ARP オペレーションコード | ARP | 数値 | arp.opcode = 2 |
arp.hwsrc | ARP 送信元ハードウェアアドレス | ARP | MAC | arp.hwsrc = "de:ad:be:ef:0:0" |
arp.psrc | ARP 送信元プロトコルアドレス | ARP | IPアドレス | arp.psrc = 192.30.70.3 |
arp.hwdst | ARP 宛先ハードウェアアドレス | ARP | MAC | arp.hwdst = "de:ad:be:ef:0:0" |
arp.pdst | ARP 宛先プロトコルアドレス | ARP | IPアドレス | arp.pdst = 192.30.70.3 |
north-american-ip | 北米のIPアドレス |
south-american-ip | 南米のIPアドレス |
asian-ip | アジアのIPアドレス |
european-ip | ヨーロッパのIPアドレス |
| サブタスク | 機能 | マニュアル |
|---|
pcap-import | PCAPファイルからpigstyファイルにパケットをインポート | cat doc/pcap-import.md |
shell | 対話モードでpigを実行 | cat doc/shell.md |