无效HTTP请求与绕过lighttpd重写规则
在最近一次针对lighttpd服务器的Web应用测试中,我遇到了一个令人困惑的情况。本文将讲述如何通过两种技术手段发现lighttpd的一个有趣漏洞,最终导致意外漏洞的整个过程。
问题发现
测试过程中,客户端提供了文档根目录的列表。当我通过Burp Repeater请求secret.html时,成功获取了秘密内容:
|
|
但通过浏览器访问相同URL时却收到"无权查看"的提示。更奇怪的是:
- Burp能获取秘密内容
- 使用Burp提供的URL时curl无法获取
- Burp生成的curl命令也失败
- netcat尝试直接挂起
技术分析
通过Wireshark抓包对比发现关键差异:
- 行尾符号:Burp使用DOS格式(\r\n),而netcat使用Unix格式(\n)
- 路径格式:Burp请求"secret.html",而curl请求"/secret.html"
实验证明:
- 请求"secret.html"可获取机密内容
- 请求"/secret.html"被拒绝
根本原因
检查lighttpd配置发现重写规则:
|
|
由于规则只匹配以"/secret.html"开头的请求,因此"secret.html"请求未被重写。
绕过技术
通过URL规范化特性发现有效载荷:
|
|
双斜线使请求变为"//secret.html",绕过正则匹配。
其他Web服务器测试
对比测试结果:
- Apache/NGINX/IIS:均拒绝无前导斜线的请求(400错误)
- 所有服务器都接受DOS/Unix行尾格式
防御方案
- 最佳实践:将敏感文件存放在文档根目录外
- 访问控制:使用mod_access模块
|
|
- 改进重写规则:
|
|
关键发现总结
- lighttpd要求HTTP请求使用DOS(\r\n)行尾
- lighttpd接受无前导斜线的请求(其他主流服务器拒绝)
- url.rewrite获取原始请求路径,$HTTP[“url”]获取规范化路径
- 计算机行为具有确定性,看似异常的行为背后都有其规则