HTTPOXY漏洞说明

作者: Laruence( ) 本文地址: http://www.laruence.com/2016/07/19/3101.html 转载请注明出处

好久没写文章了, 博客都长草了, 早上起来本来想去上班, 一看这么大雨, 这要上路了不得堵死啊.

再加上有同学对我昨天转发的微博HTTPOXY漏洞表示不理解, 问会不会影响普通应用, 于是就写篇文章介绍下, 等早高峰过了吧;)…..

不过要注意的是, 这里我只是介绍PHP这个角度, 关于Go和Python等其他角度的,因为我也不是”很”懂,你们还是看原文吧 :)

漏洞原文在这里, https://httpoxy.org/, 没看懂的一定都是英语没过6级的 :)

这里有一个核心的背景是, 长久一来我们习惯了使用一个名为”http_proxy”的环境变量来设置我们的请求代理, 比如在命令行我们经常这么用:

http_proxy=127.0.0.1:9999 wget http://www.laruence.com/

通过设置一个http_proxy的环境变量, 让wget使用代理请求http://www.laruence.com/

有据可考的是, 这样的设定最初来自1994年的CERN libwww 2.15, 我猜测大概是当时很多工具是基于这个类库做的, 于是就慢慢成了一个既定标准吧. 只不过这些应用都要求http_proxy是全部小写的, 还不足以造成今天这个漏洞.

但估计是因为环境变量习惯都是大写的原因吧, 后来有的类库开始支持大写的HTTP_PROXY, 比如yum: https://www.centos.org/docs/5/html/yum/sn-yum-proxy-server.html

再后来很多的类库, 各种语言的, 都开始支持这种配置, 有的支持大写的, 有的支持小写的, 还有的都支持.

Guzzle(支持大写):https://github.com/guzzle/guzzle/blob/10a49d5e1b8729c5e05cbdbf475b38b7099eb35e/src/Client.php#L167 Artax(大写, 小写都支持): https://github.com/amphp/artax/blob/3e3eedafcecc82c3c86c3a00ca602b5efa9c2cfa/lib/HttpSocketPool.php#L26

包括我们自己, 也很有可能在日常的工作中写出如下的代码(我就曾经在写爬虫的时候写过):

<?php
$http_proxy = getenv("HTTP_PROXY");
if ($http_proxy) {
    $context = array(
        'http' => array(
            'proxy' => $http_proxy,
            'request_fulluri' => true,
        ),

    );
    $s_context = stream_context_create($context);
} else {
    $s_context = NULL;
}
$ret = file_get_contents("http://www.laruence.com/", false, $s_context);

那么问题来了, 在CGI(RFC 3875)的模式的时候, 会把请求中的Header, 加上HTTP_ 前缀, 注册为环境变量, 所以如果你在Header中发送一个Proxy:xxxxxx, 那么PHP就会把他注册为HTTP_PROXY环境变量, 于是getenv(“HTTP_PROXY”)就变成可被控制的了. 那么如果你的所有类似的请求, 都会被代理到攻击者想要的地址,之后攻击者就可以伪造,监听,篡改你的请求了…

比如:

 curl -H "Proxy:127.0.0.1:8000" http://host.com/httpoxy.php

所以, 这个漏洞要影响你, 有几个核心前提是:

你的服务会对外请求资源 你的服务使用了HTTP_PROXY(大写的)环境变量来代理你的请求(可能是你自己写,或是使用一些有缺陷的类库) 你的服务跑在PHP的CGI模式下(cgi, php-fpm)

如果你没有满足上面的条件, 那么恭喜你,你不受此次漏洞影响 :) .

后记: 在微博上有同学提醒, 我可能把这个问题的影响潜意识的让大家觉得危害不大, 但实际上, 延伸一下: 所有HTTP_开头的环境变量在CGI下都是不可信的, 千万不要用于敏感操作, 另外一点就是, 我深刻的体会过, 做安全的同学想象力非常丰富, 虽然看似很小的一个点, 但到了安全的同学手里, 配合他们丰富的想象力, 强大的社工能力, 也是能做出巨大攻击效果的….

那知道了原理修复起来也很简单了, 以Nginx为例, 在配置中加入:

   fastcgi_param HTTP_PROXY "";

所以建议, 即使你不受此次漏洞影响, 也应该加入这个配置.

而如果你是一个类库的作者,或者你因为什么原因没有办法修改服务配置, 那么你就需要在代码中加入对sapi的判断, 除非是cli模式, 否则永远不要相信http_proxy环境变量,

<?php
if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) {
   //只有CLI模式下, HTTP_PROXY环境变量才是可控的
}

就好比Guzzle的这个修复:Addressing HTTP_PROXY security vulnerability

补充: 从PHP5.5.38开始, getenv增加了第二个参数, local_only = false, 如果这个参数为true, 则只会从系统本地的环境变量表中获取, 从而修复这个问题, 并且默认的PHP将拦截HTTP_PROXY: fix

thanks

Comments

