HTTP 协议头攻击

本文已发于《黑客X档案》2010.12期

就在上周,互联网发生一件重大事件,腾讯和 360 这两大用户量极广的公司之间发生了一场惊心动魄的激烈的冲突,至使腾讯一方做出决定——360 和 QQ 不兼容,如果用户机器上同时安装了 360 和 QQ,将导致 QQ 强行关闭。不仅如此,倘若使用 360 浏览器访问 QQ空间,将会被阻止。不过,针对 360 浏览器访问 QQ 空间的问题网上很快出现了突破方法,也正是和本文所要讲的 User-Agent 有关。

User-Agent 是 HTTP 协议请求格式的一个头域。下面来简单了解下 HTTP协议。以下是我对 http://qzone.qq.com 发出的一个 HTTP 请求,内容如下:

GET HTTP/1.1
Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application,application/x-ms-xbap,application/vnd.ms-xpsdocument, application/xaml+xml, */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Host: qzone.qq.com
Connection: Keep-Alive

顶部由 GET 和 HTTP/1.1 组成,GET 代表请求动作的方法,表示向服务器请求一个资源;HTTP/1.1 代表使用的 HTTP 协议版本,现在绝大多数的浏览器都使用的是 1.1 版本。

第一个 Accept 消息头代表接受介质的类型,这里可以忽略不管;Accept-Language 消息头代表接受的语言种类,zh-cn 表示中文;Accept-Encoding 消息头表示接受编码的方式,这里使用了 gzip,deflate压缩编码;User-Agent 消息头则是接下来将要讲到的;Host 消息头代表请求的主机,这里是 qzone.qq.com。Connection 消息头的值为 Keep-Alive 表示了浏览器与服务器保持连接。

向目标主机发送请求后会收到来自服务器的响应,由于这里不是本文重点,将不作介绍返回给浏览器的 HTTP 消息,如需要,请查阅相关文献。我们的重点是 User-Agent 消息头,注意后面跟的值似乎包含操作系统和浏览器的信息。是的,User-Agent 包含了客户端的浏览器和操作系统信息。

下面,来看一个典型的 Web 访问过程如图1:

1.jpg

图1

当客户端的浏览器向服务器发送一个 HTTP 请求后,如果发送成功,服务器则响应这个请求。而刚才的例子中向 QQ 空间服务器发送了一条 HTTP 请求,请求的内容中包含了一些关键的信息,其中 User-Agent 中包含了来自客户端的浏览器信息,由于 360 浏览器有属于自己的 User-Agent(大多数浏览器都有属于自己的),QQ 空间服务器收到来自客户端的 HTTP 请求中如果包含 360 浏览器的 User-Agent 便可禁止用户其访问,这就是其中的原理,而网上流传的突破 360 浏览器访问 QQ 空间限制的最初方法正是修改 User-Agent。

我在本地的 PHP 环境中用一段 PHP 代码输出 User-Agent(如何搭建 PHP 环境在这里省略,详细请参考相关文档),文件 test.php,代码如下:

<?
    echo $_SERVER['HTTP_USER_AGENT'];
?>

然后用 IE 浏览器访问 http://localhost/test.php ,得到的输出结果如下:

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)

再用 360 浏览器访问,得到的结果如下:

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; 360SE)

可以看出,360 输出的结果中,最后多出一项 “360SE”,当 QQ 空间服务器程序接受到的请求中检测到 360SE 字样则禁止用户的访问了。

不过这里要注意,之后 360 浏览器似乎在浏览器选项——“其他”里默认勾选了“统一 IE 和 360 安全浏览器的 User Agent 标示”,如果勾选了它,得到的结果将和IE的一样,所以需要反选此选项才会得到以上的结果。

