ox0xo infosec tutorial

CTF4B2019 writeup

2019-05-26
CTF

今年も開催されたSECCON for Beginners CTFに参加していました。 私生活のタイミングが悪く短時間しか取り組めませんでしたが、駆け出しCTFerにちょうど良い難易度設定でやりがいのある問題が多かったように思います。 来年もぜひ開催していただきたいです。

Reversing

[warmup] Seccompare

バイナリファイルが渡されるのでIDAで開く。 プログラム実行時の引数である[rsi]とフラグである[rbp+s1]を比較している。 [rbp+var_14]に終端文字0x00が入っているので直前の[rbp+var_15]まで読み進めると 63 74 66 34 62 7b 35 74 72 31 6e 67 73 5f 31 73 5f 6e 30 74 5f 65 6e 30 75 67 68 7d

asciiで読むとctf4b{5tr1ngs_1s_n0t_en0ugh}でフラグが手に入る。

Linear Operation

バイナリファイルが渡されるのでIDAで開く。 ユーザー入力を[rbp+var_50]に格納してis_correct関数を通した結果が1なら正解ルートに入る。

is_correct関数はlinear_operationの名前通りの長い直列処理が続いている。

複雑なループが無いならangrで解けるのでは? ということでツールに任せたらフラグが手に入った。 angrで解けるパターンと解けないパターンがちょっとわかってきた気がする。

# python 3.5.2
# angr 8.19.4.5

import angr

p = angr.Project("/root/Downloads/seccon4b2019/linear")
state = p.factory.entry_state()
sim = p.factory.simulation_manager(state)
sim.explore(find=(0x400000+0xcf78,), avoid=(0x400000+0xcf86,))
if len(sim.found) > 0:
        print(sim.found[0].posix.dumps(0))

Misc

containers

正体不明のファイルが渡されるので識別の手がかりを探す。 末尾にフラグをSHA1でハッシュした文字列が入っていたが普通は逆計算出来ないと思うので別の手がかりを探す。 PNGが複数入っているようなのでこれを当たってみる。

# file containers
containers: data

# strings containers | tail
m:gl
`M_8
`iG~4
 F4>
Nl2T
~vWa
hG~4
IEND
VALIDATOR.import hashlib
print('Valid flag.' if hashlib.sha1(input('Please your flag:').encode('utf-8')).hexdigest()=='3c90b7f38d3c200d8e6312fbea35668bec61d282' else 'wrong.'.ENDCONTAINER


# binwalk containers | head

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
16            0x10            PNG image, 128 x 128, 8-bit/color RGBA, non-interlaced
107           0x6B            Zlib compressed data, compressed
738           0x2E2           PNG image, 128 x 128, 8-bit/color RGBA, non-interlaced
829           0x33D           Zlib compressed data, compressed
1334          0x536           PNG image, 128 x 128, 8-bit/color RGBA, non-interlaced
1425          0x591           Zlib compressed data, compressed
1914          0x77A           PNG image, 128 x 128, 8-bit/color RGBA, non-interlaced

ファイルの抽出にはforemostを使う。

# foremost containers
Processing: containers
|*|

# cd /root/Downloads/seccon4b2019/output/png
root@user-VirtualBox:~/Downloads/seccon4b2019/output/png# ls
00000000.png  00000003.png  00000008.png  00000013.png  00000018.png  00000023.png  00000028.png  00000033.png  00000038.png  00000043.png  00000048.png  00000053.png  00000058.png
00000001.png  00000005.png  00000010.png  00000015.png  00000020.png  00000025.png  00000030.png  00000035.png  00000040.png  00000045.png  00000050.png  00000055.png  00000060.png
00000002.png  00000007.png  00000011.png  00000016.png  00000021.png  00000027.png  00000032.png  00000037.png  00000042.png  00000046.png  00000052.png  00000056.png  00000061.png

Dump

未知のファイルが渡されるので識別するとtcpdump。

# file dump
dump: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 262144)

wiresharkで読むとflagが格納されたサーバにwebシェル経由でコマンドを送っている。

URLデコードしてコマンドを読みやすくする。 flagファイルを8進数でダンプしていることが分かる。

従ってサーバから返された文字列037 213 010 ...を8進数から10進数に戻してバイナリファイルとして扱ってやれば良い。

with open("/root/Downloads/seccon4b2019/dump.txt", "r") as f:
  data = f.read()
  data = data.replace("\r\n"," ").split(" ")
  data = list(map(lambda x:int(x, 8), data))
  data = bytes(data)
  with open("/root/Downloads/seccon4b2019/dump.out.bin", "wb") as w:
    w.write(data)

gzip圧縮されたファイルが入手できるので拡張子をgzに変えてから解凍する。 更にtar圧縮されているので解凍する。

# file dump.out.bin
dump.out.bin: gzip compressed data, last modified: Sun Apr  7 10:46:34 2019, from Unix

# mv dump.out.bin dump.out.bin.gz

# gunzip dump.out.bin.gz

# file dump.out.bin
dump.out.bin: POSIX tar archive

# tar xf dump.out.bin

# ls -la
total 1536
drwxr-xr-x 2 root root    4096  5月 26 16:05 .
drwxr-xr-x 4 root root    4096  5月 26 16:02 ..
-rw-r--r-- 1 root root  767400  5月 26 16:02 dump.out.bin
-rw-r--r-- 1  501 staff    233  4月  7 19:43 ._flag.jpg
-rw-r--r-- 1  501 staff 788359  4月  7 19:43 flag.jpg


Similar Posts

Content