軟件常見漏洞的解析

理論基礎
漏洞可以定義為“在軟件和硬件組件中發(fā)現的計算邏輯(例如代碼)中的弱點,當被利用時,會對機密性,完整性或可用性產生負面影響”。

軟件漏洞是信息安全系統漏洞的重要組成部分,它通常被認為是軟件生命周期中出現的設計錯誤、編碼缺陷和運行故障造成的。

軟件漏洞從產生、發(fā)現、解決這些維度它可以分為:

1、0 day漏洞:表示已經被發(fā)現,但未被公開還未發(fā)布補丁的漏洞;

2、1 day漏洞:表示廠商已經發(fā)現并公開了相關補丁,但由于部分用戶還未及時打補丁,這個漏洞還是具有可利用性;

3、歷史漏洞:這個漏洞的補丁發(fā)布時間很久,不可利用的漏洞。

軟件漏洞的等級劃分:

1、低級漏洞:這里漏洞利用非常困難或影響很??;

2、中等漏洞:這類漏洞由于默認配置、審核或利用難度等因素大大減輕了其影響;

3、重要漏洞:利用此類漏洞可能會危及用戶數據的機密性、完整性或可用性,或者危及處理資源的完整性或可用性;

4、嚴重漏洞:利用此類漏洞,Internet病毒不需要用戶操作就可以擴散。

軟件漏洞基于成因可分類:內存破壞類漏洞、邏輯錯誤類漏洞、輸入驗證類漏洞、設計錯誤類漏洞、配置錯誤類漏洞。

 

緩沖區(qū)漏洞
當程序嘗試讀取或寫入超出范圍的緩沖區(qū)時,會發(fā)生緩沖區(qū)溢出。它可能導致覆蓋或追加現有代碼中的數據。

緩沖區(qū)溢出使攻擊者能夠執(zhí)行代碼、更改程序流程、讀取敏感數據或使系統崩潰。包含緩沖區(qū)溢出漏洞通常發(fā)生在體系結構和設計、實現或操作階段。

這個緩沖區(qū)漏洞最常發(fā)生在 C、C++的開發(fā)的程序中,但也可能發(fā)生在缺少內存管理支持的任何語言中。

緩沖區(qū)根據溢出的內存類型可以分為:棧內的數據溢出和堆內的數據溢出。

緩沖區(qū)漏洞被攻擊者利用通??梢赃M行遠程代碼執(zhí)行的功能。

導致出現緩沖區(qū)溢出漏洞問題點:

1、接受不受限制長度的輸入

2、允許對來自無效索引的數組執(zhí)行讀取操作。

下面是出現緩沖區(qū)漏洞的例子:


上面代碼從str向buffer復制數據,當str長度超過16時,就會出現緩沖區(qū)溢出。

問題根源在于strcpy沒有限制復制數據長度,存在類似的問題還有strcat(),sprintf(),vsprintf(),gets(),scanf()等。建議可以采用安全的系統函數(對操作數據進行長度判斷的函數)例如strcpy_s

下面也是同樣會出現溢出的風險,




降低緩沖區(qū)漏洞方案

若要防止利用緩沖區(qū)溢出漏洞,可以使用包含功能或擴展的編譯器來限制輸入。

還有確保正確分配緩沖區(qū)空間,并且能夠對輸入的數據進行做限制和校驗輸入大小的方法和函數。

“防止利用緩沖區(qū)溢出漏洞的最佳方法之一是在軟件投入使用之前從源代碼中檢測并消除它們”。

編碼過程中,安全函數的使用可以降低緩沖區(qū)溢出的漏洞。

可以學習下華為開源的安全函數庫,以此提高編碼過程中的安全性,從而降低開發(fā)出一些漏洞的代碼。

https://gitee.com/openarkcompiler/OpenArkCompiler/tree/master/src/mapleall/huawei_secure_c/src



字符串漏洞
在C、C++編程語言中正確和準確地操作Strings 時,必須考慮到 String 是以 null 結尾的字符序列。

對該 String 表示的不精確理解通常會導致一些最常見的錯誤:無界字符串副本、off-by-one 錯誤、空終止錯誤和字符串截斷。

