我开始研究软件安全性,但是我遇到了什么是缓冲区溢出攻击和ROP攻击的问题。
据我了解,
缓冲区溢出攻击:
当缓冲区具有特定大小时,请填充缓冲区并添加其他代码,以使攻击者可以在该代码或自己的shellcode中执行其他功能。
ROP攻击:
提供可以覆盖返回地址的特定输入,以便攻击者可以控制流。
但是两者之间的确切区别是什么?
我觉得两个人都只是提供了过多的输入,以覆盖不应接近的区域。
例如,如果我有一个代码
1 #include <stdio.h>
2
3 void check(){
4 printf("overflow occurs!\n");
5 }
6
7 int main(int argc, char* argv[]){
8 char buffer[256];
9 gets(buffer);
10 printf("%s\n", buffer);
11 return 0;
12 }
并尝试通过向check()
函数提供一定的输入来执行函数gets()
。
这是ROP攻击还是缓冲区溢出攻击?
答案 0 :(得分:2)
ROP攻击是您可以通过缓冲区溢出漏洞提供的一种有效负载。
缓冲区溢出是指错误的边界检查或隐式长度数据的处理(例如strcpy
或strcat
)使恶意输入写内存超出数组末尾的情况。当在调用堆栈上分配数组时,这变得很有趣,因此它后面的事情之一就是该函数的返回地址。
(从理论上讲,覆盖静态数组末尾的静态变量可能会用作漏洞利用程序,这也可能是缓冲区溢出。但是通常,缓冲区溢出意味着堆栈上有缓冲区,从而使攻击者可以控制返回地址。从而获得对指令指针的控制。)
除了新的寄信人地址外,您的恶意数据还将包括更多数据,这些数据将存储在该寄信人地址下方和上方的内存中。其中的一部分是有效载荷。通常,仅控制返回地址是不够的:例如,在大多数进程中,没有任何地方可以跳转到该地址(没有其他输入),execve
会使得外壳监听TCP端口。
传统上,您的有效负载将是机器代码(“ shellcode”),而返回地址将是您知道有效负载将到达的堆栈地址。 (+-NOP幻灯片,因此您不必完全正确地放置它。)
堆栈ASLR和不可执行的堆栈使传统的Shellcode注入方法无法利用普通现代程序中的缓冲区溢出。 “缓冲区溢出攻击”曾经(我认为)暗示着要注入shellcode,因为不需要寻找更复杂的攻击。</ strong>但是,这不再是事实。
ROP攻击是指有效载荷是返回地址序列和要通过pop
指令和/或某些字符串如"/bin/sh"
弹出的数据的时候。有效负载中的 first 返回地址将执行发送到可执行页中某个已知地址处的某些现有字节。
并尝试通过向
check()
函数提供一定的输入来执行函数gets()
。
目标程序中已经存在check()
的代码,因此最简单的攻击是ROP攻击。
这是ROP攻击的绝对最简单的形式,可以在单个已知地址存在执行所需功能的代码,而无需任何“函数args”。因此,是介绍该主题的一个很好的例子。
这是ROP攻击还是缓冲区溢出攻击?
都是。注入ROP有效负载是缓冲区溢出。
如果程序是使用-z execstack -no-pie
编译的,则还可以选择注入例如x86 shellcode执行了mov eax, imm32
/ jmp eax
跳转到已知的check
绝对地址。在这种情况下,这将是缓冲区溢出,而不是ROP攻击;这将是代码注入攻击。
(您可能不会将其称为“ shellcode”,因为其目的不是运行替换程序的shell,而是使用现有的代码进行操作 程序。但是术语经常被草率地使用,因此我认为许多人都会将任何可注入的机器代码称为“ shellcode”,而不论它的作用是什么。)
缓冲区溢出攻击:
当缓冲区具有特定大小时,请填充缓冲区并添加其他代码,以使攻击者可以在该代码或自己的shellcode中执行其他功能。
“在代码中”选项将是ROP攻击。您将返回地址指向已经在内存中的代码。
“或他/她自己的shellcode”选项将是代码注入攻击。您将返回地址指向刚溢出的缓冲区。 (例如,直接或通过ret2reg ROP攻击来击败堆栈ASLR,例如,在x86上寻找jmp esp
小工具。)
此“缓冲区溢出”定义仍然太窄:它不包括覆盖其他一些关键变量(例如bool user_authenticated
),而没有覆盖返回地址。
但是,是的,代码注入和ROP攻击是2种主要方法,通常无法执行的堆栈存储器使代码注入成为不可能。