我开始研究软件安全,我很难弄清楚缓冲区溢出攻击和ROP攻击是什么。
据我所知,
缓冲区溢出攻击:
当缓冲区有一定大小时,填充缓冲区并添加额外代码,以便攻击者能够在代码或自己的外壳代码中执行另一个函数。
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攻击还是缓冲区溢出攻击?
发布于 2019-06-08 19:21:17
ROP攻击是一种有效负载,可以通过缓冲区溢出漏洞提供给堆栈上的缓冲区。(溢出其他缓冲区可以让您覆盖其他数据,例如结构或附近的其他全局数据,但不能控制程序计数器)。
缓冲区溢出是当不正确的边界检查或处理隐式长度数据(例如strcpy或strcat)允许恶意输入写入内存超过数组结束时。当数组被分配到调用堆栈上时,这变得很有趣,因此下面的事情之一就是这个函数的返回地址。
(理论上,覆盖静态数组结束后的静态变量可能是有用的,这也是缓冲区溢出。但是,缓冲区溢出通常意味着堆栈上有一个缓冲区,允许攻击者控制返回地址。从而获得指令指针的控制。)
除了一个新的返回地址之外,您的恶意数据还将包含更多数据,这些数据将位于该返回地址下面和上面的内存中。其中一部分是有效载荷。仅仅控制返回地址通常是不够的:例如,在大多数进程中,没有任何地方可以跳转到(没有其他输入)将监听TCP端口的shell。
传统上,您的有效负载将是机器代码(“外壳代码”),返回地址将是堆栈地址,您知道有效载荷将在那里着陆。(+-一张NOP幻灯片,这样你就不必完全正确了)。
栈ASLR和不可执行的堆栈使得传统的外壳代码注入方法在正常的现代程序中不可能利用缓冲区溢出。的“缓冲区溢出攻击”(我认为)意味着外壳代码注入,因为没有必要寻找更复杂的攻击。,但这不再是真的。
ROP攻击是指有效负载是由指令和/或某些字符串(如"/bin/sh" )弹出的返回地址和数据的序列。负载中的第一个返回地址将执行发送到可执行页中已知地址的一些已经存在的字节。
并尝试通过向
check()函数提供特定的输入来执行gets()函数。
check()的代码已经存在于目标程序中,所以最简单的攻击就是ROP攻击。
这是ROP攻击的绝对最简单的形式,在单一的已知地址上存在完全可以执行的代码,而不需要任何“函数args”。因此,这是一个很好的例子来介绍这个话题。
这是ROP攻击还是缓冲区溢出攻击?
两者都是。注入ROP有效负载是缓冲区溢出。
如果程序是用-z execstack -no-pie编译的,您还可以选择注入x86外壳代码,该代码执行mov eax, imm32 / jmp eax以跳转到已知的check绝对地址。在这种情况下,它将是缓冲区溢出,而不是ROP攻击;它将是代码注入攻击。
(您可能不会称它为“shell代码”,因为它的目的不是运行一个shell来替换程序,而是使用程序的现有代码来做一些事情。但是术语的使用往往很草率,所以我想很多人会把任何可注入的机器代码称为“外壳代码”,而不管它是做什么的。)
缓冲区溢出攻击: 当缓冲区有一定大小时,填充缓冲区并添加额外代码,以便攻击者能够在代码或自己的外壳代码中执行另一个函数。
“代码中”选项将是ROP攻击。将返回地址指向已在内存中的代码。
“或他/她自己的外壳代码”选项将是一种代码注入攻击。将返回地址指向刚刚溢出的缓冲区。(例如,通过在ret2reg上查找jmp esp小工具,直接或通过ROP攻击击败堆栈x86。)
这个“缓冲区溢出”定义仍然有点过于狭窄:它排除了覆盖其他一些关键变量(如bool user_authenticated)而不覆盖返回地址。
但是是的,代码注入和ROP攻击是两种主要的方式,代码注入通常不可能由不可执行的堆栈内存完成。
https://stackoverflow.com/questions/56508945
复制相似问题