原創|使用教程|編輯:鄭恭琳|2020-09-09 10:37:41.690|閱讀 153 次
概述:內存管理充滿危險,尤其是在C和C++中。實際上,與內存管理弱點相關的錯誤占CWE Top 25的很大一部分。前25名中的八個與緩沖區溢出、不良指針和內存管理直接相關。 最大的軟件弱點是CWE-119,“內存緩沖區范圍內的操作限制不當”。這些類型的錯誤在各種軟件的安全性和安全性問題中占主導地位,包括汽車,醫療設備和航空電子設備中的安全關鍵型應用程序。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
內存管理充滿危險,尤其是在C和C++中。實際上,與內存管理弱點相關的錯誤占CWE Top 25的很大一部分。前25名中的八個與緩沖區溢出、不良指針和內存管理直接相關。
最大的軟件弱點是CWE-119,“內存緩沖區范圍內的操作限制不當”。這些類型的錯誤在各種軟件的安全性和安全性問題中占主導地位,包括汽車,醫療設備和航空電子設備中的安全關鍵型應用程序。
以下是與CWE Top 25中常見的漏洞枚舉有關的內存錯誤:
盡管這些錯誤困擾了C,C++和其他語言數十年,但如今它們仍在以越來越多的數量出現。就質量、安全性和可靠性的后果而言,它們是危險的錯誤,并且它們的存在是導致安全漏洞的主要原因。
Microsoft發現,在過去的12年中,其產品中超過70%的安全漏洞是由于內存安全問題引起的。這些類型的錯誤是其應用程序的最大攻擊面,黑客正在使用它。根據他們的研究,安全攻擊的最根本原因是堆越界,釋放后使用和未初始化的使用。正如他們指出的那樣,漏洞類別已經存在了20年或更長時間,并且在今天仍然很流行。
谷歌以類似的方式發現,Chromium項目(Chrome瀏覽器的開源基礎)中70%的安全漏洞是由于這些相同的內存管理問題引起的。它們的最根本原因還在于免檢后使用,其次是其他不安全的內存管理。
考慮到這些實際發現的示例,軟件團隊必須認真對待這些類型的錯誤,這一點至關重要。幸運的是,有一些方法可以通過有效而有效的靜態分析來預防和檢測這些類型的問題。
在大多數情況下,內存管理錯誤是由于不良的編程習慣所導致的,原因是在C/C++中使用了指針并直接訪問了內存。在其他情況下,這與對數據的長度和內容做出錯誤的假設有關。
這些軟件弱點最常被污染數據利用,這些數據來自應用程序外部,未經檢查其長度或格式。臭名昭著的Heartbleed漏洞是利用緩沖區溢出的一種情況。從技術上講,這是緩沖區溢出。正如我們在上一個博客中有關SQL注入的討論中所討論的那樣,使用未經檢查和不受約束的輸入會帶來安全風險。
讓我們考慮一下內存管理軟件弱點的一些主要類別。最重要的一個是CWE-119:在內存緩沖區范圍內對操作的不當限制。
緩沖區溢出
允許直接訪問內存并且不自動驗證訪問的位置是否有效且容易發生內存損壞錯誤的編程語言(通常為C和C++)。這種損壞可能發生在內存的數據和代碼區域中,從而可能暴露敏感信息,導致意外的代碼執行或導致應用程序崩潰。
以下示例顯示了CWE-120緩沖區溢出的經典情況:
char last_name[20]; printf ("Enter your last name: "); scanf ("%s", last_name);
在這種情況下,對來自scanf()的用戶輸入沒有任何限制,但last_name的長度限制為20個字符。輸入超過20個字符的姓氏,最終會將用戶輸入復制到內存中,超出了緩沖區last_name的限制。這是CWE-119的一個更微妙的示例:
void host_lookup(char *user_supplied_addr){ struct hostent *hp; in_addr_t *addr; char hostname[64]; in_addr_t inet_addr(const char *cp); /*routine that ensures user_supplied_addr is in the right format for conversion */ validate_addr_form(user_supplied_addr); addr = inet_addr(user_supplied_addr); hp = gethostbyaddr( addr, sizeof(struct in_addr), AF_INET); strcpy(hostname, hp->h_name); }
此函數采用用戶提供的包含IP地址(例如127.0.0.1)的字符串,并檢索其主機名。
該函數驗證用戶輸入(好!),但不檢查gethostbyaddr()的輸出(不好!)。 在這種情況下,較長的主機名足以溢出當前僅限于64個字符的主機名緩沖區。 請注意,如果在找不到主機名時gethostaddr()返回null,那么也會出現null指針取消引用錯誤!
釋放后使用錯誤
有趣的是,Microsoft在他們的研究中發現,售后使用錯誤是他們面臨的最常見的內存管理問題。顧名思義,該錯誤與訪問先前釋放的內存的指針(對于C/C++)有關。C和C++通常依靠開發人員來管理內存分配,這對于完全正確地進行操作通常很棘手。如以下示例(來自CWE-416)所示,通常很容易假設指針仍然有效:
char* ptr = (char*)malloc (SIZE); if (err) { abrt = 1; free(ptr); } ... if (abrt) { logError("operation aborted before commit", ptr); }
在上面的示例中,如果err為true,則指針ptr是空閑的,但是如果abrt為true(則設置為true,如果err為true),則在釋放之后,指針ptr稍后將被取消引用。這似乎是人為的,但是如果這兩個代碼段之間有很多代碼,則很容易忽略。此外,這可能僅在未經過正確測試的錯誤情況下發生。
空指針解除引用
軟件的另一個常見弱點是使用預期有效但為NULL的指針(或C++和Java中的對象)。盡管這些取消引用在Java之類的語言中被視為異常,但它們可能導致應用程序停止、退出或崩潰。以Java為例,從CWE-476中獲取以下示例:
String cmd = System.getProperty("cmd"); cmd = cmd.trim();
由于開發人員可能會假定getProperty()方法始終返回某些內容,因此這看起來很無害。實際上,如果屬性“cmd”不存在,則返回NULL,在使用該屬性時會導致NULL解除引用異常。盡管這聽起來不錯,但卻可能導致災難性的后果。
在極少數情況下,當NULL等于0x0內存地址并且特權代碼可以訪問它時,就可以寫入或讀取內存,這可能導致代碼執行。
開發人員應實施幾種緩解措施。首先,開發人員需要通過經過驗證的邏輯和全面檢查,確保指針對C和C++等語言有效。
對于所有語言,任何操作內存的代碼或庫都必須驗證輸入參數,以防止越界訪問。以下是一些可用的緩解措施。但是開發人員不應依靠它們來彌補不良的編程習慣。
編程語言選擇
某些語言提供了針對溢出的內置保護,例如Ada和C#。
安全庫的使用
可以使用諸如Safe C字符串庫之類的提供內置檢查以防止內存錯誤的庫。但是,并非所有緩沖區溢出都是字符串操作的結果。除此以外,程序員應始終使用以緩沖區長度作為參數的函數,例如strncpy()與strcpy()。
編譯和運行時強化
這種方法利用了編譯選項,這些選項將代碼添加到應用程序中以監視指針的使用情況。此添加的代碼可以防止在運行時發生溢出錯誤。
執行環境強化
操作系統具有防止在應用程序的數據區域中執行代碼的選項,例如帶有代碼注入的堆棧溢出。還有一些選項可以隨機排列內存映射,以防止黑客預測可利用代碼的位置。
盡管有這些緩解措施,但還是沒有替代適當的編碼實踐來避免緩沖區溢出的問題。因此,檢測和預防對于降低這些軟件漏洞的風險至關重要。
在軟件開發中采用DevSecOps方法意味著將安全性集成到DevOps管道的各個方面。正如在SDLC中盡早推動代碼分析和單元測試之類的質量過程一樣,安全性也是如此。
如果開發團隊更廣泛地采用這種方法,則緩沖區溢出和其他內存管理錯誤可能已成為過去。正如Google和Microsoft的研究表明的那樣,這些錯誤仍占其安全漏洞的70%。無論如何,讓我們概述一種可以盡早阻止它們的方法。
與修補已發布的應用程序相比,查找和修復內存管理錯誤可節省大量時間。下面概述的檢測和阻止方法基于將緩沖區溢出的緩解向左轉移到開發的最早階段。并通過靜態代碼分析進行檢測來增強這一點。
偵測
檢測內存管理錯誤依賴于靜態分析以在源代碼中找到這些類型的漏洞。檢測發生在開發人員的桌面和構建系統中。它可以包括現有的、舊的和第三方代碼。
連續檢測安全問題可確保找到以下所有問題:
推薦的方法是信任但驗證模型。安全性分析是在IDE級別上完成的,開發人員在該級別上根據所獲得的報告做出實時決策。接下來,在構建級別進行驗證。理想情況下,構建級別的目標不是找到漏洞。這是為了驗證系統是否干凈。
Parasoft C/C++test包括針對這些類型的內存管理錯誤(包括緩沖區溢出)的靜態分析檢查器。考慮以下示例,該示例取自C/C++測試。
圖xx:Parasoft C/C++test示例,顯示了對越界內存訪問的檢測。
放大細節,函數printMessage()錯誤會檢測到錯誤:
Parasoft C/C++test還提供有關該工具如何出現此警告的跟蹤信息:
邊欄顯示有關如何修復此漏洞的詳細信息以及適當的參考:
準確的檢測以及支持信息和補救建議對于使靜態分析和對這些漏洞的早期檢測非常有用,并使開發人員可立即采取行動至關重要。
防止緩沖區溢出和其他內存管理錯誤
防止緩沖區溢出的理想時間和地點是開發人員在其IDE中編寫代碼時。采納安全編碼標準的團隊,例如C和C++的SEI CERT C和Java和.NET的OWASP Top 10或CWE的Top 25,都具有警告內存管理錯誤的準則。
例如,CERT C包括以下有關內存管理的建議:
這些建議包括預防性編碼技術,這些技術可首先避免內存管理錯誤。每套建議都包括風險評估和修復成本,使軟件團隊可以按以下優先級排列準則:
一項關鍵的預防策略是采用符合SEI CERT等行業準則的編碼標準,并在以后的編碼中強制執行。通過更好的編碼實踐來預防這些漏洞更便宜、風險更低,并且投資回報率最高。
對新創建的代碼進行靜態分析既快速又簡單。團隊很容易將其集成到桌面IDE和CI/CD流程中。為了防止將此代碼寫入到內部版本中,最好在此階段調查所有安全警告和不安全的編碼做法。
Parasoft集成到Eclipse IDE中的屏幕截圖,它將預防和檢測漏洞帶到開發人員的桌面。
檢測不良編碼實踐的同等重要的部分是報告的實用性。了解靜態分析違規的根本原因很重要,以便快速、有效地解決它們。這就是Parasoft的C/C++test,dotTEST和Jtest等商業工具的發源地。
Parasoft的自動測試工具可對警告進行完整跟蹤,在IDE中進行說明,并連續收集構建信息和其他信息。這些收集的數據以及測試結果和指標可提供對團隊編碼標準合規性以及總體質量和安全狀態的全面了解。
開發人員可以基于其他上下文信息(例如項目中的元數據、代碼的年齡以及負責代碼的開發人員或團隊)進一步過濾發現。帶有人工智能(AI)和機器學習(ML)的Parasoft之類的工具使用此信息來幫助進一步確定最關鍵的問題。
儀表板和報告包括風險模型,這些模型是OWASP、CERT和CWE提供的信息的一部分。這樣,開發人員可以更好地了解該工具報告的潛在漏洞的影響以及應優先考慮哪些漏洞。在IDE級別生成的所有數據都與上面概述的下游活動相關。
緩沖區溢出和其他內存管理錯誤繼續困擾著應用程序。它們仍然是安全漏洞的主要原因。盡管知道它是如何工作和被利用的,但它仍然很普遍。有關最新示例,請參考。
我們提出了一種預防和檢測方法來補充主動安全性測試,該方法可以防止緩沖區溢出在SDLC中盡早將其寫入代碼之前。防止在IDE上出現此類內存管理錯誤并在CI/CD管道中檢測到這些錯誤,是將其從軟件中路由出去的關鍵。
智能軟件團隊可以最大程度地減少內存管理錯誤。他們可以通過其現有工作流程中正確的流程、工具和自動化來對質量和安全性產生影響。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn