檢測漏洞
對于無法完全防止引入一類漏洞的現(xiàn)有源代碼,例如,由于編程語言和/或API的選擇是由其他因素決定的,應(yīng)用技術(shù)來檢測是有用的在軟件的開發(fā)、測試和/或維護(hù)階段,代碼中存在漏洞。
(相關(guān)資料圖)
檢測漏洞的技術(shù)必須在檢測技術(shù)可以具有的以下兩個良好屬性之間進(jìn)行權(quán)衡:
?如果檢測技術(shù)可以正確得出結(jié)論,給定程序沒有該類別的漏洞,則檢測技術(shù)對于給定類別的漏洞是合理的。另一方面,不健全的檢測技術(shù)可能有假陰性,即檢測技術(shù)無法發(fā)現(xiàn)的實(shí)際漏洞。
?對于給定類別的漏洞,如果檢測到的任何漏洞是實(shí)際漏洞,則檢測技術(shù)是完整的。另一方面,不完整的檢測技術(shù)可能存在誤報,即它可能會檢測到并非實(shí)際漏洞的問題。
權(quán)衡是必要的,因?yàn)楦鶕?jù)賴斯定理(對于非平凡的漏洞類別)沒有一種檢測技術(shù)既健全又完整。
實(shí)現(xiàn)健全性需要對程序的所有執(zhí)行進(jìn)行推理(通常是無限多個)。這通常是通過對程序代碼進(jìn)行靜態(tài)檢查來完成的,同時對執(zhí)行進(jìn)行適當(dāng)?shù)某橄笠允狗治鼋K止。
通過執(zhí)行程序的實(shí)際、具體執(zhí)行來實(shí)現(xiàn)完整性,該程序見證了報告的任何漏洞。這通常是通過動態(tài)檢測完成的,其中分析技術(shù)必須為觸發(fā)漏洞的程序提供具體的輸入。一種非常常見的動態(tài)方法是軟件測試,其中測試人員編寫具有具體輸入的測試用例,并對相應(yīng)的輸出進(jìn)行特定檢查。
在實(shí)踐中,檢測工具可以使用靜態(tài)和動態(tài)分析技術(shù)的混合組合,以實(shí)現(xiàn)健全性和完整性之間的良好權(quán)衡。
然而,必須指出的是,一些檢測技術(shù)本質(zhì)上是啟發(fā)式的,因此沒有為它們精確定義健全性和完整性的概念。例如,檢測違反安全編碼實(shí)踐的啟發(fā)式技術(shù)(如2.3中所述)正在檢查是否符合非正式定義的規(guī)則和建議,并且并不總是能夠明確定義誤報?;蚣訇幮浴4送?,這些方法可能會突出“漏洞”,這些漏洞目前可能無法利用,但仍然應(yīng)該修復(fù),因?yàn)樗鼈兪恰安铧c(diǎn)錯過”,即將來的維護(hù)錯誤可能很容易被利用。
靜態(tài)和動態(tài)程序分析技術(shù)在計(jì)算機(jī)科學(xué)的其他領(lǐng)域被廣泛研究。本主題重點(diǎn)介紹與軟件安全最相關(guān)的分析技術(shù)。
檢測漏洞的另一種重要方法是執(zhí)行手動代碼審查和審核。這些技術(shù)在安全軟件生命周期CyBOKKnowl邊緣領(lǐng)域[1]中有所介紹。使用工具支持的靜態(tài)檢測時,調(diào)整此類后續(xù)代碼審查和其他驗(yàn)證活動是有意義的。例如,如果靜態(tài)檢測對于給定類別的漏洞是合理的,那么可以考慮在以后的階段不審查或測試該類別的漏洞。
靜態(tài)檢測
靜態(tài)檢測技術(shù)分析程序代碼(源代碼或二進(jìn)制代碼)以查找漏洞。與動態(tài)技術(shù)相反,靜態(tài)技術(shù)的優(yōu)點(diǎn)是它們可以對(尚)不可執(zhí)行的不完整代碼進(jìn)行操作,并且可以在單個分析中進(jìn)行操作。運(yùn)行它們嘗試涵蓋所有可能的程序執(zhí)行。粗略地說,人們可以區(qū)分兩類重要的技術(shù),它們的主要目標(biāo)不同。
啟發(fā)式靜態(tài)檢測
首先,有一些靜態(tài)分析技術(shù)可以檢測違反規(guī)則的情況,這些規(guī)則是安全編程實(shí)踐啟發(fā)式的正式編碼。靜態(tài)分析技術(shù)構(gòu)建了程序的語義模型,例如,包括抽象語法樹,以及程序中數(shù)據(jù)流和控制流的抽象。基于此模型,該技術(shù)可以標(biāo)記違反簡單語法規(guī)則的行為,例如,不要使用此危險的API函數(shù),或者僅將此API函數(shù)與常量字符串一起使用。參數(shù)。
漏洞存在的一個重要指標(biāo)是(可能是惡意的)程序輸入可能會影響風(fēng)險操作中使用的值(例如,索引到數(shù)組中,或連接字符串以創(chuàng)建SQL查詢)。污點(diǎn)分析(有時也稱為流分析)是一種分析技術(shù),用于確定值是否來自程序輸入(或更一般地來自指定的污點(diǎn)源))可以影響此類風(fēng)險操作中使用的值(或者更一般地說,影響流入受限接收器的值)。相同的分析還可用于檢測程序中的機(jī)密或敏感信息流向公共輸出通道的情況。
存在許多靜態(tài)污點(diǎn)分析的變體。重要的變化包括(1)代碼的牽引力,例如,路徑敏感與路徑不敏感,或上下文敏感與上下文不敏感分析,以及(2)是否由程序控制流而不是程序引起的影響考慮數(shù)據(jù)流(通常通過使用術(shù)語污點(diǎn)分析與信息流分析來區(qū)分)。
為了減少誤報的數(shù)量,污點(diǎn)分析可以考慮程序執(zhí)行的清理。由指定的清理功能處理的污染值(假設(shè)用于驗(yàn)證這些值對進(jìn)一步處理無害)將刪除其污點(diǎn)。
一個重要的挑戰(zhàn)是,必須為污點(diǎn)分析配置正確的源、水槽和消毒劑。在實(shí)踐中,這種配置目前經(jīng)常手動進(jìn)行,盡管最近的一些工作增加了工具輔助,例如,機(jī)器學(xué)習(xí)用于支持安全分析師完成這項(xiàng)任務(wù)。
聲音靜態(tài)驗(yàn)證
其次,有一些靜態(tài)分析技術(shù)旨在針對明確定義的漏洞類別保持合理性(但通常在實(shí)踐中仍然會做出妥協(xié)并放棄對漏洞的合理性某種程度上)。對于可以理解為違反規(guī)范或合同的漏洞類別,主要挑戰(zhàn)是正式表達(dá)此底層規(guī)范。完成此操作后,在計(jì)算機(jī)科學(xué)其他領(lǐng)域開發(fā)的大量靜態(tài)分析和程序驗(yàn)證知識可用于檢查是否符合規(guī)范。三種主要的相關(guān)技術(shù)是程序驗(yàn)證、抽象解釋和模型檢查。
程序驗(yàn)證使用程序邏輯來表達(dá)程序規(guī)范,并依賴于程序員/驗(yàn)證器以以下形式提供程序的充分抽象:歸納循環(huán)不變量或函數(shù)前置和后置條件,以便能夠構(gòu)造涵蓋所有程序執(zhí)行的證明。對于具有動態(tài)內(nèi)存分配的命令式語言,分離邏輯[26]是一種程序邏輯,可以表示不存在內(nèi)存管理和競爭條件漏洞(對于存儲單元上的數(shù)據(jù)爭用),以及符合程序員提供了程序API的合同。檢查是否符合分離邏輯規(guī)范通常不是自動的:它通過交互式程序驗(yàn)證完成,其中程序注釋用于提供不變量、前置條件和后置條件。但是,如果一個人只對沒有內(nèi)存管理漏洞感興趣,有時可以推斷出這些注釋,使該技術(shù)自動進(jìn)行。此外,避免使用某些語言功能(例如指針),并堅(jiān)持適合驗(yàn)證的編碼風(fēng)格,有助于使驗(yàn)證自動化。
抽象解釋是一種自動技術(shù),通過將程序操作的運(yùn)行時值映射到足夠的有限抽象域,從具體程序進(jìn)行抽象。對于不使用動態(tài)分配或遞歸的命令式程序,抽象解釋是一種成功的技術(shù),可以自動有效地證明不存在內(nèi)存管理漏洞。
模型檢查是一種自動技術(shù),它詳盡地探索程序的所有可訪問狀態(tài),以檢查是否沒有狀態(tài)違反給定規(guī)范。由于狀態(tài)爆炸問題,模型檢查只能窮盡地探索非常小的程序,在實(shí)踐中需要使用綁定探索的技術(shù),例如,通過限制程序循環(huán)的次數(shù)執(zhí)行。有界模型檢查不再合理,但仍能發(fā)現(xiàn)許多漏洞。
這些分析技術(shù)的大多數(shù)實(shí)際實(shí)現(xiàn)在某種程度上放棄了合理性。為了既合理又終止,靜態(tài)分析必須過度近似它所分析的程序的可能行為。過度逼近會導(dǎo)致誤報。真正的編程語言具有很難在不導(dǎo)致不可接受的誤報數(shù)量的情況下過度近似的功能。因此,實(shí)際實(shí)現(xiàn)必須進(jìn)行工程權(quán)衡,并且會低估某些語言功能。這使得實(shí)現(xiàn)不合理,但在減少誤報數(shù)的意義上更有用。這些工程權(quán)衡在“聲音宣言”中得到了很好的總結(jié)[27]。
動態(tài)檢測
動態(tài)檢測技術(shù)執(zhí)行程序并監(jiān)視執(zhí)行以檢測漏洞。因此,如果足夠高效,它們也可用于實(shí)時漏洞緩解(請參閱主題4)。動態(tài)檢測有兩個重要且相對獨(dú)立的方面:(1)應(yīng)該如何監(jiān)視執(zhí)行以檢測到漏洞,以及(2)執(zhí)行多少程序以及執(zhí)行哪些程序(3)即應(yīng)該監(jiān)控哪些輸入值?
監(jiān)測
對于可理解為違反單個執(zhí)行的指定屬性的漏洞類別(請參閱主題1.6),可以通過監(jiān)視違反該規(guī)范來執(zhí)行完整檢測。對于其他類別的漏洞,或者當(dāng)監(jiān)視違反規(guī)范的成本太高時,可以定義近似監(jiān)視器。
對內(nèi)存管理漏洞的監(jiān)視已經(jīng)進(jìn)行了深入研究。原則上,可以構(gòu)建完整的監(jiān)視器,但通常需要花費(fèi)大量的時間和內(nèi)存。因此,現(xiàn)有工具探索了執(zhí)行速度、內(nèi)存使用和完整性方面的各種權(quán)衡。現(xiàn)代C編譯器包括用于生成代碼以監(jiān)視內(nèi)存管理漏洞的選項(xiàng)。在動態(tài)分析是近似分析的情況下(如靜態(tài)分析),它也可能生成誤報或漏報,盡管它對具體的執(zhí)行跟蹤進(jìn)行操作。
對于結(jié)構(gòu)化輸出生成漏洞,一個挑戰(zhàn)是生成的輸出的預(yù)期結(jié)構(gòu)通常是隱式的,因此沒有可以監(jiān)視的顯式規(guī)范。因此,監(jiān)視依賴于合理的啟發(fā)式方法。例如,監(jiān)視器可以使用細(xì)粒度的動態(tài)污點(diǎn)分析[25]來跟蹤不受信任的輸入字符串的流,然后在不受信任的輸入對生成的解析樹產(chǎn)生影響時標(biāo)記違規(guī)。輸出。
軟件構(gòu)建的合同設(shè)計(jì)方法[18,c3]支持的斷言,前置條件和后置條件可以編譯到代碼中,以便在測試時提供API漏洞的監(jiān)視器,即使這些編譯的運(yùn)行時檢查的成本可能太高而無法在生產(chǎn)代碼中使用它們。
監(jiān)控競爭條件很困難,但存在一些用于監(jiān)控共享內(nèi)存單元上數(shù)據(jù)爭用的方法,例如,通過監(jiān)視所有共享內(nèi)存訪問是否遵循一致的鎖定規(guī)則。
生成相關(guān)執(zhí)行
動態(tài)檢測技術(shù)的一個重要挑戰(zhàn)是沿著導(dǎo)致發(fā)現(xiàn)新漏洞的路徑生成程序的執(zhí)行。這個問題是軟件測試中系統(tǒng)地為被測程序選擇適當(dāng)輸入的一般問題的一個例子[18,c4]。這些技術(shù)通常由模糊測試或模糊測試的總稱描述,可分為:
?黑盒模糊測試,其中輸入值的生成僅取決于被測試程序的輸入/輸出行為,而不取決于其內(nèi)部結(jié)構(gòu)。已經(jīng)提出了許多不同的黑盒模糊測試變體,包括(1)純隨機(jī)測試,其中輸入值從適當(dāng)?shù)闹涤蛑须S機(jī)采樣,(2)模型基于模糊測試,其中在生成輸入值期間考慮輸入值的預(yù)期格式(通常以語法形式)的模型,以及(3)基于突變的模糊測試,其中模糊器提供一個或多個典型輸入值,并通過對提供的輸入執(zhí)行小突變來生成新的輸入值值。
?白盒模糊測試,分析程序的內(nèi)部結(jié)構(gòu)以幫助生成適當(dāng)?shù)妮斎胫怠V饕南到y(tǒng)白盒模糊測試技術(shù)是動態(tài)符號執(zhí)行。動態(tài)符號執(zhí)行執(zhí)行具有具體輸入值的程序,并同時構(gòu)建路徑條件,這是一個邏輯表達(dá)式,用于指定程序采用此特定執(zhí)行路徑必須滿足的那些輸入值的約束。通過求解不滿足當(dāng)前執(zhí)行路徑條件的輸入值,模糊器可以確保這些輸入值將程序驅(qū)動到不同的執(zhí)行路徑,從而提高覆蓋率。
標(biāo)簽: