我正在为我的系统安全类编写一个返回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
环境变量,然后是system
,exit
和/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
它。
答案 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攻击的回归,但不要依赖于相信这在当前发行版中是可能的。祝你好运!