我正在为我的系统安全类编写一个return to 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;
}
我想使用回血攻击。编译和调试程序:
$ 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个字符的$HOME
环境变量,然后是system
、exit
和/bin/bash
的小端地址来实现。
然而,对于我尝试过的每台计算机,system
在以0x00开始的地址加载,这将null终止sprintf
正在读取的字符串并阻止攻击死亡。是否有某种方法可以强制libc
在内存的其他地方加载,或者我误解了攻击?
作为参考,我在VirtualBox (Windows主机)中运行Ubuntu Server 11.10虚拟机,gcc
版本4.6.1和gdb
版本7.3-2011.08。编辑:ASLR被禁用,我用-fno-stack-protector
编译以删除金丝雀。因为我没有从堆栈中执行任何内容,所以我不需要execstack
。
将重要的libc函数映射到包含NULL字节的地址的行为称为ASCII装甲。这种保护是RedHat Exec-shield的一部分,目前在最近的ubuntu发行版中已启用link要禁用它,你必须以root用户运行:
sysctl -w kernel.exe -shield=0
顺便说一下,您可以在exploit-db
我相当肯定这在11.10上是不可能的,至少在您提到的方面是不可能的。看一下:
https://wiki.ubuntu.com/Security/Features详细说明,并挑选一些问题与您的想法:
(1)由于金丝雀值和其他原因,缓冲区溢出到esp+4将引发分割错误异常
(2)可能意味着提取环境变量的地址,传统上是在ESP (main) +一定数量的字节。然而,由于现在即使是逻辑内存地址在编译后也会被打乱/随机化,因此每次运行都会为$HOME变量获得不同的内存地址,可能在主堆栈的另一侧
(3)据我所知,现在还有其他方法可以阻止图书馆攻击的返回。我对这些不太熟悉。这应该就是为什么地址
看到x00的原因现在在ubuntu系统上进行黑客攻击是很困难的。如果你只是需要为一个不坚持当前发行版的类做这个,那么在virtualbox中安装第一个ubuntu发行版。神奇的是,你所做的一切都会成功。没有更多的"标准溢出攻击",你也引用-即使你聪明地绕过金丝雀值等,设置nx位使这是不可能的。同样,虽然我不太确定libc攻击的返回是如何解决的,但不要依赖于相信这在当前的发行版上是可能的。好运!