分享
 
 
 

在Linux上利用FormatString漏洞

王朝system·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

与缓冲区溢出漏洞相比,Format String漏洞的历史就要短得多,而且实际的例子也少很多。比较著名的象Linux上的rpc.statd,还有wu-ftpd版本2.x,前一段时间我还想找这个2.x版本的wu-ftpd源程序来Exploit一下,找来找去没找到,估计作者把它藏起来了。

不过网上倒是有几篇介绍Format String漏洞的文章值得一读,象Team teso的"Exploiting Format String Vulerabilities",还有Kalou/Pascal Bouchareine的"Format string vulnerability",这些文章的引用率应该很高,你们到Google上保证找得到。当然,我觉得我的这篇文章也不错,欢迎大家来看啦,只是有史以来很多人都喜欢读原著,象我大学时教政治的老师,他就经常说要读马列原著才行,翻译的都不灵光。

这一章我将在Caldera Linux V2.2上演示Format String的原理以及Exploit例子,不过我想其它Flavor的Linux也能试验这一章用到的程序。演示用的机器是claton----这是我美国梦开始的地方。

针对Linux操作系统或者Linux应用程序的Exploit多如牛毛,毕竟Linux是Open Source的,各方豪杰都要围着它们显显身手、切磋武功----我也花了不少时间在Linux上操练(不好意思,自己称自己为豪杰)。

Anyway,新时代的口号: Long Live OpenSource!!!!

关于Format String漏洞的背景介绍之一:

按老规矩,在作Exploit之前,我们要先介绍一下Format String的背景知识。请看下面的程序fordemo.c

<======================fordemo.c=========================

main()

pb

char buf[512]="";

char tmp[512]="hello world\n";

memset(buf, '\0', 512);

read(0, buf, 512);

printf(tmp);

printf("%s\n%s", buf,tmp);

printf("%x==%x==%x==%x\n");

}

<========================================================

fordemo连续三次调用格式输出函数printf:第一次与第二次都属正常,大家在编写程序时也经常如此这般地调用printf;但第三次调用却有些奇怪,为什么只有格式化符号%x?根据printf的语法要求,这次调用还需要另外四个输入参数,类似于下面的形式才对:

printf("%x==%x==%x==%x\n",forx1,forx2,forx3,forx4);

那么,当程序fordemo调用第三个printf时,它会如何反应呢?让我们深入到fordemo的汇编码中看看。

先编译程序fordemo.c,编译器并不认为第三个printf调用有语法错误。

[moda@claton format]$ gcc fordemo.c -o fordemo -g

用gdb运行fordemo:

[moda@claton format]$ gdb fordemo

GNU gdb 4.17.0.11 with Linux/x86 hardware watchpoint and FPU support

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-COL-linux"...

/*

先在函数printf入口设置断点

*/

(gdb) b printf

Breakpoint 1 at 0x80484f4

(gdb) r

Starting program: /home/moda/format/fordemo

Breakpoint 1 at 0x40066c1c: file printf.c, line 30.

hello babby

/*

这里通过函数read输入字符串"hello babby"给缓冲区buf

*/

Breakpoint 1, printf (format=0xbffff8b8 "hello world\n") at printf.c:30

/*

已经进入第一次printf函数调用----"printf(tmp)",然后在断点处停下。我们看看进程当前的call stack以及当前堆栈栈顶$ESP附近的内存内容:

*/

(gdb) bt

#0

printf (format=0xbffff8b8 "hello world\n") at printf.c:30

#1

0x80486a9 in main () at fordemo.c:10

#2

0x4003286f in __libc_start_main (main=0x8048608 <main, argc=1,

argv=0xbffffd04, init=0x8048470 <_init, fini=0x8049530 <_fini,

rtld_fini=0x4000ab70 <_dl_fini, stack_end=0xbffffcfc)

at ../sysdeps/generic/libc-start.c:92

(gdb) x/20x $esp

0xbffff8a8:

0x40102e9c

0xbffffcb8

0x080486a9

0xbffff8b8

0xbffff8b8:

0x6c6c6568

0x6f77206f

0x0a646c72

0x00000000

0xbffff8c8:

0x00000000

0x00000000

0x00000000

0x00000000

0xbffff8d8:

0x00000000

0x00000000

0x00000000

0x00000000

0xbffff8e8:

0x00000000

0x00000000

0x00000000

0x00000000

