Httpoxy是一个最新曝出的一个CGI程序漏洞,它主要可能威胁到运行在CGI上的PHP,Go,Python和其他代码程序语言。
0×01 什么是httpoxy?
具体来说, httpoxy是一组影响运行在CGI 或者类似CGI环境的漏洞集,它可以理解为简单的命名空间冲突:
RFC 3875(CGI)把HTTP 头部的Proxy 字段名变换成环境变量HTTP_PROXY
HTTP_PROXY是非常通用流行用来配置对外请求的环境变量。
这将导致远程利用漏洞的后果,所以如果大家现在还在运行着CGI,应该马上屏蔽代理头部请求。当然,httpoxy是服务器端web程序漏洞,如果你并没有在web上部署代码的话,就不会受到影响。
那么如果我的web应用程序确实存在此类漏洞的话将会有什么后果呢?
如果一个存在此类漏洞的 http客户端发出一个对外请求,服务器端的 CGI应用程序在运行的时候,攻击者可以:
代理web程序对外http请求
控制服务器打开对外请求与指定地址和端口连接
通过恶意代理来强占服务器资源
从上面可以看出,httpoxy是非常容易被利用的一个漏洞,因此受此影响的web应用程序应当及时处理。
0×02 影响有多大?
以下几种情况受到的影响将会比较大:
将代码运行在CGI或类似环境下,CGI里面的环境变量已经改为了HTTP_PROXY。
一个信任HTTP_PROXY的http客户端将其作为配置代理。
客户端在程序内部做出了一个http请求处理
至今在已经确认被影响的案例中:
但显然我们还没有考虑到基于语言的区分将会带来影响的不同,随着HTTP_PROXY环境变量的愈加流行,带来被污染的可能性将会越来越大。下面就是一些经常发生的例子:
PHP
无论PHP是作为应用程序代码还是PHP库来说,此类问题相当普遍。只要运用已存漏洞库一个小小的漏洞,在处理用户请求的时候便可以被利用,并且这可以影响到PHP的任何版本。它甚至可以影响在FastCGI 中部署的HHVM等此类执行引擎。它甚至存在于Guzzle框架Artax框架等很多库中(Guzzle4.0.0以后的版本均受到影响,3以下的版本暂时没有受此影响)还有就是存在于composer流中的ContextBuilder类加载工具。
所以,如果你使用的Drupal模块中存在Guzzle6框架,你发送出了一个http请求(比如check 你的天气API),你很有可能就会被“httpoxied”了。
Python
Python代码必须部署在CGI中才会受到漏洞威胁,这意味着代码中使用了handler函数比如“wsgiref.handlers.CGIHandler”。这并不是一般部署python 应用程序(大多数人使用WSGI或者FastCGI,这两种目前都没有受到漏洞威胁) 的方法,由此可见python应用程序受影响的范围可能要小于PHP应用程序。顺便一提,WSGI受到此类漏洞威胁是不易的,因为os.environ没有被CGI的数据污染。
GO
GO语言同样必须部署在CGI环境下才有可能受到此漏洞威胁,通常情况下,这是因为代码中使用了net/http/cgi包。如同python语言一样,一般很少考虑部署GO语言到web程序中,所以对于GO语言来说,这个漏洞的影响范围更小了。
通过比较GO语言的net/http/cgi,其实它一般不会设置实际的环境变量,所以就更加安全了。
Python和GO语言容易受到攻击的版本都是使用HTTP_PROXY作出外部请求,并且没有检查CGI是否正在使用。
0×03 如何及时抢救?
最直接的抢救方法是立即屏蔽http头中带有proxy字段的请求,这是最简单同时最有效的方法。
具体方法如下:
Nginx/FastCGI
使用以下语句来屏蔽PHP-FPM和PHP-PM 之间的传递
fastcgi_param HTTP_PROXY"";
在FastCGI配置中,PHP是极其容易受到影响的(但其他使用Nginx FastCGI的语言都OK)
Apache
对于具体的apache影响我们建议你阅读官方给出的资料,官方资料将会更加准确和深入。
如果你使用的是携带mod_cgi模块的apache http服务器,这时使用python或者Go代码语言则非常易受漏洞威胁(HTTP_PROXY环境变量是“真凶”)。mod_php则是因为PHP环境才被影响,如果你使用了mod_headers模块的话,在进一步处理指令前你可以先不要预设代理头。
RequestHeader unset Proxy early
如果你使用的是mod_security模块,你可以运用SecRule来阻断代理头的流量,以下例:
SecRule &REQUEST_HEADERS:Proxy "@gt 0" "id:1000005,log,deny,msg:'httpoxy denied'"
最后,如果你使用的是apache流量服务器,它一般情况下不会受到影响,但你可以用它来strip 代理头部。具体参考ASF
HAProxy
脱离头部请求处理:
http-request del-header Proxy
varnish
对于varnish的处理:
sub vcl_recv {
[...]
unset req.http.proxy;
[...]
}
OpenBSD relayd
对于relayd,删除头部并加上过滤器:
http protocol httpfilter {
match request header remove "Proxy"
}
主要web应用程序解决方法已经列出,FreeBuf也会跟进是否这次漏洞会出现别样的漏洞利用形式。