前言:刚开始玩不断查资料学习新知识,再加上自己是菜鸡,就得不断学习别人的骚姿势哭唧唧~~~
好吧,进入正题:
说是有网站备份,然后拿出你的目录扫描工具,扫他,发现网站备份文件:www.zip
(看网上还有个扫目录的工具:dirsearch 下载地址:https://github.com/maurosoria/dirsearch)有空试试嘻嘻嘻
下载打开得到源码:
入口文件存在unserialize那必然就是反序列化的知识点了。
好吧接下来看其他文件:
Class.php和flag.php,不用想class.php必然是解题关键。
进入分析class.php:
包含flag.php,然后定义一个类:Name,Name中有自己的private变量:username,password,默认值为:nonono和yesyes
还有是三个魔术方法:__construct (创建新对象时触发)、__wakeup(反序列化时触发) 、__destruct(对象销毁时触发)
别想那么多,要是搞不清反序列化哪些会触发,那就本地试试:
先生成序列化的内容,生成一个新对象,这时触发__construct,输出序列化内容,再销毁对象触发__destruct。
那反序列呢?试试:
直接就是触发__wakeup和__destruct,所以整个过程和__construct无关嘛。
也就是说,反序列化后必然触发:wakeup魔术方法:这时username肯定会等于guest。
那完了之后,触发destruct魔术方法:判断password不等于100,就die,明显不行。那password必然等于100,然后在判断username等于字符串admin吗?等于,返回flag。不等于就die了。
所以要使password=100,username=admin。
那就生成这样的对象就行:
这是满足的对象。
但是这不满足啊,连最基本的password=100也都不满足
其实这是被前端骗了,因为view-source后发现生成满足的序列化是这样子的:
Name前面和后面都有类似空格的东西,直接复制回去试试:
发现也不行,会自动处理了。作为菜鸡还是老老实实查资料吧
参考:https://blog.csdn.net/weixin_44077544/article/details/103542260
private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上0的前缀。
所以说得有0,那0是什么东西:按我理解,就是拿这个标识private变量,因此放进url要把0变成%00。(太多要学的东西,先记住就好。)
所以,生成的东西别被前端骗了,因为php无法把0正常执行,所以靠单纯得一个class文件复现不了。直接上靶场:
构建:
?select=O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
但是:
发现是这个:也就是说password等于100了,但是呢,username还是不能等于admin,捣鬼的就是wakeup魔术方法!那就绕过魔术方法,必须走这步,所以这又学一招。
截个图就明白了,太底层的东西我还是不会,我放弃。
对象属性个数大于实际对象属性个数就行。因此,继续构建:
最终:
?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
好了ojbk。