File协议小trick
构建test文件
1 | <?php |
上面这段代码我们知道,主要是进行网址过滤,如果用户输入的网址不是规定的网址,则服务器不会发起请求。
这段代码的目的是,防止用户输入其它恶意数据,造成攻击,比如:
http://www.site.com/test.php?url=http://10.0.0.16 –攻击者尝试进入内网
http://www.site.com/test.php?url=http://www.hack.com –攻击者尝试访问不合法网址
但这里有两个小问题:
- parse_url原理
parse_url只是负责字符串解析,它不保证你的协议真伪,这里我们不用http协议,而使用一个根本不存在的协议abc测试:
1 | $url = 'abc://www.baidu.com/test'; |
输出结果为:
array(3) { [“scheme”]=> string(3) “abc” [“host”]=> string(13) “www.baidu.com" [“path”]=> string(11) “/test” }
- curl支持的协议很多
curl是基于libcurl实现的,支持的协议非常多。
所以我们可以发现两处问题
- 白名单只是检测了host,但没有检测协议
- curl除了支持http协议,还支持file协议
这里给出sample
http://url/test.php?url=file://www.site.com/etc/passwd
phpcurl识别出来这是个file协议,会忽略后面的host www.site.com,直接去读取文件/etc/passwd