打开环境如下
提示说到他有备份网站的习惯,那就用御剑扫一下,但是扫不出来,什么也没有
应该是字典不全,换用dirsearch扫到了www.zip进去下载,有index.php,flag.php和class.php
flag.php如下
提交并不对
class.php如下
这里是考察了反序列化
要得到flag的关键就是在__destruct()方法中的password=100,username=admin
但是在__wakeup()方法这里会把username=guest,所以最最关键的就是绕过__wakeup()方法
绕过wakeup方法就是让对象的个数大于实际个数
exp就是
得到
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}
在使用它时将
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}
改为
O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}
就可以绕过__wakeup()方法
在index.php中提示我们get select
get后发现有问题
看了wp发现是因为private声明的字段在序列化时类名和字段名会加上 的前缀,而在url栏中会出现 有空白符,复制的时候会丢失,所以加上%00。
- protected 声明的字段为保护字段,在所声明的类和该类的子类中可见,但在该类的对象实例中不可见。因此保护字段的字段名在序列化时,字段名前面会加上 * 的前缀。这里的 表示 ASCII 码为 0 的字符(不可见字符),而不是 组合。这也许解释了,为什么如果直接在网址上,传递 * username会报错,因为实际上并不是 ,只是用它来代替ASCII值为0的字符。必须用python传值才可以。
- private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上 的前缀。字符串长度也包括所加前缀的长度。其中 字符也是计算长度的。
所以在 类名和字段名前加上%00就可以


![BUUCTF [极客大挑战 2019]PHP BUUCTF [极客大挑战 2019]PHP](http://www.mshxw.com/aiimages/31/286387.png)
