盾怪网教程:是一个免费提供流行杀毒软件教程、在线学习分享的学习平台!

编写自己的缓冲区溢出使用程序

时间:2024/10/30作者:未知来源:盾怪网教程人气:

[摘要](内存低址) 注: 字符A的十六进制ASCII码值为0x41. iii) 从上图可以看出: 如果我们用的是进程可以访问的某个地址而不是0x41414141 来改写调用函数的返回地址, 而这个地址正好...
 (内存低址) 

注: 字符A的十六进制ASCII码值为0x41. 

iii) 从上图可以看出: 如果我们用的是进程可以访问的某个地址而不是0x41414141 
来改写调用函数的返回地址, 而这个地址正好是我们准备好的代码的入口, 那么 
进程将会执行我们的代码. 否则, 如果用的是进程无法访问的段的地址, 将会导 
致进程崩馈--Segment Fault Core dumped (段出错内核转储); 如果该地址处有 
无效的机器指令数据, 将会导致非法指令(Illigal Instruction)错误, 等等. 

4) 缓冲区在Heap(堆)区或BBS区的情况 
i) 如果缓冲区的内存空间是在函数里通过动态申请得到的(如: 用malloc()函数申请), 那 
么在函数的栈帧中只是分配了存放指向Heap(堆)中相应申请到的内存空间的指针. 这种 
情况下, 溢出是发生在(Heap)堆中的, 想要复盖相应的函数返回地址, 看来几乎是不可 
能的. 这种情况的利用可能性要看具体情形, 但不是不可能的. 
ii) 如果缓冲区在函数中定义为静态(static), 则缓冲区内存空间的位置在非初始化(BBS)区, 
和在Heap(堆)中的情况差不多, 利用是可能的. 但还有一种特姝情况, 就是可以利用它来 
复盖函数指针, 让进程后来调用相应的函数变成调用我们所指定的代码. 


3. 从缓冲区溢出的利用可以得到什么? 
从上文我们看到, 缓冲区溢出的利用可以使我们能够改写相关内存的内容及函数的返回地址, 从而 
改变代码的执行流程, 让进程去执行我们准备好的代码. 

但是, 进程是以我们当前登录的用户身份来运行的. 能够执行我们准备好的代码又怎样呢? 我们还 
是无法突破系统对当前用户的权限设置, 无法干超越权限的事. 

换句话来说, 要想利用缓冲区溢出得到更高的权限, 我们还得利用系统的一些特性. 

对于UNIX来讲, 有两个特性可以利用. 
i) SUID及SGID程序 
UNIX是允许其他用户可以以某个可执行文件的文件拥有者的用户ID或用户组ID的身份来执行该 
文件的,这是通过设置该可执行文件的文件属性为SUID或SGID来实现的. 
也就是说如果某个可执行文件被设了SUID或SGID, 那么当系统中其他用户执行该文件时就相当 
于以该文件属主的用户或用户组身份来执行该文件. 
如果某个可执行文件的属主是root, 而这个文件被设了SUID, 那么如果该可执行文件存在可利 
用的缓冲区溢出漏洞, 我们就可以利用它来以root的身份执行我们准备好的代码. 没有比让它 
为我们产生一个具有超级用户root身份的SHELL更吸引人了, 是不是? 

ii) 各种端口守护(服务)进程 
UNIX中有不少守护(服务)进程是以root的身份运行的, 如果这些程序存在可利用的缓冲区溢出, 
那么我们就可以让它们以当前运行的用户身份--root去执行我们准备被好的代码. 
由于守护进程已经以root的身份在运行, 我们并不需要相对应的可执行文件为SUID或SGID属性. 
又由于此类利用通常是从远程机器上向目标机器上的端口发送有恶意的数据造成的, 所以叫做 
"远程溢出"利用. 

4. 一个有问题的程序 
以下例程纯属虚构, 如有雷同, 纯属巧合. 

/* 
* 文件名 : p.c 
* 编译 : gcc -o p p.c 
*/ 

#include <stdio.h> 

void vulFunc(char* s) 

char buf[10]; 
strcpy(buf, s); 
printf("String=%s\n", buf); 


main(int argc, char* argv[]) 

if(argc == 2) 

vulFunc(argv[1]); 

else 

printf("Usage: %s <A string>\n", argv[0]); 




这个例程接受用户在命令行的字串输入, 然后在标准输出(屏幕)上打印出来. 我们可以看出在 
vulFunc()这个函数里, 定义了一个最多可以装十个字符的缓冲区buf. 如果我们在命令行输入 
小于等于十个字符的字串, 则一切都很正常. 但是, 如果我们输入的字串长度大于十呢? 情况 
会怎样? 缓冲区太小装不下了, 所以溢出了? 答案有待于具体分析一下才知道. 

对于这个程序在不同操作系统下的分析和模拟攻击. 请看第二部份基楚篇 


第二部份 基楚篇 
5. Linux x86 平台 
本文使用了如下Linux平台: 
Red Hat Linux release 6.2 (Zoot) 
Kernel 2.2.14-12 on an i586 

所使用的编译器及版本: 
bash$ gcc -v 
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs 
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) 

注意: 不同版本的编译器编译相同代码所生成的机器指令可能不同. 

1) 例程p.c在Linux x86平台下的剖析. 
i) 首先我们编译p.c并用gdb对相关函数进行反汇编 
结果见如下清单: 

