56
パケット操作の ライブラリを作った話 すらんく @slankdev

libpgenでパケット操作

Embed Size (px)

Citation preview

Page 1: libpgenでパケット操作

パケット操作のライブラリを作った話

すらんく @slankdev

Page 2: libpgenでパケット操作

自己紹介 すらんく(@slankdev)• http://slankdev.net

• 城倉弘樹(しろくらひろき)

• 2015 IPA セキュリティ・キャンプ全国大会卒業生

• 法政大学理工学部 B2takahoyoさんの後輩です

• ネットワーク関係が趣味(初心者) CTF (NW問だけ)

• 宗派は Vim Arch C/C++

Page 3: libpgenでパケット操作

今日話すこと

• 趣味でパケット操作のライブラリをC++で書いたんでその話をすることと、普及活動

• まさかり大歓迎ですそもそもこのライブラリはまさかりで生きているようなものです

Page 4: libpgenでパケット操作

パケットを見たこと、ありますか?

Page 5: libpgenでパケット操作

パケットを作ったりいじったこと、ありますか?

Page 6: libpgenでパケット操作

パケットをつくる

• ネットワークでパケットを理解する上でパケットを見るだけではだめ

• 作って試していろいろしたい

• 自己環境ならなにやったって大丈夫

Page 7: libpgenでパケット操作

パケットを作ろう• パケットジェネレータとして一番優秀なのは多分

scapy(pythonのモジュール)イケメンパケリストが説明してくれるのでなにも説明しません。

• python 便利だしよさそうだけどそれで作ってもscapyあるし誰も使ってくれない。。

• 普段C使うしCで書くかぁ

Page 8: libpgenでパケット操作

libpcap• http://tcpdump.org

• tcpdump の開発者が開発しているマルチOSサポートのパケットキャプチャのライブラリ

• Linux をはじめ様々なOSで簡単にパケットキャプチャが作れるから簡単だし入門にはいいかも

• tcpdump のを開発しやすくするためにlibpcapを作った

Page 9: libpgenでパケット操作

tcpdumpの機能追加で作成

Page 10: libpgenでパケット操作

超カッケーじゃんそういうの

• 今回のライブラリはそんな厨二心で始まりました

• 情報関係のとっかかりは厨二心でいいと考えています

• このライブラリも一応簡単なプログラムの機能追加のために作成って建前で作り始めました

Page 11: libpgenでパケット操作

libpgen ってのを開発しました

• http://libpgen.org

• ソースコードはGitHubで管理しています

• 現在はEthernet, ARP, IP, ICMP, TCP, UDP, DNS, DHCP, ar_droneに対応

• 開発は現在進行中です (協力してくれるひと募集してます)

• scapyに負けたくない

Page 12: libpgenでパケット操作

自分でパケットを作って送る感動

Page 13: libpgenでパケット操作

Wiresharkとかで準備して

Page 14: libpgenでパケット操作

こんな感じに作って送って

Page 15: libpgenでパケット操作

見れた時の感動

Page 16: libpgenでパケット操作

想像を絶する感動 !!!

Page 17: libpgenでパケット操作

巣立っていった我が子が帰ってくるような特別な気持ち

Page 18: libpgenでパケット操作

巣立っていった我が子が帰ってくるような特別な気持ち

別に子供とかまだいません

Page 19: libpgenでパケット操作

設計段階 その⓪• 自由にパケットを作ることだけできればいい(ユーザはプロトコルの知識以外なにもなくてもできれば最高)

• エンディアンとか気にしないでパケット作れるようにしたい

• ソケット開いてオプションとか設定したりとか考えたくない

• アドレスとかもいつも同じ作業だしめんどくさい

• とりあえずARP好きだからEthernetとARPだけ実装しよっと

この辺は全然実用段階でないので説明をはしょります

Page 20: libpgenでパケット操作

完成したもの その⓪• ARP送れる。わー。。。終わり

• まったく使えない。。機能すくなすぎ。

• まあこれでも初心者なので僕自身は勉強になりました

• SocketのPF_PACKETでソケットを開いて実装(Linuxのみ対応)

