TDUCTF 2015 「Portscan」のWrite-upを丁寧に
TDUCTF 2015 に参加した.connpass.com
今回はPortscan(500pt)というNetwork問題で最も点数の高かった問題のWrite-upを書く.解けた人が4人と少なく,tsharkの使い方を知らない人が多い感じがしたので,試行の過程・ツールの使い方も含めて丁寧に書いていく.他の問題は大したものを解いてない or CTF終了後にWrite-up発表があったので,今回は省略する.
最後にCTFの結果と所感を述べる.
tsharkの使い方
問題を解く前提知識として,tsharkの使い方をまとめておく.tsharkとはWiresharkのCUI版であり,Wiresharkで出来るようなことがCUI上で行える.pcapデータを整形したり統計をとったりしたいときなどはこのtsharkが大活躍することがある.スクリプトを書く必要もなく,ワンライナーのコマンドですべてが解決する.Wiresharkがインストールされている環境であればtsharkも一緒に入っているはず.
オプション一覧も日本語でまとめられている.
CTFでよく使うオプションまとめ
-r [infile]
: [infile]で指定したpcapファイルを読み込む.-Y "[display filter]"
: [display filer]で指定したパケットに絞り込む.フィルタはWiresharkのDisplay filterで使えるものと同じ.-T fields
,-e [field]
: パケットのフィールドを指定して表示させる.フィールドの名前も同様にWiresharkのDisplay filterで使えるものと同じ.複数選択するときに区切り文字を指定したいときは-E separator=[char]
を使ってお好みで.-c [packet count]
: 表示するパケットの数を指定する.
すべてのDisplay filterは以下のページで参照できる.
Wiresharkでパケットを開いて,「このパケットのこのフィールドのDisplay filterを知りたい!」という時は,そのフィールド上で右クリック→Apply as Filter→SelectedでWiresharkのFilter欄に表示される.
コマンド例
「secretmsg.pcapを読み込み,送信先IPアドレスが192.168.0.238のパケットに絞り込み,送信先ポート,UDPチェックサム,ペイロードを並べて10パケット表示させたい」とき,コマンドは以下のようになる.
# tshark -r secretmsg.pcap -Y "ip.dst==192.168.0.238" -T fields -e udp.dstport -e udp.checksum -e data.data -c 10
出力は以下のとおり.
➜ tshark -r secretmsg.pcap -Y "ip.dst==192.168.0.238" -T fields -e udp.dstport -e udp.checksum -e data.data -c 10 1 0x0000f25f 23 1 0x00000000 2 0x0000f25d 23 2 0x00000000 3 0x0000f25b 23 3 0x00000000 4 0x0000f259 23 4 0x00000000 5 0x0000f257 23 5 0x00000000
パケットに指定したフィールドが存在しない場合は空白になる.また,ICMP Destination Unreachableなどの"パケットの中にパケットが存在する"ようなパケットの場合には,指定したフィールドがカンマで区切って複数個表示される場合がある.
Portscan (Network 500pt) Write-up
問題文:
ポートスキャンが仕掛けられた!ん?何かメッセージがついてきているぞ?
問題ファイル:
secretmsg.pcap
pcapファイルが渡されるので開いてみると,UDPスキャンを行っている通信が見れる.
ポートスキャンといえばSYNスキャンが主流だが,UDPのサービスを調査するときにはUDPパケットを送ってスキャンを行うことがある.ちなみにNmapでは-sU
オプションを付けてUDPスキャンを行うことが出来る.
今回のpcapでは,192.168.100.60から192.168.0.238(1~1288ポート)に向かってUDPパケットを送信し,すべてのポートからICMP Destination Unreachableが返ってきている.
問題文より,192.168.100.60が送信するUDPパケットにメッセージが隠されていることが推測できる.パケットにメッセージが隠されているとすれば,当然そのペイロードに注目する.ペイロードを見てみると,それぞれ1バイトのデータがあり,ぱっと見で0x20,0x23,0x0aの3種類しかないことがわかる(たまにペイロードがないものもある).
そこで,先ほどのtsharkを用いてUDPパケットのペイロードのみを抽出してみる.
➜ tshark -r secretmsg.pcap -Y "udp and !(icmp)" -T fields -e data.data 23 23 23 23 23 23 20 20 23 23 23 ....
Display filter を"!(icmp)"としたのは,前述のようにICMPパケットの中にUDPパケットが含まれており,"udp"というFilterだけではICMPパケットも同時に表示されるためである.これをリダイレクト(>)を用いてテキストファイル(out.txt)に出力しておく.
ここで,0x20,0x23,0x0aをそれぞれASCII文字で表すと,0x20はスペース,0x23は#(シャープ),0x0aは制御文字で改行を意味する.
先ほど生成したテキストファイルに対して,スクリプトを用いて文字の置換を行う.またペイロードがなかったものに関しては"@"とでもしておく.
solve.py
f = open("out.txt","r") str = "" for l in f: l = l.strip() if(l==""): l ="@" if(l=="0a"): l="\n" if(l=="20"): l=" " if(l=="23"): l="#" str += l print str f.close()
実行結果
ということで,フラグの文字がASCIIアートで表示された.
ヒントとしては,0x0aの出現回数が少なく,等間隔に存在するため,ここで改行したら長方形型になるかな?と推測できる.
フラグはTDU{PORTSCAN_PAYLOAD}
結果と所感
結果は69人中9位というつらい成績だった.上の人を見るとア。という感じ.
悔やまれる点
- Networkのメールの問題.zipファイルを見た瞬間に既知平文攻撃ができるとわかり,すぐにpkcrackを使ったがなぜか解凍できなかった.ファイルが壊れていたのか,既知平文のデータ量が少なかったのか,VMのメモリが足りなかったのか未だに謎.
- Webのアップロードのやつ.同じような問題が前回のTDUCTFでも出ており,しかも時間内に解いていたにも関わらず今回はやらなかった.やればよかった.
- 全体的にどうでもいいところでつまづくところがあった(pcap破損してて開けねえ!とか).競技中は音楽など聞かずに運営の方の話をちゃんと聞こうと思った.
問題数の割に時間が足りなくて全てに取り組むことができなくて残念だったが,取り組んだ問題に関しては楽しく解くことができた.
運営のみなさま,ありがとうございました!