缓冲区溢出攻击和ROP攻击有什么区别?

时间:2019-06-08 18:04:45

标签: security assembly buffer-overflow exploit

我开始研究软件安全性,但是我遇到了什么是缓冲区溢出攻击和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攻击还是缓冲区溢出攻击?

1 个答案:

答案 0 :(得分:2)

ROP攻击是您可以通过缓冲区溢出漏洞提供的一种有效负载。


缓冲区溢出是指错误的边界检查或隐式长度数据的处理(例如strcpystrcat)使恶意输入写内存超出数组末尾的情况。当在调用堆栈上分配数组时,这变得很有趣,因此它后面的事情之一就是该函数的返回地址。

(从理论上讲,覆盖静态数组末尾的静态变量可能会用作漏洞利用程序,这也可能是缓冲区溢出。但是通常,缓冲区溢出意味着堆栈上有缓冲区,从而使攻击者可以控制返回地址。从而获得对指令指针的控制。)

除了新的寄信人地址外,您的恶意数据还将包括更多数据,这些数据将存储在该寄信人地址下方和上方的内存中。其中的一部分是有效载荷。通常,仅控制返回地址是不够的:例如,在大多数进程中,没有任何地方可以跳转到该地址(没有其他输入),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种主要方法,通常无法执行的堆栈存储器使代码注入成为不可能。