ROP编程(36)
ROP编程
什么是ROP?
ROP是一种–返回导向编程,这是一种高级的内存攻击技术,可以用来进行绕过。绕过一些防御,比如:内存不可执行和代码签名。
栈溢出的特点是ret处,那么ROP的核心思想就是利用ret结尾指令序列吧栈中应该返回EIP的地址改成我们需要的值,从而控制程序的执行流程
ROP是一种绕过开启了NX一种办法。NX是:不可执行的意思。
NX
原理:将数据所在内存页标志为不可执行,当程序溢出成功转入shellcode的时候,程序会尝试在数据页面上执行指令,这个时候CPU就会抛出异常,而不是去执行恶心代码。
当NX开启的时候,往栈上或者堆上注入代码的方法难以发挥效果。
这个时候就可以用ROP来进行绕过。
ROP
思想:在栈缓冲区溢出的基础上,利用程序中已有小片段【gadgets】来改变某些寄存器或者变量的值,从而控制程序的执行流程。
gadgets
- 就是以ret结尾的指令序列。
- 通过这些指令序列,我们可以修改某些地址的内容,方便控制程序的执行顺序
核心在于
- 利用指令集中的ret指令,改变了指令流的执行顺序
条件
- 程序存在溢出,并且可以控制返回地址
- 可以找到满足条件的gadgets以及gadgets的地址
- 如果gadgets每次的地址是不固定的,那么就需要想办法来动态获取对应的地址了
基本的ROP
- ret2text
- ret2shellcode
- ret2syscall
- ret2libc
- ..
例子:
题目链接:
下载下来:首先运行来看看
可以用checksec ret2shellcode
来看看它开保护没有
很明显啥保护都没,铁定溢出
他说:No system for you this time !!!
没有system – 也就是没有后门
这里保持不信的态度,用IDA看看
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
进入眼前的就是gets 和 puts 函数,这俩个实在是太容易溢出了
strncpy 把s中的100个字符copy到buf2中
点过去看到这个buf2是放在bss段中
bss段
- 通常是指用来存放程序中未初始化的全局变量的一块内存区域
- bss段属于静态内存分配
这里动态调试一下,看看bss段是否可以执行
- 涨知识了,数据段还可以执行
看到这个buf2的地址:0804A080
通过vmmp这个指令
0x08049f08 0x0804a0e4 rw-p
发现这个是可以写的
0804858
首先我们将payload输入到变量s也就是栈上,然后将main函数的返回地址覆盖为buf2_addr(此bss段可执行),之后main函数执行strncpy(buf2, &s, 100u);(虽然shellcode被截断为100,但是被截断的内容只是A,并不影响shellcode的完整度),将内容复制到了buf2,由于main函数的返回地址被覆盖为shellcode的地址,因此在main函数执行完毕之后,EIP转向执行shellcode
1 | #!/usr/bin/env python |
主要还是要以后慢慢琢磨