服务热线:010-65014696

安全研究

椒图关注 FOCUS ON JOWTO

PHP获取X-Forwarded-For值的有趣现象

[2015-1-10]

今天发现了PHP一个有趣的现象,就是关于X-Forwarded-For这个值获取的方式。关键字X-Forwarded-For是HTTP的一个扩展字段,有的Web程序就会使用这个字段获取用户的真实IP,类似下面的代码:

$ip = $_SERVER[‘HTTP_X_FORWARDED_FOR’];

而程序在后面如果不检查$ip这个变量的值而直接带入select进行数据库查询,就可能会造成SQL注入攻击点,如很老版本的discuz论坛就存在这种类型的注入。

PHP在接收HTTP_X_FORWARDED_FOR内容的时候很有意思,也可以说容错性非常高,客户端在发送的时候在X和FORWARDED和FOR之间的分隔字符可以是任意可显示的特殊字符,如下面HTTP请求:

GET /test.php HTTP/1.1

Host: 192.168.200.101:81

Proxy-Connection: keep-alive

Cache-Control: max-age=0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)

Chrome/39.0.2171.95 Safari/537.36

Accept-Encoding: gzip, deflate, sdch

Accept-Language: zh-CN,zh;q=0.8

X-Forwarded!For:8.8.8.8

Content-Length: 4

我把X-Forwarded-For变成了X-Forwarded!For,而test.php依然可以获得正确的HTTP_X_FORWARDED_FOR值,如下:


HTTP/1.1 200 OK

Date: Sat, 10 Jan 2015 08:28:18 GMT

Server: Apache/2.2.9 (APMServ) mod_ssl/2.2.9 OpenSSL/0.9.8h PHP/5.2.6

X-Powered-By: PHP/5.2.6

Content-Length: 7

Content-Type: text/html


8.8.8.8

除了“:”这个符号由于在HTTP头中有特殊含义不可用外,其他键盘可输入的特殊字符都可以做分隔符,PHP好强大。

那么这个有什么用处呢?如果Web应用程序存在X-Forwarded-For注入漏洞的情况下而是用了一些WAF,那么利用这个特性就有可能绕过WAF对X-Forwarded-For字段的防护,虽然这样的情况可能比较少发生。