【发布时间】:2015-02-12 16:48:28
【问题描述】:
在研究和测试了对 32 位 linux 机器的各种类型的攻击(shellcode 注入、返回 libc、GOT 覆盖)之后,我专注于 64 位世界。我在执行基本的 shellcode 注入攻击时没有任何问题。
但现在我正试图返回对 x86_64 的 libc 攻击,以绕过 NX 堆栈保护。现在,在 64 世界中,易受攻击程序的文本段使用空字节保护,因此您无法将执行重定向到受害者内部的指令。
(gdb) disas main
Dump of assembler code for function main:
0x00000000004005bc <+0>: push %rbp
0x00000000004005bd <+1>: mov %rsp,%rbp
.........................................................
0x0000000000400600 <+68>: callq 0x400480 <strcpy@plt>
0x0000000000400605 <+73>: lea -0x40(%rbp),%rax
.........................................................
End of assembler dump.
地址的 8 个字节中有 5 个是空字节(4 个中的 1 个是空字节 -> 找到 32 位 pop-ret 小工具不是解决方案)。
与 32 架构一样,libc 中的指令使用 NULL 字节进行保护:
(gdb ) p execve<br/>
$ 1 = { <text variable, no debug info> } 0x7ffff7ad2cc0 <execve>
8 个字节中的 2 个是 null 字节。
我找到了一篇关于我正在尝试实现的技术的文章:
但是在将输入(带有空字节?)传递给程序(文章的第 241 行)时,它只是说“将其输入受害者”。据我所知,没有办法利用易受攻击的函数(gets、strcpy)在字符串中注入具有多个空字节的输入。
如果有人能帮助我理解这一点或就 x86_64 机器上的 ret2libc 攻击提供建议,我将不胜感激。
【问题讨论】:
-
gets在换行处停止,因此它应该接受输入中嵌入的null字节。 -
如果您将攻击字符串作为程序参数注入(而不是使用gets或strcpy)并且程序接受可变数量的参数,您可以通过传入空字符串作为参数来注入更多的空值。跨度>
-
"inject an input with more null byte in a string" -> 使用我的 shell printf 似乎可以做到:
printf "blablabla\0\0\0\0 ... \0hellowworld\n" | ./a.out -
谢谢。一直在基于 strcpy 的受害者程序上工作,我对 get 的行为做出了绝对错误的假设。所以我猜你可能会说:如果漏洞是由于 get 的存在,则有可能实现 return-to-libc 漏洞利用(包含许多空字节),但如果漏洞是由于 strcpy 的存在,则不是可能会意识到这一点,因为 strcpy 将在第一个空字节处停止。我错了吗?任何其他观点都可以接受。
-
我也有同样的问题。你有没有想出一个方法来实现它?显然,环境变量损坏在这里不起作用,堆栈执行也被禁用。 ret2libc 的想法很简单,很容易在 32 位机器上实现。
标签: c linux security x86-64 buffer-overflow