[极客大挑战 2019]PHP
极客大挑战 2019

打开网页,显示的是一个互动画面,上面有一段话,其中有一句说到备份网站的习惯,想到网站源码文件备份
网站文件备份

常用的备份有.bak和.zip两个,使用/www.zip得到一个压缩包,解压得到备份文件
或者使用dirsearch-master对网站进行扫描,得到/www.zip


发现里面有个flag.php,打开看看

这个不是真正的flag,打开index.php,检查源代码,发现加载了class.php的文件,并且发现后面反序列化了

审查class.php里的代码,如果username=‘admin’并且password=100,在执行__destruct()时会输出flag

序列化
序列化是将对象状态转换为可保持或可传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据

构造序列化化代码

得到序列化后的值:O:4:"Name":2:{s:14:" Name username";s:5:"admin";s:14:" Name password";i:100;}

Wakeup
执行unserialize()函数之前会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup方法,预先准备对象需要的资源
绕过__Wakeup
Name后有一个数字2,这个2是代表这个类有一个属性。wakeup()漏洞就是与整个属性个数值有关。当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过wakeup的执行。
这里将2改为3跳过__wakeup
O:4:"Name":3:{s:14:" Nameusername";s:5:"admin";s:14:" Namepassword";i:100;}
这里提交后发现网页报错,原来是private声明的字段是私有字段
Private
private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
用GET提交方法将O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}作为select的变量值提交
payload:?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}


浙公网安备 33010602011771号