最近几次比赛都用到了parse_url的解析漏洞,所以我就在这里做一波总结
- php协议错误
先放测试代码1
2
3
$url = $_GET['url'];
var_dump(parse_url($url));
众所周知,parse_url在url不能被解析的时候就会返回false,然而却没有表明为什么他会爆错。
我们从源码里看一下parse_url
全版本通杀
当一个url没有协议的时候,但是给一个端口url的字符串的时候parse_url就会爆错1
/pupiles.com:80
这个经测试在windwos下应该是php版本全通杀的(5.2-7.0),linux没测试过
url解析错误
接上发现只要端口后面跟字母还是会解析,比如1
2
3/pupiles.com:80a
array (size=1)
'path' => string '/pupiles.com:80a' (length=16)
端口解析错误
php5.5以上1
//pupiles.com/about:1234
这样的url用parse_url解析后预测的结果是1
2
3
4
5
6array(2) {
["host"]=>
string(11) "pupiles.com"
["path"]=>
string(9) "/about:1234"
}
然而实际结果是1
2
3
4
5
6
7
8array(3) {
["host"]=>
string(11) "pupiles.com"
["port"]=>
int(1234)
["path"]=>
string(9) "/about:1234"
}
会默认解析出一个port
key
路径解析错误
1 | <!--?php |
输出结果1
2
3
4
5
6
7
8
9
10Array
(
[path] => /upload
[query] => /home/binarycloud/
)
Array
(
[host] => upload?
[path] => /home/binarycloud/
)
端口溢出
在php5.3.13版本以下,当输入如下url1
http://pupiles:78325
按照正常来说应该会返回false,但是这里会返回1
2
3
4
5array(3) {
["scheme"]=> string(4) "http"
["host"]=> string(7) "pupiles"
["port"]=> int(12789)
}