6.3 Twitter HTTP响应分割攻击

难度:

URL:https://twitter.com/i/safety/report_story/

报告位置:https://hackerone.com/reports/52042/

报告日期:2015年3月15日

支付奖金:3500美元

当你在寻找漏洞时,记住要跳出思维定式,并提交编码后的值来查看网站如何处理这些输入信息。在某些情况下,网站会通过使用黑名单来抵御CRLF注入攻击。换句话说,网站会对照黑名单检测输入中的每个字符,然后相应地通过删除这些黑名单上的字符或不允许发出HTTP请求来给出响应。然而,攻击者有时可以通过字符编码规避黑名单检查。

2015年3月,FileDescriptor操纵了Twitter处理字符编码的方式,从而发现了一个允许他通过HTTP请求设置cookie的漏洞。

FileDescriptor测试的HTTP请求包含了一个发往https://twitter.com/i/safety/report_story/(一个Twitter用于存放用户所报告的不当广告的存档网址)的reported_tweet_id参数。当进行响应时,Twitter也会返回一个包含随HTTP请求提交过来的该参数的cookie。在FileDescriptor的测试过程中,他注意到CR和LF字符已经上了黑名单并且会被滤除。Twitter会用空格替换LF,并且当接收到CR时会返回一个HTTP 400(错误的请求)错误,因此就抵御了CRLF注入攻击。但是FileDescriptor知道一个Firefox(火狐浏览器)的漏洞,该漏洞不能正确解码cookie并且可能会允许用户向网站中注入恶意的负载数据。对该漏洞的了解促使他进一步去测试Twitter上是否也有类似的漏洞。

在Firefox漏洞中,Firefox会删除cookie中除ASCII字符之外的任何Unicode字符。但是Unicode字符可以是由多字节构成的。如果一个多字节字符中的某些字节被删除了,那么剩下的字节可能就会成为用于网页呈现的恶意字符。

FileDescriptor测试了使用同样的多字节字符技术,攻击者是否可以通过Twitter的黑名单机制偷偷地剩下一个恶意字符。随后FileDescriptor发现了一个Unicode字符,它的编码以%0A(LF)结尾,并且其他的字节对应的字符并不包含在HTTP字符集中。他使用了Unicode字符“嘊”,它的十六进制编码为U+560A(56 0A)。但是当该字符被用在URL中时,它将被UTF-8编码为URL字符%E5%98%8A。这三个字节%E5 原文是%E3,应该为笔误。——译者注、%98、%8A规避了Twitter的黑名单检查,因为它们不是恶意字符。

当FileDescriptor提交该值时,他发现Twitter不会滤除这些URL编码的字符,并且仍然可以将这些UTF-8编码的字符%E5%98%8A解码为Unicode值56 0A。Twitter将56作为无效字符丢弃,留下了换行符0A。另外,他发现字符“嘍”(Unicode编码为56 0D)也可以用来在HTTP响应中插入必要的回车符(%0D)。

当他确信这种方法可行时,FileDescriptor传给Twitter的URL参数为%E5%98% 8A%E5%98%8DSet-Cookie:%20test。Twitter将解码这些字符,去除超出范围的字符,在HTTP请求中留下了%0A和%0D,最后得出的值为%0A%0DSet-Cookie:%20test。CRLF将拆分HTTP响应为两个响应,并且第二个响应将仅由Set-Cookie:test构成,这正是用于设置cookie的HTTP头。

当考虑XSS攻击时,CRLF攻击将会变得更为危险。尽管对于本例来说利用XSS的细节并不重要,FileDescriptor还是进一步给出了这种漏洞验证程序(POC)。他通过如下URL向Twitter显示了如何利用该CRLF漏洞来执行恶意JavaScript:

其中最重要的细节是贯穿其中的3字节值:%E5%98%8A、%E5%98%8D、%E5%98%BC和%E5%98%BE。在进行解码和字符滤除后,剩下的部分分别为%0A、%0D、%3C和%3E,这些都是特殊的HTML字符。%3C表示左尖括号(<),%3E表示右尖括号(>)。

HTTP响应中HTML包含的其他字符如上。因此,当编码字符解码并用换行符分割后,头部信息如下:

上面的负载将被解码为注入头信息content-type text/html,这告诉了浏览器响应消息中包含HTML。而后面的Location头使用了一个<svg>标签来执行JavaScript代码alert(innerHTML)。alert代码通过使用DOM的innerHTML属性(innerTHML属性返回给定元素对应的HTML)创建了一个包含网页内容的告警窗口。在这种情况下,告警信息可能会包含已登录用户的会话cookie和身份认证cookie,以表明攻击者可以窃取这些信息。窃取身份认证cookie使得攻击者可以登录目标对象的账号,这也解释了为什么FileDescriptor因发现该漏洞而获得了3500美元的奖励。

要点

如果服务器会以某种方式滤除字符%0D%0A,请你考虑网站是怎样做到的,而你是否能够规避这些,比如使用双重编码。你可以使用传递多字节字符并检查这些字符是否被解码为其他字符来测试网站是否会不当处理额外的字符 本例中正常的字符是字母表中的字符,其他的都是额外字符,本例中不当处理方式就是丢弃,从而就给拼凑成CRLF这种攻击类字符留下了机会。——译者注

[1] 原文是%E3,应该为笔误。——译者注

[2] 本例中正常的字符是字母表中的字符,其他的都是额外字符,本例中不当处理方式就是丢弃,从而就给拼凑成CRLF这种攻击类字符留下了机会。——译者注