写前面
这篇文章讲的实在是太棒了 https://medium.com/secjuice/php-ssrf-techniques-9d422cb28d51
php版本:
测试代码:
1 |
|
首先调用了filter_var
进行URL的验证,然后再用parse_url
去解析URL,php7的版本中这个函数是没有问题的
同时通过preg_match
函数限定只能以google.com
结尾
如果达到ssrf呢?
正常情况下
攻击者:
此时$r[‘host’]显然不是以google.com
结尾的
绕过URL验证和正则表达式
许多URL schema保留某些特殊含义的字符:它们在URL的特定于方案的部分中的外观具有指定的语义。如果在方案中保留对应于八位字节的字符,则必须对八位字节进行编码。字符“;”,“/”,“?”,“:”,“@”,“=”和“&”可以保留用于方案内的特殊含义。在方案中不能保留其他字符。
通常会用一些保留字符,比如;
和=
,,
分割参数和参数值
一个可能是用name;v=1.1
来表示name=version 1.1,然而也可以用name,1.1
达到相同的效果,这根据算法来区分
curl或者wget会认为evil.com;google.com
中hostname
为evil.com
,querystring
为google.com
但是并没有绕过filter_var
函数filter_var()
函数可以解析很多不同的URL scheme
如果改成这样:
此时已经成功地绕过了URL验证和正则表达式
但是curl命令却没有执行,于是考虑加上端口号
再次修改:
php test.php "111://evil.com:80;google.com:80/"
同样用逗号也行
parse_url只会尽可能地分割URL,而不是验证它,作者还提到了一种更好的方式:
0://evil$google.com
注意这里必须用单引号括起来。。
实现XSS
作者之后修改了代码:
1 |
|
作者想要注入一点东西,但是并没有成功
继续尝试:
data://google.com/plain;base64,SSBsb3ZlIFBIUAo=
那么XSS就很容易了