下面代碼段展示了未綁定字符串副本的案例。該程序準備從標準輸入(stdin)接收最多八個字符。然而,使用函數 gets() 并不能限制用戶輸入的字符數。攻擊者可以通過輸入8個以上的字符并將其傳遞給程序來探索此問題。

由于在這種情況下空終止符是重疊的,因此程序未分配的其他內存位置用于存儲可能導致程序出現意外行為的額外字符。




在這類型的編碼中,建議更改fgets函數的使用來直接緩解。該替代函數“最多將少于指定數量的字符從流讀取到數組中”。

下面也是一個漏洞例子,其中發(fā)生了一個偏差錯誤。與未綁定的字符串副本一樣,逐個錯誤與寫入字符串邊界外的字符有關。






在此類問題中,長度為 10 的字符串正確存儲在準確定義了存儲容量的變量源中。該漏洞始于字符串dest的內存分配。此操作使用函數strlen來計算字符串的字符數,直到找到空終止符。因此,并沒有為dest字符串保留負責指示字符串終止的字符的位置。

由于將字符從字符串源復制到字符串dest的循環(huán)從位置 1 開始,因此最后一個命令將零字符寫入字符串dest 的邊界之外。




上面的問題點,可以通過在字符串分配期間考慮空終止符的位置并調整為負責字符復制的循環(huán)定義的索引來修復。

下圖是上面的修復后的安全編碼風格。




整數漏洞
當計算嘗試遞增一個大于用于在相關表示形式中存儲該整數的整數值時,存在整數溢出漏洞。發(fā)生此錯誤時,整數值可能會轉換為負數或非常小的數字。

當計算結果用于處理控制循環(huán),確定行為(如復制,內存分配,串聯等)的大小或偏移量并做出決定時,此弱點變得安全至關重要。

整數操作中的大多數錯誤和漏洞都涉及對存儲此類型數據的變量進行限制檢查不足。





下面的代碼顯示了由不精確的類型轉換生成的常見錯誤。

盡管該函數檢查通知的 size參數值是否符合最大數組大小的限制,但沒有與參數值的信號相關的檢查。因此,傳遞給函數的負大小將被視為它允許的大小,并且malloc 函數將使用負值調用。由于malloc期望size_t類型的參數,它將大小值轉換為較大的無符號數字,這可能導致值大于MAX_ARRAY_SIZE中定義的值。



不正確的權限或身份驗證漏洞
當未正確分配、跟蹤、修改或驗證用戶特權和憑據時,會發(fā)生不正確的特權或身份驗證。這些漏洞可能使攻擊者能夠濫用權限、執(zhí)行受限任務或訪問受限數據。

權限或身份驗證不當的示例包括:

1、未撤消的臨時權限提升。

2、通過列入黑名單而不是白名單來限制權限。

3、允許較低權限級別影響較高權限的帳戶,例如重置管理員密碼。

4、不受限制的登錄嘗試或會話限制。

特權或身份驗證漏洞通常在開發(fā)的體系結構和設計、實現或操作階段引入。任何語言都可能出現這些漏洞。

權限不當或身份驗證的漏洞預防措施
應該將最小特權原則應用于與你的軟件和系統交互的所有用戶和服務。通過在整個程序和環(huán)境中應用訪問控制來限制用戶和實體功能。應將權限限制為用戶或服務所需的那些資源。

如果可能,請將高級權限分為多個角色。分離有助于限制“高級用戶”,并降低攻擊者濫用訪問權限的能力。這樣還可以應用多重身份驗證方法,以防止攻擊者繞過系統或輕松訪問。

 

小結
軟件漏洞似乎不可避免,但大多數漏洞可以被消除或至少減少,只有通過細致的軟件設計,良好的編碼,發(fā)現漏洞后快速的響應來盡量減少軟件漏洞的產生,以及降低漏洞被利用后所帶來的危害。

同時為了提高軟件的安全性減少漏洞的出現,做好代碼審計,并且對軟件進行做靜態(tài)和動態(tài)運行時測試代碼,以確保軟件在發(fā)布前能夠發(fā)現漏洞,解決漏洞。



作者:小道安全


歡迎關注微信公眾號 :小道安全