在2018年5月到12月,伴隨著阿里安全主辦的軟件供應(yīng)鏈安全大賽,我們自身在設(shè)計(jì)、引導(dǎo)比賽的形式規(guī)則的同時(shí),也在做著反思和探究,直接研判諸多方面潛在風(fēng)險(xiǎn),以及透過業(yè)界三方的出題和解題案例分享,展示了行業(yè)內(nèi)一線玩家對(duì)問題、解決方案實(shí)體化的思路
(參見如下歷史文章:
1、軟件供應(yīng)鏈安全大賽,C源代碼賽季總結(jié)
2、阿里軟件供應(yīng)鏈安全大賽到底在比什么?C源代碼賽季官方賽題精選出爐!
3、『功守道』軟件供應(yīng)鏈安全大賽·PE二進(jìn)制賽季啟示錄:上篇
4、『功守道』軟件供應(yīng)鏈安全大賽·PE二進(jìn)制賽季啟示錄:下篇
5、『功守道』軟件供應(yīng)鏈安全大賽·Java賽季總結(jié)
另外,根據(jù)近期的一些歷史事件,也做了一些深挖和聯(lián)想,考慮惡意的上游開發(fā)者,如何巧妙(或者說,處心積慮)地將問題引入,并在當(dāng)前的軟件供應(yīng)鏈生態(tài)體系中,造成遠(yuǎn)比表面上看起來要深遠(yuǎn)得多的影響(參見:《深挖CVE-2018-10933(libssh服務(wù)端校驗(yàn)繞過)兼談軟件供應(yīng)鏈真實(shí)威脅》)。
以上這些,拋開體系化的設(shè)想,只看案例,可能會(huì)得到這樣的印象:這種威脅,都是由蓄意的上游或第三方參與者造成的;即便在最極端情況下,假使一個(gè)大型軟件商或開源組織,被發(fā)現(xiàn)存在廣泛、惡意的上游代碼污染,那它頂多也不過相當(dāng)于“奧創(chuàng)”一樣的邪惡寡頭,與其劃清界限、清除歷史包袱即可,雖然可能有陣痛。
可惜,并非如此。
在我們組織比賽的后半程中,對(duì)我們面臨的這種威脅類型,不斷有孤立的事例看似隨機(jī)地發(fā)生,對(duì)此我以隨筆的方式對(duì)它們做了分析和記錄,以下與大家分享。
Ⅰ. 從感染到遺傳:LibVNC與TightVNC系列漏洞
2018年12月10日晚9:03,OSS漏洞預(yù)警平臺(tái)彈出的一封漏洞披露郵件,引起了我的注意。披露者是卡巴斯基工控系統(tǒng)漏洞研究組的Pavel Cheremushkin。
一些必要背景
VNC是一套屏幕圖像分享和遠(yuǎn)程操作軟件,底層通信為RFB協(xié)議,由劍橋某實(shí)驗(yàn)室開發(fā),后1999年并入AT&T,2002年關(guān)停實(shí)驗(yàn)室與項(xiàng)目,VNC開源發(fā)布。
VNC本被設(shè)計(jì)用在局域網(wǎng)環(huán)境,且誕生背景決定其更傾向研究性質(zhì),商用級(jí)安全的缺失始終是個(gè)問題。后續(xù)有若干新的實(shí)現(xiàn)軟件,如TightVNC、RealVNC,在公眾認(rèn)知中,AT&T版本已死,后起之秀一定程度上修正了問題。
目前各種更優(yōu)秀的遠(yuǎn)程控制和分享協(xié)議取代了VNC的位置,盡管例如蘋果仍然系統(tǒng)內(nèi)建VNC作為遠(yuǎn)程方式。但在非桌面領(lǐng)域,VNC還有我們想不到的重要性,比如工控領(lǐng)域需要遠(yuǎn)程屏幕傳輸?shù)膱?chǎng)景,這也是為什么這系列漏洞作者會(huì)關(guān)注這一塊。
漏洞技術(shù)概況
Pavel總結(jié)到,在階段漏洞挖掘中共上報(bào)11個(gè)漏洞。在披露郵件中描述了其中4個(gè)的技術(shù)細(xì)節(jié),均在協(xié)議數(shù)據(jù)包處理代碼中,漏洞類型古典,分別是全局緩沖區(qū)溢出、堆溢出和空指針解引用。其中緩沖區(qū)溢出類型漏洞可方便構(gòu)造PoC,實(shí)現(xiàn)遠(yuǎn)程任意代碼執(zhí)行的漏洞利用。
漏洞本身原理簡(jiǎn)單,也并不是關(guān)鍵。以其中一個(gè)為例,Pavel在發(fā)現(xiàn)時(shí)負(fù)責(zé)任地向LibVNC作者提交了issue,并跟進(jìn)漏洞修復(fù)過程;在第一次修復(fù)之后,復(fù)核并指出修復(fù)代碼無效,給出了有效patch。這個(gè)過程是常規(guī)操作。
漏洞疑點(diǎn)
有意思的是,在漏洞披露郵件中,Pavel重點(diǎn)談了自己對(duì)這系列漏洞的一些周邊發(fā)現(xiàn),也是這里提到的原因。其中,關(guān)于存在漏洞的代碼,作者表述:
我最初認(rèn)為,這些問題是libvnc開發(fā)者自己代碼中的錯(cuò)誤,但看起來并非如此。其中有一些(如CoRRE數(shù)據(jù)處理函數(shù)中的堆緩沖區(qū)溢出),出現(xiàn)在AT&T實(shí)驗(yàn)室1999年的代碼中,而后被很多軟件開發(fā)者原樣復(fù)制(在Github上搜索一下HandleCoRREBPP函數(shù),你就知道),LibVNC和TightVNC也是如此。
為了證實(shí),翻閱了這部分代碼,確實(shí)在其中數(shù)據(jù)處理相關(guān)代碼文件看到了劍橋和AT&T實(shí)驗(yàn)室的文件頭GPL聲明注釋,
這證實(shí)這些文件是直接從最初劍橋?qū)嶒?yàn)室版本VNC移植過來的,且使用方式是?直接代碼包含,而非獨(dú)立庫引用方式。在官方開源發(fā)布并停止更新后,LibVNC使用的這部分代碼基本沒有改動(dòng)——除了少數(shù)變量命名方式的統(tǒng)一,以及本次漏洞修復(fù)。通過搜索,我找到了2000年發(fā)布的相關(guān)代碼文件,確認(rèn)這些文件與LibVNC中引入的原始版本一致。
另外,Pavel同時(shí)反饋了TightVNC中相同的問題。TightVNC與LibVNC沒有繼承和直接引用關(guān)系,但上述VNC代碼同樣被TightVNC使用,問題的模式不約而同。Pavel測(cè)試發(fā)現(xiàn)在Ubuntu最新版本TightVNC套件(1.3.10版本)中同樣存在該問題,上報(bào)給當(dāng)前軟件所有者GlavSoft公司,但對(duì)方聲稱目前精力放在不受GPL限制的TightVNC 2.x版本開發(fā)中,對(duì)開源的1.x版本漏洞代碼“可能會(huì)進(jìn)行修復(fù)”。看起來,這個(gè)問題被踢給了各大Linux發(fā)行版社區(qū)來焦慮了——如果他們?cè)敢饨渝仭?/p>
問題思考
在披露郵件中,Pavel認(rèn)為,這些代碼bug“如此明顯,讓人無法相信之前沒被人發(fā)現(xiàn)過……也許是因?yàn)槟承┨厥饫碛刹攀冀K沒得到修復(fù)”。
事實(shí)上,我們都知道目前存在一些對(duì)開源基礎(chǔ)軟件進(jìn)行安全掃描的大型項(xiàng)目,例如Google的OSS;同時(shí),仍然存活的開源項(xiàng)目也越來越注重自身代碼發(fā)布前的安全掃描,F(xiàn)ortify、Coverity的掃描也成為很多項(xiàng)目和平臺(tái)的標(biāo)配。在這樣一些眼睛注視下,為什么還有這樣的問題?我認(rèn)為就這個(gè)具體事例來說,可能有如下兩個(gè)因素:
但是透過這個(gè)具體例子,再延伸思考相關(guān)的實(shí)踐,這里最根本的問題可以總結(jié)為一個(gè)模式:?復(fù)制粘貼風(fēng)險(xiǎn)。復(fù)制粘貼并不簡(jiǎn)單意味著剽竊,實(shí)際是當(dāng)前軟件領(lǐng)域、互聯(lián)網(wǎng)行業(yè)發(fā)展的基礎(chǔ)模式,但其中有一些沒人能嘗試解決的問題:
在Synopsys下BLACKDUCK軟件之前發(fā)布的《2018 Open Source Security and Risk Analysis Report》中分析,96%的應(yīng)用中包含有開源組件和代碼,開源代碼在應(yīng)用全部代碼中的占比約為57%,78%的應(yīng)用中在引用的三方開源代碼中存在歷史漏洞。也就是說,現(xiàn)在互聯(lián)網(wǎng)上所有廠商開發(fā)的軟件、應(yīng)用,其開發(fā)人員自己寫的代碼都是一少部分,多數(shù)都是借鑒來的。而這還只是可統(tǒng)計(jì)、可追溯的;至于上面提到的非規(guī)范的代碼引用,如果也納入進(jìn)來考慮,三方代碼占應(yīng)用中的比例會(huì)上升到多少?曾經(jīng)有分析認(rèn)為至少占80%,我們只期望不會(huì)更高。
Ⅱ. 從碎片到亂刃:OpenSSH在野后門一覽
在進(jìn)行基礎(chǔ)軟件梳理時(shí),回憶到反病毒安全軟件提供商ESET在2018年十月發(fā)布的一份白皮書《THE DARK SIDE OF THE FORSSHE: A landscape of OpenSSH backdoors》。其站在一個(gè)具有廣泛用戶基礎(chǔ)的軟件提供商角度,給出了一份分析報(bào)告,數(shù)據(jù)和結(jié)論超出我們對(duì)于當(dāng)前基礎(chǔ)軟件使用全景的估量。以下以我的角度對(duì)其中一方面進(jìn)行解讀。
一些必要背景
SSH的作用和重要性無需贅言;雖然我們站在傳統(tǒng)互聯(lián)網(wǎng)公司角度,可以認(rèn)為SSH是通往生產(chǎn)服務(wù)器的生命通道,但當(dāng)前多樣化的產(chǎn)業(yè)環(huán)境已經(jīng)不止于此(如之前l(fā)ibssh事件中,不幸被我言中的,SSH在網(wǎng)絡(luò)設(shè)備、IoT設(shè)備上(如f5)的廣泛使用)。
OpenSSH是目前絕大多數(shù)SSH服務(wù)端的基礎(chǔ)軟件,有完備的開發(fā)團(tuán)隊(duì)、發(fā)布規(guī)范、維護(hù)機(jī)制,本身是靠譜的。如同絕大多數(shù)基礎(chǔ)軟件開源項(xiàng)目的做法,OpenSSH對(duì)漏洞有及時(shí)的響應(yīng),針對(duì)最新版本代碼發(fā)出安全補(bǔ)丁,但是各大Linux發(fā)行版使用的有各種版本的OpenSSH,這些社區(qū)自行負(fù)責(zé)將官方開發(fā)者的安全補(bǔ)丁移植到自己系統(tǒng)搭載的低版本代碼上。
白皮書披露的現(xiàn)狀
如果你是一個(gè)企業(yè)的運(yùn)維管理人員,需要向企業(yè)生產(chǎn)服務(wù)器安裝OpenSSH或者其它基礎(chǔ)軟件,最簡(jiǎn)單的方式當(dāng)然是使用系統(tǒng)的軟件管理安裝即可。但是有時(shí)候,出于遷移成本考慮,可能企業(yè)需要在一個(gè)舊版本系統(tǒng)上,使用較新版本的OpenSSL、OpenSSH等基礎(chǔ)軟件,這些系統(tǒng)不提供,需要自行安裝;或者需要一個(gè)某有種特殊特性的定制版本。這時(shí),可能會(huì)選擇從某些rpm包集中站下載某些不具名第三方提供的現(xiàn)成的安裝包,或者下載非官方的定制化源碼本地編譯后安裝,總之從這里引入了不確定性。
這種不確定性有多大?我們粗估一下,似乎不應(yīng)成為問題。但這份白皮書給我們看到了鮮活的數(shù)據(jù)。
ESET研究人員從OpenSSH的一次歷史大規(guī)模Linux服務(wù)端惡意軟件Windigo中獲得啟示,采用某種巧妙的方式,面向在野的服務(wù)器進(jìn)行數(shù)據(jù)采集,主要是系統(tǒng)與版本、安裝的OpenSSH版本信息以及服務(wù)端程序文件的一個(gè)特殊簽名。整理一個(gè)簽名白名單,包含有所有能搜索到的官方發(fā)布二進(jìn)制版本、各大Linux發(fā)行版本各個(gè)版本所帶的程序文件版本,將這些標(biāo)定為正常樣本進(jìn)行去除。最終結(jié)論是:
白皮書用了大篇幅做技術(shù)分析報(bào)告,此處供細(xì)節(jié)分析,不展開分析,以下為根據(jù)惡意程序復(fù)雜度描繪的21個(gè)家族圖譜:
問題思考
問題引入的可能渠道,我在開頭進(jìn)行了一點(diǎn)推測(cè),主要是由人的原因切入的,除此以外,最可能的是惡意攻擊者在利用各種方法入侵目標(biāo)主機(jī)后,主動(dòng)替換了目標(biāo)OpenSSH為惡意版本,從而達(dá)成攻擊持久化操作。但是這些都是止血的安全運(yùn)維人員該考慮的事情;關(guān)鍵問題是,透過表象,這顯露了什么威脅形式?
這個(gè)問題很好回答,之前也曾經(jīng)反復(fù)說過:基礎(chǔ)軟件碎片化。
如上一章節(jié)簡(jiǎn)單提到,在開發(fā)過程中有各種可能的渠道引入開發(fā)者不完全了解和信任的代碼;在運(yùn)維過程中也是如此。二者互相作用,造成了軟件碎片化的龐雜現(xiàn)狀。在企業(yè)內(nèi)部,同一份基礎(chǔ)軟件庫,可能不同的業(yè)務(wù)線各自定制一份,放到企業(yè)私有軟件倉庫源中,有些會(huì)有人持續(xù)更新供自己產(chǎn)品使用,有些由系統(tǒng)軟件基礎(chǔ)設(shè)施維護(hù)人員單獨(dú)維護(hù),有些則可能是開發(fā)人員臨時(shí)想起來上傳的,他們自己都不記得;后續(xù)用到的這個(gè)基礎(chǔ)軟件的開發(fā)和團(tuán)隊(duì),在這個(gè)源上搜索到已有的庫,很大概率會(huì)傾向于直接使用,不管來源、是否有質(zhì)量背書等。長此以往問題會(huì)持續(xù)發(fā)酵。而我們開最壞的腦洞,是否可能有黑產(chǎn)人員入職到內(nèi)部,提交個(gè)惡意基礎(chǔ)庫之后就走人的可能?現(xiàn)行企業(yè)安全開發(fā)流程中審核機(jī)制的普遍缺失給這留下了空位。
將源碼來源碎片化與二進(jìn)制使用碎片化并起來考慮,我們不難看到一個(gè)遠(yuǎn)遠(yuǎn)超過OpenSSH事件威脅程度的圖景。但這個(gè)問題不是僅僅靠開發(fā)階段規(guī)約、運(yùn)維階段規(guī)范、企業(yè)內(nèi)部管控、行業(yè)自查、政府監(jiān)管就可以根除的,最大的問題歸根結(jié)底兩句話:?不可能用一場(chǎng)戰(zhàn)役對(duì)抗持續(xù)威脅;不可能用有限分析對(duì)抗無限未知。
Ⅲ. 從自信到自省:RHEL、CentOS backport版本BIND漏洞
2018年12月20日凌晨,在備戰(zhàn)冬至的軟件供應(yīng)鏈安全大賽決賽時(shí),我注意到漏洞預(yù)警平臺(tái)捕獲的一封郵件。但這不是一個(gè)漏洞初始披露郵件,而是對(duì)一個(gè)稍早已披露的BIND在RedHat、CentOS發(fā)行版上特定版本的1day漏洞CVE-2018-5742,由BIND的官方開發(fā)者進(jìn)行額外信息澄(shuǎi)清(guō)的郵件。
一些必要背景
關(guān)于BIND
互聯(lián)網(wǎng)的一個(gè)古老而基礎(chǔ)的設(shè)施是DNS,這個(gè)概念在讀者不應(yīng)陌生。而BIND“是現(xiàn)今互聯(lián)網(wǎng)上最常使用的DNS軟件,使用BIND作為服務(wù)器軟件的DNS服務(wù)器約占所有DNS服務(wù)器的九成。BIND現(xiàn)在由互聯(lián)網(wǎng)系統(tǒng)協(xié)會(huì)負(fù)責(zé)開發(fā)與維護(hù)參考。”所以BIND的基礎(chǔ)地位即是如此,因此也一向被大量白帽黑帽反復(fù)測(cè)試、挖掘漏洞,其開發(fā)者大概也一直處在緊繃著應(yīng)對(duì)的處境。
關(guān)于ISC和RedHat
說到開發(fā)者,上面提到BIND的官方開發(fā)者是互聯(lián)網(wǎng)系統(tǒng)協(xié)會(huì)(ISC)。ISC是一個(gè)老牌非營利組織,目前主要就是BIND和DHCP基礎(chǔ)設(shè)施的維護(hù)者。而BIND本身如同大多數(shù)歷史悠久的互聯(lián)網(wǎng)基礎(chǔ)開源軟件,是4個(gè)UCB在校生在DARPA資助下于1984年的實(shí)驗(yàn)室產(chǎn)物,直到2012年由ISC接管。
那么RedHat在此中是什么角色呢?這又要提到我之前提到的Linux發(fā)行版和自帶軟件維護(hù)策略。Red Hat Enterprise Linux(RHEL)及其社區(qū)版CentOS秉持著穩(wěn)健的軟件策略,每個(gè)大的發(fā)行版本的軟件倉庫,都只選用最必要且質(zhì)量久經(jīng)時(shí)間考驗(yàn)的軟件版本,哪怕那些版本實(shí)在是老掉牙。這不是一種過分的保守,事實(shí)證明這種策略往往給RedHat用戶在最新漏洞面前提供了保障——代碼總是跑得越少,潛在漏洞越多。
但是這有兩個(gè)關(guān)鍵問題。
一方面,如果開源基礎(chǔ)軟件被發(fā)現(xiàn)一例有歷史沿革的代碼漏洞,那么官方開發(fā)者基本都只為其最新代碼負(fù)責(zé),在當(dāng)前代碼上推出修復(fù)補(bǔ)丁。
另一方面,互聯(lián)網(wǎng)基礎(chǔ)設(shè)施雖然不像其上的應(yīng)用那樣爆發(fā)性迭代,但依然持續(xù)有一些新特性涌現(xiàn),其中一些是必不可少的,但同樣只在最新代碼中提供。
兩個(gè)剛需推動(dòng)下,各Linux發(fā)行版對(duì)長期支持版本系統(tǒng)的軟件都采用一致的策略,即保持其基礎(chǔ)軟件在一個(gè)固定的版本,但對(duì)于這些版本軟件的最新漏洞、必要的最新軟件特性,由發(fā)行版維護(hù)者將官方開發(fā)者最新代碼改動(dòng)“向后移植”到舊版本代碼中,即backport。這就是基礎(chǔ)軟件的“官宣”碎片化的源頭。
講道理,Linux發(fā)行版維護(hù)者與社區(qū)具有比較靠譜的開發(fā)能力和監(jiān)督機(jī)制,backport又基本就是一些復(fù)制粘貼工作,應(yīng)當(dāng)是很穩(wěn)當(dāng)?shù)摹媸侨绱藛幔?/p>
CVE-2018-5742漏洞概況
CVE-2018-5742是一個(gè)簡(jiǎn)單的緩沖區(qū)溢出類型漏洞,官方評(píng)定其漏洞等級(jí)moderate,認(rèn)為危害不大,漏洞修復(fù)不積極,披露信息不多,也沒有積極給出代碼修復(fù)patch和新版本rpm包。因?yàn)樵撀┒磧H在設(shè)置DEBUG_LEVEL為10以上才會(huì)觸發(fā),由遠(yuǎn)程攻擊者構(gòu)造畸形請(qǐng)求造成BIND服務(wù)崩潰,在正常的生產(chǎn)環(huán)境幾乎不可能具有危害,RedHat官方也只是給出了用戶自查建議。
這個(gè)漏洞只出現(xiàn)在RHEL和CentOS版本7中搭載的BIND 9.9.4-65及之后版本。RedHat同ISC的聲明中都證實(shí),這個(gè)漏洞的引入原因,是RedHat在嘗試將BIND 9.11版本2016年新增的NTA機(jī)制向后移植到RedHat 7系中固定搭載的BIND 9.9版本代碼時(shí),偶然的代碼錯(cuò)誤。NTA是DNS安全擴(kuò)展(DNSSEC)中,用于在特定域關(guān)閉DNSSEC校驗(yàn)以避免不必要的校驗(yàn)失敗的機(jī)制;但這個(gè)漏洞不需要對(duì)NTA本身有進(jìn)一步了解。
漏洞具體分析
官方?jīng)]有給出具體分析,但根據(jù)CentOS社區(qū)里先前有用戶反饋的bug,我得以很容易還原漏洞鏈路并定位到根本原因。
若干用戶共同反饋,其使用的BIND 9.9.4-RedHat-9.9.4-72.el7發(fā)生崩潰(coredump),并給出如下的崩潰時(shí)調(diào)用棧backtrace:
這個(gè)調(diào)用過程的邏輯為,在#9 dns_message_logfmtpacket函數(shù)判斷當(dāng)前軟件設(shè)置是否DEBUG_LEVEL大于10,若是,對(duì)用戶請(qǐng)求數(shù)據(jù)包做日志記錄,先后調(diào)用#8 dns_message_totext、#7 dns_message_sectiontotext、#6 dns_master_rdatasettotext、#5 rdataset_totext將請(qǐng)求進(jìn)行按協(xié)議分解分段后寫出。
由以上關(guān)鍵調(diào)用環(huán)節(jié),聯(lián)動(dòng)RedHat在9.9.4版本BIND源碼包中關(guān)于引入NTA特性的源碼patch,進(jìn)行代碼分析,很快定位到問題產(chǎn)生的位置,在上述backtrace中的#5,masterdump.c文件rdataset_totext函數(shù)。漏洞相關(guān)代碼片段中,RedHat進(jìn)行backport后,這里引入的代碼為:
這里判斷對(duì)于請(qǐng)求中的注釋類型數(shù)據(jù),直接通過isc_buffer_putstr宏對(duì)緩存進(jìn)行操作,在BIND工程中自定義維護(hù)的緩沖區(qū)結(jié)構(gòu)對(duì)象target上,附加一字節(jié)字符串(一個(gè)分號(hào))。而漏洞就是由此產(chǎn)生:isc_buffer_putstr中不做緩沖區(qū)邊界檢查保證,這里在緩沖區(qū)已滿情況下將造成off-by-one溢出,并觸發(fā)了緩沖區(qū)實(shí)現(xiàn)代碼中的assertion。
而ISC上游官方版本的代碼在這里是怎么寫的呢?找到ISC版本BIND 9.11代碼,這里是這樣的:
這里可以看到,官方代碼在做同樣的“附加一個(gè)分號(hào)”這個(gè)操作時(shí),審慎的使用了做緩沖區(qū)剩余空間校驗(yàn)的str_totext函數(shù),并額外做返回值成功校驗(yàn)。而上述提到的str_totext函數(shù)與RETERR宏,在移植版本的masterdump.c中,RedHat開發(fā)者也都做了保留。但是,查看代碼上下文發(fā)現(xiàn),在RedHat開發(fā)者進(jìn)行代碼移植過程中,對(duì)官方代碼進(jìn)行了功能上的若干剪裁,包括一些細(xì)分?jǐn)?shù)據(jù)類型記錄的支持;而這里對(duì)緩沖區(qū)寫入一字節(jié),也許開發(fā)者完全沒想到溢出的可能,所以自作主張地簡(jiǎn)化了代碼調(diào)用過程。
問題思考
這個(gè)漏洞本身幾乎沒什么危害,但是背后足以引起思考。
沒有人在“借”別人代碼時(shí)能不出錯(cuò)
不同于之前章節(jié)提到的那種場(chǎng)景——將代碼文件或片段復(fù)制到自己類似的代碼上下文借用——backport作為一種官方且成熟的做法,借用的代碼來源、粘貼到的代碼上下文,是具有同源屬性的,而且開發(fā)者一般是追求穩(wěn)定性優(yōu)先的社區(qū)開發(fā)人員,似乎質(zhì)量應(yīng)該有足夠保障。但是這里的關(guān)鍵問題是:代碼總要有一手、充分的語義理解,才能有可信的使用保障;因此,只要是處理他人的代碼,因?yàn)椴粔蚶斫舛e(cuò)誤使用的風(fēng)險(xiǎn),只可能減小,沒辦法消除。
如上分析,本次漏洞的產(chǎn)生看似只是做代碼移植的開發(fā)者“自作主張”之下“改錯(cuò)了”。但是更廣泛且可能的情況是,原始開發(fā)者在版本迭代中引入或更新大量基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)、API的定義,并用在新的特性實(shí)現(xiàn)代碼中;而后向移植開發(fā)人員僅需要最小規(guī)模的功能代碼,所以會(huì)對(duì)增量代碼進(jìn)行一定規(guī)模的修改、剪裁、還原,以此適應(yīng)舊版本基本代碼。這些過程同樣伴隨著第三方開發(fā)人員不可避免的“望文生義”,以及隨之而來的風(fēng)險(xiǎn)。后向移植操作也同樣助長了軟件碎片化過程,其中每一個(gè)碎片都存在這樣的問題;每一個(gè)碎片在自身生命周期也將有持續(xù)性影響。
多級(jí)復(fù)制粘貼無異于雪上加霜
這里簡(jiǎn)單探討的是企業(yè)通行的系統(tǒng)和基礎(chǔ)軟件建設(shè)實(shí)踐。一些國內(nèi)外廠商和社區(qū)發(fā)布的定制化Linux發(fā)行版,本身是有其它發(fā)行版,如CentOS特定版本淵源的,在基礎(chǔ)軟件上即便同其上游發(fā)行版最新版本間也存在斷層滯后。RedHat相對(duì)于基礎(chǔ)軟件開發(fā)者之間已經(jīng)隔了一層backport,而我們則人為制造了二級(jí)風(fēng)險(xiǎn)。
在很多基礎(chǔ)而關(guān)鍵的軟件上,企業(yè)系統(tǒng)基礎(chǔ)設(shè)施的維護(hù)者出于與RedHat類似的初衷,往往會(huì)決定自行backport一份拷貝;通過早年心臟滴血事件的洗禮,即暴露出來OpenSSL一個(gè)例子。無論是需要RHEL還沒來得及移植的新版本功能特性,還是出于對(duì)特殊使用上下文場(chǎng)景中更高執(zhí)行效率的追求,企業(yè)都可能自行對(duì)RHEL上基礎(chǔ)軟件源碼包進(jìn)行修改定制重打包。這個(gè)過程除了將風(fēng)險(xiǎn)冪次放大外,也進(jìn)一步加深了代碼的不可解釋性(包括基礎(chǔ)軟件開發(fā)人員流動(dòng)性帶來的不可解釋)。
Ⅳ. 從武功到死穴:從systemd-journald信息泄露一窺API誤用
1月10日凌晨兩點(diǎn),漏洞預(yù)警平臺(tái)爬收取一封漏洞披露郵件。披露者是Qualys,那就鐵定是重型發(fā)布了。最后看披露漏洞的目標(biāo),systemd?這就非常有意思了。
一些必要背景
systemd是什么,不好簡(jiǎn)單回答。Linux上面軟件命名,習(xí)慣以某軟件名后帶個(gè)‘d’表示后臺(tái)守護(hù)管理程序;所以systemd就可以說是整個(gè)系統(tǒng)的看守吧。而即便現(xiàn)在描述了systemd是什么,可能也很快會(huì)落伍,因?yàn)槠涑跏技昂诵拈_發(fā)者Lennart Poettering(供職于Red Hat)描述它是“永無開發(fā)完結(jié)完整、始終跟進(jìn)技術(shù)進(jìn)展的、統(tǒng)一所有發(fā)行版無止境的差異”的一種底層軟件。籠統(tǒng)講有三個(gè)作用:中央化系統(tǒng)及設(shè)置管理;其它軟件開發(fā)的基礎(chǔ)框架;應(yīng)用程序和系統(tǒng)內(nèi)核之間的膠水。如今幾乎所有Linux發(fā)行版已經(jīng)默認(rèn)提供systemd,包括RHEL/CentOS 7及后續(xù)版本。總之很基礎(chǔ)、很底層、很重要就對(duì)了。systemd本體是個(gè)主要實(shí)現(xiàn)init系統(tǒng)的框架,但還有若干關(guān)鍵組件完成其它工作;這次被爆漏洞的是其journald組件,是負(fù)責(zé)系統(tǒng)事件日志記錄的看守程序。
額外地還想簡(jiǎn)單提一句Qualys這個(gè)公司。該公司創(chuàng)立于1999年,官方介紹為信息安全與云安全解決方案企業(yè),to B的安全業(yè)務(wù)非常全面,有些也是國內(nèi)企業(yè)很少有布局的方面;例如上面提到的涉及碎片化和代碼移植過程的歷史漏洞移動(dòng),也在其漏洞管理解決方案中有所體現(xiàn)。但是我們對(duì)這家公司粗淺的了解來源于其安全研究團(tuán)隊(duì)近幾年的發(fā)聲,這兩年間發(fā)布過的,包括有『stack clash』、『sudo get_tty_name提權(quán)』、『OpenSSH信息泄露與堆溢出』、『GHOST:glibc gethostbyname緩沖區(qū)溢出』等大新聞(僅截至2017年年中)。從中可見,這個(gè)研究團(tuán)隊(duì)專門啃硬骨頭,而且還總能開拓出來新的啃食方式,往往爆出來一些別人沒想到的新漏洞類型。從這個(gè)角度,再聯(lián)想之前刷爆朋友圈的《安全研究者的自我修養(yǎng)》所倡導(dǎo)的“通過看歷史漏洞、看別人的最新成果去舉一反三”的理念,可見差距。
CVE-2018-16866漏洞詳情
這次漏洞披露,打包了三個(gè)漏洞:
漏洞分析已經(jīng)在披露中寫的很詳細(xì)了,這里不復(fù)述;而針對(duì)16866的漏洞成因來龍去脈,Qualys跟蹤的結(jié)果留下了一點(diǎn)想象和反思空間,我們來看一下。
漏洞相關(guān)代碼片段是這樣的(漏洞修復(fù)前):
讀者可以先肉眼過一遍這段代碼有什么問題。實(shí)際上我一開始也沒看出來,向下讀才恍然大悟。
這段代碼中,外部信息輸入通過*buf傳入做記錄處理。輸入數(shù)據(jù)一般包含有空白字符間隔,需要分隔開逐個(gè)記錄,有效的分隔符包括空格、制表符、回車、換行,代碼中將其寫入常量字符串;在逐字符掃描輸入數(shù)據(jù)字符串時(shí),將當(dāng)前字符使用strchr在上述間隔符字符串中檢索是否匹配,以此判斷是否為間隔符;在240行,通過這樣的判斷,跳過記錄單元字符串的頭部連續(xù)空白字符。?但是問題在于,strchr這個(gè)極其基礎(chǔ)的字符串處理函數(shù),對(duì)于C字符串終止字符’\0’的處理上有個(gè)坑:’\0’也被認(rèn)為是被檢索字符串當(dāng)中的一個(gè)有效字符。所以在240行,當(dāng)當(dāng)前掃描到的字符為字符串末尾的NULL時(shí),strchr返回的是WHITESPACE常量字符串的終止位置而非NULL,這導(dǎo)致了越界。
看起來,這是一個(gè)典型的問題:API誤用(API mis-use),只不過這個(gè)被誤用的庫函數(shù)有點(diǎn)太基礎(chǔ),讓我忍不住想是不是還會(huì)有大量的類似漏洞……當(dāng)然也反思我自己寫的代碼是不是也有同樣情況,然而略一思考就釋然了——我那么笨的代碼都用for循環(huán)加if判斷了:)
漏洞引入和消除歷史
有意思的是,Qualys研究人員很貼心地替我做了一步漏洞成因溯源,這才是單獨(dú)提這個(gè)漏洞的原因。漏洞的引入是在2015年的一個(gè)commit中:
在GitHub中,定位到上述2015年的commit信息,這里commit的備注信息為:
journald: do not strip leading whitespace from messages.
Keep leading whitespace for compatibility with older syslog implementations. Also useful when piping formatted output to the?logger?command. Keep removing trailing whitespace.
OK,看起來是一個(gè)兼容性調(diào)整,對(duì)記錄信息不再跳過開頭所有連續(xù)空白字符,只不過用strchr的簡(jiǎn)潔寫法比較突出開發(fā)者精煉的開發(fā)風(fēng)格(并不),說得過去。
之后在2018年八月的一個(gè)當(dāng)時(shí)尚未推正式版的另一次commit中被修復(fù)了,先是還原成了ec5ff4那次commit之前的寫法,然后改成了加校驗(yàn)的方式:
雖然Qualys研究者認(rèn)為上述的修改是“無心插柳”的改動(dòng),但是在GitHub可以看到,a6aadf這次commit是因?yàn)橛型獠坑脩舴答伭溯斎霐?shù)據(jù)為單個(gè)冒號(hào)情況下journald堆溢出崩潰的issue,才由開發(fā)者有目的性地修復(fù)的;而之后在859510這個(gè)commit再次改動(dòng)回來,理由是待記錄的消息都是使用單個(gè)空格作為間隔符的,而上一個(gè)commit粗暴地去掉了這種協(xié)議兼容性特性。
如果沒有以上糾結(jié)的修改和改回歷史,也許我會(huì)傾向于懷疑,在最開始漏洞引入的那個(gè)commit,既然改動(dòng)代碼沒有新增功能特性、沒有解決什么問題(畢竟其后三年,這個(gè)改動(dòng)的代碼也沒有被反映issue),也并非出于代碼規(guī)范等考慮,那么這么輕描淡寫的一次提交,難免有人為蓄意引入漏洞的嫌疑。當(dāng)然,看到幾次修復(fù)的原因,這種可能性就不大了,雖然大家仍可以保留意見。但是拋開是否人為這個(gè)因素,單純從代碼的漏洞成因看,一個(gè)傳統(tǒng)但躲不開的問題仍值得探討:API誤用。
API誤用:程序員何苦為難程序員
如果之前的章節(jié)給讀者留下了我反對(duì)代碼模塊化和復(fù)用的印象,那么這里需要正名一下,我們認(rèn)可這是當(dāng)下開發(fā)實(shí)踐不可避免的趨勢(shì),也增進(jìn)了社會(huì)開發(fā)速度。而API的設(shè)計(jì)決定了寫代碼和用代碼的雙方“舒適度”的問題,由此而來的API誤用問題,也是一直被當(dāng)做單純的軟件工程課題討論。在此方面?zhèn)€人并沒有什么研究,自然也沒辦法系統(tǒng)地給出分類和學(xué)術(shù)方案,只是談一下自己的經(jīng)驗(yàn)和想法。
一篇比較新的學(xué)術(shù)文章總結(jié)了API誤用的研究,其中一個(gè)獨(dú)立章節(jié)專門分析Java密碼學(xué)組件API誤用的實(shí)際,當(dāng)中引述之前論文認(rèn)為,密碼學(xué)API是非常容易被誤用的,比如對(duì)期望輸入數(shù)據(jù)(數(shù)據(jù)類型,數(shù)據(jù)來源,編碼形式)要求的混淆,API的必需調(diào)用次序和依賴缺失(比如缺少或冗余多次調(diào)用了初始化函數(shù)、主動(dòng)資源回收函數(shù))等。湊巧在此方面我有一點(diǎn)體會(huì):曾經(jīng)因?yàn)闃I(yè)務(wù)方需要,需要使用C++對(duì)一個(gè)Java的密碼基礎(chǔ)中間件做移植。Java對(duì)密碼學(xué)組件支持,有原生的JDK模塊和權(quán)威的BouncyCastle包可用;而C/C++只能使用第三方庫,考慮到系統(tǒng)平臺(tái)最大兼容和最小代碼量,使用Linux平臺(tái)默認(rèn)自帶的OpenSSL的密碼套件。但在開發(fā)過程中感受到了OpenSSL滿滿的惡意:其中的API設(shè)計(jì)不可謂不反人類,很多參數(shù)沒有明確的說明(比如同樣是表示長度的函數(shù)參數(shù),可能在不同地方分別以字節(jié)/比特/分組數(shù)為計(jì)數(shù)單位);函數(shù)的線程安全沒有任何解釋標(biāo)注,需要自行試驗(yàn);不清楚函數(shù)執(zhí)行之后,是其自行做了資源釋放還是需要有另外API做gc,不知道資源釋放操作時(shí)是否規(guī)規(guī)矩矩地先擦除后釋放……此類問題不一而足,導(dǎo)致經(jīng)過了漫長的測(cè)試之后,這份中間件才提供出來供使用。而在業(yè)務(wù)場(chǎng)景中,還會(huì)存在比如其它語言調(diào)用的情形,這些又暴露出來OpenSSL API誤用的一些完全無從參考的問題。這一切都成為了噩夢(mèng);當(dāng)然這無法為我自己開解是個(gè)不稱職開發(fā)的指責(zé),但僅就OpenSSL而言其API設(shè)計(jì)之惡劣也是始終被人詬病的問題,也是之后其他替代者宣稱改進(jìn)的地方。
當(dāng)然,問題是上下游都脫不了干系的。我們自己作為高速迭代中的開發(fā)人員,對(duì)于二方、三方提供的中間件、API,又有多少人能自信地說自己仔細(xì)、認(rèn)真地閱讀過開發(fā)指南和API、規(guī)范說明呢?做過通用產(chǎn)品技術(shù)運(yùn)營的朋友可能很容易理解,自己產(chǎn)品的直接用戶日常拋出不看文檔的愚蠢問題帶來的困擾。對(duì)于密碼學(xué)套件,這個(gè)問題還好辦一些,畢竟如果在沒有背景知識(shí)的情況下對(duì)API望文生義地一通調(diào)用,絕大多數(shù)情況下都會(huì)以拋異常形式告終;但還是有很多情況,API誤用埋下的是長期隱患。
不是所有API誤用情形最終都有機(jī)會(huì)發(fā)展成為可利用的安全漏洞,但作為一個(gè)由人的因素引入的風(fēng)險(xiǎn),這將長期存在并困擾軟件供應(yīng)鏈(雖然對(duì)安全研究者、黑客與白帽子是很欣慰的事情)。可惜,傳統(tǒng)的白盒代碼掃描能力,基于對(duì)代碼語義的理解和構(gòu)建,但是涉及到API則需要預(yù)先的抽象,這一點(diǎn)目前似乎仍然是需要人工干預(yù)的事情;或者輕量級(jí)一點(diǎn)的方案,可以case by case地分析,為所有可能被誤用的API建模并單獨(dú)掃描,這自然也有很強(qiáng)局限性。在一個(gè)很底層可信的開發(fā)者還對(duì)C標(biāo)準(zhǔn)庫API存在誤用的現(xiàn)實(shí)內(nèi),我們需要更多的思考才能說接下來的解法。
Ⅴ. 從規(guī)則到陷阱:NASA JIRA誤配置致信息泄露血案
軟件的定義包括了代碼組成的程序,以及相關(guān)的配置、文檔等。當(dāng)我們說軟件的漏洞、風(fēng)險(xiǎn)時(shí),往往只聚焦在其中的代碼中;關(guān)于軟件供應(yīng)鏈安全風(fēng)險(xiǎn),我們的比賽、前面分析的例子也都聚焦在了代碼的問題;但是真正的威脅都來源于不可思議之處,那么代碼之外有沒有可能存在來源于上游的威脅呢?這里就借助實(shí)例來探討一下,在“配置”當(dāng)中可能栽倒的坑。
引子:發(fā)不到500英里以外的郵件?
讓我們先從一個(gè)輕松愉快的小例子引入。這個(gè)例子初見于Linux中國的一篇譯文。
簡(jiǎn)單說,作者描述了這么一個(gè)讓人啼笑皆非的問題:?jiǎn)挝坏泥]件服務(wù)器發(fā)送郵件,發(fā)送目標(biāo)距離本地500英里范圍之外的一律失敗,郵件就像悠悠球一樣只能飛出一定距離。這個(gè)問題本身讓描述者感到尷尬,就像一個(gè)技術(shù)人員被老板問到“為什么從家里筆記本上Ctrl-C后不能在公司臺(tái)式機(jī)上Ctrl-V”一樣。
經(jīng)過令人窒息的分析操作后,筆者定位到了問題原因:筆者作為負(fù)責(zé)的系統(tǒng)管理員,把SunOS默認(rèn)安裝的Senmail從老舊的版本5升級(jí)到了成熟的版本8,且對(duì)應(yīng)于新版本諸多的新特性進(jìn)行了對(duì)應(yīng)配置,寫入配置文件sendmail.cf;但第三方服務(wù)顧問在對(duì)單位系統(tǒng)進(jìn)行打補(bǔ)丁升級(jí)維護(hù)時(shí),將系統(tǒng)軟件“升級(jí)”到了系統(tǒng)提供的最新版本,因此將Sendmail實(shí)際回退到了版本5,卻為了軟件行為一致性,原樣保留了高版本使用的配置文件。但Sendmail并沒有在大版本間保證配置文件兼容性,這導(dǎo)致很多版本5所需的配置項(xiàng)不存在于保留下來的sendmail.cf文件中,程序按默認(rèn)值0處理;最終引起問題的就是,郵件服務(wù)器與接收端通信的超時(shí)時(shí)間配置項(xiàng),當(dāng)取默認(rèn)配置值0時(shí),郵件服務(wù)器在1個(gè)單位時(shí)間(約3毫秒)內(nèi)沒有收到網(wǎng)絡(luò)回包即認(rèn)為超時(shí),而這3毫秒僅夠電信號(hào)打來回飛出500英里。
這個(gè)“故事”可能會(huì)給技術(shù)人員一點(diǎn)警醒,錯(cuò)誤的配置會(huì)導(dǎo)致預(yù)期之外的軟件行為,但是配置如何會(huì)引入軟件供應(yīng)鏈方向的安全風(fēng)險(xiǎn)呢?這就引出了下一個(gè)重磅實(shí)例。
JIRA配置錯(cuò)誤致NASA敏感信息泄露案例
我們都聽過一個(gè)事情,馬云在帶隊(duì)考察美國公司期間問Google CEO Larry Page自視誰為競(jìng)爭(zhēng)對(duì)手,Larry的回答是NASA,因?yàn)樽顑?yōu)秀的工程師都被NASA的夢(mèng)想吸引過去了。由此我們顯然能窺見NASA的技術(shù)水位之高,這樣的人才團(tuán)隊(duì)大概至少是不會(huì)犯什么低級(jí)錯(cuò)誤的。
但也許需要重新定義“低級(jí)錯(cuò)誤”……1月11日一篇技術(shù)文章披露,NASA某官網(wǎng)部署使用的缺陷跟蹤管理系統(tǒng)JIRA存在錯(cuò)誤的配置,可分別泄漏內(nèi)部員工(JIRA系統(tǒng)用戶)的全部用戶名和郵件地址,以及內(nèi)部項(xiàng)目和團(tuán)隊(duì)名稱到公眾,如下:
問題的原因解釋起來也非常簡(jiǎn)單:JIRA系統(tǒng)的過濾器和配置面板中,對(duì)于數(shù)據(jù)可見性的配置選項(xiàng)分別選定為All users和Everyone時(shí),系統(tǒng)管理人員想當(dāng)然地認(rèn)為這意味著將數(shù)據(jù)對(duì)所有“系統(tǒng)用戶”開放查看,但是JIRA的這兩個(gè)選項(xiàng)的真實(shí)效果逆天,是面向“任意人”開放,即不限于系統(tǒng)登錄用戶,而是任何查看頁面的人員。看到這里,我不厚道地笑了……“All users”并不意味著“All ‘users’”,意不意外,驚不驚喜?
但是這種字面上把戲,為什么沒有引起NASA工程師的注意呢,難道這樣逆天的配置項(xiàng)沒有在產(chǎn)品手冊(cè)文檔中加粗標(biāo)紅提示嗎?本著為JIRA產(chǎn)品設(shè)計(jì)找回尊嚴(yán)的態(tài)度,我深入挖掘了一下官方說明,果然在Atlassian官方的一份confluence文檔(看起來更像是一份增補(bǔ)的FAQ)中找到了相關(guān)說明:
所有未登錄訪客訪問時(shí),系統(tǒng)默認(rèn)認(rèn)定他們是匿名anonymous用戶,所以各種權(quán)限配置中的all users或anyone顯然應(yīng)該將匿名用戶包括在內(nèi)。在7.2及之后版本中,則提供了“所有登錄用戶”的選項(xiàng)。
可以說是非常嚴(yán)謹(jǐn)且貼心了。比較諷刺的是,在我們的軟件供應(yīng)鏈安全大賽·C源代碼賽季期間,我們?cè)O(shè)計(jì)圈定的惡意代碼攻擊目標(biāo)還包括JIRA相關(guān)的敏感信息的竊取,但是卻想不到有這么簡(jiǎn)單方便的方式,不動(dòng)一行代碼就可以從JIRA中偷走數(shù)據(jù)。
軟件的使用,你“配”嗎?
無論是開放的代碼還是成型的產(chǎn)品,我們?cè)谑褂猛獠寇浖臅r(shí)候,都是處于軟件供應(yīng)鏈下游的消費(fèi)者角色,為了要充分理解上游開發(fā)和產(chǎn)品的真實(shí)細(xì)節(jié)意圖,需要我們付出多大的努力才夠“資格”?
上一章節(jié)我們討論過源碼使用中必要細(xì)節(jié)信息缺失造成的“API誤用”問題,而軟件配置上的“誤用”問題則復(fù)雜多樣得多。從可控程度上討論,至少有這幾種因素定義了這個(gè)問題:
Ⅵ. 從逆流到暗流:惡意代碼溯源后的挑戰(zhàn)
如果說前面所說的種種威脅都是面向關(guān)鍵目標(biāo)和核心系統(tǒng)應(yīng)該思考的問題,那么最后要拋出一個(gè)會(huì)把所有人拉進(jìn)賽場(chǎng)的理由。除了前面所有那些在軟件供應(yīng)鏈下游被動(dòng)污染受害的情況,還有一種情形:你有跡可循的代碼,也許在不經(jīng)意間會(huì)“反哺”到黑色產(chǎn)業(yè)鏈甚至特殊武器中;而現(xiàn)在研究用于對(duì)程序進(jìn)行分析和溯源的技術(shù),則會(huì)讓你陷入百口莫辯的境地。
案例:黑產(chǎn)代碼模塊溯源疑云
1月29日,獵豹安全團(tuán)隊(duì)發(fā)布技術(shù)分析通報(bào)文章《電信、百度客戶端源碼疑遭泄漏,驅(qū)魔家族竊取隱私再起波瀾》,矛頭直指黑產(chǎn)上游的惡意信息竊取代碼模塊,認(rèn)定其代碼與兩方產(chǎn)品存在微妙的關(guān)聯(lián):中國電信旗下“桌面3D動(dòng)態(tài)天氣”等多款軟件,以及百度旗下“百度殺毒”等軟件(已不可訪問)。
文章中舉證有三個(gè)關(guān)鍵點(diǎn)。
首先最直觀的,是三者使用了相同的特征字符串、私有文件路徑、自定義內(nèi)部數(shù)據(jù)字段格式;
其次,在關(guān)鍵代碼位置,三者在二進(jìn)制程序匯編代碼層面具有高度相似性;
最終,在一定范圍的非通用程序邏輯上,三者在經(jīng)過反匯編后的代碼語義上顯示出明顯的雷同,并提供了如下兩圖佐證(圖片來源:http://bbs.duba.net/thread-23531362-1-1.html):
文章指出的涉事相關(guān)軟件已經(jīng)下線,對(duì)于上述樣本文件的相似度試驗(yàn)暫不做復(fù)現(xiàn),且無法求證存在相似、疑似同源的代碼在三者中占比數(shù)據(jù)。對(duì)于上述指出的代碼雷同現(xiàn)象,獵豹安全團(tuán)隊(duì)認(rèn)為:
我們懷疑該病毒模塊的作者通過某種渠道(比如“曾經(jīng)就職”),掌握有中國電信旗下部分客戶端/服務(wù)端源碼,并加以改造用于制作竊取用戶隱私的病毒,另外在該病毒模塊的代碼中,我們還發(fā)現(xiàn)“百度”旗下部分客戶端的基礎(chǔ)調(diào)試日志函數(shù)庫代碼痕跡,整個(gè)“驅(qū)魔”病毒家族疑點(diǎn)重重,其制作傳播背景愈發(fā)撲朔迷離。
這樣的推斷,固然有過于直接的依據(jù)(例如三款代碼中均使用含有“baidu”字樣的特征注冊(cè)表項(xiàng));但更進(jìn)一步地,需要注意到,三個(gè)樣本在所指出的代碼位置,具有直觀可見的二進(jìn)制匯編代碼結(jié)構(gòu)的相同,考慮到如果僅僅是惡意代碼開發(fā)者先逆向另外兩份代碼后借鑒了代碼邏輯,那么在面臨反編譯、代碼上下文適配重構(gòu)、跨編譯器和選項(xiàng)的編譯結(jié)果差異等諸多不確定環(huán)節(jié),仍能保持二進(jìn)制代碼的雷同,似乎確實(shí)是只有從根本上的源代碼泄漏(抄襲)且保持相同的開發(fā)編譯環(huán)境才能成立。
但是我們卻又無法做出更明確的推斷。這一方面當(dāng)然是出于嚴(yán)謹(jǐn)避免過度解讀;而從另一方面考慮,黑產(chǎn)代碼的一個(gè)關(guān)鍵出發(fā)點(diǎn)就是“隱藏自己”,而這里居然如此堂而皇之地照搬了代碼,不但沒有進(jìn)行任何代碼混淆、變形,甚至沒有抹除疑似來源的關(guān)鍵字符串,如果將黑產(chǎn)視為智商在線的對(duì)手,那這里背后是否有其它考量,就值得琢磨了。
代碼的比對(duì)、分析、溯源技術(shù)水準(zhǔn)
上文中的安全團(tuán)隊(duì)基于大量樣本和粗粒度比對(duì)方法,給出了一個(gè)初步的判斷和疑點(diǎn)。那么是否有可能獲得更確鑿的分析結(jié)果,來證實(shí)或證偽同源猜想呢?
無論是源代碼還是二進(jìn)制,代碼比對(duì)技術(shù)作為一種基礎(chǔ)手段,在軟件供應(yīng)鏈安全分析上都注定仍然有效。在我們的軟件供應(yīng)鏈安全大賽期間,針對(duì)PE二進(jìn)制程序類型的題目,參賽隊(duì)伍就紛紛采用了相關(guān)技術(shù)手段用于目標(biāo)分析,包括:同源性分析,用于判定與目標(biāo)軟件相似度最高的同軟件官方版本;細(xì)粒度的差異分析,用于嘗試在忽略編譯差異和特意引入的混淆之外,定位特意引入的惡意代碼位置。當(dāng)然,作為比賽中針對(duì)性的應(yīng)對(duì)方案,受目標(biāo)和環(huán)境引導(dǎo)約束,這些方法證明了可行性,卻難以保證集成有最新技術(shù)方案。那么做一下預(yù)言,在不計(jì)入情報(bào)輔助條件下,下一代的代碼比對(duì)將能夠到達(dá)什么水準(zhǔn)?
這里結(jié)合近一年和今年內(nèi),已發(fā)表和未發(fā)表的學(xué)術(shù)領(lǐng)域頂級(jí)會(huì)議的相關(guān)文章來簡(jiǎn)單展望:
代碼溯源技術(shù)面前的“挑戰(zhàn)”
作為軟件供應(yīng)鏈安全的獨(dú)立分析方,健壯的代碼比對(duì)技術(shù)是決定性的基石;而當(dāng)腦洞大開,考慮到行業(yè)的發(fā)展,也許以下兩種假設(shè)的情景,將把每一個(gè)“正當(dāng)”的產(chǎn)品、開發(fā)者置于尷尬的境地。
代碼仿制
在本章節(jié)引述的“驅(qū)魔家族”代碼疑云案例中,黑產(chǎn)方面通過某種方式獲得了正常代碼中,功能邏輯可以被自身復(fù)用的片段,并以某種方法將其在保持原樣的情況下拼接形成了惡意程序。即便在此例中并非如此,但這卻暴露了隱憂:將來是不是有這種可能,我的正常代碼被泄漏或逆向后出現(xiàn)在惡意軟件中,被溯源后扣上黑鍋?
這種擔(dān)憂可能以多種渠道和形式成為現(xiàn)實(shí)。
從上游看,內(nèi)部源碼被人為泄漏是最簡(jiǎn)單的形式(實(shí)際上,考慮到代碼的完整生命周期似乎并沒有作為企業(yè)核心數(shù)據(jù)資產(chǎn)得到保護(hù),目前實(shí)質(zhì)上有沒有這樣的代碼在野泄漏還是個(gè)未知數(shù)),而通過程序逆向還原代碼邏輯也在一定程度上可獲取原始代碼關(guān)鍵特征。
從下游看,則可能有多種方式將惡意代碼偽造得像正常代碼并實(shí)現(xiàn)“碰瓷”。最簡(jiǎn)單地,可以大量復(fù)用關(guān)鍵代碼特征(如字符串,自定義數(shù)據(jù)結(jié)構(gòu),關(guān)鍵分支條件,數(shù)據(jù)記錄和交換私有格式等)。考慮到在進(jìn)行溯源時(shí),分析者實(shí)際上不需要100%的匹配度才會(huì)懷疑,因此僅僅是仿造原始程序?qū)τ诘谌焦_庫代碼的特殊定制改動(dòng),也足以將公眾的疑點(diǎn)轉(zhuǎn)移。而近年來類似自動(dòng)補(bǔ)丁代碼搜索生成的方案也可能被用來在一份最終代碼中包含有二方甚至多方原始代碼的特征和片段。
基于開發(fā)者溯源的定點(diǎn)滲透
既然在未來可能存在準(zhǔn)確將代碼與自然人對(duì)應(yīng)的技術(shù),那么這種技術(shù)也完全可能被黑色產(chǎn)業(yè)利用。可能的憂患包括強(qiáng)針對(duì)性的社會(huì)工程,結(jié)合特定開發(fā)者歷史代碼缺陷的漏洞挖掘利用,聯(lián)動(dòng)第三方泄漏人員信息的深層滲透,等等。這方面暫不做聯(lián)想展開。
〇. 沒有總結(jié)
作為一場(chǎng)旨在定義“軟件供應(yīng)鏈安全”威脅的宣言,阿里安全“功守道”大賽將在后續(xù)給出詳細(xì)的分解和總結(jié),其意義價(jià)值也許會(huì)在一段時(shí)間之后才能被挖掘。
但是威脅的現(xiàn)狀不容樂觀,威脅的發(fā)展不會(huì)靜待;這一篇隨筆僅僅挑選六個(gè)側(cè)面做摘錄分析,可即將到來的趨勢(shì)一定只會(huì)進(jìn)入更加發(fā)散的境地,因此這里,沒有總結(jié)。