前面说了 HTTP 的请求内容是来自客户端,那么作为客户端,是可以随意改变请求的内容的。我们可以通过代理服务器的方式来改变请求内容。代理服务器是介于客户端和目的服务器之间的一台服务器,当客户端浏览器设置了代理服务器地址和端口后,浏览器首先将消息发送到代理服务器,然后由代理服务器向目的服务器发送 HTTP 请求的,代理服务器是通过客户端发送的 HTTP 消息中 HOST 消息头来确定将要发送到的目的服务器地址的。当目的服务器响应后并返回一个请求,请求也首先返回到代理服务器,然后由代理服务器将接受到请求转发给客户端浏览器。所以代理服务器在接受到来自客户端的请求内容后是可以随意修改消息内容的(事实上它的确对消息内容做了细微的修改)。其过程如图2:

2.jpg

了解了代理服务器的运作方式后,我们完全可以自己搭建一台本地代理服务器来修改请求内容。这里所讲的本地代理服务器是指在本地运行一个代理服务器程序,然后将浏览器的代理 IP 设置成本机地址和指定的端口号,在访问网页发出 HTTP 请求时,代理服务器软件首先捕获请求,然后再将请求发送给目标服务器,在捕获到浏览器发送来的 HTTP 消息后,完全可以修改消息头内容后再提交给目标服务器。

这里将使用 Web 安全工具中大名鼎鼎的 Burp-Suite 来实现本地代理服务器,在其 官方网站( http://portswigger.net/burp/download.html )下载免费版本(单击 Download now)。因为 Burp-Suite 是基于 Java 平台的,所以需要安装 JRE(随光盘附带)。安装了 JRE 后,运行 Brup-Suite 目录下的 suite.bat,即可启动 Brup-Suite,程序界面如图3:

3.jpg

图3

运行后 Brup-Suite 默认使用的代理端口号是 8080,所以就不设置而直接使用。然后用 360 浏览器设置代理,选择 360 浏览器工具栏中的“代理服务器”——“代理服务器设置”,填入 127.0.0.1:8080 并确定。设置以后,再在“代理服务器”选项中勾选添加好的“127.0.0.1:8080”,此时本地代理服务器已经设置完毕。我们再来访问刚才的建立的 test.php,浏览器中输入 http://localhost/test.php ,此时浏览器一直处于等待状态,无任何显示。而 Brup-Suite 却有反应了,选择“proxy”选项卡,就可以看到浏览器发送的请求内容了,如图4:

4.jpg

这时可以修改消息的任何内容,我们将 User-Agent 可以修改成任何内容,比如将“360SE”字样删除(当时就可以通过此方法绕过 QQ 空间的访问限制)。但是如果我们提交一串跨站字符呢?我们将 User-Agent 冒号后的内容修改成 <script>alert("test")</script> 后按“forward”按扭,浏览器将弹出内容为“test”的显示,如图5:

5.jpg

图5

现在很多网站(比如论坛程序)会将客户端浏览器信息写入数据库,倘若某站点没有对获得的 UserAgent(PHP 获得 UserAgent 的变量是:$SERVER['HTTPUSERAGENT'];ASP 获得 UserAgent 对象的方法是:Request.ServerVariables("HTTPUSERAGENT")

进行过滤而直接写入数据库并且显示在页面中,那么将存在一处攻击点。曾经动网论坛出现过一次 User-Agent 注入。

其实靠 User-Agent 来限制浏览器访问并达不到绝对效果的,因为 HTTP 请求的内容来自客户端,客户端是可以修改任何内容的。其次,在 Web 安全编程中,应该严格过滤来自客户端数据,比如 GET、POST、Cookie、User-Agent,任何来自客户端的输入不能保证是安全的,可以采用白名单的方法来验证请求的数据,即“只允许提交某些内容,其余的均为不允许”,而不是使用黑名单方式——将带有威胁的内容一一排除。比如上传漏洞中,用白名单方式过滤内容,只允许上传 .jpg 和 .gif,其余格式均不允许的;如果用黑名单方式,将 .asp、.php、.aspx 等后缀列入危险黑名单中时,可能会忽略掉其中一种格式,导致漏洞产生。

同时,因为代理服务器可以接受来自客户端和服务器之间的消息,并且可以随意修改其内容,也证明了代理服务器的不安全性,那么在选择代理服务器时应该警惕代理服务器是否安全的。