本記事は、オライリージャパンから発行されている「サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考(原題:Black Hat Python)」の学習メモとして、書籍ではPython2で書かれていますが、自分なりに解釈した上でPython3に書き直しをしています。
前回はPython標準のsocketライブラリを用いたプログラミング方法について学びました。
今回はScapyという強力なライブラリを使用したネットワークプログラミングの方法について学んでいきます。
Scapyとは
Scapyは、Pythonで書かれたパケットの解析・作成などを行うライブラリです。
現在では2018年12月にリリースされた2.4.0が最新バージョンとなっています。
以下が公式のドキュメントになります。
Welcome to Scapy’s documentation! — Scapy 2.4.0-dev documentation
sniff()を使ってパケットキャプチャしてみる
Scapyでは、TCPやUDPまたはARPなどの低レイヤのプロトコルまで、簡単にパケットを作成することができます。
また、通常ではありえないパケットやIPアドレスおよびMACアドレスの偽装なども簡単に実装することが可能です。
今回はその手軽さを実感するために、sniff関数を使ってパケットキャプチャをしてみます。
スクリプトの作成
今回は手始めにARPパケットのみをフィルタにかけて、パケットキャプチャをしてみます。
# arp_sniff.py from scapy.all import * def arp_monitor_callback(pkt): pkt.show() sniff(prn=arp_monitor_callback, filter="arp", count=1)
sniff()については、"prn"でフィルターにマッチしたパケットを渡すコールバック関数を指定します。
コールバック関数であるarp_monitor_callback()では、show()メソッドを使って、キャプチャしたパケットの詳細を表示します。
ここでは"filter"に"arp"を指定し、このフィルターはBPF(Berkeley Packet Filter)というフォーマットで記述します。
Linuxで使うtcpdumpコマンドやWiresharkなどもこの構文を使ってパケットをフィルタします。
"count"には、キャプチャするパケットの数を指定します。
今回は動作確認のため、パケットを一つキャプチャしたら終了します。
動作確認
それでは、上記のスクリプトを起動してみます。
> python arp_sniffer.py ###[ Ethernet ]### dst = ff:ff:ff:ff:ff:ff src = 02:00:4c:4f:4f:50 type = 0x806 ###[ ARP ]### hwtype = 0x1 ptype = 0x800 hwlen = 6 plen = 4 op = who-has hwsrc = 02:00:4c:4f:4f:50 psrc = 192.168.2.1 hwdst = 00:00:00:00:00:00 pdst = 192.168.2.254
送信されたARPパケットの詳細がしっかりとキャプチャされているのが確認できました。
最後に
今回はScapyを使ったパケットの取得および解析方法について学びました。
前回までで学んだsocketライブラリを使うよりも少ないコーディングで実装することができます。