PHP运行模式与HTTP_PROXY漏洞分析

0x00 PHP的运行模式

PHP是一个php脚本的解释器,在不同的场合下它以不同的场合运行。PHP有个SAPI (Server API) 模块来处理不同的调用。
常见的调用方法有以下几种:

  • 模块加载方式
  • CGI模式
  • FastCGI模式
  • ISAPI方式
  • CLI方式

下面详细介绍一下

模块加载方式是比较常用的加载方式,ubuntu下libapache2-mod-php5就是适配Apache的PHP5的模块。这种情况下,PHP集成在服务器中,以同一个进程运行。

CGI模式比较少见,每次请求都会创建CGI的子线程,处理完php脚本后把结果交回给HTTP服务器。

FastCGI克服了CGI线程创建开销大的缺点,类似于常驻内存的CGI,使用进程池来维护CGI进程,提供解释PHP的服务。PHP使用php-fpm,即PHP FastCGI Process Manager管理进程。

ISAPI方式是Windows下Apache使用的方式。

CLI方式是使用命令行调用PHP使用的方式。

对这方面比较陌生的同学可以参看PHP填坑记之FastCGI与mod_php详解

0x01HTTP_PROXY漏洞

这个漏洞的背景是根据RFC文档,在CGI模式中,会把HTTP请求中的头部,加上HTTP_的前缀,注册到环境变量中。

另外,一个常用的设置代理方法是,在环境变量中设置http_proxy,例如wget命令的设置:

1
export http_proxy=127.0.0.1:8080 && wget http://blog.nudtcat.org

如果wget组件在获取环境变量中的proxy的时候用的是HTTP_PROXY,而且攻击者在发送请求的时候在HTTP头部中加入了PROXY,那么这个PROXY会加上HTTP_的前缀,指定代理,于是,从服务器发出的请求就会从这个
代理通过。而Proxy的环境变量使用大写还是小写没有规定。

0x02 影响范围

这个漏洞的影响范围有限,要求PHP使用CGI或者FastCGI方式启动,某个组件使用的HTTP_PROXY是大写的,而且服务器得向外发送HTTP请求。
幸好wget和curl都是使用的”http_proxy”,不会受影响。