6.4.1 缓冲区溢出

缓冲区溢出在解释型或者高级编程语言编写的应用中出现的可能性比较小。例如,你可能比较难写出容易遭到这种攻击的PHP或者Java应用。但是溢出可能存在于某个语言的内建功能中。最终,把时间花在其他输入校验问题、会话管理和其他Web安全主题上更好一些。当然,如果你的应用由定制的IIS ISAPI过滤器或者定制的Apache模块组成,那么就要测试缓冲区溢出,更有效的可能是引导一次代码安全评审。

为了进行缓冲区溢出攻击,你只要向输入域转储尽可能多的数据。这是最粗野的攻击,但是返回的应用错误很有用。Perl最适合发动这种类型的攻击。一条指令就可以创建攻击一个参数所需要的任意长度:


$ perl -e 'print "a" x 500'
aaaaaaa...repeated 500 times

你可以创建一个Perl脚本建立HTTP请求(使用LWP模块),或者通过netcat转储输出。代替正常的参数提交,在反短斜线(backticks)中封装一个Perl代码行来替换参数。下面是正常的请求:


$ echo -e "GET /login.php?user=faustus\nHTTP/1.0\n\n" | \
nc -vv website 80

下面是从命令行调用Perl的缓冲区测试:


$ echo -e "GET /login.php?user=\
> 'perl -e 'print "a" x 500''\nHTTP/1.0\n\n" | \
nc -vv website 80

上述命令发送了一个500个“a”组成的字符串作为user值发送给login.php文件。这种Perl花招可以用于Unix(或者Cygwin)命令行的任何地方。例如,将这种技术与cURL程序组合,可以减少处理SSL的问题:


$ curl https://website/login.php?user='perl -e 'print "a" x 500''

在你尝试用不同载荷和不同长度进行缓冲区溢出测试时,目标应用可能返回不同的错误。这些错误可能都是“密码错误”,但是有些错误可能指出了user参数的边界条件。缓冲区溢出测试的经验法则是遵循基本的差异分析或者异常检测:

1.向应用发送常规的请求,记录服务器响应。

2.向应用发送第一个缓冲区溢出测试,记录服务器响应。

3.发送下一个缓冲区,记录服务器响应。

4.必要时重复步骤3。

每当服务器的响应与“常规”请求不同时,检查变化的内容,这能帮助你跟踪特定的产生错误的载荷(例如URL上的7809个斜杠可以接受,但是7810个不行)。在某些情况下,缓冲区溢出攻击使攻击者能够在服务器上执行任意命令。这种任务第一次较难完成,但是很容易复制。换句话说,需要老练的安全审计才能找到漏洞并创建一个攻击,但是不老练的攻击者可以下载和运行预先制作的攻击。

注意  大部分时候这些缓冲区溢出攻击是“盲目”进行的。没有访问到应用连接调试程序或者查看日志或者系统信息,制作一个导致系统命令执行的缓冲区溢出攻击是非常困难的。例如,如果没有用于测试的对系统的完全访问权,就无法导致IIS上FrontPage服务扩展溢出。