軟件常見漏洞的解析
理論基礎(chǔ)
漏洞可以定義為“在軟件和硬件組件中發(fā)現(xiàn)的計算邏輯(例如代碼)中的弱點,當(dāng)被利用時,會對機(jī)密性,完整性或可用性產(chǎn)生負(fù)面影響”。
軟件漏洞是信息安全系統(tǒng)漏洞的重要組成部分,它通常被認(rèn)為是軟件生命周期中出現(xiàn)的設(shè)計錯誤、編碼缺陷和運行故障造成的。
軟件漏洞從產(chǎn)生、發(fā)現(xiàn)、解決這些維度它可以分為:
1、0 day漏洞:表示已經(jīng)被發(fā)現(xiàn),但未被公開還未發(fā)布補丁的漏洞;
2、1 day漏洞:表示廠商已經(jīng)發(fā)現(xiàn)并公開了相關(guān)補丁,但由于部分用戶還未及時打補丁,這個漏洞還是具有可利用性;
3、歷史漏洞:這個漏洞的補丁發(fā)布時間很久,不可利用的漏洞。
軟件漏洞的等級劃分:
1、低級漏洞:這里漏洞利用非常困難或影響很?。?br>
2、中等漏洞:這類漏洞由于默認(rèn)配置、審核或利用難度等因素大大減輕了其影響;
3、重要漏洞:利用此類漏洞可能會危及用戶數(shù)據(jù)的機(jī)密性、完整性或可用性,或者危及處理資源的完整性或可用性;
4、嚴(yán)重漏洞:利用此類漏洞,Internet病毒不需要用戶操作就可以擴(kuò)散。
軟件漏洞基于成因可分類:內(nèi)存破壞類漏洞、邏輯錯誤類漏洞、輸入驗證類漏洞、設(shè)計錯誤類漏洞、配置錯誤類漏洞。
緩沖區(qū)漏洞
當(dāng)程序嘗試讀取或?qū)懭氤龇秶木彌_區(qū)時,會發(fā)生緩沖區(qū)溢出。它可能導(dǎo)致覆蓋或追加現(xiàn)有代碼中的數(shù)據(jù)。
緩沖區(qū)溢出使攻擊者能夠執(zhí)行代碼、更改程序流程、讀取敏感數(shù)據(jù)或使系統(tǒng)崩潰。包含緩沖區(qū)溢出漏洞通常發(fā)生在體系結(jié)構(gòu)和設(shè)計、實現(xiàn)或操作階段。
這個緩沖區(qū)漏洞最常發(fā)生在 C、C++的開發(fā)的程序中,但也可能發(fā)生在缺少內(nèi)存管理支持的任何語言中。
緩沖區(qū)根據(jù)溢出的內(nèi)存類型可以分為:棧內(nèi)的數(shù)據(jù)溢出和堆內(nèi)的數(shù)據(jù)溢出。
緩沖區(qū)漏洞被攻擊者利用通??梢赃M(jìn)行遠(yuǎn)程代碼執(zhí)行的功能。
導(dǎo)致出現(xiàn)緩沖區(qū)溢出漏洞問題點:
1、接受不受限制長度的輸入
2、允許對來自無效索引的數(shù)組執(zhí)行讀取操作。
下面是出現(xiàn)緩沖區(qū)漏洞的例子:
上面代碼從str向buffer復(fù)制數(shù)據(jù),當(dāng)str長度超過16時,就會出現(xiàn)緩沖區(qū)溢出。
問題根源在于strcpy沒有限制復(fù)制數(shù)據(jù)長度,存在類似的問題還有strcat(),sprintf(),vsprintf(),gets(),scanf()等。建議可以采用安全的系統(tǒng)函數(shù)(對操作數(shù)據(jù)進(jìn)行長度判斷的函數(shù))例如strcpy_s
下面也是同樣會出現(xiàn)溢出的風(fēng)險,
降低緩沖區(qū)漏洞方案
若要防止利用緩沖區(qū)溢出漏洞,可以使用包含功能或擴(kuò)展的編譯器來限制輸入。
還有確保正確分配緩沖區(qū)空間,并且能夠?qū)斎氲臄?shù)據(jù)進(jìn)行做限制和校驗輸入大小的方法和函數(shù)。
“防止利用緩沖區(qū)溢出漏洞的最佳方法之一是在軟件投入使用之前從源代碼中檢測并消除它們”。
編碼過程中,安全函數(shù)的使用可以降低緩沖區(qū)溢出的漏洞。
可以學(xué)習(xí)下華為開源的安全函數(shù)庫,以此提高編碼過程中的安全性,從而降低開發(fā)出一些漏洞的代碼。
https://gitee.com/openarkcompiler/OpenArkCompiler/tree/master/src/mapleall/huawei_secure_c/src
字符串漏洞
在C、C++編程語言中正確和準(zhǔn)確地操作Strings 時,必須考慮到 String 是以 null 結(jié)尾的字符序列。
對該 String 表示的不精確理解通常會導(dǎo)致一些最常見的錯誤:無界字符串副本、off-by-one 錯誤、空終止錯誤和字符串截斷。
下面代碼段展示了未綁定字符串副本的案例。該程序準(zhǔn)備從標(biāo)準(zhǔn)輸入(stdin)接收最多八個字符。然而,使用函數(shù) gets() 并不能限制用戶輸入的字符數(shù)。攻擊者可以通過輸入8個以上的字符并將其傳遞給程序來探索此問題。
由于在這種情況下空終止符是重疊的,因此程序未分配的其他內(nèi)存位置用于存儲可能導(dǎo)致程序出現(xiàn)意外行為的額外字符。
在這類型的編碼中,建議更改fgets函數(shù)的使用來直接緩解。該替代函數(shù)“最多將少于指定數(shù)量的字符從流讀取到數(shù)組中”。
下面也是一個漏洞例子,其中發(fā)生了一個偏差錯誤。與未綁定的字符串副本一樣,逐個錯誤與寫入字符串邊界外的字符有關(guān)。
在此類問題中,長度為 10 的字符串正確存儲在準(zhǔn)確定義了存儲容量的變量源中。該漏洞始于字符串dest的內(nèi)存分配。此操作使用函數(shù)strlen來計算字符串的字符數(shù),直到找到空終止符。因此,并沒有為dest字符串保留負(fù)責(zé)指示字符串終止的字符的位置。
由于將字符從字符串源復(fù)制到字符串dest的循環(huán)從位置 1 開始,因此最后一個命令將零字符寫入字符串dest 的邊界之外。
上面的問題點,可以通過在字符串分配期間考慮空終止符的位置并調(diào)整為負(fù)責(zé)字符復(fù)制的循環(huán)定義的索引來修復(fù)。
下圖是上面的修復(fù)后的安全編碼風(fēng)格。
整數(shù)漏洞
當(dāng)計算嘗試遞增一個大于用于在相關(guān)表示形式中存儲該整數(shù)的整數(shù)值時,存在整數(shù)溢出漏洞。發(fā)生此錯誤時,整數(shù)值可能會轉(zhuǎn)換為負(fù)數(shù)或非常小的數(shù)字。
當(dāng)計算結(jié)果用于處理控制循環(huán),確定行為(如復(fù)制,內(nèi)存分配,串聯(lián)等)的大小或偏移量并做出決定時,此弱點變得安全至關(guān)重要。
整數(shù)操作中的大多數(shù)錯誤和漏洞都涉及對存儲此類型數(shù)據(jù)的變量進(jìn)行限制檢查不足。
下面的代碼顯示了由不精確的類型轉(zhuǎn)換生成的常見錯誤。
盡管該函數(shù)檢查通知的 size參數(shù)值是否符合最大數(shù)組大小的限制,但沒有與參數(shù)值的信號相關(guān)的檢查。因此,傳遞給函數(shù)的負(fù)大小將被視為它允許的大小,并且malloc 函數(shù)將使用負(fù)值調(diào)用。由于malloc期望size_t類型的參數(shù),它將大小值轉(zhuǎn)換為較大的無符號數(shù)字,這可能導(dǎo)致值大于MAX_ARRAY_SIZE中定義的值。
不正確的權(quán)限或身份驗證漏洞
當(dāng)未正確分配、跟蹤、修改或驗證用戶特權(quán)和憑據(jù)時,會發(fā)生不正確的特權(quán)或身份驗證。這些漏洞可能使攻擊者能夠濫用權(quán)限、執(zhí)行受限任務(wù)或訪問受限數(shù)據(jù)。
權(quán)限或身份驗證不當(dāng)?shù)氖纠ǎ?br>
1、未撤消的臨時權(quán)限提升。
2、通過列入黑名單而不是白名單來限制權(quán)限。
3、允許較低權(quán)限級別影響較高權(quán)限的帳戶,例如重置管理員密碼。
4、不受限制的登錄嘗試或會話限制。
特權(quán)或身份驗證漏洞通常在開發(fā)的體系結(jié)構(gòu)和設(shè)計、實現(xiàn)或操作階段引入。任何語言都可能出現(xiàn)這些漏洞。
權(quán)限不當(dāng)或身份驗證的漏洞預(yù)防措施
應(yīng)該將最小特權(quán)原則應(yīng)用于與你的軟件和系統(tǒng)交互的所有用戶和服務(wù)。通過在整個程序和環(huán)境中應(yīng)用訪問控制來限制用戶和實體功能。應(yīng)將權(quán)限限制為用戶或服務(wù)所需的那些資源。
如果可能,請將高級權(quán)限分為多個角色。分離有助于限制“高級用戶”,并降低攻擊者濫用訪問權(quán)限的能力。這樣還可以應(yīng)用多重身份驗證方法,以防止攻擊者繞過系統(tǒng)或輕松訪問。
小結(jié)
軟件漏洞似乎不可避免,但大多數(shù)漏洞可以被消除或至少減少,只有通過細(xì)致的軟件設(shè)計,良好的編碼,發(fā)現(xiàn)漏洞后快速的響應(yīng)來盡量減少軟件漏洞的產(chǎn)生,以及降低漏洞被利用后所帶來的危害。
同時為了提高軟件的安全性減少漏洞的出現(xiàn),做好代碼審計,并且對軟件進(jìn)行做靜態(tài)和動態(tài)運行時測試代碼,以確保軟件在發(fā)布前能夠發(fā)現(xiàn)漏洞,解決漏洞。
作者:小道安全
歡迎關(guān)注微信公眾號 :小道安全