2024年12月30日に開催されたAlpacaHack Round 8 (Rev)に参加しました。
1問も解けませんでした。
が、Writeupを書かないと、またgdbの書き方を忘れてしまうので、やったことを備忘として書きます。
1. gdbする前の事前調査
サイトから問題ファイルをダウンロードします。masking-tape というファイルでした。
lessします(私はいつでもlessします。「バイナリだけどほんとに見る?」と聞かれても見ます)。
elfでした。
objdump -d |less します。
ちゃんとobjdumpできているようなので、ファイルに書き出しました。
masking-tape.oを眺めます。難しくはなさそうですが、stackを使ってガチャガチャしているので、静的解析はいったん諦めました。
2. gdbで冒頭を眺める
gdbします。
$ gdb masking-tape
runします。
(gdb) run
第1引数にが必要だよ、と怒られました。正解のフラグを第1引数に取ると良いことが起きるのでしょう。
第1引数に hoge を入れてみます。で、runします。
(gdb) set args hoge
(gdb) run
3. 中身を見ていく
(gdb) layout asm
(gdb) break main
(gdb) run
少し進めましょう。
(gdb) stepi
(gdb) stepi
一応、レジスタを見ておきましょう。
i rは省略しないと info registerです。
このあとは c [Enter] と打てば抜けられます(必要回数だけ、c [Enter]を打ちます)。
レジスタを指定することもできます。i r rax などと打ちます。
あてはありませんが、-0x34(%rbp)の中身を見てみましょう
(これの記法をいつも忘れる)。
(gdb) p/x *(char *)($rbp-0x34)
0x2が入っていました。<main+19>の行の比較から想像するに、ガードの一種でしょうか?
と思っていたのですが、あとから実験したら、入力文字列がないときには0x1でした。ということはargc?いつか調べましょう。
4. 進む
下矢印キーで、見ていきましょう。
一行前のコマンドをもう一度入力したいときは、上矢印ではなくて Ctrl-p を必要回数押しましょう。ちなみに、コマンドの方では左右矢印も使えません。
ずーっと下の方まで見ていくと、strcmpしています。ブレイクポイントを貼って、そこまで行きましょう。
(gdb) b *main+398
(gdb) c
雰囲気的に rsiの中身と rdiの中身を比較しているのでしょう。
値を見てみましょう。
(gdb) p/x *(char *)($rsi)
(gdb) p/x *(char *)($rdi)
0x3と0x8ですね。合わないのですね。Flagはhogeではないのでしょう。
ここまでで入力文字列をぐちゃぐちゃにして(=マスキングテープを使って)、同じようにぐちゃぐちゃにしたFlagと比較するのでしょう。
\nがあるか探してみましょう。strcmpを使うのであれば、0x0で終わらなければなりません。strcmpが困らないよう、0x0は0x0に写像されるはずです。
rsiの5文字目が0x0でした!入力した文字はhoge(4文字)なので、理屈は通っています。
5. その後
このあと、入力文字列を Alpaca などにして試してみましたが、解答にはたどり着けませんでした。
他の方のWriteupを読んで復習します。
AlpacaHackの中の方、いつも楽しい時間をありがとうございます。