SECCON CTF 横浜大会 (SECCON 2012 予選) writeup
SECCON CTF 横浜大会にチーム 0x0として参加しました。
チームメンバーは nash氏、wasao氏、waidotto氏、nullmineral氏と私です。
成績
score: たぶん8120
\
✌(‘ω’)
解けた問題の解説
パスワードを答えよ (Binary)
問題ページにあるzipファイルを解凍するとtlscb-iwa.exeが出てくる。
$ file tlscb-iwa.exe
tlscb-iwa.exe: PE32 executable (console) Intel 80386, for MS Windows
\
OllyDbgで実行すると、エントリポイントに到達する前に TLS Callbacksでコードを実行していることが分かります。
IDA に食わせると TlsCallbacksという怪しい配列があることが分かります。
この配列の関数が スレッドの起動時と終了時に呼ばれます。\
.rdata:0040610C TlsCallbacks dd offset TlsCallback_0_copy_commandline
.rdata:0040610C ; DATA XREF: .rdata:TlsCallbacks_ptr.o
.rdata:00406110 dd offset TlsCallback_3_encode
.rdata:00406114 dd offset TlsCallback_4_xor
.rdata:00406118 dd offset TlsCallback_3_encode
.rdata:0040611C dd offset TlsCallback_4_xor
.rdata:00406120 dd offset TlsCallback_5_check
.rdata:00406124 dd 0
\
これらの関数を読み進めていくと、
- TlsCallback_0では コマンドラインを取得してバッファにコピー
- TlsCallback_3では 256バイトのバイト列(以下encval)を使って バッファを置換
- TlsCallback_4では 0xab, 0xcd, 0xefでバッファをXOR
- TlsCallback_5では TlsCallback_3 とTlsCallback_4をさらに実行した後、バイト列(以下checkval)とバッファが一致していたら正解とする
ことが分かる。
つまり、checkvalから入力を逆算すると答えが分かる。
checkval = [0xd4, 0x46, 0xf0, 0x4f, 0xb6, 3, 6, 0xaa, 0xfe, 0x31, 0xae, 0x8a]
encval = open("tlscb-iwa.exe").read()[0x6a00:0x6a00 + 256]
xorval = [0xab, 0xcd, 0xef]
def callback_reverse4():
for i in range(len(checkval)):
checkval[i] ^= xorval[i % 3]
def callback_reverse3():
#answer[i] = encval[answer[i]]
for i in range(len(checkval)):
checkval[i] = encval.index(chr(checkval[i]))
callback_reverse4()
callback_reverse3()
callback_reverse4()
callback_reverse3()
callback_reverse4()
callback_reverse3()
print "".join([chr(c) for c in checkval])
答えは「7LSCaLL13aCK」\
Find the key. (Network)
USB通信のキャプチャからkeyを取り出す問題。
\
$ file 7d157d658655465f35a6e06fc95b1446
7d157d658655465f35a6e06fc95b1446: tcpdump capture file (little-endian) - version 2.4, capture length 65535)
\
\
\
Wiresharkでパケットを眺めてみると、 USBメモリとの通信をキャプチャしたものであることと、
SCSI Read パケットで LBAとセクタ数を指定して read要求をし、 直後のSCSI Data In パケットでその結果を受け取っていることが分かる。
Mass Storageのプロトコルを調べるのが面倒なので、かなり適当な方法でパケットをパースしてディスクイメージを組立てた。
#-*- coding: utf-8 -*-
from struct import *
from scapy.all import *
pcap = rdpcap("7d157d658655465f35a6e06fc95b1446")
disk = open("disk.img", "w")
lba = 0
skip = False
for pkt in pcap:
signature = pkt.load[0x40:0x40 + 4]
urb_type = pkt.load[8]
transfer_type = ord(pkt.load[9])
endpoint = ord(pkt.load[0x0a])
device = ord(pkt.load[0x0b])
bus_id = unpack('<H', pkt.load[0x0c:0x0c + 2])[0]
#SCSI Read Inパケットのみを取り出す。汚い
if urb_type == 'C' and transfer_type == 3 and endpoint == 0x81 and device == 4 and bus_id == 1:
if signature == 'USBS':
continue
if skip:
#read 以外のSCSIコマンドの結果
continue
#read の結果
data = pkt.load[0x40:]
disk.seek(lba * 512)
disk.write(data)
#SCSI Readコマンドのみを取り出す。汚い
if urb_type == 'S' and transfer_type == 3 and endpoint == 0x02 and device == 4 and bus_id == 1:
if signature != "USBC":
continue
scsi_type = ord(pkt.load[0x4f])
if scsi_type != 0x28:
#other request
skip = True
continue
#scsi read コマンド
lba = unpack('>L', pkt.load[0x51:0x51 + 4])[0]
skip = False
\
ディスクイメージをバイナリエディタで見ると最後の方に答えらしき文字列があることが分かる。
答えは「Haiyore! Yuzuharatan!」でした。
\
ちなみに、ディスクイメージの中身は↓こんな感じでした。
$ sudo mount -t vfat -o loop,offset=4194304,rw,iocharset=utf8,codepage=932 disk.img mnt
mnt$ ls -al
合計 1892
drwxr-xr-x 2 root root 32768 1月 1 1970 .
drwxrwxr-x 3 superbacker superbacker 4096 12月 24 03:39 ..
-rwxr-xr-x 1 root root 1811122 10月 6 16:52 dame.bmp
-rwxr-xr-x 1 root root 21 10月 6 16:41 key.txt
-rwxr-xr-x 1 root root 4632 7月 16 01:56 やる夫.png
mnt$ cat key.txt
Haiyore! Yuzuharatan!\
mnt$ xdg-open dame.bmp
mnt$ xdg-open やる夫.png
\
別解
\
strings→目grepすると、最後のほうに答えらしきものがあることが分かる。
key.txtはサイズが小さいので、複数のセクタ もしくは パケットにまたがることはない。そのため、ディスクイメージを組み立てる必要はなかった。
動かした気になろう (Binary)
問題文: 忘れた。
“ファイルが出力する最後の行を答えよ"という内容だったと思う。
\
$ file mondai
mondai: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, BuildID[sha1]=0x4d9acce3c74d7d3431fcf3a7d9651902e3b3aa09, with unknown capability 0x41000000 = 0x13676e75, with unknown capability 0x10000 = 0xb0401, not stripped
# chroot ~/multistrap-debian-squeeze-powerpc
# (path)/mondai
Hello Fukuoka
Hello Kyutech
\
QEMUとPowerPC環境を使い、ファイルを実行すると文字列が出る。
「Hello Kyutech」が答えでした。
反省点
Find the key.をstringsした時答えに気づかなかったため、時間がかかってしまった。
もっと時間があればAccending Orderを解けたと思う。
\