在過去N年裡,緩衝區溢出一直是網絡攻擊中最常被利用的漏洞。 看一下緩衝區是如何創建的,就能知道原因所在。
下面是C語言的一個例子:
第一步,程式設計師使用 malloc 函數並定義緩衝區內存的數量(例如32位)
第二步,返回指針,指示內存中緩衝區的開始位置
第三步,當程式設計師需要讀取或寫入該緩衝區時,程式設計師都會使用該指針
有了指針,程式設計師很容易忘記分配給指定緩衝區的實際內存量。編譯器在程序中使用元數據來分配適當的緩衝區大小,但是這個元數據通常在構建時被丟棄了。
如果在程序內或程序之間傳輸的數據隨後超出原定義的緩衝區大小,則數據信息將覆蓋相鄰的內存。這會導致內存訪問錯誤或崩潰,以及安全漏洞。
緩衝區溢出和漏洞利用黑客可以使用堆棧緩衝區溢出替換帶有惡意代碼的可執行文件,這樣他們就可以利用系統資源,比如堆內存或者調用堆棧的本身。例如,控制流劫持利用堆棧緩衝區溢出,將代碼執行重定向到正常操作中以外的位置。
圖1 控制流劫持
一旦掌握了控制流程,一個控制流程的劫持者可以修改指針和重用現有代碼,同時還可能替換代碼。控制流的命令還允許攻擊者修改用於間接調用、跳轉和函數返回的指針,這些指針會留下一個有效圖來隱藏它們的行為。
在發生代碼執行之前,動態位址空間配置的隨機載入(ASLR)機制和用於檢測並防止緩衝區溢出的堆棧金絲雀,這些仍然是一個挑戰。
安全: 軟體還是晶片負責?ASLR和堆棧金絲雀是基於軟體的緩衝區溢出保護機制,這些機制確實使攻擊者更難利用緩衝區溢出。例如,ASLR,動態地重新定位內存區域,以便黑客有效地猜測目標組件的地址空間,如基礎可執行文件、庫、堆棧內存。不幸的是,最近像 Spectre 和 Meltdown 這樣的漏洞洩露了CPU分支預測器的信息,這些明顯的原因限制了ASLR的有效性。
另一方面,堆棧金絲雀在內存中的返回指針之前插入小整數。檢查這些整數以確保它們沒有改變,一個進程就可以使用相應的返回指針。儘管如此,如果黑客們確信包含了正確的金絲雀值,那麼黑客們還是有可能讀懂這些金絲雀,然後簡單地重寫它以及隨後的緩衝區。此外,雖然金絲雀保護控制數據不被更改,但它們不能保護指針或任何其他的數據。
當然,基於軟體的安全解決方案的另一個挑戰是,它們極易受到漏洞的影響。據不完全統計,每1000行代碼中就有15-50個漏洞,這意味著解決方案中存在的軟體越多,漏洞的數量就越大。
當處理這種問題而不僅僅是緩衝區溢出的症狀時,一個更加健壯的方法是在晶片中實現安全性,而堆棧緩衝區溢出開發是為了操縱軟體程序。了解這類攻擊的根本原因,首先要認識到處理器無法確定某個程序是否正確執行。
除了減輕軟體缺陷的影響之外,晶片不可能被遠程改變。但是一個處理器或者一塊晶片必須在運行時識別試圖寫入內存或外圍設備的指令是合法執行還是非法操作。
運行時的晶片安全性Dover Microsystems 開發了一種叫做 CoreGuard 的技術,這是一個可以與RISC 處理器架構集成在一起的IP core,用於在運行時識別無效的指令。作為RTL交付,解決方案可以針對各種功率和區域需求進行優化,或者修改並支持自定義的處理器擴展。
圖2 CoreGuard的體系結構
如圖2所示,CoreGuard 體系結構包括一個硬體關聯鎖,控制主機處理器和系統其他部分之間的所有通信。硬體連接將這些通信匯集到一個政策執行者。
另外,CoreGuard 使用稱為micropolicy 的可更新安全規則,這些規則是在高級別專有語言中創建的簡單管理策略。 這些規則安裝在一個安全的、無法訪問的內存區域,與其他作業系統或應用程式代碼隔離開來。此外,CoreGuard 還為編譯器通常丟棄的應用程式元數據保留一個小的內存分配,用於為系統中的所有數據和指令生成唯一的標識符。這些組件在系統啟動時加載。
當一個指令試圖在運行時執行的時候,CoreGuard策略執行核心或主機處理器在特權模式下運行時,將指令的元數據與定義的micropolicy交叉引用。 硬體交互只能確保處理器輸出有效的內存或外設指令,從而防止無效代碼的執行。應用程式會被告知類似於一個零除錯誤的策略違規,並通知用戶。
與主機處理器集成,支持指令跟蹤輸出、失速輸入、非可屏蔽中斷(NMI)輸入和中斷輸出所需的所有功能。對於非晶片設計者來說,其CoreGuard技術正被某些 NXP 處理器所設計採用。
消除各種攻擊在緩衝區溢出的情況下,像 CoreGuard 這樣的技術的好處是顯而易見的。作為經常丟棄的編譯器元數據的一部分而捕獲的緩衝區大小可以被合併,以限制攻擊者在網絡上作業系統上訪問堆棧的能力。進一步說,同樣的原理可以應用於一般的控制流劫持,因為來自內存中不同點的返回值可以在發生之前受到限制。
實際上,這種實時意識也為安全行業創造了一個新的競爭環境。通過在損壞發生之前識別錯誤或者攻擊,用戶可以選擇動態地重新分配內存,在繼續運行相同程序的同時切換到單獨的、更安全的程序或日誌事件。如何執行代碼完全取決於應用程式或業務案例的需要。
何時才能看到zero-day 漏洞的終結呢?!
(本文編譯自 http://www.embedded-computing.com/iot/eliminating-buffer-overflow-vulnerabilities-on-the-iot)