SECCON CTF 2019 QUALS writeup

SECCON CTF 2019 QUALS

yharima で参加.今回は6人で参加.
自分にあまり人権はなかったが,メンバーが頑張ってくれて 1954pts で 45位.決勝は厳しそう.
pwn 担当なのでいつも通り pwn ばっかり手を出してたけど爆死しました.

ソース: https://github.com/yuta1024/ctf_log/tree/master/SECCON_CTF_2019_QUALS

f:id:yharima:20191020162004p:plain

Beeeeeeeeeer

最初は pwn がなかったので適当に手を出した.
実行するとわけわからん感じだけど,中身をみるとやたら長い base64 エンコードされたものがある.
echo <やたらながい> |base64 -d|gunzip|bash 圧縮されてるし解凍して bash に詳してるし怪しい.
この部分を取り出すと for 文が回ってたりするがまた長い base64 がある.
ただ今度は暗号化されてるようで echo <やたらながい> |base64 -d|openssl aes-256-cbc -d -pass pass:$(echo -n $n|md5sum |cut -c2,3,5,12) -md md5 2>/dev/null |bash; となっている.
$n は上のほうでランダムに決定されていて取りうる範囲は 1 - 10 なので適当に1から10ためしてみると3で復号できる.
また難読化されたものがでるが,末尾が SECCON{$S1$n$_____};echo -e '\033[?7h';となっていてフラグっぽい.
$n3 として $S1 は? と思ったけどメンバーがすでに解析終わっていたようで hogefuga らしい.
あとは $_____ だけどどうすれば…とおもっていたらメンバーが順番に echo していけば読めると教えてくれたので読んでいくとどうやら bash らしい.
というわけで bash といれてみると,以下のようになった.

$ S1=hogefuga n=3 bash beer3
Enter the password
bash
Good Job!

                                                                                                                            }

どゆこと…?でも Good Job だからあってるんだよなあとおもって strace にかける,

$ S1=hogefuga n=3 strace bash beer3
(snip)
write(1, "Good Job!\n", 10Good Job!
)             = 10
write(1, "\n", 1
)                       = 1
write(1, "\33[?7l                           "..., 1024                                                                      4
write(1, "     ", 5     )                    = 5
write(1, "SECCON{hogefuga3bash}\n", 22SECCON{hogefuga3bash}
) = 22
write(1, "\33[?7h\n", 6
)                = 6
read(255, "", 8192)                     = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
exit_group(0)                           = ?
+++ exited with 0 +++

フラグでとるやん!制御文字でクリアでもされているのか?という話に.
というわけで SECCON{hogefuga3bash} が答え.

Sum

実行すると数字を与えて最後に 0 を入れると加算結果を表示してくれる.
1 1 1 1 0 みたいなのはいいけど 1 1 1 1 1 0 みたいにするとセグフォで落ちる.

=> 0x40077a <sum+35>:   mov    QWORD PTR [rax],0x0

このときに rax0x0で入力を他の数字にかえてみる.(1 1 1 1 1 1).

=> 0x40077a <sum+35>:   mov    QWORD PTR [rax],0x0

どうも6個目の入力のアドレス先に 0 を代入してるらしい.さらに読み進めていくとここに加算された結果を足しこんでいくようだ.
ということは任意のアドレスを書き換えることができる.ひとまず書き換えが1回だけでは何も出来ないので main が何回も実行されるようにしたい.
6個以上入力を食わすと exit されるので exit の got を上書きして main に飛ぶようにする.
注意しないといけないのは6個の合計値が加算されるので,書き換えたい先のアドレス分の値は引いておかないといけない.
ここまできたら libc のアドレスを leak して one_gadget のアドレスを求めたら exit の got を上書きして飛ばしてあげれば良い.
ただ,libc を leak する方法で迷走した.GOT を上書きしてなんとかしたいが,都合よく libc のアドレスを leak できそうな引数をとってるものがない.
setup をみると setvbuf0x601060(stdout) が指定されていてちょっと使えそうなきがしたのでまず exit => main から exit => _start にして setup が何度も呼ばれるようにする.
そして setvbufputs に書き換えて実行してみるもどうもそれっぽい値がでない.
ここから迷走したが最終的には 0x601060 にさらに puts@got のアドレスを書き込んでやると libc が leak できたのであとは one_gadget に飛ばした.他にいい方法がありそうな気もする.

https://github.com/yuta1024/ctf_log/blob/master/SECCON_CTF_2019_QUALS/sum/sum.py

$ python sum.py
[+] Opening connection to sum.chal.seccon.jp on port 10001: Done
[+] libc_base addr = 0x7fee79528000
[*] Switching to interactive mode
$ ls
bin
boot
dev
etc
flag.txt
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
start.sh
sum
sys
tmp
usr
var
$ cat flag.txt
SECCON{ret_call_call_ret??_ret_ret_ret........shell!}

まとめ

2問しかも1つは半分くらいメンバーも手を出していたので人権1.5だった.
pwn 難しすぎなのと heap から逃げてたけどいい加減向き合うことにします. one は解けないといけない問題であった‥.
決勝でれたらいいな….

嘆き

lazy

無限に時間を溶かした上に解けなかった問題.
ID/PASS は BOF して抜いてバイナリを拾ってくるまでは簡単.
さらに BOF があるので ROP し放題なわけだが libc をダウンロードできない.
無理やり ROP してダウンロードしてみるも 4MB くらいで EOF が返ってくる.
中の関数などを使って直接フラグを表示させる方法も試行したが,おそらくシェルをとってその上で同じディレクトリにある cat コマンドを使わないとだめな雰囲気を感じた. 以下のようにフラグファイルが見えて他のファイルが読めたので心がつらかった.

$ python lazy.py
[+] Opening connection to lazy.chal.seccon.jp on port 33333: Done

[+] Receiving all data: Done (193B)
[*] Closed connection to lazy.chal.seccon.jp port 33333
run.sh
lazy
ld.so
cat
.profile
libc.so.6
810a0afb2c69f8864ee65f0bdca999d7_FLAG
.bashrc
q
.bash_logout
run.sh
Sending 68 bytes#!/bin/sh

export HOME="/home/lazy"
./ld.so --library-path . ./lazy
$ python lazy.py
[+] Opening connection to lazy.chal.seccon.jp on port 33333: Done

[+] Receiving all data: Done (52B)
[*] Closed connection to lazy.chal.seccon.jp port 33333
810a0afb2c69f8864ee65f0bdca999d7_FLAG
No such file!

もっと勉強します….

追記

繰り上げで国内決勝に出れることになりました! :tada: