張 勇,張合磊,趙 平
(1.國(guó)家工業(yè)信息安全發(fā)展研究中心,北京 100040;2.北京酷德啄木鳥(niǎo)信息技術(shù)有限公司,北京 100041)
軟件開(kāi)發(fā)是一項(xiàng)復(fù)雜的任務(wù),尤其是現(xiàn)在軟件技術(shù)飛速發(fā)展,開(kāi)發(fā)環(huán)境不斷演變,軟件架構(gòu)和組成變得多樣化。企業(yè)使用開(kāi)源軟件的比例越來(lái)越高,軟件主要由自主開(kāi)發(fā)代碼、開(kāi)源代碼和開(kāi)源組件組裝而成。其中,開(kāi)源代碼、開(kāi)源組件提供了必要的構(gòu)建塊,使組織能夠交付價(jià)值、提高質(zhì)量、降低風(fēng)險(xiǎn)并縮短上線時(shí)間。但同時(shí)其衍生出的軟件安全管理問(wèn)題也越來(lái)越多,軟件團(tuán)隊(duì)只關(guān)注檢測(cè)自主代碼的潛在問(wèn)題,往往忽視了對(duì)應(yīng)用組件構(gòu)成和應(yīng)用所包含的開(kāi)源代碼中已知漏洞和開(kāi)源協(xié)議的檢查。
盡管安全人員和開(kāi)發(fā)人員不斷通過(guò)安全編碼指南制定、軟件測(cè)試和各種形式的代碼審查等辦法來(lái)提高軟件質(zhì)量和安全性,但通用漏洞披露(Common Vulnerabilities & Exposures,CVE)的數(shù)據(jù)記錄顯示,漏洞數(shù)量依舊呈增長(zhǎng)趨勢(shì)[1]。
鑒于軟件的整體安全性高度依賴于軟件漏洞的識(shí)別和緩解能力。因此,高效的分析代碼中存在的漏洞可以幫助開(kāi)發(fā)人員識(shí)別并修復(fù)源代碼中的缺陷。
本文提出了一種自動(dòng)發(fā)現(xiàn)源代碼中安全漏洞的方案,通過(guò)從開(kāi)放漏洞數(shù)據(jù)庫(kù)中抽取所有可用的CVE 記錄,并從相關(guān)的開(kāi)源項(xiàng)目所在的開(kāi)源存儲(chǔ)庫(kù)中收集易受攻擊的代碼,建立開(kāi)源缺陷代碼庫(kù)。利用搜索引擎與源代碼分析規(guī)范多樣化聯(lián)合應(yīng)用,根據(jù)不同結(jié)構(gòu)的代碼相似性特征,挖掘代碼缺陷庫(kù)中的缺陷匹配信息,具有較高的缺陷搜索匹配速度和準(zhǔn)確性。
靜態(tài)代碼分析是白盒測(cè)試的一種方法,通過(guò)代碼檢查可以確定代碼和設(shè)計(jì)的一致性、代碼結(jié)構(gòu)的合理性、代碼編寫(xiě)的標(biāo)準(zhǔn)性和可讀性、代碼邏輯表達(dá)的正確性等。
靜態(tài)代碼缺陷分析是指在不運(yùn)行目標(biāo)程序的前提下分析目標(biāo)程序(源代碼或二進(jìn)制)的詞法、語(yǔ)法和語(yǔ)義等,并結(jié)合程序的數(shù)據(jù)流、控制流信息,通過(guò)類(lèi)型推導(dǎo)、安全規(guī)則檢查、模型檢測(cè)等技術(shù)挖掘程序中的漏洞。
靜態(tài)漏洞挖掘是常用的軟件測(cè)試技術(shù),在軟件測(cè)試中占有非常重要的地位。具有代表性的靜態(tài)漏洞挖掘工具包括:面向C/C++源碼的Cppcheck[2]、FlawFinder[3],面向PHP 源碼的RIPS,面向Java 源碼的FindBugs,以及能支持多種類(lèi)型目標(biāo)對(duì)象的著名商業(yè)化漏洞檢測(cè)工具VeraCode、Fortify、Coverity、Checkmarx[4]等。另外,LLVM[5]、Clang[6]等編譯器也為軟件源代碼提供了大量的靜態(tài)檢測(cè)功能,從而在編譯階段實(shí)現(xiàn)對(duì)源代碼的安全性檢查。
靜態(tài)代碼分析技術(shù)主要用于挖掘未知問(wèn)題,發(fā)現(xiàn)潛在的不安全及不規(guī)范的代碼,但是不涉及被測(cè)軟件的運(yùn)行及動(dòng)態(tài)驗(yàn)證,這與漏洞掃描、滲透測(cè)試、病毒掃描等方面的技術(shù)原理完全不同,因此靜態(tài)代碼分析技術(shù)存在的誤報(bào)問(wèn)題往往給開(kāi)發(fā)人員帶來(lái)困擾,尤其是在信息系統(tǒng)頻繁迭代開(kāi)發(fā)場(chǎng)景下的多次檢測(cè)會(huì)顯著增加開(kāi)發(fā)人員的工作量,開(kāi)發(fā)人員或?qū)徲?jì)人員需要大量精力用于排除靜態(tài)分析誤報(bào)問(wèn)題。
軟件主要由自主開(kāi)發(fā)代碼、開(kāi)源代碼和開(kāi)源組件組裝而成。自主開(kāi)發(fā)代碼的缺陷是未知的,但是開(kāi)源代碼存在的缺陷卻是公開(kāi)的,因此,可以基于公開(kāi)漏洞庫(kù),從開(kāi)源項(xiàng)目所在的開(kāi)源代碼庫(kù)中收集易受攻擊的代碼建立開(kāi)源缺陷代碼庫(kù),用于軟件中開(kāi)源代碼的缺陷識(shí)別。相對(duì)于傳統(tǒng)的靜態(tài)代碼分析,此技術(shù)路線具有較高的準(zhǔn)確性。
本文提出一種開(kāi)源代碼缺陷識(shí)別方案,能夠快速準(zhǔn)確地識(shí)別軟件代碼中存在的開(kāi)源代碼缺陷。通過(guò)抽取已知的開(kāi)源代碼中的缺陷信息構(gòu)建缺陷知識(shí)庫(kù),利用搜索技術(shù)和代碼分詞多種規(guī)范化表達(dá)方式,在目標(biāo)代碼中可以有效地識(shí)別已知代碼缺陷(精準(zhǔn)搜索)和缺陷變體(相似搜索)。
開(kāi)源代碼缺陷識(shí)別系統(tǒng)架構(gòu)如圖1 所示,系統(tǒng)分為缺陷數(shù)據(jù)處理流程、缺陷數(shù)據(jù)索引流程和缺陷代碼搜索3 個(gè)模塊。
圖1 開(kāi)源代碼缺陷識(shí)別系統(tǒng)架構(gòu)
首先構(gòu)建缺陷代碼知識(shí)庫(kù),為了保障分析效果,知識(shí)庫(kù)應(yīng)包含多個(gè)級(jí)別的缺陷代碼粒度,例如與缺陷代碼相關(guān)的文件、類(lèi)、函數(shù)等,并涵蓋廣泛使用的編程語(yǔ)言。本研究通過(guò)在CVE記錄中自動(dòng)收集漏洞描述信息,挖掘托管在GitHub、GitLab 和Bitbucket 以及開(kāi)源項(xiàng)目自有代碼管理庫(kù)上的代碼缺陷記錄,收集易受攻擊的代碼樣本。
CVE 數(shù)據(jù)信息主要來(lái)自美國(guó)國(guó)家計(jì)算機(jī)通用漏洞數(shù)據(jù)庫(kù)(National Vulnerability Database,NVD),這是一個(gè)由美國(guó)國(guó)家標(biāo)準(zhǔn)與技術(shù)研究院(National Institute of Standards and Technology,NIST)維護(hù)的漏洞管理數(shù)據(jù)庫(kù)。NIST 使用各種數(shù)據(jù)源發(fā)布整個(gè)NVD 數(shù)據(jù)庫(kù)供安全人員使用,漏洞數(shù)據(jù)包含漏洞源、安全檢查、與安全相關(guān)的軟件缺陷、錯(cuò)誤配置、產(chǎn)品名稱和缺陷影響。缺陷描述文件包含每日更新的CVE 漏洞信息,對(duì)于較早期的缺陷信息描述,主要按照來(lái)源年份有序排列發(fā)布。
在CVE的描述文件中,每個(gè)漏洞都有CVE-ID標(biāo)號(hào)、發(fā)布日期、描述、關(guān)聯(lián)參考鏈接、易受攻擊的產(chǎn)品配置、通用缺陷枚舉(Common Weakness Enumeration,CWE)[7]缺陷分類(lèi)和其他指標(biāo)。每個(gè)漏洞的嚴(yán)重性都使用通用漏洞評(píng)分系統(tǒng)(Common Vulnerability Scoring System,CVSS)進(jìn)行排名。CVSS 由3 個(gè)指標(biāo)組成,即基礎(chǔ)、時(shí)間和環(huán)境,漏洞的特征和上下文信息。漏洞影響評(píng)分系統(tǒng)存在兩個(gè)版本:CVSSv2 和CVSSv3,它們都對(duì)缺陷進(jìn)行細(xì)致描述。CVSSv3為CVSSv2 的升級(jí)描述,用來(lái)更準(zhǔn)確地對(duì)漏洞進(jìn)行影響評(píng)分,并提供更多信息來(lái)區(qū)分不同類(lèi)型的漏洞。當(dāng)開(kāi)源項(xiàng)目中的漏洞被修復(fù)時(shí),CVE 記錄信息將更新,增加一個(gè)或多個(gè)指向相關(guān)源代碼存儲(chǔ)庫(kù)的引用,包括修復(fù)缺陷時(shí)提交記錄生成的哈希。這些信息可用來(lái)在本研究中作為代碼缺陷庫(kù)的組成信息。缺陷數(shù)據(jù)處理流程如圖2所示。
圖2 缺陷數(shù)據(jù)處理流程
2.1.1 收集CVE 記錄信息
采集工具從NVD 服務(wù)器檢索所有已發(fā)布的JSON 格式的漏洞源,搜集范圍包括2002 年首次發(fā)布到收集之日最后一次發(fā)布的CVE。然后對(duì)獲取到的JSON 文件進(jìn)行聚合、加工和處理,濾掉CVE 記錄中所有在reference 字段中沒(méi)有與之關(guān)聯(lián)的修復(fù)程序CVE 記錄信息,因?yàn)檫@些CVE無(wú)法收集相應(yīng)的易受攻擊或已修復(fù)的代碼。在處理和過(guò)濾完缺陷記錄后,CVE 記錄信息包括CVE-ID、發(fā)布日期、最后修改日期、參考數(shù)據(jù)、CVSS 嚴(yán)重性評(píng)分、漏洞影響和范圍、可利用性評(píng)分等漏洞的描述。
通常,CVE 缺陷類(lèi)型由CWE 進(jìn)行分類(lèi),因此還需要收集這些CWE 類(lèi)型的詳細(xì)信息,并將它們與適當(dāng)?shù)腃VE 記錄進(jìn)行映射,用來(lái)區(qū)分具體的缺陷類(lèi)型。
2.1.2 修復(fù)記錄提取
在分析CVE 缺陷記錄信息時(shí),只分析存在修復(fù)記錄的CVE,通過(guò)提取修復(fù)CVE 記錄信息中與代碼相關(guān)的開(kāi)源倉(cāng)庫(kù)信息,利用git 工具在本地克隆代碼項(xiàng)目,并根據(jù)CVE 記錄中提交的哈希值,通過(guò)git 來(lái)收集有關(guān)易受攻擊的缺陷代碼信息,包括代碼的語(yǔ)言、版本、發(fā)布時(shí)間、CVE 記錄、CWE 記錄、存儲(chǔ)庫(kù)地址信息、提交記錄、受影響的文件和受影響的方法等信息,并將收集到的信息存儲(chǔ)在數(shù)據(jù)庫(kù)中。
2.1.3 構(gòu)建元數(shù)據(jù)信息
CVE 中涉及開(kāi)源項(xiàng)目相關(guān)的代碼庫(kù)信息主要來(lái)自GitHub、GitLab 和Bitbucket,其中項(xiàng)目所屬GitHub 的比例最高。在抽取缺陷代碼信息過(guò)程中,需要在缺陷數(shù)據(jù)庫(kù)中覆蓋代碼倉(cāng)庫(kù)的項(xiàng)目基本信息,例如存儲(chǔ)庫(kù)名稱、描述、創(chuàng)建日期、最后推送日期、主頁(yè)、編程語(yǔ)言、分支數(shù)和星數(shù)等指標(biāo),這些信息可作為過(guò)濾數(shù)據(jù)的參數(shù),例如星數(shù)大小是關(guān)注項(xiàng)目成熟度的一個(gè)重要評(píng)判指標(biāo),即星數(shù)越大的項(xiàng)目,成熟度越高。
2.1.4 缺陷代碼提取
一般來(lái)說(shuō),只要修復(fù)了開(kāi)源代碼漏洞,CVE 描述記錄就會(huì)包含存儲(chǔ)庫(kù)的統(tǒng)一資源定位符(Uniform Resource Locator,URL),利用抽取到的缺陷修復(fù)提交時(shí)生成的哈希和地址信息,通過(guò)git 即可在本地克隆開(kāi)源代碼項(xiàng)目,并根據(jù)哈希信息抽取修復(fù)之前和之后的代碼信息,這些信息包括缺陷修復(fù)時(shí)所涉及的代碼文件和代碼片段。其中提交信息中的每個(gè)條目可能與一個(gè)或多個(gè)CVE 相關(guān)聯(lián)。提交的信息還包括作者、時(shí)間和日期、提交的描述消息等內(nèi)容。
與缺陷相關(guān)的文件信息主要包含更改前后的文件內(nèi)容,以及在git 提交過(guò)程中生成的diff信息。此外,還需要收集一些元數(shù)據(jù),例如文件名、新舊路徑、修改類(lèi)型(即添加、刪除、修改或重命名)、在該文件中添加或刪除的行數(shù)、代碼行數(shù)變化等。
提取修改后的代碼片段,與抽取文件級(jí)別的更改過(guò)程相似,利用git 工具抽取代碼片段的變更信息。除代碼外,涉及的數(shù)據(jù)信息,例如片段所在的方法名稱、其簽名性質(zhì)、參數(shù)、方法的開(kāi)始行和結(jié)束行、代碼行數(shù)等作為方法元數(shù)據(jù)信息也會(huì)被抽取出來(lái)。
為了更好地識(shí)別文件和代碼片段使用的具體編程語(yǔ)言信息,識(shí)別過(guò)程通過(guò)linguist[8]來(lái)檢測(cè)給定代碼內(nèi)容中使用的實(shí)際編程語(yǔ)言。
提取缺陷代碼后,需要對(duì)缺陷數(shù)據(jù)加工處理,存入數(shù)據(jù)庫(kù)中,形成缺陷代碼知識(shí)庫(kù),供查詢模塊使用。缺陷數(shù)據(jù)索引流程如圖3 所示。
圖3 缺陷數(shù)據(jù)索引流程
2.2.1 前端解析
所有的代碼信息都要經(jīng)過(guò)編譯處理,用來(lái)從程序代碼中獲取函數(shù)信息并分析其詞法,但如果源代碼不完整或包含語(yǔ)法錯(cuò)誤,將會(huì)影響整個(gè)解析過(guò)程。因此,為了保障分析的可靠性,采用antlr4 完成代碼詞法解析,解析過(guò)程不需要代碼編譯構(gòu)建環(huán)境,能夠解析單個(gè)代碼文件,并且在解析過(guò)程中遇到語(yǔ)法錯(cuò)誤時(shí)不會(huì)失敗,即使被測(cè)代碼不完整,也會(huì)兼容錯(cuò)誤分析,保障解析順利通過(guò)。
2.2.2 預(yù)處理規(guī)范化
整個(gè)數(shù)據(jù)索引和后邊的缺陷查詢過(guò)程均以代碼片段為基本單元,查詢過(guò)程中需要考慮代碼相似問(wèn)題,如圖4 所示,如下代碼可能會(huì)存在4 種變種情況。
圖4 原始代碼片段
Type-1:精確相似。被檢測(cè)代碼去掉空格、回車(chē)、注釋等與代碼無(wú)關(guān)信息后,與缺陷代碼保持一致。如圖5 所示,與原代碼相比,代碼片段僅少了回車(chē)、空格信息。
圖5 Type-1 代碼片段
Type-2:重命名相似。與被檢測(cè)代碼中缺陷代碼相比,除了類(lèi)型、標(biāo)識(shí)符、函數(shù)名、注釋和空格的修改,其他信息保持一致。如圖6所示,與原代碼相比,代碼片段中的方法名、參數(shù)類(lèi)型做了部分修改,其他信息保持一致。
圖6 Type-2 代碼片段
Type-3:重組相似。即被檢測(cè)代碼與缺陷代碼相比,存在進(jìn)一步的結(jié)構(gòu)修改(例如刪除、插入或重新排列語(yǔ)句)。如圖7 所示,代碼片段增加了幾條新的語(yǔ)句。
圖7 Type-3 代碼片段
Type-4:語(yǔ)義相似。被檢測(cè)代碼與缺陷代碼在語(yǔ)法實(shí)現(xiàn)上完全不同,但實(shí)現(xiàn)的最終功能相同。如圖8 所示,代碼片段實(shí)現(xiàn)的功能與圖4相同,但是語(yǔ)法表示方式已經(jīng)完全不同。
圖8 Type-4 代碼片段
Type-4 語(yǔ)義相似目前很難通過(guò)代碼相似查找實(shí)現(xiàn),故暫不在本研究的范圍之內(nèi)。本次只考慮Type-1、Type-2、Type-3 型查詢。為了獲取更好的查找效果,需要對(duì)分詞的相似度進(jìn)行規(guī)范化處理。在預(yù)處理階段,為了更準(zhǔn)確地找到缺陷代碼及其變種,需要從目標(biāo)源代碼中提取代碼塊并將其轉(zhuǎn)換為token 序列,進(jìn)行重組規(guī)范化,這里采用n-gram 實(shí)現(xiàn)分詞重組。對(duì)于n而言,選擇一個(gè)大的數(shù)量原則上存在更長(zhǎng)的重疊區(qū)域,并且攜帶更多單詞信息,精度會(huì)更高一些,但是會(huì)嚴(yán)重影響處理n-gram 所需的內(nèi)存和磁盤(pán)I/O時(shí)間。相反,選擇小的n-gram 允許更大的間隙和更好的匹配靈活性,并且需要更少的內(nèi)存和磁盤(pán)訪問(wèn)時(shí)間,但也會(huì)導(dǎo)致檢索出缺陷代碼片段的概率更高,因此需要找到一個(gè)合適的n值,在查找速度和結(jié)果精度上得到平衡。
首先定義一個(gè)包含a0、a1、a2 及a3 的數(shù)組:
(1)原始表示a0:一個(gè)token 序列,代表了原始代碼片段信息。
(2)Type-1 表示a1:包含來(lái)自原始代碼的標(biāo)記的n-gram 的token 序列,其為原始代碼token 序列的組合。
(3)Type-2 表示a2:包含來(lái)自原始代碼的標(biāo)記的n-gram 的token 序列,其中原始代碼token 序列中的標(biāo)識(shí)符、文字和類(lèi)型標(biāo)記被代表標(biāo)記替換。
(4)Type-3 表示a3:包含來(lái)自原始代碼的標(biāo)記的n-gram的token序列,除字符{、}、[、]、(、)和;外,其他的全部按標(biāo)準(zhǔn)替換處理。標(biāo)點(diǎn)符號(hào)未標(biāo)準(zhǔn)化,因?yàn)樗鼈儗?duì)代碼結(jié)構(gòu)順序有著重要意義。
通過(guò)調(diào)試分析,當(dāng)n值為4 時(shí),工具表現(xiàn)出了良好的性能。因此,當(dāng)預(yù)處理模塊中的4個(gè)代碼表示為a0 時(shí),則表示為原生分詞,不做任何排序組合;a1、a2和a3則表示選擇了4-gram。3 個(gè)基于n-gram 的表示(a1,a2,a3)是從原有的函數(shù)方法內(nèi)容中演變而來(lái)。通過(guò)預(yù)處理模塊的加工組合,將原有的代碼結(jié)構(gòu)進(jìn)行了規(guī)范化,從而使其更適合代碼搜索。
token 規(guī)范化表示類(lèi)型如表1 所示,其中D代表數(shù)據(jù)類(lèi)型,J 代表類(lèi)名,K代表關(guān)鍵字,P代表包,O 代表運(yùn)算符,S 代表字符串文字,V代表數(shù)字,W 代表變量。a2 中所有標(biāo)識(shí)符、類(lèi)型、數(shù)字和字符串文字分別被代表標(biāo)記W、D、V 和S 替換。a3 中所有的分析都替換為它們各自的代表標(biāo)記形成規(guī)范化分詞序列。
表1 token 規(guī)范化表示類(lèi)型
以圖9 的代碼片段為例,規(guī)范化以后的分詞序列生成的內(nèi)容如圖10 ~圖13 所示。
圖9 代碼片段樣例
圖10 a0 規(guī)范化
圖11 a1 規(guī)范化
圖12 a2 規(guī)范化
圖13 a3 規(guī)范化
這種預(yù)處理能夠保障在搜索期間查詢的代碼關(guān)鍵信息與索引中代碼片段的表示相匹配。另外,在索引和查詢階段都會(huì)用到預(yù)處理規(guī)范化技術(shù):在索引階段,搜索引擎為給定的代碼片段創(chuàng)建一個(gè)新文檔,并將4 個(gè)表示放在文檔內(nèi)的單獨(dú)字段中,然后將文檔存儲(chǔ)在搜索索引中。在查詢階段,通過(guò)預(yù)處理將查詢內(nèi)容加工為一個(gè)組合查詢,組合包含4 種關(guān)鍵字組成的子查詢序列。
2.2.3 缺陷數(shù)據(jù)索引
數(shù)據(jù)存儲(chǔ)采用非關(guān)系索引數(shù)據(jù)庫(kù)工具Zinc,其具有索引功能,也是一種輕量級(jí)的搜索引擎,能夠滿足不同用戶的各種搜索需求,為所有類(lèi)型的數(shù)據(jù)提供近乎實(shí)時(shí)的搜索和分析。對(duì)于結(jié)構(gòu)化或非結(jié)構(gòu)化的文本、數(shù)字?jǐn)?shù)據(jù)及地理空間數(shù)據(jù),都能夠以快速搜索的方式高效地存儲(chǔ)和索引數(shù)據(jù)。
建立缺陷數(shù)據(jù)索引的過(guò)程主要是對(duì)提取的開(kāi)源代碼數(shù)據(jù)信息進(jìn)行加工處理。整個(gè)流程為:將預(yù)處理加工過(guò)的規(guī)范化序列存儲(chǔ)到Zinc 數(shù)據(jù)庫(kù)中,Zinc 會(huì)生成反向索引,索引包括一組在document 中出現(xiàn)的唯一單詞及單詞所出現(xiàn)的位置。索引建好后,可以通過(guò)Zinc 所支持的文件和方法兩種類(lèi)型的代碼完成查詢,對(duì)于完整的代碼文件,將代碼文件序列化后,以a0 方式存入到數(shù)據(jù)庫(kù)中。對(duì)于文件中的方法,預(yù)處理后生成4 種規(guī)范化標(biāo)識(shí)表示,這些規(guī)范化表示可以捕獲不同級(jí)別的代碼結(jié)構(gòu),能夠有效地識(shí)別出缺陷代碼和缺陷變種。
缺陷代碼搜索主要利用分詞規(guī)范化和搜索引擎自身的索引查詢功能來(lái)搜索代碼中是否存在缺陷信息,在缺陷知識(shí)庫(kù)中搜索通過(guò)預(yù)處理后生成的關(guān)鍵字信息,并利用分詞規(guī)范化來(lái)提高代碼缺陷搜索的精度和相似匹配的靈活性。缺陷代碼搜索如圖14 所示。
圖14 缺陷代碼搜索
當(dāng)用戶提交待查詢的代碼后,首先對(duì)代碼進(jìn)行詞法解析和預(yù)處理,這個(gè)過(guò)程與索引階段采用相同的方式。預(yù)處理結(jié)束后,一個(gè)序列化后的代碼查詢序列被發(fā)送到預(yù)處理模塊,生成4 種查詢關(guān)鍵字,利用Zinc 檢索功能,通過(guò)關(guān)鍵字檢索組合缺陷庫(kù)中的索引信息,匹配命中信息,并將最后的結(jié)果報(bào)告返回給用戶。
本文通過(guò)搜索技術(shù)實(shí)現(xiàn)了一種開(kāi)源代碼缺陷識(shí)別系統(tǒng),通過(guò)一個(gè)實(shí)例來(lái)驗(yàn)證系統(tǒng)的有效性。
在大多數(shù)情況下,各種Linux 發(fā)行版默認(rèn)提供的內(nèi)核都運(yùn)行穩(wěn)定,但有些時(shí)候必須重新構(gòu)造和定制內(nèi)核來(lái)滿足實(shí)際需求,例如,系統(tǒng)中加入了當(dāng)前內(nèi)核不支持的或者尚未啟用相應(yīng)功能的硬件,或者物聯(lián)網(wǎng)設(shè)備操作系統(tǒng)、Android移動(dòng)操作系統(tǒng)等都需要完成Linux 系統(tǒng)的定制遷移。
Linux 各種主要發(fā)行版本中由供應(yīng)商提供的內(nèi)核往往明顯落后于最前沿的技術(shù),而且它們的更新很不及時(shí),這就導(dǎo)致系統(tǒng)中可能存在既有的安全風(fēng)險(xiǎn)。
CVE-2016-5195[9]是Linux Kernel 中的條件競(jìng)爭(zhēng)漏洞,攻擊者可以利用Linux 內(nèi)核中的寫(xiě)入復(fù)制技術(shù)中存在的邏輯漏洞完成對(duì)文件的越權(quán)讀寫(xiě)。具體細(xì)節(jié)為:Linux 內(nèi)核的內(nèi)存子系統(tǒng)在處理寫(xiě)入復(fù)制(Copy-on-Write)時(shí)產(chǎn)生了競(jìng)爭(zhēng)條件(Race Condition)。惡意用戶可利用此漏洞來(lái)獲取高權(quán)限,對(duì)只讀內(nèi)存映射進(jìn)行寫(xiě)訪問(wèn)。競(jìng)爭(zhēng)條件是指任務(wù)執(zhí)行順序異常,可導(dǎo)致應(yīng)用崩潰,或令攻擊者有機(jī)可乘,進(jìn)一步執(zhí)行其他代碼。攻擊者可利用這一漏洞提升目標(biāo)系統(tǒng)權(quán)限,甚至可能獲得root 權(quán)限、代碼,如圖15 所示。
圖15 CVE-2016-5195 缺陷代碼
Linux 發(fā)行版本,如紅帽、Debian 和CentOS,已經(jīng)發(fā)布了更新來(lái)解決內(nèi)核上存在的問(wèn)題,但是很多由公司維護(hù)的移動(dòng)操作系統(tǒng)卻沒(méi)有更新該內(nèi)核漏洞。使用本文提出的源代碼安全漏洞挖掘技術(shù)分析Android 7.0、Android 6.0.1、Android 6.0 源代碼,均發(fā)現(xiàn)了系統(tǒng)中存在著CVE-2016-5195 漏洞,如圖16 所示。
圖16 CVE-2016-5195 缺陷代碼命中結(jié)果
對(duì)于變種的缺陷,工具依舊保持較高的準(zhǔn)確度,CVE-2005-0504 漏洞[10]如圖17 所示,未進(jìn)行正確的長(zhǎng)度檢查可能導(dǎo)致數(shù)據(jù)緩沖區(qū)溢出漏洞,本地攻擊者可以利用這個(gè)漏洞提升特權(quán)。
圖17 CVE-2005-0504 代碼缺陷
變種后的代碼片段如圖18 所示,其為CVE-2005-0504 漏洞代碼的變種,對(duì)函數(shù)名和部分參數(shù)做了重命名,但是代碼結(jié)構(gòu)與原存在缺陷代碼一致,工具能夠精準(zhǔn)地識(shí)別并告警,CVE-2005-0504 缺陷代碼命中結(jié)果如圖19 所示,表現(xiàn)出了彈性兼容識(shí)別代碼變種的能力。
圖18 變種后的CVE-2005-0504 代碼片段
圖19 CVE-2005-0504 缺陷代碼命中結(jié)果
靜態(tài)代碼分析系統(tǒng)在安全開(kāi)發(fā)領(lǐng)域得到了越來(lái)越廣泛的應(yīng)用,本文在主流源代碼靜態(tài)分析技術(shù)的基礎(chǔ)上,提出了一種自動(dòng)發(fā)現(xiàn)源代碼中安全漏洞的方案,通過(guò)從開(kāi)放漏洞數(shù)據(jù)庫(kù)中抽取所有可用的CVE 記錄,并從相關(guān)的開(kāi)源項(xiàng)目所在開(kāi)源存儲(chǔ)庫(kù)中收集易受攻擊的代碼建立開(kāi)源缺陷代碼庫(kù)。通過(guò)搜索引擎與源代碼分析規(guī)范多樣化聯(lián)合應(yīng)用,利用不同結(jié)構(gòu)的代碼同源性特征,挖掘代碼缺陷庫(kù)中的缺陷匹配信息,并通過(guò)應(yīng)用實(shí)例展示了該技術(shù)研究的可行性,驗(yàn)證了該系統(tǒng)具有較高的缺陷搜索匹配速度和準(zhǔn)確性。下一步,可研究擴(kuò)大漏洞采集的范圍,涵蓋CVE、中國(guó)國(guó)家信息安全漏洞庫(kù)(China National Vulnerability Database of Information Security,CNNVD)及主流社區(qū)漏洞庫(kù)的開(kāi)源代碼漏洞,同時(shí)優(yōu)化分詞規(guī)范化算法,以提高源代碼缺陷的檢測(cè)精度。