創提部落格
希望我們能與您分享和探討成長中的點點滴滴
揭示AUTOSAR中隱藏的漏洞
分享到
AUTOSAR是一個普遍採用的軟體框架,用於各種汽車零部件,如ABS, ECU,自動照明、環境控制、充電控制器、資訊娛樂系統等。AUTOSAR的創建目的是促進汽車零部件之間形成標準介面,可以在不同製造商之間互通。
因此,任何配備微控制器(MCU)的汽車零部件都應符合AUTOSAR的規定。
AUTOSAR標準不僅管理用於模組間通信的資料格式,還規定了這些模組的標準API。在汽車行業內使用的AUTOSAR平臺有兩個版本:Classic和Adaptive。
Adaptive平臺是為高性能設備量身定制的,例如資訊娛樂系統或高級駕駛輔助系統(ADAS),這些設備通常在Linux或QNX等資源豐富的作業系統上運行。另一方面,Classic平臺部署於運行在微控制器單元裸板(MCU)上的低性能設備中,包括ABS, EBD, 安全氣囊控制單元、車身控制模組、傳輸控制模組等系統。
雖然AUTOSAR是一個穩健而可靠的開發框架,但它並非沒有潛在的錯誤和漏洞。在對AUTOSAR檔進行內部分析時,我們偶然發現了一個特別有趣的漏洞,這個漏洞可能會帶來很大的安全風險。程式碼中的缺陷並不是由於AUTOSAR本身造成的,而是對AUTOSAR使用不當的結果。
在本文中,我們打算深入研究和剖析這個具體的案例。
AUTOSAR Classic固件開發
在大多數情況下,固件是利用兩家領先的AUTOSAR軟體提供商(Vector和Elektrobit)提供的工具鏈開發的。
Vector和Elektrobit都提供了配置工具和SDK,其中包括標準AUTOSAR模組的預構建實現,如MicroSAR OS運行時、CAN介面、NVM API、診斷模組、加密和記憶體介面等。這種被稱為基本軟體(Basic Software,簡稱BSW)的SDK是以中介軟體方式執行,因此不能在目標硬體上獨立運行。
除了BSW之外,還有一套被稱為微控制器抽象層(Microcontroller Abstraction Layer,簡稱MCAL)的驅動程式和庫,用於對硬體的訪問。每個打算將其MCU用於汽車行業的硬體製造商都提供了適用於其MCU的AUTOSAR MCAL。例如,有來自博世、恩智浦、瑞薩和英飛淩的MCAL。MCAL驅動程式和庫也需要遵循AUTOSAR標準,以確保BSW可以與任何硬體製造商的MCAL一起使用。
新固件的開發通常從配置工具開始。在這裡,開發人員構建要使用的硬體平臺,為他們的項目選擇所需的MCAL和BSW模組,然後在所有模組之間建立連接。例如,開發人員可以指定BSW中的CanIf模組應該使用哪個MCAL的CAN介面。一旦配置階段完成,配置工具就會生成原始程式碼,這些原始程式碼本質上是MCAL和BSW的一個子集。
生成原始程式碼之後,可以使用任何編譯器或整合式開發環境(IDE)對其進行編譯,然後再將其安裝到目標設備上。由配置工具輸出的原始程式碼已經包含了設備以預設行為操作所必需的一切。因此,開發人員可能不需要對所生成的程式碼進行任何修改。在BSW層之上的任何自訂程式碼往往都是最小化了的,通常占固件總大小的10%以下。
基於AUTOSAR的固件漏洞
在我們進行紅隊滲透測試的過程中,我們獲得了基於AUTOSAR的固件進行安全評估。從攻擊者和滲透測試者的角度來看,基於AUTOSAR的檔的潛在攻擊點非常有限。該模組的原始程式碼非常可靠,始終經過程式碼審查和漏洞分析。
關於常規漏洞和通用缺陷枚舉(CWE),發現它們的可能性相當小。沒有動態記憶體分配,所有變數要麼是全域的,要麼是堆疊上的,從而消除了發現double-free或use-after-free等漏洞的機會。汽車程式碼不執行字串操作,而只關注二進位解析。因此,通過sprintf, sscanf, strcpy等操作遇到堆疊溢位的可能性在這裡是不存在的。
當涉及到潛在的競態條件漏洞時,AUTOSAR Classic不允許動態任務初始化或動態創建的同步原語。任務和同步事件清單是在配置階段預先確定的。因此,考慮到靜態的、預先配置的任務資源和事件集,自動生成的程式碼不太可能包含鎖死或競態條件。
因此,我們必須深入研究AUTOSAR框架,瞭解它的用法和對API的潛在使用不當,特別關注用戶如何以可能導致漏洞的方式調用它。
我們在NvM模組中遇到了一組函數:NvM_ReadBlock, NvM_WriteBlock和NvM_RestoreBlockDefaults,這組函數通常用於在NVM中載入和存放裝置設置(如EEPROM, NAND, NOR記憶體等)。
通過對NVRAM管理器規範中的函數原型進行研究:
很明顯,這些函數缺少緩衝區大小檢查,僅使用塊ID來確定在配置階段配置的特殊塊表中的資料大小。換句話說,用戶有責任包含在寫入時驗證保存在NvM塊中的資料大小是否合適的程式碼。同樣,當從NvM塊中讀取資料時,使用者有責任提供足夠大的緩衝區,因為NvM_ReadBlock只是根據NvM塊的大小簡單地覆蓋緩衝區。
因此,這樣的API調用可能會導致越界(Out of Bounds, 簡稱OOB)讀取或寫入。根據作為NvM_DstPtr/NvM_SrcPtr傳遞的緩衝區類型,可能會出現各種問題:
• 如果使用者提供了一個小的堆疊變數,但讀取了一個大的NvM塊,NvM_ReadBlock將在堆疊變數之外寫入資料,這會導致堆疊損壞,並可能為遠端程式碼執行(Remote Code Execution,簡稱RCE)打開大門。
• 如果提供的變數是全域變數,NvM_ReadBlock將覆蓋鄰近的全域變數。這可能會導致程式碼中出現未定義的行為。
• 如果使用者為NvM_WriteBlock提供了一個小的堆疊或全域變數,將導致NvM_WriteBlock讀取變數外的資料,並將亂數據存儲到NVM中。
利用這種方法,我們發現了一個有趣的由於AUTOSAR API使用不當導致緩衝區溢位漏洞的案例。
發現基於AUTOSAR的漏洞
讓我們看一下我們遇到的漏洞的簡化版本:
NvM_ReadBlock將從NVM讀取0x110位元組,然後將其寫入myVar的位置。雖然NvM_ReadBlock會準確地寫入myVar的值,但之後它仍將繼續用不可預測的值覆蓋鄰近的全域變數。
在我們發現的案例中,NvM_ReadBlock被設置為在堆疊上執行越界寫入操作,這可能會覆蓋函數的返回位址。
在這個具體案例中,對易受攻擊函數的調用被MCU複雜的自訂工作流程所掩蓋。然而,它仍然是可觸發的,並且確實導致了執行崩潰。
緩解威脅
程式碼生成之後,管理原始程式碼中與NvM API一起使用的變數大小就完全是開發人員的責任了。因此,AUTOSAR開發人員應當盡一切努力在配置器中對齊變數和NVM塊的大小。AUTOSAR開發人員還應當避免修改生成的程式碼,除非他們完全理解有關NVM塊大小的約束。
此外,沒有NVM函數可以提供NVM塊的大小來執行如下檢查:assert(sizeof(myVar) == NvM_BlockSize(Block_ID));這是因為塊大小被硬編碼到NvM模組配置中,並被視為內部資料。
即使在使用AUTOSAR這樣的標準化框架時,在某些情況下,也可能無意中引入重大的記憶體漏洞。為了減少這種情況,強烈建議採用持續的品質保證措施和定期的滲透測試。
總結
雖然AUTOSAR為汽車軟體發展提供了一個穩健而標準的框架,但由於使用不當,特別是在NvM API的變數管理中,仍然可能出現潛在的漏洞。隨著汽車技術越來越複雜,有必要通過持續的品質保證和定期的滲透測試來加強軟體安全性。這些實踐,加上對正在使用的框架的深刻理解,可以幫助開發人員降低潛在的安全風險,並提高汽車系統的整體安全性。