Zend Framework遠(yuǎn)程執(zhí)行代碼漏洞
Zend Framework (ZF)是Zend公司推出的一套PHP開(kāi)發(fā)框架。是用 PHP 5 來(lái)開(kāi)發(fā) web程序和服務(wù)的開(kāi)源框架。ZF 用 100% 面向?qū)ο缶幋a實(shí)現(xiàn)。 ZF 的組件結(jié)構(gòu)獨(dú)一無(wú)二,每個(gè)組件幾乎不依靠其他組件。這樣的松耦合結(jié)構(gòu)可以讓開(kāi)發(fā)者獨(dú)立使用組件。 我們常稱(chēng)此為 “use-at-will”設(shè)計(jì)。
Zend類(lèi)是整個(gè)Zend Framework的基類(lèi),之所以有這個(gè)類(lèi)是為了使Zend Framework遵循DRY原則(Don't Repeat Yourself)。這個(gè)類(lèi)只包含靜態(tài)方法,這些類(lèi)方法具有Zend Framework中的很多組件都需要的功能。
Zend Framework出現(xiàn)漏洞已經(jīng)不是第一次了,早在2012年,WooYun就曝出了Zend Framework(ZF)框架中的XMLRPC模塊存在xxe(XML external entity)注入漏洞,攻擊者可借此讀取服務(wù)器上的任意文件,包括密碼文件及PHP源代碼。當(dāng)時(shí)200余家網(wǎng)站存在這一漏洞,知名開(kāi)源建站平臺(tái)Magento等使用ZF框架的建站系統(tǒng)也受該漏洞影響。
本周bleepingcomputer揭露了一個(gè)不受信任的反序列化漏洞,攻擊者可以利用Zend Framework在PHP站點(diǎn)上實(shí)現(xiàn)遠(yuǎn)程代碼執(zhí)行。
目前這個(gè)漏洞被命名為CVE-2021-3007,此漏洞也可能影響Zend的替代項(xiàng)目Laminas,在一年前,Linux 基金會(huì)與 Zend Technologies、Rogue Wave Software 一起宣布 Zend 框架正在過(guò)渡到 Linux 基金會(huì),并在新的治理框架下改名為 Laminas 項(xiàng)目。
Zend Framework由安裝超過(guò)5.7億次的PHP包組成,開(kāi)發(fā)人員使用該框架構(gòu)建面向?qū)ο蟮膚eb應(yīng)用程序。
從不受信任的反序列化到RCE
本周,安全研究員Ling Yizhou披露了Zend Framework 3.0.0中的一個(gè)特定gadget鏈?zhǔn)侨绾伪粸E用于不受信任的反序列化攻擊中的。
如果漏洞被利用,遠(yuǎn)程攻擊者可以在某些情況下對(duì)易受攻擊的PHP應(yīng)用程序進(jìn)行遠(yuǎn)程代碼執(zhí)行(remote code execution, RCE)攻擊。
Zend Framework 3.0.0有一個(gè)反序列化漏洞,如果內(nèi)容是可控的,可能導(dǎo)致遠(yuǎn)程代碼執(zhí)行,這與Stream中的Zend\Http\Response\Stream類(lèi)的__destruct方法有關(guān)。
雖然實(shí)際的不受信任的反序列化必須來(lái)自易受攻擊的應(yīng)用程序,而且Zend框架本身并不存在,但Zend提供的類(lèi)鏈可能幫助攻擊者實(shí)現(xiàn)RCE。
當(dāng)應(yīng)用程序從用戶(hù)或系統(tǒng)接收的已編碼數(shù)據(jù)在應(yīng)用程序解碼之前未經(jīng)過(guò)適當(dāng)驗(yàn)證時(shí),應(yīng)用程序中就會(huì)出現(xiàn)不受信任的反序列化漏洞。
一個(gè)易受攻擊的應(yīng)用程序可能會(huì)反序列化并處理接收到的格式不正確的數(shù)據(jù),這可能會(huì)導(dǎo)致從應(yīng)用程序崩潰(拒絕服務(wù))到攻擊者能夠在應(yīng)用程序上下文中運(yùn)行任意命令等一系列后果。
在Zend的示例中,漏洞源于Stream類(lèi)的析構(gòu)函數(shù),這是一個(gè)PHP魔術(shù)方法。
在面向?qū)ο缶幊讨校瑯?gòu)造函數(shù)和析構(gòu)函數(shù)是在創(chuàng)建和銷(xiāo)毀新類(lèi)對(duì)象時(shí)分別調(diào)用的方法。
例如,在本例中,一個(gè)新創(chuàng)建的Stream對(duì)象將通過(guò)構(gòu)造函數(shù)在其概念處運(yùn)行一系列命令。
一旦對(duì)象在整個(gè)程序執(zhí)行工作流程中達(dá)到其目的,PHP解釋程序?qū)⒆罱K調(diào)用該對(duì)象的析構(gòu)函數(shù),并遵循另一組命令來(lái)釋放內(nèi)存,執(zhí)行清理任務(wù)并刪除任何臨時(shí)文件,這是一種好方法。
Yizhou指出,Stream的析構(gòu)函數(shù)調(diào)用的用于刪除文件的unlink()方法需要一個(gè)文件名作為參數(shù),文件名是字符串?dāng)?shù)據(jù)類(lèi)型。

