源码审计之缓冲区溢出漏洞
缓冲区溢出算是安全界常见的漏洞,也是一种最初级的漏洞,但是这种漏洞时至今日依旧层出不穷。大部分由于项目庞大,调用逻辑层次复杂,以及测试时测试用例问题,不能及时发现这类漏洞。
一. 缓冲区溢出的原因。
由于缓冲区溢出而使得有用的存储单元被改写,往往会引发不可预料的后果。程序在运行过程中,为了临时存取数据的需要,一般都要分配一些内存空间,通常称这些空间为缓冲区。如果向缓冲区中写入超过其本身长度的数据,以致于缓冲区无法容纳,就会造成缓冲区以外的存储单元被改写,这种现象就称为缓冲区溢出。缓冲区长度一般与用户自己定义的缓冲变量的类型有关。
总结以上原因,可以获得缓冲区溢出的两个必要条件。
1. 缓冲区。
2. 对缓冲区操作造成缓冲区外的存储单元的数据被改写。
找到原因后可以总结代码中出现的情况。
缓冲区: 数组,malloc/new 申请, struct和class中数组。
写入操作:对缓冲写入操作时,没有对长度做校验,导致数据被覆盖改写。(strcpy,strcat,scanf,memcpy, memmove, memeccpy Getc(),fgetc(),getchar;read,printf等函数)。
二. 常见的代码审计工具弱点
代码审计对复杂项目的审计效果不好:
1.函数调用是个复杂的过程,当审计工具找到敏感函数时,回溯函数的调用路径常常会遇到困难。
2. 如果程序使用了复杂框架,代码审计工具往往由于缺乏对框架的支持,从而造成误报或漏报。
三. 源码中白盒审计分析
本次审计的开源软件为Dmitry1.3a(源码自行下载).用到的工具sourceinsight,gdb,peda。
使用sourceinsight对源码进行解析。
1. 查找所有容易产生溢出的函数调用点。
是否对长度有控制,有控制需要查看控制是否合理,不合理可能会引起溢出。没有长度控制是很大隐患点。
使用sourceinsgiht可以在工程所有文件中查找容易引起溢出的函数的代码和文件。
逐个查看函数调用是否安全。
2. 逐个分析是否存在可能溢出
溢出原因对缓冲区操作时没有对缓冲区空间的大小进行校验。
如果使函数的参数,需要查找其调用函数,查看实参参入时长度是否和函数体内长度一致。如果小于实参长度,就容易产生溢出。
找到可疑点,并做记录。
可疑点1.
可疑点2:
可疑点3:函数内部定义fhost最大值为128
但是main函数内部调用时没有检查长度。
可疑点4:函数内部定义为hostwww最大长度为64.
但是调用函数main里面。
可疑点5:
但是调用函数main里面:
可疑点6:
在main函数里面调用,参数strings被输入时没有长度验证。
四. 验证可疑点
对源代码做了白盒设计分析后,需要对程序的流程和数据做验证分析,输入引发溢出的数据,查看是否能够引起溢出。
验证可疑点1:
使用gdb调试程序。
设置其参数:set args -oBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB aaaaaaaaaaaaaaa(-o选项,当optorg != 最后一个参数的时候)执行strcpy(outputfile,optarg); 其中outputfile[64]。参数中104个B。可以引发溢出。
运行查看结果:
可以看到outputfile被写入BBB,超过了64位的长度。 但是没有引发异常。
查看outputfile的定义,是一个全局变量,被写入超长数据覆盖一部分数据,数据并没有使用,所以没有引发异常。
缓冲区溢出算是安全界常见的漏洞,也是一种最初级的漏洞,但是这种漏洞时至今日依旧层出不穷。大部分由于项目庞大,调用逻辑层次复杂,以及测试时测试用例问题,不能及时发现这类漏洞。
一. 缓冲区溢出的原因。
由于缓冲区溢出而使得有用的存储单元被改写,往往会引发不可预料的后果。程序在运行过程中,为了临时存取数据的需要,一般都要分配一些内存空间,通常称这些空间为缓冲区。如果向缓冲区中写入超过其本身长度的数据,以致于缓冲区无法容纳,就会造成缓冲区以外的存储单元被改写,这种现象就称为缓冲区溢出。缓冲区长度一般与用户自己定义的缓冲变量的类型有关。
总结以上原因,可以获得缓冲区溢出的两个必要条件。
1. 缓冲区。
2. 对缓冲区操作造成缓冲区外的存储单元的数据被改写。
找到原因后可以总结代码中出现的情况。
缓冲区: 数组,malloc/new 申请, struct和class中数组。
写入操作:对缓冲写入操作时,没有对长度做校验,导致数据被覆盖改写。(strcpy,strcat,scanf,memcpy, memmove, memeccpy Getc(),fgetc(),getchar;read,printf等函数)。
二. 常见的代码审计工具弱点 本文来自无奈人生安全网
代码审计对复杂项目的审计效果不好:
1.函数调用是个复杂的过程,当审计工具找到敏感函数时,回溯函数的调用路径常常会遇到困难。
2. 如果程序使用了复杂框架,代码审计工具往往由于缺乏对框架的支持,从而造成误报或漏报。
三. 源码中白盒审计分析
本次审计的开源软件为Dmitry1.3a(源码自行下载).用到的工具sourceinsight,gdb,peda。
使用sourceinsight对源码进行解析。
1. 查找所有容易产生溢出的函数调用点。
是否对长度有控制,有控制需要查看控制是否合理,不合理可能会引起溢出。没有长度控制是很大隐患点。
使用sourceinsgiht可以在工程所有文件中查找容易引起溢出的函数的代码和文件。
逐个查看函数调用是否安全。
2. 逐个分析是否存在可能溢出
溢出原因对缓冲区操作时没有对缓冲区空间的大小进行校验。
如果使函数的参数,需要查找其调用函数,查看实参参入时长度是否和函数体内长度一致。如果小于实参长度,就容易产生溢出。
找到可疑点,并做记录。
可疑点1.
内容来自无奈安全网
可疑点2:
可疑点3:函数内部定义fhost最大值为128
但是main函数内部调用时没有检查长度。
可疑点4:函数内部定义为hostwww最大长度为64.
但是调用函数main里面。
copyright 无奈人生
可疑点5:
但是调用函数main里面:
可疑点6:
在main函数里面调用,参数strings被输入时没有长度验证。
四. 验证可疑点
对源代码做了白盒设计分析后,需要对程序的流程和数据做验证分析,输入引发溢出的数据,查看是否能够引起溢出。
验证可疑点1:
使用gdb调试程序。
设置其参数:set args -oBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB aaaaaaaaaaaaaaa(-o选项,当optorg != 最后一个参数的时候)执行strcpy(outputfile,optarg); 其中outputfile[64]。参数中104个B。可以引发溢出。
运行查看结果:
可以看到outputfile被写入BBB,超过了64位的长度。 但是没有引发异常。
查看outputfile的定义,是一个全局变量,被写入超长数据覆盖一部分数据,数据并没有使用,所以没有引发异常。
无奈人生安全网