Page 21: libpgenでパケット操作

設計段階①• いろんなプロトコルに対応させたいけどどうしたら効率良いか下位のプロトコルの操作をどうすればいいかちょっとだけオブジェクトしこーにするか

• 将来的に他のOSでもうごかしたい。。OSごとに違う実装になるところだけ完全に切り離す

• パケット編集のインターフェースを直感的にしたい

Page 22: libpgenでパケット操作

アーキテクチャ図

• こんな感じ設計しました

• パケットクラスパケット操作を担当

• アドレスクラスIP,MACアドレス操作を担当

• NetutilsOSごとの違いを吸収

OS

Netutils

パケットクラス

アドレスクラス

Page 23: libpgenでパケット操作

アドレスクラス• IPアドレスとMACアドレスの操作を簡単にできるようにする

• ネットワーク内をスキャンとかする時はIPアドレスの大小表現とかも必要だからそういう演算子も定義しといた

Page 24: libpgenでパケット操作

パケットクラス• 直感的なインターフェースからパケットのバイナリを生成パケットインスタンス名.プロトコル.要素名でパケットの各要素にアクセスできるようにした。

• 以下はARPの例 (これも普通じゃないパケットの状態ですが。。。)

後ほどこのクラスの説明を少し

Page 25: libpgenでパケット操作

Netutils• ネットワークプログラミング関連の作業はすべてこいつに任せよう。ネットワーク関連の処理以外はほとんど高度(低レベル)なことしないのでこの部分だけ完全にきりはなしました

• 表面的には今のとこと出てこないので、ここの説明は省略。

• 詳しくはhttp://libpgen.org/documentation/components/netutils/ を参照

• もはや現在はネットワークユーティリティーな状態でないので、近々名前変えよう

Page 26: libpgenでパケット操作

完成したもの①

• 機能を綺麗に分担できています。

• アドレスクラス、パケットクラス、Netutilsを別々にインストールとかできたらいいかも

Page 27: libpgenでパケット操作

パケット送信はとりあえずできたしあとはたくさんのプロトコルに対応させていけばいい

Page 28: libpgenでパケット操作

パケット送信はとりあえずできたしあとはたくさんのプロトコルに対応させていけばいい

それだけじゃ大して面白くないしつまらない

よく考えたらscapyに勝る機能が何もない

Page 29: libpgenでパケット操作

設計段階②• 既存のパケットのバイナリを読み込ませてパケットクラスにパースできるようにしよう

• ならパケットの受信機能も簡単に実装するか

• pcapファイル読み込みたいTDUCTFに参加させてもらった時に発案pcapファイル読み込んで送ったり、受信した特定のパケットだけpcapファイルに保存したりとできたらかっちょいいかも

• 送受信を行う上でやはりディスクリタみたいなのがあると便利

Page 30: libpgenでパケット操作

パケットをキャストする機能を追加

• 以前まではパケットクラス-->バイナリの一方向のみの変換だった

• パケットクラスにcastメンバ関数を追加してバイナリをパースして、パケットクラスの形に変換して、解析を簡単にできるようにした

aabb ccdd eeff 0011 2233 4455 0806 00010800 0604 0001 0011 2233 4455 c0a8 0004aabb ccdd eeff c0a8 0001

パケットクラス

Page 31: libpgenでパケット操作

cast関数の問題点

• 例えばARPパケットのバイナリをDHCPとしてcastしようとすると危険→あらかじめパケットの種類を簡単に調べときたい

• ついでにIPアドレスとかMACアドレスとかポート番号とかで簡単に調べられる機能とかもあるといい

Page 32: libpgenでパケット操作

unknownパケット• unknown型のパケットって思ってください

• isUDP とか isICMP とかL4までの基本情報をまとめて解析してくれる特別なパケットクラス

• ポート番号とかでいろいろ絞り込めるようにしました。

Page 33: libpgenでパケット操作

unknownパケット

• こんな感じにパケットがだいたいどんな感じのパケットか、とか送信元とかが簡単に調べられる

