《模糊测试--强制发掘安全漏洞的利器》阅读笔记(二)
第二部分 6-8章
主要讲了本地模糊测试的数据生成方法与原则,具体的模糊测试的方法,具体的模糊测试的工具
重要知识点
- 模糊测试的优点是自动化,自动化的生成可重现的测试用例。
- 注意生成模糊试探值的集合,并非是完备集
- 类UNIX的权限管理:用户,组,其他
普通知识点
自动化与数据生成
- 选择有效的编程语言,有用的构造块,合适的模糊值
- 可重用性和重现性
- 有用的库和工具
- ETHEREAL/WIRESHARK:包含很多开源的协议分析器
- LIBDASM/LIBDISASM:免费开源反汇编库,反汇编AT&T和Intel
- LIBNET/LIBNETNT:用于向底层网络报构建和注入数据包
- LIBPCAP:创建跨平台的网络捕获和分析工具提供支持
- METRO PACKET LIBRARY:C#库,提供IPv4,TCP,UDP,ICMP交互的抽象接口,帮助创建包嗅探器和网络分析工具
- PTRACE:Unix平台上的调试工具
- PYTHON扩展:Pcapy,Scapy,PyDbg
- 选择合适的编程语言,没有特殊要求,灵活就好:shell,C,java,Ruby,Python等等都可以
数据生成与模糊试探值
模糊测试不是说用完备的测试集去做测试,而是选择有特点,有代表性的数据去做测试。
- 模糊试探值:由存在潜在危险的模糊字符串和模糊数据组成的集合。
-
整数值:试探值注意选取容易导致上溢、下溢的数、测试值倍数的数
-
字符串重复:经典长字符串
perl -e print "A"*5000
-
字段分隔符:Sendmail协议头处理安全漏洞,分隔符如下
!@#$%^&*()-_=+{}|;:'",<.>/?~` -
格式化字符串:例如%d,%08x,%s等,这些会导致从栈中进行内存读取;%n是唯一会导致对内存写入操作
-
字符转换:在做字符转换时需要动态分配内存来存储转换后的数据大小,这容易导致基于堆的缓冲区溢出。如IE浏览器将UTF-8转为Unicode时
-
目录遍历:模糊试探值列表应该包含
../../
和....
这样的目录遍历修饰符 -
命令注入:只要会向
exec()
或是system()
等API传递未经过滤掉,或是不恰当过滤的用户数据,都潜在对包含有命令注入安全漏洞。如下:directory = socket.recv(1024) listing = os.system("ls /" + directory) socket.send(listing)
由于缺乏过滤,例如当传入
var/lib;rm -fr /
时,就会引起灾难性的后果
-
环境变量与参数模糊测试
本地模糊测试可用来做提权操作。
-
获取参数的3种方式:标准输入输出、命令行参数和进程环境变量。
- 命令行参数:argv,argc
- 环境变量:如HOME,PATH,USER等
-
本地模糊测试原则:在一个具有特权的应用中找到允许普通用户提升权限的缓冲区溢出漏洞
-
寻找测试目标:目标一般是执行时具有高特权的程序。特点是setuid或是setgid位被置位。使用find命令可以找出这些程序:-perm指明权限,-o使用"或"逻辑
find / -type f -perm -4000 -o -perm -2000
Linux的文件有三组权限,分别对应用户、组、其他。例如:ddvv拥有读写权限,staff拥有读权限,其他没有任何权限
-rw-r-----@ 1 ddvv staff 62K 11 4 15:42 gr_gsm.docx
-
本地模糊测试方法:由于环境变量和命令行参数都是简单的ASCII字符串,所有可以采用基础的手工测试方法对其进行模糊测试。例如使用perl来测试HOME变量
HOME=`perl -e 'print "X"x10000'`
-
枚举环境变量:
- 利用库预加载的特性,采用hook的方式劫持
getenv()
函数,将调用记录到日志文件 - 采用调试的方法,如利用GDB,查看
getenv()
调用时的参数
- 利用库预加载的特性,采用hook的方式劫持
-
自动化的环境变量模糊测试:使用库预加载的特性,hook上
getenv()
函数,可快速检查不安全的环境变量使用。-
使用GPL sharefuzz工具,可以在setuid应用中找到大量的安全漏洞。将编写好的C语言代码编译到一个共享库中,并使用操作系统的预加载功能,就可以测试了,代码如下:
gcc -shared -fPIC -o my_getenv.so my_getenv.c LD_PRELOAD=./mygetenv.so /usr/bin/targe
-
-
检测问题:识别奔溃的几种方式
- 检查应用的返回值:如果应用因为一个未被处理掉信号而终止,shell返回码应该等于128加上信号读值。例如段错误(segmentation fault)会导致shell返回139;由于非法指令终止,则返回132
- 使用fork,然后在子进程中使用execve,在父进程中使用wait或waitpid,检查wait/waitpid中的状态值来判断奔溃
- 如果希望捕获被应用程序处理的信号,是使用系统的调试API,附加到进程上,在信号处理子例程被调用前截获它。在UNIX上可以私用ptrace达成这个目的,不过ptrace的兼容性不好,换系统了需要重新配置。
自动化的环境变量与参数模糊测试
主要利用iFUZZ工具进行本地模糊测试。
- iFUZZ模块
- argv模糊测试器模块:对argv[0],argv[1]进行模糊测试
- 单选项/多选项模糊测试器模块:简单地针对每一个可能的选项,把字符串值传给被测应用
- getopt模糊测试器模块:对getopt进行模糊测试
- 开发iFUZZ工具
- 开发思路是让熊模块化和可扩展。
- 首先开发基础引擎和辅助功能
- 接着开发argv[0]模糊测试模块
- 然后是单选项模糊测试模块
- 再然后是多选项模糊测试模块
- getopt模糊测试模块
- 最后是捕获异常的模块
- 开发使用的语言:C语言,性能好一些
- 案例研究:使用这个工具发现了IBM AIX 5.3上的超过50个本地安全漏洞
- 优缺点
- iFUZZ没有考虑系统性能,使用了硬编码的sleep让系统保持低负载
- iFUZZ没有提供选项来制定触发崩溃的字符串的大致长度
- 缺少自动定位系统中所有setuid和setgid应用的位置
- 缺少用户交互
- 没有生成C语言代码的能力