1.漏洞概述
回车符(CR)和换行符(LF)合称为 CRLF,是 HTTP 协议中用于表示行尾或新行开头的特殊字符序列。Web 服务器和浏览器使用 CRLF 来区分 HTTP 头和响应主体。这些字符在各种 Web 服务器类型(如 Apache 和 Microsoft IIS)的 HTTP/1.1 通信中被广泛使用。
2.CRLF漏洞案例(HTTP响应拆分)
HTTP 响应拆分发生在以下情况:
- 数据通过不受信任的来源(最常见的是 HTTP 请求)进入 Web 应用程序。
- 该数据包含在发送给 Web 用户的 HTTP 响应标头中,且未经过恶意字符验证。
从根本上来说,攻击很简单:攻击者将恶意数据传递给易受攻击的应用程序,并且该应用程序将数据包含在 HTTP 响应标头中
要成功利用该漏洞,应用程序必须允许将包含 CR(回车符,也由 %0d
或 \r
给出)和 LF(换行符,也由 %0a
或 \n
给出)字符输入到标头
以下代码段从 HTTP 请求中读取博客条目作者的姓名,并将其设置在 HTTP 响应的 cookie 标头中:
String author = request.getParameter(AUTHOR_PARAM);
...
Cookie cookie = new Cookie("author", author);
cookie.setMaxAge(cookieExpiration);
response.addCookie(cookie);
一个正常的请求(例如“Jane Smith”),则包含此 cookie 的 HTTP 响应可能采用以下形式:
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
如果攻击者提交恶意字符串,例如“Wiley Hacker\r\nContent-Length:999\r\n\r\n...
”,则 HTTP 响应将被拆分为冒名顶替者响应,后跟原始响应:
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
Content-Length: 999
<html>malicious content...</html> (to 999th character in this example)
Original content starting with character 1000, which is now ignored by the web browser...
攻击者构造任意 HTTP 响应的能力允许产生各种攻击,包括:跨用户破坏、缓存中毒、跨站点脚本 (XSS)和页面劫持
3.日志文件中的 CRLF 注入
假设有一个日志信息,其格式为:IP - 时间 - 访问路径。典型条目可能如下所示:
123.123.123.123 - 08:15 - /index.php?page=home
攻击者可以利用CRLF注入来操纵这个日志。通过在HTTP请求中注入CRLF字符,攻击者可以改变输出流并伪造日志条目。例如,一个注入的序列可能会将日志条目转换为:
/index.php?page=home&%0d%0a127.0.0.1 - 08:15 - /index.php?page=home&restrictedaction=edit
在这里,%0d
和 %0a
分别代表了 CR 和 LF 的 URL 编码形式。攻击后,日志会误导性地显示:
123.123.123.123 - 08:15 - /index.php?page=home&
127.0.0.1 - 08:15 - /index.php?page=home&restrictedaction=edit
攻击者通过使恶意活动看起来像是本地主机执行了这些操作来掩盖他们的恶意活动。服务器将以 %0d%0a
开头的查询部分解释为单个参数,而 restrictedaction 参数被解析为另一个单独的输入。操纵后的查询有效地模仿了一个合法的管理命令:/index.php?page=home&restrictedaction=edit
4.修复方案
为了减轻Web应用程序中CRLF(回车符和换行符)或HTTP标头注入的风险,建议采取以下策略:
- 避免在响应标头中直接使用用户输入:最安全的方法是避免直接将用户提供的输入合并到响应标头中。
- 编码特殊字符:如果无法避免直接使用用户输入,请确保使用专门用于编码特殊字符(如CR(回车符)和LF(换行符))的函数。这种做法可以防止CRLF注入的可能性。
- 更新编程语言:定期将Web应用程序中使用的编程语言更新到最新版本。选择一个在负责设置HTTP标头的函数中禁止CR和LF字符注入的版本。
5.工具和fuzz列表
工具:
fuzz字典: