一、缓冲区溢出
a. 栈溢出:
char _username[32]
strcpy(_username,username);
不固定长度的变量复制到固定长度的栈变量中出现栈溢出。攻击者重写邻近内存中的数据。
b. 堆溢出:
char *_username=(char*)malloc(32);
strcpy(_username,username);
堆以一个双向链接表的形式执行:在内在中,每个块的前面是一个控制结构,其中包含埠的大小、一个指向堆上前一个块的指针以及一个指向堆上后一个块的指针。当堆缓冲区溢出时,邻近的堆块的控制结构被用户控制的数据重写。
比栈溢出更难以利用,一种常见的利用方法是在被重写的堆控制结构中写入专门设计的值,以在将来某个时间重写任何一个关键的指针。在一个用户控制的地址中写入一个用户控制的值,可以重写内存中的任意指针,从而执行任意代码。
c. ”一位偏移“漏洞:
攻击者可以在一个被分配的缓冲区之后写入一个字节或少数几字节。
超长的输入,如果是简单的复制操作,可能会流入到内存邻近的数据中,从而读取其他用户的数据。
渗透测试步骤:
a. 向每一个目标数据提交一系列稍大于常用缓冲区大小的长字符串,如1100,4200,33000
b. 一次针对一个数据实施攻击,最大程度地覆盖应用程序中的所有代码路径
c. 可使用intruder中的字符块有效载荷来源自动 生成各种大小的有效载荷
d. 监控异常响应,包括:HTTP 500状态码;内容详细的消息;TCP连接未返回响应,突然关闭;整个Web停止响应
e. 如果是堆溢出被触发,可能会在将来而非立即导致系统崩溃
f. ”一位偏移“漏洞可能不会造成系统崩溃,但会有反常行为。
有时是需要发送一个特殊长度或者在较小的长度范围内的超长字符串才能触发。
二、整数漏洞
(1)整数溢出
如unsigned short len =strlen(username)+1,short类型的整数包含16位,保存0-65535之间的值,如果提交的username为65535的字符串,再+1的话使得这个值又变为0,这样以len来分配堆内存时就会造成溢出
(2)符号错误
将一个有符号的值与无符号的值进行直接比较,或者向一个仅接受无符号的值的函数提交有符号的值,都会出现错误。有符号的值都会被当做其对应的无符号的值处理,一个负数变成一个大整数。
查找整数漏洞:
查找提交整数值的部分以及嵌入到二进制数据巨对象中的整数值。
a. 轮流向每一个目标数据发送一个不同的值,分别表示不同有符号与无符号整数值的边界情况。如:
0x7f与0x80(127与128); 0xff与0x100(255与256).....
b. 如果被修改的数据以十六进制表示,应该发送每个测试字符串的little-endian与big-endian版本,如ff7f与7fff,注意编码。
三、格式化字符串漏洞
如果格式化字符串中的说明符比提交给函数的个数可变的参数多,而函数又无法探查到这一点,那么它就会继续处理调用栈中的参数。
步骤:
a. 轮流向每个目标参数提交包含大量格式化说明符%n与%s的字符串
基于安全考虑,一些格式化字符串操作可能会忽略%n说明符,相反,提交%s说明符将使函数废弃栈上的每一个参数,如果应用程序易于受到攻击,就可能导致非法访问
b. Windows FormatMessage函数以一种不同的方式使用printf,应使用以下字符串进行测试
%1!n!%2!n!%3!n!...
%1!s!%2!s!%3!n!...
c. 将%进行URL编码为%25
d. 监控反常事件