libpgenでパケット操作
Transcript of libpgenでパケット操作
パケット操作のライブラリを作った話
すらんく @slankdev
自己紹介 すらんく(@slankdev)• http://slankdev.net
• 城倉弘樹(しろくらひろき)
• 2015 IPA セキュリティ・キャンプ全国大会卒業生
• 法政大学理工学部 B2takahoyoさんの後輩です
• ネットワーク関係が趣味(初心者) CTF (NW問だけ)
• 宗派は Vim Arch C/C++
今日話すこと
• 趣味でパケット操作のライブラリをC++で書いたんでその話をすることと、普及活動
• まさかり大歓迎ですそもそもこのライブラリはまさかりで生きているようなものです
パケットを見たこと、ありますか?
パケットを作ったりいじったこと、ありますか?
パケットをつくる
• ネットワークでパケットを理解する上でパケットを見るだけではだめ
• 作って試していろいろしたい
• 自己環境ならなにやったって大丈夫
パケットを作ろう• パケットジェネレータとして一番優秀なのは多分
scapy(pythonのモジュール)イケメンパケリストが説明してくれるのでなにも説明しません。
• python 便利だしよさそうだけどそれで作ってもscapyあるし誰も使ってくれない。。
• 普段C使うしCで書くかぁ
libpcap• http://tcpdump.org
• tcpdump の開発者が開発しているマルチOSサポートのパケットキャプチャのライブラリ
• Linux をはじめ様々なOSで簡単にパケットキャプチャが作れるから簡単だし入門にはいいかも
• tcpdump のを開発しやすくするためにlibpcapを作った
tcpdumpの機能追加で作成
超カッケーじゃんそういうの
• 今回のライブラリはそんな厨二心で始まりました
• 情報関係のとっかかりは厨二心でいいと考えています
• このライブラリも一応簡単なプログラムの機能追加のために作成って建前で作り始めました
libpgen ってのを開発しました
• http://libpgen.org
• ソースコードはGitHubで管理しています
• 現在はEthernet, ARP, IP, ICMP, TCP, UDP, DNS, DHCP, ar_droneに対応
• 開発は現在進行中です (協力してくれるひと募集してます)
• scapyに負けたくない
自分でパケットを作って送る感動
Wiresharkとかで準備して
こんな感じに作って送って
見れた時の感動
想像を絶する感動 !!!
巣立っていった我が子が帰ってくるような特別な気持ち
巣立っていった我が子が帰ってくるような特別な気持ち
別に子供とかまだいません
設計段階 その⓪• 自由にパケットを作ることだけできればいい(ユーザはプロトコルの知識以外なにもなくてもできれば最高)
• エンディアンとか気にしないでパケット作れるようにしたい
• ソケット開いてオプションとか設定したりとか考えたくない
• アドレスとかもいつも同じ作業だしめんどくさい
• とりあえずARP好きだからEthernetとARPだけ実装しよっと
この辺は全然実用段階でないので説明をはしょります
完成したもの その⓪• ARP送れる。わー。。。終わり
• まったく使えない。。機能すくなすぎ。
• まあこれでも初心者なので僕自身は勉強になりました
• SocketのPF_PACKETでソケットを開いて実装(Linuxのみ対応)
設計段階①• いろんなプロトコルに対応させたいけどどうしたら効率良いか下位のプロトコルの操作をどうすればいいかちょっとだけオブジェクトしこーにするか
• 将来的に他のOSでもうごかしたい。。OSごとに違う実装になるところだけ完全に切り離す
• パケット編集のインターフェースを直感的にしたい
アーキテクチャ図
• こんな感じ設計しました
• パケットクラスパケット操作を担当
• アドレスクラスIP,MACアドレス操作を担当
• NetutilsOSごとの違いを吸収
OS
Netutils
パケットクラス
アドレスクラス
アドレスクラス• IPアドレスとMACアドレスの操作を簡単にできるようにする
• ネットワーク内をスキャンとかする時はIPアドレスの大小表現とかも必要だからそういう演算子も定義しといた
パケットクラス• 直感的なインターフェースからパケットのバイナリを生成パケットインスタンス名.プロトコル.要素名でパケットの各要素にアクセスできるようにした。
• 以下はARPの例 (これも普通じゃないパケットの状態ですが。。。)
後ほどこのクラスの説明を少し
Netutils• ネットワークプログラミング関連の作業はすべてこいつに任せよう。ネットワーク関連の処理以外はほとんど高度(低レベル)なことしないのでこの部分だけ完全にきりはなしました
• 表面的には今のとこと出てこないので、ここの説明は省略。
• 詳しくはhttp://libpgen.org/documentation/components/netutils/ を参照
• もはや現在はネットワークユーティリティーな状態でないので、近々名前変えよう
完成したもの①
• 機能を綺麗に分担できています。
• アドレスクラス、パケットクラス、Netutilsを別々にインストールとかできたらいいかも
パケット送信はとりあえずできたしあとはたくさんのプロトコルに対応させていけばいい
パケット送信はとりあえずできたしあとはたくさんのプロトコルに対応させていけばいい
それだけじゃ大して面白くないしつまらない
よく考えたらscapyに勝る機能が何もない
設計段階②• 既存のパケットのバイナリを読み込ませてパケットクラスにパースできるようにしよう
• ならパケットの受信機能も簡単に実装するか
• pcapファイル読み込みたいTDUCTFに参加させてもらった時に発案pcapファイル読み込んで送ったり、受信した特定のパケットだけpcapファイルに保存したりとできたらかっちょいいかも
• 送受信を行う上でやはりディスクリタみたいなのがあると便利
パケットをキャストする機能を追加
• 以前まではパケットクラス-->バイナリの一方向のみの変換だった
• パケットクラスにcastメンバ関数を追加してバイナリをパースして、パケットクラスの形に変換して、解析を簡単にできるようにした
aabb ccdd eeff 0011 2233 4455 0806 00010800 0604 0001 0011 2233 4455 c0a8 0004aabb ccdd eeff c0a8 0001
パケットクラス
cast関数の問題点
• 例えばARPパケットのバイナリをDHCPとしてcastしようとすると危険→あらかじめパケットの種類を簡単に調べときたい
• ついでにIPアドレスとかMACアドレスとかポート番号とかで簡単に調べられる機能とかもあるといい
unknownパケット• unknown型のパケットって思ってください
• isUDP とか isICMP とかL4までの基本情報をまとめて解析してくれる特別なパケットクラス
• ポート番号とかでいろいろ絞り込めるようにしました。
unknownパケット
• こんな感じにパケットがだいたいどんな感じのパケットか、とか送信元とかが簡単に調べられる
• ポート番号が53か?とかで調べたい時はbool res = インスタンス名.portis(53);とかで調べられる。
簡易的なパケット受信機能
• sniff関数をNetutilsに追加
• void sniff(pgen_t*, (bool)(const u_char*, int));
• パケットを受信待機して受信したら、コールバック関数を呼ぶ。
• まあこれはなにも工夫もないしデバッグしやすくするために追加しただけ
sniff 関数
recv packet!!
コールバック関数
aabb ccdd eeff 00112233 4455 0806 00010800 0604 0001 00112233 4455 c0a8 0004aabb ccdd eeff c0a80001 length is 42 bytes
こっちでパケット解析とかをする
pcapファイルも読み込みたい
• せっかくバイナリのパース機能追加したならpcapファイルを読み込んでそこからパケットを受信したいってのが漢意気ってもんよ
• みんな大好きpcapファイル読めたらウケいいかも
• pcapngにも今度対応させますngに対応してるパケット解析ツール結構少ないから案外いいかも
なんてことになるかもしれない….
pcapファイルも読み込みたい
• ファイルポインタで基本どうりにファイル開いてパケットを書き込む時はパケットの先頭にpcapパケットヘッダを追加するだけ
• この機能が一番簡単に実装できたからL2で送信する機能より先に取りかかっとけば簡単だし作業加速したかも
magic number
major version minor version
time zorne
sigfigs
snaplen
link type
pcap file header
timestampcaplenlen
pcap packet header
pgenディスクリプタ使いたい
• 今までのパケット送信部分はユーザがソケットを意識しなくてもいいようにうんこきもい実装になってた。
• 送受信を両方行うプログラムを書くならやっぱりを意識しないといけない
• pcapファイルに書き込んだり、ネットワークインターフェースから送信したりいろいろあるからまとめて管理できるようにした
pgenディスクリプタ使いたい
pgenディスクリプタ
pgen_open 関数or
pgen_open_offline関数
開きたいインタフェースやファイル名など
ディスクリプタの種類によって入出力先を指定できる上の例ではtest.pcapへの書き込み専用モードでパケットはtest.pcapに書き込まれる
完成したもの②• バイナリを解析して、パケットクラスで読み取れるようになった
• 受信したパケットを改変して別のインターフェースから送信することもできる
• pcapファイルにパケットを書き込んだり、pcapファイルひとつづつパケットを読み込んでcast関数で解析できるようになった。
• pgen_tって感じでディスクリプタを使えるようにした
• この時点で簡単なルータとかブリッジなら即席で作れます
libpgenで中間者攻撃のツール作成
• せっかくある程度使える状態にしたので、取りあえず好きなARPで実験的なのしました。
• 超適当にはしょって作ったARPスプーフィングでMITMアタックするプログラムです
• http://slankdev.net/blog/2015/08/30/libpgen-arp-mitm/
http://wp.me/p5YcBp-7N (短縮URL)
設計段階④ 現在
• 他のOSに対応させたい
• 拡張しやすくしたい
• 全体が正しいい動作をするのか自動でチェックする機能追加
• パケット解析ツールだしネットワーク以外のパケットも見たくね?某鮫ツールはいろいろ読めるし
他のOSに対応させたい
• とりあえず一番の愛機がMBPなので、OSXに対応させました。友達がMac使ってる人結構いるし、対応させたら使ってもらえるし
• OSXはBSD系なのでBSDに対応させるコードを追加すればいいだけ
• BSDはBPFってのでリンクレイヤープログラミングをすればいい
• LinuxのPF_PACKETよりなんか分かりやすいからこっちの方が好きだったり
他のOSに対応させたい
• OS依存している関数のみを#ifdef __linuxとかで囲むだけ
• あとはエンディアンに気をつけているかを全体的にチェックするだけ
• 一番ひっかったのはインストール場所。(まだ調べてない)OSXは/usr/local/includeとか/usr/includeにインクルードパス張ってなくて(怒)xcode.appの中にあるヘッダとかからインクルードしてる変態
• 知ってる人誰か教えて下さい ( > < )
拡張しやすくしたい
• 現在開発中です
• ユーザが簡単にプロトコルの追加とかできるようにしたかった。一人でこんな作業いつまでもやってらんない
• プロトコル解析のコードはコアな部分から独立させよう
• チーム開発しやすいようにしたい
全体が正しい動作をしてるか確かめる
• 対応させてるプロトコルが増えるとその分テストが大変になるので、自動化したい
• これも今実装中なんですけど、これがうまくいけばいろいろ楽になる。アドレスクラスは低機能だし、少ないからいいとして、パケットクラスの動作チェックを自動化したい
• 機能追加したり、リファクタリングしたりしたあと全体がうまく動くか確かめていたけど、毎回やってたらきりがない。。
• どうやってうまく動いているか確認しよう。。
• 各コンポーネントごとにチェックしていった方が良さそう
全体が正しい動作をしてるか確かめる
• パケットクラスでチェックが必要なのはバイナリ解析部分と生成部分
• サンプルパケットを幾つか読ませて、そこから再度バイナリを生成して元のパケットとdiffをとる.
• この処理はプロトコルごとに実装しなくていいので、名案かな
aabb ccdd eeff 0011 2233 4455 0806 00010800 0604 0001 0011 2233 4455 c0a8 0004aabb ccdd eeff c0a8 0001
パケットクラス
aabb ccdd eeff 0011 2233 4455 0806 00010800 0604 0001 0011 2533 4455 c0a8 0004aabb ccdd eeff c0a8 0001
キャスト
再度バイナリ生成
ここが同じか確かめる
ネットワーク以外のパケット• 開発初期と比べていろいろ拡張しやすくなってきたし、ネットワーク以外のパケットも操作できたらいいかも。
• USBとか、HDMIとかCTFの作問もできるかも
• あくまで、いろいろな勉強のためにそういうことしてる段階なので、社会貢献できていない。
• USB機器とかのファジングツールとか将来的にできたらタノシイカモネ
完成したもの ④ (まだ途中です)
• 一応BSD用のコードを追加できた、うまく動いている?
• 拡張しやすくする構造はwiresharkを参考にしました
• まだ現在製作中です
まとめ、感想 ①• ソースを読経する力がすこーしだけついたかなって感じです。
• 始めた時は/usr/include ? ナニソレオイシイノ だったので
• デバッグ力も少し
• プロトコルの知識もつきました
• OSのプロトコル実装の手抜きとかも見れるのが楽しいBSDのARPとか、LinuxのICMPとか…
まとめ、感想 ②• だいたい日本一の学生でパケットに詳しい鮫アイコンの人がscapyの普及活動を行っている時点でこのままでは到底敵わないではないか!
• scapyにない機能とかいろいろ追加したりいろいろやっていつかscapyと比べられるくらいのパケット解析ツールにしていきたいです
• 開発に時間がかかりすぎてる。
• http://libpgen.org にドキュメントとかも書いておいているので、一度見て文句などを言ってくれると元気がでます。
まとめ、感想 ③
• チーム開発とかやったことないから友達見つけてちょっとずつ協力してもらいたいと感じました
• 社会貢献してない
libpgenについて
• http://libpgen.org で詳細を説明してます。各プロトコルのパケットクラスの資料がまだ完成していないのでもう少し待ってください。。
最後に一言
• このライブラリは現在、一人で開発しているのですが、セキュリティキャンプ講師の方、 2015年度全国大会卒業生の方をはじめ、たくさんの方にアイディアや助言をいただいております。本当にありがとうございます。 今後とも宜しくお願いします。
aabb ccdd eeff 0011 2233 4455 0800 45002800 0001 0000 4006 b9a2 c0a8 b302 c0a86501 3039 3039 0000 0000 0000 0000 50012000 961c 0000
aabb ccdd eeff 0011 2233 4455 0800 45002800 0001 0000 4006 b9a2 c0a8 b302 c0a86501 3039 3039 0000 0000 0000 0000 50012000 961c 0000
ヒント
aabb ccdd eeff 0011 2233 4455 0800 45002800 0001 0000 4006 b9a2 c0a8 b302 c0a86501 3039 3039 0000 0000 0000 0000 50012000 961c 0000
TCP FIN パケットです. ありがとうございました