例题可看:https://www.cnblogs.com/v2ish1yan/articles/16118319.html
今天才学的,做个记录。
字符串逃逸分为两种,减少和增多。
主要是通过一个preg_replace()函数来进行字符串的减少和增多。
首先要知道逃逸的原理,就是反序列化时,是以}来进行结尾的,同时在字符串内,是以关键字后面的数字来规定所读取的内容的长度。
1.字符串增多
demo:
得到结果为:
string(45) "O:1:"A":2:{s:1:"a";s:1:"q";s:1:"b";s:2:"21";}"
要将反序列后$b的值变为我们想要的值。
我们还要有一个关键的函数。
function filter($a){
$filter='/q/i';
return preg_replace($filter,'ww',$a);
}
这个就是将序列化后的值,将所有的'q'变为'ww'。
例子:
';
$r=filter(serialize($a));
var_dump($r);
得到:
假设我们想要$b=104,构造的$b的值的序列化后为:
";s:1:"b";s:3:"104";} 这里的";是用来闭合前面的,往下看就知道了
如何进行逃逸
我们先看看把上面的字符串加到$a后是什么样的。
然后仔细看,如果我们把s:28后面的内容以字符串按要求填满了28个,那么s:1:"b";s:3:"104";}就会被包含在序列化字符串内。而}”后面的内容,即;s:1:"b";s:2:"21";}"就不会被认为是序列化字符串的内容,从而执行了我们构造的";s:1:"b";s:3:"104";},即让一个成员b的值为104。
然后进行构造:
在上面,只要让'w'字符的数量按要求达到s:后面所要求的的数量(28)即可。
但是我们要根据实际情况来选择构造多少个w。
因为在filter函数中,一个q被换成了两个w,所以让q的数量等于";s:1:"b";s:3:"104";}的字符串长度就行了。因为";s:1:"b";s:3:"104";} 的字符串长度为21,让q的数量为21,反序列化后a的值的长度为就是q的数量加上";s:1:"b";s:3:"104";} 的长度(42),在filter()之后,w的数量就是刚好42,而我们添加上去的字符串就会被逃逸出来,会在反序列化的时候成功执行。【文笔不好】
';
$r=filter(serialize($a));
var_dump($r);
得到
string(87) "O:1:"A":2:{s:1:"a";s:42:"qqqqqqqqqqqqqqqqqqqqq";s:1:"b";s:3:"104";}";s:1:"b";s:2:"21";}"
string(108) "O:1:"A":2:{s:1:"a";s:42:"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww";s:1:"b";s:3:"104";}";s:1:"b";s:2:"21";}"
然后再进行反序列化就可以发现,$b的值变成了104。
接上面代码:
print_r(unserialize($r));
总的就是说,让字符'w'占用了原本属于";s:1:"b";s:3:"104"}的位置,从而让";s:1:"b";s:3:"104"}逃逸出去而成功执行。
2.字符串减少
demo:
';
$r=filter(serialize($a));
var_dump($r);
由名字可知,这个就是让字符串变少。
那么要如何让字符串逃逸呢?
同上面字符串增加:如果要让$b=104,那么他的序列化后就是:";s:1:"b";s:3:"104";}
但是前面要加个东西,如:A";s:1:"b";s:3:"104";},那个A是用来闭合的。
我们先把$b=A";s:1:"b";s:3:"104";}
得到:
这里可以看到,在序列化字符串里,有两个 s:1:"b",第一个是序列化得到的,第二个是我们自己构造的。
那么要如果让我们构造的104生效呢?
就要让s:1:"a":s:32:"读取到s:22:"A",这样s:22:"A就会变成$a的值了,后面的内容就可以执行,所以这个时候就要想如何使这些字符串在一个合理的数量了。
有filter可以知道,两个q会变成一个w,所以只要让w的个数等于黄色字符串的长度
"O:1:"A":2:{s:1:"a";s:44:"wwwwwwwwwwwwwwwwwwwwww";s:1:"b";s:22:"A";s:1:"b";s:3:"104";}";}"
这个黄色字符串长度为17,所以qq的数量就为17,就有34个q。
所以这样:
';
$r=filter(serialize($a));
var_dump($r);
print_r(unserialize($r));
就可以得到
看$b变成了104。
与字符串增加的区别:
1.字符串增加:构造的序列化加在qqqq(就是值有很多qqqq的)那个变量里。字符串减少:构造的序列化加在另一个变量里。
2.字符串增加:字符串'qqqqxxx'的数量依照构造的那个序列化字符串的长度。字符串减少:字符串'qqqqxxx'的数量依照"O:1:"A":2:{s:1:"a";s:44:"wwwwwwwwwwwwwwwwwwwwww";s:1:"b";s:22:"A";s:1:"b";s:3:"104";}";}"中黄色字符串的长度。(只能意会)(doge)