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
  1. sub rsp, 30hなのでスタック領域が0x30byte確保されている。
  2. cmp [rbp+var_4], 0DEADBEEFhなので 0x04の位置に0xDEADBEEFが存在すればFLAGを入手できる。
  3. call _getsに渡されるバッファアドレスは lea rax, [rbp+var_30]で指定されている通り0x30なので 0x30-0x04分のオフセットを考慮する必要がある。

deadbeef

この条件を踏まえたコードで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}
  • スタックの状態を想像するのが解決の糸口