PHP反序列化字元逃逸學習

2020-10-14 13:01:03

過濾後字元變多

首先給出原生的php程式碼,很簡單不做過多的解釋,就是把反序列化後的一個x替換成為兩個

<?php

function change($str){
    return str_replace("xx","3",$str);
}

$name = $_GET['name'];
$age = "I am 11";
$arr = array($name,$age);
echo "反序列化字串:";
var_dump(serialize($arr));
echo "<br/>";
echo "過濾後:";
$old = change(serialize($arr));
$new = unserialize($old);
var_dump($new);
echo "<br/>此時,age=$new[1]";

正常情況下
在這裡插入圖片描述

如果此時多傳入一個x的話會怎樣,毫無疑問反序列化失敗,由於溢位(s本來是4結果多了一個字元出來),我們可以利用這一點實現字串逃逸
在這裡插入圖片描述

首先看看效果
在這裡插入圖片描述

我們傳入name=hggxxxxxxxxxxxxxxxxxxxx";i:1;s:6:"woaini";}
";i:1;s:6:"woaini";}這一部分一共二十個字元
由於一個x會被替換為兩個,我們輸入了一共20個x,現在是40個,多出來的20個x其實取代了我們的這二十個字元";i:1;s:6:"woaini";},從而造成";i:1;s:6:"woaini";}的溢位,而"閉合了前串,使得我們的字串成功逃逸,可以被反序列化,輸出woaini
Add:
最後的;}閉合反序列化全過程導致原來的";i:1;s:7:"I am 11";}"被捨棄,不影響反序列化過程`

過濾後字元變少

<?php

function change($str){
    return str_replace("xx","3",$str);
}

$arr['name'] = $_GET['name'];
$arr['age'] = $_GET['age'];
echo "反序列化字串:";
var_dump(serialize($arr));
echo "<br/>";
echo "過濾後:";
$old = change(serialize($arr));
var_dump($old);
echo "<br/>";
$new = unserialize($old);
var_dump($new);
echo "<br/>此時,age=";
echo $new['age'];

這是正常的情況,
在這裡插入圖片描述

加了兩個x後
在這裡插入圖片描述

老規矩看看最後的效果
在這裡插入圖片描述
簡單來說,就是前面少了一半,導致後面的字元被吃掉,從而執行了我們後面的程式碼;
我們來看,這部分是age序列化後的結果
在這裡插入圖片描述
由於前面是40個x所以導致少了20個字元,所以需要後面來補上,這一部分剛好20個,後面由於有"閉合了前面因此後面的引數就可以由我們自定義執行了
在這裡插入圖片描述