编写一个返回libc攻击,但libc在内存中加载到0x00

时间:2011-10-15 17:47:14

标签: c buffer-overflow libc exploit

我正在为我的系统安全类编写一个返回libc攻击。首先,易受攻击的代码:

//vuln.c
#include <stdio.h>
#include <stdlib.h>

int loadconfig(void){
  char buf[1024];
  sprintf(buf, "%s/.config", getenv("HOME"));
  return 0;
}

int main(int argc, char **argv){
  loadconfig();
  return 0;
}

我想使用返回libc攻击。编译和调试程序:

$ gcc -g -fno-stack-protector -o vuln vuln.c
$ gdb vuln
(gdb) break loadconfig
(gdb) run
Reached breakpoint blah blah blah.
(gdb) p $ebp
$1 = (void *) 0xbfffefb0
(gdb) p system
$2 = {<text variable, no debug info>} 0x0016db20 <system>
(gdb) p exit
$3 = {<text variable, no debug info>} 0x001639e0 <exit>
(gdb) x/2000s $esp
...
0xbffff5af:    "SHELL=/bin/bash"

要执行攻击,我想将缓冲区溢出到loadconfig的返回地址(又名$esp+4),将其替换为system的返回地址,然后返回地址对于exit(因为system需要一个真实的返回地址),然后命令名称(SHELL=/bin/bash的地址加上6,以修剪SHELL=部分)。这应该可以通过制作1024个字符的crap的$HOME环境变量,然后是systemexit/bin/bash的小端地址来实现。

但是,对于我尝试的每台计算机,system都会加载到以0x00开头的地址,这将使sprintf正在读取的字符串终止并停止攻击。有没有办法迫使libc加载到内存中的其他位置,或者我是否误解了攻击?

作为参考,我在VirtualBox(Windows主机)中运行Ubuntu Server 11.10虚拟机,gcc版本4.6.1和gdb版本7.3-2011.08。编辑:ASLR已禁用,我使用-fno-stack-protector进行编译以删除金丝雀。由于我没有从堆栈中执行任何操作,因此我不需要execstack它。

2 个答案:

答案 0 :(得分:5)

将重要的libc函数映射到包含NULL字节的地址的行为称为ASCII装甲。 此保护是RedHat Exec-shield的一部分,目前已在最近的ubuntu发行版link上启用 要禁用它,您必须以root身份运行:

sysctl -w kernel.exec-shield = 0

解释here

顺便提一下,你可以找到有关如何绕过ASCII装甲的有趣资料here on exploit-db

答案 1 :(得分:1)

我相当肯定这在11.10是不可能的,至少在你提到的方式。看看:

https://wiki.ubuntu.com/Security/Features

详细而言,只是选择了一些问题:

(1)由于金丝雀值和其他原因,缓冲区溢出到esp + 4会引发分段错误异常

(2)你可能意味着要提取环境变量的地址,传统上它应该是ESP(主)+一定数量的字节。但是,由于现在甚至逻辑内存地址在编译后都被加扰/随机化,因此您将为每次运行获取$ HOME变量的不同内存地址,可能位于主堆栈另一侧的某处

(3)据我所知,目前还有其他方法可以阻止图书馆攻击的回归。我不太熟悉那些。这应该是你看到地址

的x00的原因

现在在ubunti系统上黑客攻击很难。如果您只需要为不支持当前发行版的类执行此操作,请在virtualbox中安装第一个ubunti发行版。奇怪的是,你所尝试的一切都会奏效。没有更多的“标准溢出攻击”你也参考 - 即使你巧妙地绕过金丝雀值等,设置nx位也不可能。同样地,虽然我不太确定如何解决从libc攻击的回归,但不要依赖于相信这在当前发行版中是可能的。祝你好运!