• ポート番号が53か?とかで調べたい時はbool res = インスタンス名.portis(53);とかで調べられる。

Page 34: libpgenでパケット操作

簡易的なパケット受信機能

• 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

こっちでパケット解析とかをする

Page 35: libpgenでパケット操作

pcapファイルも読み込みたい

• せっかくバイナリのパース機能追加したならpcapファイルを読み込んでそこからパケットを受信したいってのが漢意気ってもんよ

• みんな大好きpcapファイル読めたらウケいいかも

• pcapngにも今度対応させますngに対応してるパケット解析ツール結構少ないから案外いいかも

なんてことになるかもしれない….

Page 36: libpgenでパケット操作

pcapファイルも読み込みたい

• ファイルポインタで基本どうりにファイル開いてパケットを書き込む時はパケットの先頭にpcapパケットヘッダを追加するだけ

• この機能が一番簡単に実装できたからL2で送信する機能より先に取りかかっとけば簡単だし作業加速したかも

magic  number

major  version minor  version

time  zorne

sigfigs

snaplen

link  type

pcap file header

timestampcaplenlen

pcap packet header

Page 37: libpgenでパケット操作

pgenディスクリプタ使いたい

• 今までのパケット送信部分はユーザがソケットを意識しなくてもいいようにうんこきもい実装になってた。

• 送受信を両方行うプログラムを書くならやっぱりを意識しないといけない

• pcapファイルに書き込んだり、ネットワークインターフェースから送信したりいろいろあるからまとめて管理できるようにした

Page 38: libpgenでパケット操作

pgenディスクリプタ使いたい

pgenディスクリプタ

pgen_open 関数or

pgen_open_offline関数

開きたいインタフェースやファイル名など

ディスクリプタの種類によって入出力先を指定できる上の例ではtest.pcapへの書き込み専用モードでパケットはtest.pcapに書き込まれる

Page 39: libpgenでパケット操作

完成したもの②• バイナリを解析して、パケットクラスで読み取れるようになった

• 受信したパケットを改変して別のインターフェースから送信することもできる

• pcapファイルにパケットを書き込んだり、pcapファイルひとつづつパケットを読み込んでcast関数で解析できるようになった。

• pgen_tって感じでディスクリプタを使えるようにした

• この時点で簡単なルータとかブリッジなら即席で作れます

Page 40: libpgenでパケット操作

libpgenで中間者攻撃のツール作成

• せっかくある程度使える状態にしたので、取りあえず好きなARPで実験的なのしました。

• 超適当にはしょって作ったARPスプーフィングでMITMアタックするプログラムです

• http://slankdev.net/blog/2015/08/30/libpgen-arp-mitm/

http://wp.me/p5YcBp-7N (短縮URL)

Page 41: libpgenでパケット操作

設計段階④ 現在

• 他のOSに対応させたい

• 拡張しやすくしたい

• 全体が正しいい動作をするのか自動でチェックする機能追加

• パケット解析ツールだしネットワーク以外のパケットも見たくね?某鮫ツールはいろいろ読めるし

Page 42: libpgenでパケット操作

他のOSに対応させたい

• とりあえず一番の愛機がMBPなので、OSXに対応させました。友達がMac使ってる人結構いるし、対応させたら使ってもらえるし

• OSXはBSD系なのでBSDに対応させるコードを追加すればいいだけ

• BSDはBPFってのでリンクレイヤープログラミングをすればいい

• LinuxのPF_PACKETよりなんか分かりやすいからこっちの方が好きだったり

Page 43: libpgenでパケット操作

他のOSに対応させたい

• OS依存している関数のみを#ifdef __linuxとかで囲むだけ

• あとはエンディアンに気をつけているかを全体的にチェックするだけ

• 一番ひっかったのはインストール場所。(まだ調べてない)OSXは/usr/local/includeとか/usr/includeにインクルードパス張ってなくて(怒)xcode.appの中にあるヘッダとかからインクルードしてる変態

• 知ってる人誰か教えて下さい ( > < )

Page 44: libpgenでパケット操作

拡張しやすくしたい