2016/07/19, Ethan writes: 感谢鸟哥!我们各种接口调用,又是nginx的,可能是高危群体了吧。2016/07/19, rambone writes: 这就是咱们鸟哥 第一时间 从前方发回报道2016/07/19, Axios writes: 还是鸟哥的博客看着舒服,比英文的好多啦~2016/07/19, guest writes: 各位Apache下php_mod不会收到影响吗?2016/07/19, Bun writes: 终于更新blog了,支持鸟哥,感谢鸟哥2016/07/19, windsor writes: 赞2016/07/19, JV writes: 鸟哥终于更新了2016/07/19, Cheng writes: 鸟哥威武2016/07/19, pz writes: 能说没看懂吗?脚本里的代理为什么会去用 用户设置的代理?2016/07/19, kisto writes: 受益匪浅2016/07/19, 石樱灯笼 writes: 昨天就把VPS的Apache加了 ``` LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so RequestHeader unset Proxy early ``` 然而并不知道能不能生效……2016/07/19, Anonymous writes: 很多框架信任http_x_forwaded_for作为ip地址,危害更大2016/07/23, fy writes: php扩展迁到php7要注意什么呢,哪里能看到所有的改动呢2016/07/28, 木木老蔫 writes: 啊,鸟哥已经8.6万微博粉丝了啊2016/08/03, yangakw writes: 做安全的想象力真的佩服2016/08/03, 志斌 writes: 在PHP5.4版本下使用opcache的一个问题,pfsockopen打开了一个长连接,当服务器主动断开连接后(第一个请求结束之后),第二次请求使用fgets不能获取服务器的返回 The first request with strace: sendto(11, "POST /users/api.php HTTP/1.1\r\nHo"..., 860, MSG_DONTWAIT, NULL, 0) = 860 poll([{fd=11, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout) poll([{fd=11, events=POLLIN|POLLERR|POLLHUP}], 1, 3000) = 1 ([{fd=11, revents=POLLIN}]) recvfrom(11, "HTTP/1.1 200 OK\r\nServer: openres"..., 8192, MSG_DONTWAIT, NULL, NULL) = 1102 And after a few mintue anthor request with strace sendto(11, "POST /users/api.php HTTP/1.1\r\nHo"..., 860, MSG_DONTWAIT, NULL, 0) = 860 poll([{fd=11, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 1 ([{fd=11, revents=POLLIN}]) recvfrom(11, "", 1, MSG_PEEK, NULL, NULL) = 0 poll([{fd=11, events=POLLIN|POLLERR|POLLHUP}], 1, 3000) = 1 ([{fd=11, revents=POLLIN}]) recvfrom(11, "", 8192, MSG_DONTWAIT, NULL, NULL) = 0 However when i use fsockopen(or whitout opcache), it won't occur this problem my php version is 5.4.412016/08/18, Francis writes: 给你提个你网站的bug: 在最新版的chrome(52.0.2743.116)下站点久久的打不开, 只能看到空白页在旋转加载, 估计能有好几分钟打不开. 但换做firefox后, 页面能正常显示内容,至少能看到内容. 观察加载后发现, 可能是由于apis.google.com/js/plusone.js这个js加载不到引起的白屏. 希望能处理一下.2016/08/27, ian writes: 大哥你那yaf框架封装的太好了,我在$app->bootstrap()->run();之前做了$_GET,$_POST,$_REQUEST脏词过滤,最后一点效果没有。感觉一点不人性。2016/09/07, PHP程序员雷雪松 writes: 高大上啊!膜拜。2016/09/21, Terry writes: 拜读....2016/09/27, 游客 writes: 收益匪浅 http://www.jfeet.com2016/09/28, 个人博客网站 writes: 大神写的就是经典2016/10/04, pulsa online writes: 感谢鸟哥!我们各种接口调用,又是nginx的,可能是高危群体了吧。2016/10/05, GenialX writes: 学习了,谢过。那么在PHP中,用小写形式来获取http_proxy是不是就可信了?2016/10/19, PHP程序员雷雪松 writes: 好高深啊!!!2016/10/20, fanfan writes: 学习了,鸟哥威武!2016/10/26, taylor writes: 这个漏洞触发比较特殊2016/10/28, pz writes: 这下就看懂了,之前几篇文字我都没看明白2016/10/31, Anonymous writes: 英语没过2级的路过2016/11/10, bjmayor writes: 鸟哥最近在忙啥,博客好久没更新了。2016/11/14, zzm writes: 已更新就是猛料啊 鸟哥2016/11/30, hongbo819 writes: 刚看到。。。那些牛逼的站点们还是要做下优化的。。。2016/12/12, 宁波汽车座椅包真皮 writes: 鸟哥,学习了,谢谢2016/12/17, SH writes: 学习了,谢谢~2016/12/17, PHP问答 writes: php扩展迁到php7有啥需要注意的呢?2017/01/05, 菲皇彩票 writes: 鸟哥很久没有更新了2017/01/13, 神圣时时彩计划软件 writes: 这就是咱们鸟哥 第一时间 从前方发回报道2017/02/13, MonacoEscort writes: Very interesting post, good writing. For escorts and companions in Israel please visit: http://www.monacoescort.co.il/2017/02/13, נערות ליווי writes: Very good post, thanks for sharing with us! If you are interested in V.I.P Israeli companions and call girls to order you are welcome to visit: http://www.monacoescort.co.il/%d7%9c%d7%99%d7%95%d7%95%d7%99-vip2017/06/02, spanish to english writes: 那知道了原理修复起来也很简单了, 以Nginx为例2017/11/01, 111 writes: 4442017/11/07, godaddy优惠码 writes: 朋友 交换链接吗2017/11/25, Crossworld writes: 受教了,感谢鸟哥!2017/11/29, 理想网赚 writes: 博主大才,受教了Copyright © 2010 风雪之隅 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)

Related Posts:

通过构造Hash冲突实现各种语言的拒绝服务攻击让你的PHP7更快(GCC PGO)在PHP中使用协程实现多任务调度GCC优化引起的一个”问题”Curl的毫秒超时的一个”Bug”Weibo LAMP演变 – 6月在上海分享的PPT一个小玩意PHP-Valgrind的介绍PHP浮点数的一个常见问题的解答Yaf and Phalcon, which is faster?Yar – 并行的RPC框架(Concurrent RPC framework)

文章来源:

Author:Laruence
link:http://www.laruence.com/2016/07/19/3101.html