Zend Framework和Laminas項(xiàng)目中的漏洞破壞程序
實(shí)際上,如果streamName對(duì)象為非字符串類(lèi)型,則在應(yīng)用程序執(zhí)行結(jié)束時(shí),仍將其傳遞給析構(gòu)函數(shù)。因此,只期望字符串值的析構(gòu)函數(shù)將嘗試調(diào)用對(duì)象的__toString方法,以獲取與字符串等價(jià)的值。但是,可以由對(duì)象的創(chuàng)建者,或者對(duì)象實(shí)例化的類(lèi)的創(chuàng)建者,輕松地自定義__toString方法。例如,Yizhou強(qiáng)調(diào)了Zend Framework的Gravatar類(lèi)中的__toString方法是由其程序員編寫(xiě)的,其最終返回了攻擊者可以直接控制的值,以執(zhí)行任意代碼。
這意味著,如果將Stream類(lèi)傳遞到預(yù)期為streamName的Gravator對(duì)象,在某些情況下,攻擊者可以在使用Zend構(gòu)建的易受攻擊的PHP應(yīng)用程序中運(yùn)行任意命令。
研究人員演示了至少2種情況,可以將序列化的對(duì)象傳遞給Zend,當(dāng)通過(guò)PHP應(yīng)用程序?qū)ζ溥M(jìn)行解析時(shí),將在呈現(xiàn)的網(wǎng)頁(yè)上呈現(xiàn)攻擊者命令的輸出。
在概念驗(yàn)證(PoC)漏洞中,研究人員演示了web應(yīng)用程序的phpinfo頁(yè)面是如何成功解析他的系統(tǒng)命令“whoami”通過(guò)一個(gè)序列化的HTTP請(qǐng)求,并返回Windows帳戶(hù)名“nt authority\system”。
研究人員在演示對(duì)講機(jī)上成功運(yùn)行了“whoami”命令,獲得了“nt authority system”輸出
使用Laminas構(gòu)建的應(yīng)用也可能會(huì)受到影響
在2020年1月,Zend框架被遷移到Laminas項(xiàng)目,大量的代碼被遷移到新的代碼庫(kù)中。
例如,帶有上述析構(gòu)函數(shù)的Zend的Stream.php類(lèi)在某些版本的Laminas中仍然存在。
該代碼可能與Laminas項(xiàng)目Laminas -http有關(guān)。維護(hù)人員不再支持Zend框架。然而,并不是所有的Zend Framework 3.0.0漏洞都存在于Laminas項(xiàng)目版本中。
雖然這并不一定表明所有用Laminas項(xiàng)目構(gòu)建的應(yīng)用程序都是脆弱的,但建議開(kāi)發(fā)人員做好必要的防護(hù)。
考慮到PHP能夠在一定程度上控制大約80%的互聯(lián)網(wǎng)站點(diǎn),并且考慮到Zend Framework的普及程度,建議開(kāi)發(fā)人員徹底檢查他們的web應(yīng)用程序,以確定是否存在不受信任的對(duì)象反序列化。
本周在Yii Framework中發(fā)現(xiàn)了一個(gè)類(lèi)似的gadget鏈,攻擊者可以使用它們來(lái)攻擊易受攻擊的應(yīng)用程序。
對(duì)應(yīng)用程序執(zhí)行徹底的安全審計(jì)是一種不時(shí)發(fā)現(xiàn)零日和特定于環(huán)境的漏洞的方法。
本文翻譯自:
https://www.bleepingcomputer.com/news/security/zend-framework-remote-code-execution-vulnerability-revealed/