CTF終了後に@kusano_kさんのwrite-upを参考にさせて頂いたものです。
前置き
pwnカテゴリの[warmup] conditionで提供されたサーバプログラムを逆アセンブルしたところ 0xdeadbeefという4byteの文字列を指定アドレスに読み込ませればFLAGが得られる事は分かった。 単純に4byteを送信してもダメなのでデータの送信方法を工夫する必要がある。
スタックの状態を読む
競技中は0xDEADBEEF
の渡し方が分からなかったが
バッファオーバーフローを使えば良いらしい。
その前提でアセンブリを改めて眺めてみる。
var_30= byte ptr -30h
var_4= dword ptr -4
push rbp
mov rbp, rsp
sub rsp, 30h
mov [rbp+var_4], 0
mov edi, offset format ; "Please tell me your name..."
mov eax, 0
call _printf
lea rax, [rbp+var_30]
mov rdi, rax
mov eax, 0
call _gets
cmp [rbp+var_4], 0DEADBEEFh
jnz short loc_4007BF
sub rsp, 30h
なのでスタック領域が0x30byte確保されている。cmp [rbp+var_4], 0DEADBEEFh
なので 0x04の位置に0xDEADBEEF
が存在すればFLAGを入手できる。call _gets
に渡されるバッファアドレスはlea rax, [rbp+var_30]
で指定されている通り0x30なので 0x30-0x04分のオフセットを考慮する必要がある。
この条件を踏まえたコードでdeadbeefの受け渡しに成功した。 リトルエンディアンなのでDEADBEEFはEFBEADDEにする必要がある。
b'OK! You have permission to get flag!!'
b'\nctf4b{T4mp3r_4n07h3r_v4r14bl3_w17h_m3m0ry_c0rrup710n}\n'
まとめ
- FLAGはctf4b{T4mp3r_4n07h3r_v4r14bl3_w17h_m3m0ry_c0rrup710n}
- スタックの状態を想像するのが解決の糸口