bash$ gcc -o p p.c 
bash$ gdb p 
GNU gdb 19991004 
Copyright 1998 Free Software Foundation, Inc. 
GDB is free software, covered by the GNU General Public License, and you are 
welcome to change it and/or distribute copies of it under certain conditions. 
Type "show copying" to see the conditions. 
There is absolutely no warranty for GDB. Type "show warranty" for details. 
This GDB was configured as "i386-redhat-linux"... 
(gdb) disas main 
Dump of assembler code for function main: 
0x804842c <main>: push %ebp 
0x804842d <main+1>: mov %esp,%ebp 
0x804842f <main+3>: cmpl $0x2,0x8(%ebp) 
0x8048433 <main+7>: jne 0x8048448 <main+28> 
0x8048435 <main+9>: mov 0xc(%ebp),%eax 
0x8048438 <main+12>: add $0x4,%eax 
0x804843b <main+15>: mov (%eax),%edx 
0x804843d <main+17>: push %edx 
0x804843e <main+18>: call 0x8048400 <vulFunc> 
0x8048443 <main+23>: add $0x4,%esp 
0x8048446 <main+26>: jmp 0x804845b <main+47> 
0x8048448 <main+28>: mov 0xc(%ebp),%eax 
0x804844b <main+31>: mov (%eax),%edx 
0x804844d <main+33>: push %edx 
0x804844e <main+34>: push $0x80484bb 
0x8048453 <main+39>: call 0x8048330 <printf> 
0x8048458 <main+44>: add $0x8,%esp 
0x804845b <main+47>: leave 
0x804845c <main+48>: ret 
0x804845d <main+49>: nop 
0x804845e <main+50>: nop 
0x804845f <main+51>: nop 
End of assembler dump. 
(gdb) disas vulFunc 
Dump of assembler code for function vulFunc: 
0x8048400 <vulFunc>: push %ebp 
0x8048401 <vulFunc+1>: mov %esp,%ebp 
0x8048403 <vulFunc+3>: sub $0xc,%esp 
0x8048406 <vulFunc+6>: mov 0x8(%ebp),%eax 
0x8048409 <vulFunc+9>: push %eax 
0x804840a <vulFunc+10>: lea 0xfffffff4(%ebp),%eax 
0x804840d <vulFunc+13>: push %eax 
0x804840e <vulFunc+14>: call 0x8048340 <strcpy> 
0x8048413 <vulFunc+19>: add $0x8,%esp 
0x8048416 <vulFunc+22>: lea 0xfffffff4(%ebp),%eax 
0x8048419 <vulFunc+25>: push %eax 
0x804841a <vulFunc+26>: push $0x80484b0 
0x804841f <vulFunc+31>: call 0x8048330 <printf> 
0x8048424 <vulFunc+36>: add $0x8,%esp 
0x8048427 <vulFunc+39>: leave 
0x8048428 <vulFunc+40>: ret 
0x8048429 <vulFunc+41>: lea 0x0(%esi),%esi 
End of assembler dump. 


这里我们只对所关心的main和vulFunc两个函数进行反汇编分析. 

ii) 进程的运行及其在内存中的情况分析 
我们用gdb来跟踪看看进程是如何在内存中运行的. 

首先把程序调入. 
bash$ gdb p 
GNU gdb 19991004 
Copyright 1998 Free Software Foundation, Inc. 
GDB is free software, covered by the GNU General Public License, and you are 
welcome to change it and/or distribute copies of it under certain conditions. 
Type "show copying" to see the conditions. 
There is absolutely no warranty for GDB. Type "show warranty" for details. 
This GDB was configured as "i386-redhat-linux"... 
(gdb) 

把断点设到main的第一条可执行汇编指令上 
(gdb) b *0x804842c 
Breakpoint 1 at 0x804842c 

运行程序 
(gdb) r AAAAAAAA 
Starting program: /home/vcat/p AAAAAAAA 

Breakpoint 1, 0x804842c in main () 

在断点处停下来了. 
看一下这时各寄存器的值 
(gdb) i reg 
eax 0x4010b3f8 1074836472 
ecx 0x804842c 134513708 
edx 0x4010d098 1074843800 
ebx 0x4010c1ec 1074840044 
esp 0xbffff6bc -1073744196 
ebp 0xbffff6d8 -1073744168 
esi 0x4000ae60 1073786464 
edi 0xbffff704 -1073744124 
eip 0x804842c 134513708 
eflags 0x246 582 
cs 0x23 35 
ss 0x2b 43 
ds 0x2b 43 
es 0x2b 43 
fs 0x0 0 
gs 0x0 0 
cwd 0xffff037f -64641 
swd 0xffff0000 -65536 
twd 0xffffffff -1 
fip 0x40034d70 1073958256 
fcs 0x35d0023 56426531 
fopo 0xbfffe400 -1073748992 
fos 0xffff002b -65493 

我们这里关心的是栈底(ebp), 栈顶(esp)及指令寄存器(eip). 
此时, ebp的值为0xbffff6d8, esp的值为0xbffff6bc, 相差28个字节. 
eip的值为0x804842c, 正好是我们所设的断点. 
(注: 这里的值可能会随着程序运行在不同的系统环境而不同) 

我们再看看当前栈帧里有什么内容? 
(gdb) x/8x $esp 
0xbffff6bc: 0x400349cb 0x00000002 0xbffff704 0xbffff710 
0xbffff6cc: 0x40013868 0x00000002 0x08048350 0x00000000 

也就是说, main函数刚被调用时进程在内存中的相关部份的影像是这样的: 
(内存高址) 

关键词:编写自己的缓冲区溢出运用程序




Copyright © 2012-2018 盾怪网教程(http://www.dunguai.com) .All Rights Reserved 网站地图 友情链接

免责声明:本站资源均来自互联网收集 如有侵犯到您利益的地方请及时联系管理删除,敬请见谅!

QQ:1006262270   邮箱:kfyvi376850063@126.com   手机版