• 現在開発中です

• ユーザが簡単にプロトコルの追加とかできるようにしたかった。一人でこんな作業いつまでもやってらんない

• プロトコル解析のコードはコアな部分から独立させよう

• チーム開発しやすいようにしたい

Page 45: libpgenでパケット操作

全体が正しい動作をしてるか確かめる

• 対応させてるプロトコルが増えるとその分テストが大変になるので、自動化したい

• これも今実装中なんですけど、これがうまくいけばいろいろ楽になる。アドレスクラスは低機能だし、少ないからいいとして、パケットクラスの動作チェックを自動化したい

• 機能追加したり、リファクタリングしたりしたあと全体がうまく動くか確かめていたけど、毎回やってたらきりがない。。

• どうやってうまく動いているか確認しよう。。

• 各コンポーネントごとにチェックしていった方が良さそう

Page 46: libpgenでパケット操作

全体が正しい動作をしてるか確かめる

• パケットクラスでチェックが必要なのはバイナリ解析部分と生成部分

• サンプルパケットを幾つか読ませて、そこから再度バイナリを生成して元のパケットと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

キャスト

再度バイナリ生成

ここが同じか確かめる

Page 47: libpgenでパケット操作

ネットワーク以外のパケット• 開発初期と比べていろいろ拡張しやすくなってきたし、ネットワーク以外のパケットも操作できたらいいかも。

• USBとか、HDMIとかCTFの作問もできるかも

• あくまで、いろいろな勉強のためにそういうことしてる段階なので、社会貢献できていない。

• USB機器とかのファジングツールとか将来的にできたらタノシイカモネ

Page 48: libpgenでパケット操作

完成したもの ④ (まだ途中です)

• 一応BSD用のコードを追加できた、うまく動いている?

• 拡張しやすくする構造はwiresharkを参考にしました

• まだ現在製作中です

Page 49: libpgenでパケット操作

まとめ、感想 ①• ソースを読経する力がすこーしだけついたかなって感じです。

• 始めた時は/usr/include ? ナニソレオイシイノ だったので

• デバッグ力も少し

• プロトコルの知識もつきました

• OSのプロトコル実装の手抜きとかも見れるのが楽しいBSDのARPとか、LinuxのICMPとか…

Page 50: libpgenでパケット操作

まとめ、感想 ②• だいたい日本一の学生でパケットに詳しい鮫アイコンの人がscapyの普及活動を行っている時点でこのままでは到底敵わないではないか!

• scapyにない機能とかいろいろ追加したりいろいろやっていつかscapyと比べられるくらいのパケット解析ツールにしていきたいです

• 開発に時間がかかりすぎてる。

• http://libpgen.org にドキュメントとかも書いておいているので、一度見て文句などを言ってくれると元気がでます。

Page 51: libpgenでパケット操作

まとめ、感想 ③

• チーム開発とかやったことないから友達見つけてちょっとずつ協力してもらいたいと感じました

• 社会貢献してない

Page 52: libpgenでパケット操作

libpgenについて

• http://libpgen.org で詳細を説明してます。各プロトコルのパケットクラスの資料がまだ完成していないのでもう少し待ってください。。

Page 53: libpgenでパケット操作

最後に一言

• このライブラリは現在、一人で開発しているのですが、セキュリティキャンプ講師の方、 2015年度全国大会卒業生の方をはじめ、たくさんの方にアイディアや助言をいただいております。本当にありがとうございます。 今後とも宜しくお願いします。

Page 54: libpgenでパケット操作

aabb ccdd eeff 0011 2233 4455 0800 45002800 0001 0000 4006 b9a2 c0a8 b302 c0a86501 3039 3039 0000 0000 0000 0000 50012000 961c 0000

Page 55: libpgenでパケット操作

aabb ccdd eeff 0011 2233 4455 0800 45002800 0001 0000 4006 b9a2 c0a8 b302 c0a86501 3039 3039 0000 0000 0000 0000 50012000 961c 0000

ヒント

Page 56: libpgenでパケット操作

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 パケットです. ありがとうございました