CRLF注入

2018/11/22 15:21 下午 posted in  注入

文章翻译自OWASP的CRLF_Injection

CRLF即回车Carriage Return (ASCII 13, \r) 和 换行 Line Feed (ASCII 10, \n)。他们被用于注释掉一行的终止。不过不同系统的处理方式有点不同。windows中,CR和LF都被用于注释掉一行的结尾,而linux/unix中只需要一个LF。在HTTP协议中,CRLF序列始终用于一行的终止。
当用户设法将CRLF提交到应用程序时,可能发生CRLF注入攻击,这通常是通过修改HTTP参数或URL来完成。

CRLF注入可能产生这样的问题:

  • HTTP响应拆分
  • 日志注入
    ## HTTP响应拆分
    通常,当出现以下情况时会发生HTTP响应拆分
  • 数据通过不受信任的来源进入Web应用程序,如HTTP请求。
  • 数据包含在发送给Web用户的HTTP响应标头中,而不会对恶意字符进行验证。
    HTTP响应拆分是达到目的的手段而不是目的本身。
    攻击方式如下:攻击者将恶意数据传递给易受攻击的应用程序,应用程序将数据包含在HTTP响应中。
    要成功利用漏洞,应用程序必须允许包含有 CR(回车,即 %0d 或者 \r\n)和 LF(换行符,%0a 或者 \n)的输入在header中和底层平台必须容易注入这样的字符。

大多数现代应用程序服务器(无论用什么语言编写的代码),都已经不存在HTTP响应拆分漏洞。

下面上一段java代码来举例说明:

String author = request.getParameter(AUTHOR_PARAM);
...
Cookie cookie = new Cookie("author", author);
      cookie.setMaxAge(cookieExpiration);
      response.addCookie(cookie);

上述代码的意思是:从客户端HTTP请求中接受参数(author),并将其设置在HTTP响应的cookie头中。
如果我们正常提交数据(author=lonelyor),HTTP响应应该是这样:

HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...

但是,由于源代码中的cookie是由未经验证的用户输入组成的,因此如果我们提交恶意代码Hacker By xxx\r\nContent-Length:45\r\n\r\n...则HTTP响应将被拆分为原始响应和伪造响应。

HTTP/1.1 200 OK
    ...
    Set-Cookie: author=Hacker By xxx
    Content-Length: 999
    
    <html>恶意内容...</html> (这个例子中为第999个字符)
    原始内容以1000开头, 现在被浏览器忽略了...

危害

攻击者构建任意HTTP响应的能力可能导致以下攻击:
跨用户污染(Cross-User_Defacement)——利用条件很苛刻
缓存中毒(Cache_Poisoning)——利用条件很苛刻
XSS跨站脚本攻击
页面劫持

日志注入

将未经验证的用户输入写入日志文件可能导致攻击者伪造日志或者将恶意内容注入日志。
以下情况可能导致日志伪造漏洞:

  • 数据从不受信任的来源进入应用程序
  • 数据将写入应用程序或者系统日志文件

下面上一段java代码来举例说明:

...
String val = request.getParameter("val");
try {
  int value = Integer.parseInt(val);
}
catch (NumberFormatException) {
  log.info("Failed to parse val = " + val);
}
...

上述代码的功能是,从请求对象中读取整数值,如果该值无法解析为整数,则会记录输入,并显示一条错误信息。
如果用户提交字符串“one”,则会记录以下条目
INFO: Failed to parse val=one
然而,如果攻击者提交字符串one%0a%0aINFO:+User+logged+out%3dbadguy则会在日志中显示:

    INFO: Failed to parse val=one

    INFO: User logged out=badguy

显然攻击者可以使用相同机制插入任意日志条目。