/*

观察一下call stack可以知道,0x080486a9是函数printf返回main的地址,它前面的0xbffffcb8应该是main的堆栈栈底($EBP)地址,而它后面的0xbffff8b8就是函数printf的输入参数,也就是指向缓冲区tmp的起始地址的指针。我们可以核实一下:

*/

(gdb) x/s 0xbffff8b8

0xbffff8b8:

"hello world\n"

/*

上面这个"printf(tmp)"调用是最简单的情况,只需要一个字符串指针0xbffff8b8作为输入参数,而且这个指针参数是紧接在printf返回地址后面。

我顺便提醒一下(因为可能有人在打瞌睡):指针0xbffff8b8所指向的缓冲区tmp就紧跟在这个指针的后面。

下面继续执行,我们要看一下第二个printf调用时内存的内容。

*/

(gdb) c

Continuing.

hello world

Breakpoint 1, printf (format=0x8049562 "%s\n%s") at printf.c:30

/*

程序已经进入"printf("%s\n%s", buf,tmp);",现在停在断点处。我们看看进程当前的call stack以及当前堆栈栈顶$ESP附近的内存内容:

*/

(gdb) bt

#0

printf (format=0x8049562 "%s\n%s") at printf.c:30

#1

0x80486c4 in main () at fordemo.c:11

#2

0x4003286f in __libc_start_main (main=0x8048608 <main, argc=1,

argv=0xbffffd04, init=0x8048470 <_init, fini=0x8049530 <_fini,

rtld_fini=0x4000ab70 <_dl_fini, stack_end=0xbffffcfc)

at ../sysdeps/generic/libc-start.c:92

(gdb) x/20x $esp

0xbffff8a0:

0x40102e9c

0xbffffcb8

0x080486c4

0x08049562

0xbffff8b0:

0xbffffab8

0xbffff8b8

0x6c6c6568

0x6f77206f

0xbffff8c0:

0x0a646c72

0x00000000

0x00000000

0x00000000

0xbffff8d0:

0x00000000

0x00000000

0x00000000

0x00000000

0xbffff8e0:

0x00000000

0x00000000

0x00000000

0x00000000

/*

0xbffffcb8是函数main的堆栈栈底($EBP)地址,0x080486c4是printf返回main的地址,而紧跟在0x080486c4后面的应该是printf函数的输入参数。源程序中的printf有三个输入参数:"%s\n%s"、buf、tmp,它们分别对应着0x080486c4后面的0x08049562、0xbffffab8、0xbffff8b8。在printf最后作格式化输出时,0xbffffab8、0xbffff8b8所指向的字符串将替换格式化字符串"%s\n%s"中的两个%s。

*/

(gdb) x/s 0x08049562

0x8049562 <_IO_stdin_used+18:

"%s\n%s"

(gdb) x/s

0xbffffab8

0xbffffab8:

"hello babby\n"

(gdb) x/s 0xbffff8b8

0xbffff8b8:

"hello world\n"

/*

从上面的内存分配情况可以看出,当printf的输入参数中有格式化符号时,比如说"%s\n%s",系统会把实现(或者说替换)这些格式化符号的"真实的"参数或参数指针分配在格式化符号串的后面。这一点对于我们理解Format String的漏洞很重要!的确很重要!

如果你还不理解这一点的重要性,请想象一下如果我们忘记提供替换"%s\n%s"的两个字符串(不管是有意还是无意),printf会这么处理??

这就是我们第三个printf调用"printf("%x==%x==%x==%x\n");"所要说明的!

*/

(gdb) c

Continuing.

hello babby

hello world

Breakpoint 1, printf (format=0x8049568 "%x==%x==%x==%x\n") at printf.c:30

/*

现在程序已经进入"

printf("%x==%x==%x==%x\n")"。我们看看程序当前的call stack以及当前堆栈栈顶$ESP附近的内存内容:

*/

(gdb) bt

#0

printf (format=0x8049568 "%x==%x==%x==%x\n") at printf.c:30

#1

0x80486d1 in main () at fordemo.c:12

#2

0x4003286f in __libc_start_main (main=0x8048608 <main, argc=1,

argv=0xbffffd04, init=0x8048470 <_init, fini=0x8049530 <_fini,

rtld_fini=0x4000ab70 <_dl_fini, stack_end=0xbffffcfc)

at ../sysdeps/generic/libc-start.c:92

(gdb) x/20x $esp

0xbffff8a8:

0x40102e9c

0xbffffcb8

0x080486d1

0x08049568

0xbffff8b8:

0x6c6c6568

0x6f77206f

0x0a646c72

0x00000000

0xbffff8c8:

0x00000000

0x00000000

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有