官术网_书友最值得收藏!

11.3 汽車黑客的思維及方法

本節將以一輛智能汽車作為攻擊目標。我們平時對汽車的了解僅限于簡單的駕駛操作,所以要在短時間內攻破它需要經過認真思考。整車攻擊面如圖11-1所示,我們將在接下來的內容中進一步介紹。

11.3.1 初始訪問條件分析

假設我們要攻擊一輛智能汽車,首先,根據以往經驗,我們會查看這輛車的功能,包括進入汽車、下載手機應用、登錄、在中控大屏上進行各種設置等一系列動作。經過數小時后,我們終于完成了初步了解,此時我們很可能對它的高級功能感到驚嘆。同時,我們知道越高級、復雜的東西越容易被攻破。

在熟悉了功能后,我們會嘗試構建攻擊場景,這是一個非常自然的過程,因為我們天生具有聯想能力。即使一個沒有任何安全攻防經驗的人,也能想象自己的汽車有可能受到哪些威脅。例如:我的手機可以打開車門,那么黑客能否做到這點呢?我的車可以上網,那么黑客能否通過網絡給我的車發送病毒呢?我的車上有各種插口,那么黑客能否通過插口破壞汽車呢?

作為攻擊者,我們需要更專業一些,要盡可能不遺漏地分析出所有的攻擊場景。如何做到呢?我們采用最容易的思考方法——聚類模式。首先,我們不需要列舉出所有可能的攻擊場景,因為車輛功能太多,一時間無法全面考慮。因此,我們首先思考攻擊者想要攻擊汽車的必要條件,即初始訪問條件是什么。這對攻擊者來說,在熟悉車輛的功能后可以很快地分析出來。例如:通過手機可以對汽車遠程解鎖,那么黑客也可以遠程攻擊;車輛具有近程通信功能,黑客也可以近程攻擊;車輛具有物理接口,黑客也可以進行接口攻擊。

下面列舉一些初始訪問條件。

?無授權的遠程攻擊場景:表示攻擊者不受距離影響,無須授權就能控制車輛。

?無授權的中程攻擊場景:表示攻擊者在一定距離范圍內無須授權就能控制車輛。

?有授權的遠程攻擊場景:表示攻擊者需要獲取某些授權才能遠程控制車輛。

?需要用戶交互的遠程攻擊場景:表示攻擊者需要通過車主在車內執行一些操作,才能獲取車輛控制權。

?有授權的中程攻擊場景:表示攻擊者需要在一定距離范圍內,獲取某些授權后才能控制車輛。

?車外物理接觸攻擊場景:表示攻擊者需要與車的外表面進行物理接觸,以獲取車輛控制權。

?車內物理接觸攻擊場景:表示攻擊者需要通過車內的接口等進行操作,從而獲取車輛控制權。

?具有車機應用權限的攻擊場景:表示攻擊者需要在目標車機中獲取應用權限以執行自己的代碼。

?具有其他ECU權限的攻擊場景:表示攻擊者需要在除車機以外的ECU中執行自己的代碼。

?需要拆車的攻擊場景:表示攻擊者需要將車輛拆開,因為ECU的接口并非都暴露在外面,有些是隱藏在車輛的內飾后面以及ECU的盒子里面的,攻擊者需要拆車后才能接觸到。

11.3.2 攻擊向量分析

相信大多數人都可以做到初始訪問條件分析,那么接下來該怎么做呢?我們需要思考,在這些前提條件下,能通過什么來攻擊汽車。在無任何前置經驗的情況下,這一步是需要配合專業的技術手段來實現的,接下來我們將對此進行介紹。

1.遠程初始訪問

在分析遠程攻擊條件后,我們可以進一步思考如何攻擊汽車。針對這些初始條件,我們需要結合專業技術手段進行深入分析。以下是對幾種可能的攻擊方法的分析。

首先是無授權的遠程攻擊手段。這種攻擊方式主要是指那些開放在公網上的云端平臺,如車輛云端和App云端,以及遠程的無線電(如GPS和Radio)等。這種攻擊方式的特點是攻擊者不需要獲得授權就可以進行攻擊。這種攻擊方式的危害比較大,因為攻擊者可以直接通過云端平臺和無線電進行攻擊。

其次是有授權的遠程攻擊手段。這種攻擊方式主要是指那些能夠獲得授權訪問云端平臺的攻擊方式,例如訪問OEM后臺、供應鏈后臺、車輛云端賬戶、App賬戶等。相對于無授權的遠程攻擊方式來說,攻擊者采用這種方式需要通過一定的授權手段獲得權限,但一旦攻擊成功,其危害也是很大的。

圖11-1 整車攻擊面分析

最后是One Click遠程攻擊手段。這種攻擊方式主要針對車機上具有遠程交互的App,例如瀏覽器和社交軟件等。這種攻擊方式的特點是攻擊者可以通過車主的一次點擊操作進行攻擊,攻擊成本低,危害也很大。

綜上所述,針對這些初始條件,需要結合專業技術手段進行深入分析,以便有效地防范和應對各種遠程攻擊。

2.中程初始訪問

與遠程攻擊類似,我們可以從車輛的功能入手來分析中程攻擊的可能性。首先,有一些顯而易見的中程功能,包括藍牙鑰匙控車、車載無線Wi-Fi熱點、NFC卡片鑰匙等。其次,通過查閱資料可以了解到自動駕駛主要依賴各種傳感器,利用這些傳感器也能實現中程攻擊。最后,還有一些比較隱蔽的功能,例如TPMS(輪胎壓力監測系統),則需要對車輛有一定了解才能知道。

具體來說,中程攻擊可以分為以下幾種類型。

?無授權的中程攻擊手段:主要指通過藍牙、Wi-Fi、UWB、NFC以及其他無線電技術與車輛進行無授權的近程通信。

?無授權的中程(傳感器)攻擊手段:指利用傳感器實現近程通信,例如攝像頭、激光雷達、超聲波傳感器等。

?有授權的中程攻擊手段:主要指通過藍牙綁定、Wi-Fi密碼等方式實現授權的車輛近程通信。

3.物理接觸初始訪問

物理接觸攻擊是一種通過直接接觸車輛電子系統進行攻擊的手段,其攻擊手段主要包括車外和車內兩種情況。在熟悉車輛后,幾乎所有的電子插孔都可以成為物理接觸攻擊的目標。

車外物理接觸攻擊手段主要指利用車外的物理接口實現攻擊,比如充電口等。而車內物理接觸攻擊手段則主要指利用車內的物理接口實現攻擊,比如OBD、USB、CD、AUDIO等插孔,這些插孔都可以被攻擊者利用來進行物理接觸攻擊,因此需要進行加固或者限制訪問權限,以保障車輛安全。

4.ECU權限初始訪問

在進行ECU權限初始訪問時,需要先了解車輛的電子電氣架構,包括各個ECU之間的通信方式和權限。一些公開的架構資料可以幫助我們了解這些信息,例如車輛的技術規范、用戶手冊、網絡資料等。

在獲得足夠的信息后,攻擊者可以嘗試利用漏洞或弱點進行攻擊。如果攻擊者已經獲得了車機的應用權限,那么可以通過車機的提權等方式進行后滲透。如果攻擊者已經獲得了其他ECU的權限,那么可以利用這些權限進行車內網絡的橫向滲透。

需要注意的是,在進行ECU權限初始訪問時需要遵守法律法規,避免那些違反相關法律法規的行為。車輛制造商正在不斷加強車輛的安全性能,例如增加加密措施、限制ECU之間的通信等。同時,攻擊者也在更新攻擊技術和手段,以適應不斷提高的車輛安全性能。

5.拆車權限初始訪問

拆車權限初始訪問是指攻擊者通過拆卸車輛內部電子設備進行攻擊。攻擊者可以使用這種方法來直接物理接觸和操作車輛內部的電子設備,例如ECU和總線等。

為了獲得這種權限,攻擊者需要對車輛的電子電氣架構有深入的了解,包括車內ECU的排布、總線的排布、ECU芯片類型等。攻擊者需要對車輛內部進行分析,確定物理接觸攻擊的向量,例如車內物理接線攻擊、PCB硬件攻擊等。

由于這種攻擊方式需要直接操作車輛內部的設備,攻擊者必須擁有足夠的專業知識和技能才能夠順利地進行攻擊。此外,這種攻擊方式可能會留下明顯的物理痕跡,因此容易被發現。

11.3.3 攻擊面分析

有了攻擊向量之后,我們就有了研究方向。當然,這些方向還不夠明確,我們需要沿著攻擊向量進一步細化要研究的目標。這一步會涉及很多技術和方法,這也是表現攻擊者技術高低的重要步驟之一。一些非常嚴重的漏洞往往出現在一些未被人發現的攻擊面中。我們將在后續的內容中逐一講解探索各個攻擊面的過程,本節只列舉出我們的分析結果,主要攻擊面如圖11-2所示。

圖11-2 汽車網絡安全攻擊面

主要攻擊面及對應的攻擊方式如下。

?云端:OTA服務器、TSP服務器、手機應用程序登錄、車輛鑰匙分享API、遠程控制API等。

?藍牙:協議棧、BLE(低功耗藍牙)鑰匙、經典藍牙耳機、藍牙通話等。

?Wi-Fi:協議棧、開放端口、中間人攻擊等。

?傳感器:欺騙、干擾、致盲、模型攻擊等。

?應用程序:JavaScript引擎、社交媒體消息解析、媒體文件解析、WebView攻擊、中間人攻擊等。

?OBD:DoCAN、DoIP等協議攻擊。

?提權:用戶態提權、內核態提權等。

11.3.4 攻擊點分析

經過攻擊面的分析,我們基本確定了要攻擊的目標,但每個目標都可能涉及很多內容,攻擊點分析就是找到具體的點,也就是確定是哪個程序(Binary)、哪個進程、哪段代碼等。在這個過程中我們很難全面列舉,因為不同目標使用的代碼不同,除非使用一些通用庫,否則我們需要根據自己的目標進行研究。攻擊點分析是整個攻擊過程中非常重要且耗時的步驟。通常我們會使用抓包分析的方式進行初步信息收集,然后對感興趣的報文進行逆向代碼分析,查找相關線索。

實際上,在這個過程中,我們已經開始了漏洞挖掘。一旦發現一個新的攻擊點,就需要構思該點的漏洞可能出現在哪里,并進一步編寫代碼、通信和逆向調試來驗證。此外,如果該攻擊點具有復雜的處理邏輯,那我們還可以使用Fuzz的方式來探索漏洞。

汽車網絡安全集成了Web、逆向、物聯網(IoT)、移動和無線等多個方面的綜合安全性。對于汽車漏洞挖掘而言,硬件分析和固件分析是必備的能力,如果不具備這兩種能力,則無法深入挖掘汽車漏洞。

11.3.5 前置技能之硬件分析

硬件分析是一個汽車黑客需要掌握的通用前置技能。硬件分析的知識點如圖11-3所示,它并不是一個針對汽車攻擊面的研究。如果讀者已經掌握該技能,可以跳過此部分。

圖11-3 硬件分析的知識點

為何需要掌握硬件分析技能呢?因為對于黑盒汽車來說,我們無法獲得它的固件、設計資料或系統權限,只能通過硬件這個最直接的入口去獲取更多信息。該技能對于后續的攻擊面分析、固件提取、逆向和調試都是不可或缺的幫手之一。

1.拆解ECU

拆解ECU需要由專業的車輛維修工程師來完成。一般來說,拆卸中央集成控制器的步驟包括打開前機艙蓋、斷開蓄電池負極電纜、拆卸儀表板左側下護板、拆卸中央集成控制器固定螺絲、斷開中央集成控制器控制插頭、取出中央集成控制器總成、拆除模塊外殼,如圖11-4所示。

圖11-4 拆解中央集成控制器的一般步驟

拆解ECU后,就要進行具體分析了。ECU板上包含了很多有價值的信息。例如,通過處理器芯片,我們可以了解到它的功能大致包括什么;存儲芯片可以幫助我們提取固件;調試接口可以幫助我們動態分析ECU的功能;通信接口可以讓我們了解與ECU通信的方式。

2.絲印查看

通常,我們需要依靠PCB板上的絲印信息進行分析。通過放大鏡或顯微鏡可以查看芯片型號。如果板上的絲印信息不足,我們就需要使用萬用表進行測量(測量方法在上冊中介紹過)。不同的引腳有不同的測量方式。例如,我們可能通過絲印看到JTAG接口,如圖11-5所示,各引腳的用途如下。

?VCC(Voltage Common Collector):電源引腳。

?TRST(Test Reset Input):對TAP(Test Access Port)進行復位,即初始化。

?TDI(Test Data Input):測試數據輸入。

?TMS(Test Mode Select):測試模式選擇引腳。

?TCLK(Test Clock):時鐘信號。

?RTCK(Return Test Clock):將JTAG信號與內部時鐘同步。

?TDO(Test Data Out):測試數據輸出。

?RESET(Test Reset):直接對目標系統復位。

圖11-5 JTAG接口

3.FCC ID查看

FCC ID是美國聯邦通信委員會(FCC)注冊的硬件產品唯一標識符,主要分配給在美國合法銷售的無線設備。設備制造商需要向FCC提供設備的實驗數據、產品手冊、文檔、照片等資料進行注冊。大多數智能設備都有FCC ID,對于這些設備,可以通過FCC網站查詢其詳細信息,例如設備的內部照片、工作頻率等。這些信息對于識別組件以及了解該設備使用的射頻技術至關重要。

在針對車輛的無線鑰匙的例子中,我們首先拆解鑰匙并查看其FCC ID,如圖11-6所示。

圖11-6 FCC ID查看

然后去fccid.io上搜索這個編號——NBG009066T,可以得到公開的鑰匙信息,包括照片、測試報告、用戶手冊等,如圖11-7所示。

4.芯片DataSheet查看

當我們確定了PCB上的芯片型號后,可以查找芯片的手冊,即DataSheet。常見的芯片在其官網上都能找到手冊,里面明確定義了芯片的引腳、內存映射等信息。這些信息可以幫助我們了解硬件調試接口和固件的基址信息。

例如,圖11-8顯示的是英飛凌芯片TC37系列產品的手冊中BGA封裝的引腳定義,圈出的是JTAG引腳,我們已經介紹過它們的含義了。

圖11-7 通過FCC ID獲取無線鑰匙的信息

圖11-8 芯片引腳定義

圖11-9顯示的是英飛凌芯片TC3xx的內存映射表,我們可以從中看出不同的內存地址所存放的內容是什么,比如0x80000000是Flash的基地址。

圖11-9 芯片內存映射表

5.硬件分析匯總

經過上述的絲印查看和芯片手冊查看之后,可以得到一個ECU芯片的示意圖,并從中了解到ECU上有哪些芯片。通過這些芯片的DataSheet上的相關描述,我們可以知道它們的功能,從而了解該ECU大致具備的功能。以T-BOX和IVI為例,我們可以標記板上所有芯片的型號,并調查它們所具備的功能。

1)T-BOX:包括一個英飛凌的MCU(微控制器)和一塊LTE的SOC(System On Chip,系統級芯片),外置了一塊Kioxia America eMMC 8GB 5.1 2D 15nm芯片用于存放日志信息等數據,如圖11-10所示。

圖11-10 T-BOX芯片標記(正面)

2)IVI:包括一個英飛凌的MCU(TriCore SAK-TC275TP-64 F200N)、一塊高通8155芯片(PMM8996AU)以及一個東芝UFS存儲芯片,如圖11-11所示。

圖11-11 IVI芯片標記(正面)

11.3.6 前置技能之固件逆向

了解了芯片的功能后,如果想繼續深入研究,就需要掌握固件逆向的技能。這是汽車黑客必須掌握的前置技能之一。如果讀者已經掌握了該技能,可以跳過本節。本節知識點如圖11-12所示。

圖11-12 固件逆向的知識點

為何需要此項技能?因為對于攻擊者來說,汽車是一個黑盒產品。在做完一些通用的基礎黑盒測試后,攻擊者勢必要了解車載系統具體的代碼實現,才能進一步發現更多漏洞,比如一些協議、功能的具體實現等都需要通過固件逆向來完成。

1.固件分類

固件是車輛控制器的軟件。不同固件的復雜度不同,從MCU的Bare Metal(裸機)固件,到用于智能座艙、自動駕駛等更復雜模塊的基于微處理器的成熟操作系統,如Linux、Android、QNX等。逆向是幫助我們對固件進行進一步分析的重要步驟,在本節中,我們將討論如何使用各種工具對固件進行逆向工程。讓我們先來看看什么是Bare Metal固件。

(1)Bare Metal固件

根據車輛ECU的功能選擇技術棧。如果功能單一、不需要UI交互、不涉及復雜網絡協議,則使用裸機(Bare Metal)固件,例如電池管理、車身控制、底盤管理等模塊。那么什么是Bare Metal固件呢?簡單來說,這類固件可以直接與硬件交互,不涉及驅動程序或內核。現在車內的Bare Metal通常都是基于Autosar CP實現的標準嵌入式系統。Bare Metal不會運行太多復雜任務,它的任務通常不超過3或4個,被安排在特定的條件下運行。Autosar供應商為這些功能提供了SDK,并提供了生命周期管理方法,使得這些程序員編寫的功能在循環中運行。

基本的Bare Metal固件都是用C語言編寫的,所以內存攻擊也適用于這些固件,例如利用緩沖區溢出相關漏洞。這些ECU通常會使用CAN或其他總線與其他設備進行通信,因此可能會存在通信協議漏洞,例如不正確的數據包處理、密鑰泄露、緩沖區溢出等。而發現這些漏洞,就需要固件逆向工程了。

首先,Bare Metal固件就是一個二進制文件,它的逆向與Windows EXE和Linux ELF文件不同,因為它沒有預定義的文件結構。對于Bare Metal二進制代碼,我們需要了解芯片手冊,在反匯編工具(例如IDA、Ghidra等)中創建內存映射,以進行適當的反匯編。內存映射可以幫助我們了解MCU與哪些GPIO及其他外圍設備交互,這些信息將有助于我們了解ECU的功能。

(2)成熟的操作系統固件

現代智能汽車的功能越來越復雜,例如Wi-Fi連接、藍牙連接,以及娛樂、會議、防火墻等功能。要實現所有這些功能,需要一個成熟的操作系統來支持。

嵌入式系統有許多不同的操作系統選項,如Linux、Windows CE、Cisco IOS、Symbian、Android、VxWorks等。其中一些是專用的,如用于路由器的Cisco IOS,其他大多數則更加通用。在嵌入式系統產品中,最受歡迎的操作系統是Linux。這有很多原因,首先它是開源的、靈活的,最重要的是它是免費的。你可以在周圍找到許多使用Linux的設備,例如互聯網路由器、信息娛樂系統等。

這類固件通常至少包含3個組件:引導加載程序(BootLoader)、內核和文件系統。引導加載程序是用于加載操作系統、內核并傳遞各種信息需求的軟件。一旦引導加載程序執行完畢,內核就會接管,并啟動其他用戶應用程序,以便最終用戶可以使用操作系統。這通常涉及在后臺啟動各種應用程序和服務,一旦所有這些步驟都完成了,用戶就可以與系統交互了。此外,所有用戶應用程序和應用程序數據都存儲在文件系統上。

2.固件解包

提取固件的方法在前文已經介紹過了?,F在我們已經拿到了固件,接下來的步驟就是對固件進行解包,以便我們使用逆向工具進行分析。我們需要從Flash中提取固件并進行分解。

(1)清除OOB

在分析從Flash中提取的固件時,需要進行預處理。Out-Of-Band(OOB)“空閑”區塊被插入到每頁數據或者每個數據塊的末端。這些空白的存儲區塊被主控用于跟蹤壞塊、擦除計數等。因此,當從整塊芯片提取原始數據時,這些空白區塊也會被一并提取。這意味著我們需要將所有這些空閑區塊剔除,才能從芯片的固件中獲得連續的真實文件。

如圖11-13所示,有兩種常見的存儲數據方式。一種方式是每頁大小為2112字節,其中512字節為數據區,16字節為OOB。另一種方式是首先存儲4個512字節的數據區,其對應的每個16字節的OOB在頁面尾部按順序跟隨。因此,我們可以編寫一個腳本,將每個2048字節的頁面中后面64字節的OOB數據刪除,腳本如下。

圖11-13 Flash芯片的OOB

(2)解包固件

Binwalk是最流行的固件解包工具之一,它試圖從任何二進制BLOB中提取二進制文件。它通過搜索許多常見的二進制文件格式(如ZIP、TAR、EXE、ELF等)的簽名來實現這一點。Binwalk具有一個二進制頭簽名數據庫,簽名匹配是針對該數據庫進行的。使用該工具的主要目的是提取嵌入在固件二進制文件中的文件系統,如Squashfs、yaffs2、Cramfs、extfs、jffs2等。文件系統包含將在設備上運行的所有應用程序代碼。該工具還有許多參數,我們可以調整這些參數以便更好地進行提取,比如使用binwalk-eM<filename>命令進行迭代解包,如圖11-14所示。

圖11-14 使用binwalk-eM<filename>命令進行迭代解包

更多使用方法請參考https://github.com/ReFirmLabs/binwalk/wiki/Usage。

(3)特殊文件系統解包

如果Binwalk無法提取相應的文件,則首先需要判斷該固件是否包含文件系統。如果它是一個Bare Metal系統,則可以直接使用IDA等工具進行逆向分析。如果它包含文件系統,就需要確定它使用的是哪種文件系統。可以根據特定文件系統的定義編寫自己的解包工具,或者尋找第三方工具來解包。以下是一些常用于解包QNX固件包和Android固件包的工具。

?OS image(IFS)固件:dumpifs。

使用dumpifs解包IFS固件,如下所示。

?Flash filesystem image(EFS)固件:dumpefs。

使用dumpefs解包EFS固件,如下所示。

?system.img和vendor.img固件。

使用simg2img解包system固件,如下所示。

?boot.img固件。

使用工具(https://github.com/osm0sis/mkbootimg)解包boot固件,如下所示。

?ramdisk固件。

解包ramdisk固件,如下所示。

3.Bare Metal固件逆向

在逆向階段,Bare Metal固件的逆向比較困難,因為它使用的指令集特殊,沒有固定的文件格式,因此我們需要手動設置基地址、分配段等。而使用富操作系統的固件相對來說容易一些,因為這些系統的程序都有標準的文件格式,如ELF格式,其中定義了基地址、指令集、符號等各種信息。通常,類似IDA這樣的工具都會很好地支持這些格式。

因此,本節將主要介紹Bare Metal固件的逆向方法,而不再介紹使用富操作系統的固件的逆向方法。

(1)指令集識別

只要知道芯片型號,就可以知道指令集。此外,Binwalk的參數-A可以自動識別指令集。如果Binwalk識別不出來,則可以嘗試使用IDA進行窮舉,因為常見的指令集并不多,例如ARM、PowerPC、Tricore、MIPS等。圖11-15展示了IDA選擇指令集的界面。

圖11-15 IDA選擇指令集界面

詳細的IDA支持指令集列表請參考https://hex-rays.com/products/ida/processors/。

(2)獲取固件基地址

Bare Metal固件是一個沒有頭格式的純bin文件,因此固件中不包含基地址信息。所以,在進行逆向時,我們需要手動指定基地址。筆者根據個人經驗,提供以下幾種方法。

1)在有芯片手冊的情況下可以查看DataSheet來確定基地址,如圖11-16所示,0x80000000是基地址。

2)在沒有手冊的情況下可以通過一些工具獲取,比如rbasefind、basefind.py、binbloom。筆者最推薦的是binbloom,它的原理如下。

?利用熵值來確定代碼段和數據段。

?收集固件中數據段的興趣點(比如字符串、數組)。

?收集固件代碼段中對興趣點的指針引用,并生成候選基址列表。

?對每個候選基址列表所包含的有效指針數量進行排序,最高的那個可能就是基地址。

圖11-16 根據芯片手冊獲取基地址

3)switch定位法。該方法主要是先找到switch的跳轉指令,然后看switch指令的跳轉表地址,再通過該地址獲取基地址。如圖11-17所示,跳轉表內的0x2XXX都是函數地址,它減去文件的偏移即基地址。

圖11-17 switch跳轉表

(3)固件符號恢復

從Flash提取的Bare Metal固件是一個純bin文件,它沒有調試符號,我們通過反編譯工具所看到的都是一系列沒有名字的函數和變量,如圖11-18所示。

圖11-18 沒有符號的固件

因此,我們通常會想盡一切手段來恢復一些符號,常見的手段有以下幾種。

1)log函數恢復法。這是一種常用的逆向方法。在固件中通常都會存在輸出信息的函數,比如log和print函數,這些函數在輸出時通常會帶上函數名,這些函數名也是存在于固件中的。因此,我們可以定位到log函數,對它的所有引用進行搜索,在每個引用處檢查log函數所輸出的函數名,并將其作為引用log函數的未命名函數的名字。

下面是一個用于在IDA中通過log函數恢復函數名的腳本。

2)BSP(Board Support Package)重編譯Diff法。如果我們恰好擁有與該芯片固件相對應的BSP軟件包,就可以編譯一個包含基礎庫的演示程序。例如,如果目標芯片是TICC2642,就可以使用TI官方提供的IDE(https://www.ti.com/tool/SMARTRFTM-STUDIO)編譯一個演示程序。由于我們自己編譯的程序帶有符號,因此可以采用Diff法,即對比兩個固件相似的函數,并對BSP函數名進行修復。如圖11-19所示,使用了bindiff二進制對比工具恢復符號。左側是原始的固件,沒有函數名稱;右側是我們編譯的BSP固件,包含符號。將它們進行對比后,我們可以找到相似的函數,并恢復左側函數的名稱。

圖11-19 使用bindiff恢復符號

3)CMSIS-SVD符號恢復法。該方法主要用于修復固件訪問外設寄存器的符號。對于Bare Metal固件,許多外設寄存器都是以內存地址的形式進行訪問的。因此,在進行逆向工程時需要查閱芯片手冊并逐個匹配寄存器地址及定義寄存器名稱,這會帶來很高的人力成本。為了減輕這一負擔,可以使用SVD(System View Description)文件來加速這個過程。SVD是一種描述文件,IDA等工具都支持該文件,如圖11-20所示。

圖11-20 在IDA上使用SVD文件

CMSIS-SVD規范描述了基于ARM Cortex-M處理器的微控制器所包含的系統信息,特別是芯片外設的內存映射寄存器。SVD文件中有著與芯片手冊相同的詳細信息,包括了外設的高級功能描述,以及內存映射寄存器中單個位字段的定義和用途等。我們可以在https://github.com/posborne/cmsis-svd/tree/master/data上獲取相應的SVD文件。

經過對SVD文件的解析,如圖11-21所示,可以看到固件中的寄存器名稱。

圖11-21 經過SVD恢復符號后的結果

(4)固件代碼定位

現在,我們已經完成了對固件的初步處理,可以開始逆向工程的操作了。Linux等成熟操作系統的固件逆向工程比較容易,因為它具有標準的庫函數、系統調用等,并且具有動態鏈接機制(例如ELF),會將各個功能劃分到不同的文件中,因此實施起來比較輕松。而Bare Metal固件的逆向工程則相對困難一些,因為它沒有任何標準的API,底層操作僅限于硬件寄存器訪問,并且對一些協議的使用也是自己實現或者通過靜態鏈接完成的,最終編譯后的結果是所有的代碼都集成在一個大的二進制文件中。因此,對于攻擊者來說,如何在Bare Metal的海量無符號匯編代碼中找到感興趣的關鍵代碼尤為重要。接下來,我們將介紹一些在Bare Metal中定位關鍵函數的方法。

①固件解密流程定位

有些固件是被加密的,但它們無論如何都會有一段未加密的代碼,用來解密并加載后續的程序,我們可以稱之為init boot。通常,這段解密代碼是固件頭部的一部分。我們可以通過跟蹤復位中斷函數找到解密某些數據并將其復制到指定位置的代碼,并最終跳轉到該位置以執行代碼。這段代碼具有非常明顯的特征,如下所示。

②常見壓縮算法定位

在之前的討論中,我們提到了固件解密的問題。然而,在固件中還有許多數據或代碼是被壓縮存儲的。因此,如果我們想要還原這些數據或代碼,就需要識別它們使用的壓縮算法。

其中,GZIP是一種常見的壓縮算法,經常被用于固件中。我們通常可以通過識別其magic number(魔數)——0x1F和0x8B來發現該算法,具體示例如下。

除了GZIP外,LZSS也是一種常見的壓縮算法,它并沒有magic number可用于識別。因此,我們需要通過分析其函數邏輯來判斷固件中是否使用了該算法。

一般情況下,LZSS會定義一個WINDOW_SIZE,然后根據壓縮與否決定是否進行解壓。具體實現的示例可以參考圖11-22。

除了軟件解壓外,有些壓縮算法也可以通過硬件實現解壓,這種方式通常是通過識別協處理器寄存器來實現的,例如下面的p15寄存器。

圖11-22 LZSS解壓算法邏輯

③任務定位

在實時操作系統(RTOS)中,任務(Task)通常作為一個運行單元,類似于Linux中的進程。因此,在逆向工程過程中,識別任務尤為重要。通過任務,我們可以分析出該固件包含哪些業務方向,還可以跟隨任務的代碼流程進一步分析其具體邏輯。

通常,任務包含以下幾種屬性。

其中,任務入口地址和任務名稱非常重要,它們提供了關于任務的啟動地址和名稱的信息。如圖11-23所示,這是一個任務結構的數組,包含了多個任務的信息。

圖11-23 RTOS中的任務結構

一旦我們找到了這類結構體,就可以搜索其引用,進而找到創建任務的位置,如圖11-24所示。

圖11-24 在實時操作系統中找到創建任務的位置

④通信代碼定位

在進行固件分析時,確定網絡通信的代碼段非常重要,因為通信與漏洞密切相關。以下是一些常見的通信代碼段定位方法。

1)校驗和定位法。通常,程序會使用某些校驗和算法來驗證數據包的完整性,例如CRC、SHA、ParityCheck、CheckSUM等。其中,奇偶校驗是一種常見的校驗和算法,如下所示,它通過計算數據位中的奇數和偶數個數來實現校驗和。

2)寄存器設置定位法。一些底層的通信協議需要設置相應的硬件寄存器,我們可以通過對比芯片手冊或者查找代碼中設置寄存器的邏輯來判斷當前代碼是否反映了協議的收發過程。例如,I2C協議需要設置I2C相關的寄存器,如下所示。

首先要設置緩沖區大小。

然后將數據寫入data register,即數據寄存器。

最后令寄存器寫入1來啟動該功能,與啟動DMA類似。

(5)固件調試

對于漏洞研究來說,僅使用純靜態逆向是不夠的。必須與動態調試相結合,才能更好地分析代碼邏輯并發現其中的漏洞。我們通常使用的調試方法分為軟件級和芯片級,它們的主要區別在于軟件級調試與系統關聯緊密,而芯片級調試則與芯片型號關聯緊密。除了軟件級調試和芯片級調試之外,還有Patch固件調試。下面是更詳細的介紹。

①軟件級調試

軟件級調試指的是固件的操作系統本身支持調試,例如Linux的GDB。這樣,我們就可以通過軟件的方式對系統內的進程進行調試。首先需要進入目標系統獲取shell,通??梢岳么?、USB口或網絡等獲取shell。獲取shell之后,我們可以直接在目標設備上使用GDB進行調試,也可以開啟GDB Server進行遠程調試。如下是GDB調試進程。

關于更多GDB使用方法,請參考GDB手冊:https://sourceware.org/gdb/current/onlinedocs/gdb.html/。

②芯片級調試

芯片級調試一般指MCU自帶的調試功能,比如JTAG。Bare Metal系統不存在shell和軟件調試機制,因此需要進行芯片級調試,這通常使用JTAG/SWD等方式,例如使用J-Link GDB Server軟件進行調試。如圖11-25所示,用J-Link連接了芯片的JTAG后,打開J-Link GDB Server調試軟件,它會創建一個GDB Server。

圖11-25 J-Link連接JTAG

配置好該軟件后,我們就可以用GDB進行芯片級調試了。

③Patch固件調試

利用Patch固件調試法,通過在想要調試的位置添加hook代碼,并將內容通過GPIO引腳輸出,可以在沒有軟件和芯片級調試的情況下進行調試。首先需要找到一些GPIO引腳,可以通過芯片的DataSheet來查找,如圖11-26所示。

圖11-26 GPIO的寄存器地址

通過以上的DataSheet,我們可以看到一個芯片擁有非常多GPIO引腳,如圖11-27所示,所有標記為GP的引腳都是GPIO引腳。

圖11-27 GPIO引腳

然后我們需要修改固件,在想要查看信息的地方進行掛鉤(hook),將寄存器等信息通過GPIO輸出。下面是一個示例,演示如何在代碼中添加hook跳轉指令。

在hook點跳轉后,需要編寫一段shellcode來完成上述輸出GPIO的過程。這通常需要以下幾個步驟。

?保存所有寄存器。

?禁止中斷。

?將數據輸出到GPIO。

?恢復中斷。

?恢復所有寄存器。

?返回原地址繼續執行。

對應代碼如下所示。

由于GPIO是原始引腳,為了方便地解析數據,我們可以通過GPIO來輸出UART協議的數據。于是需要編寫一段輸出UART數據的GPIO shellcode,如下所示。

接下來,我們需要將已經修改好的固件刷寫回去,并且使用UART轉USB工具將其連接到GPIO口上,如圖11-28所示。

圖11-28 使用UART轉USB工具

接下來運行程序,就可以在電腦上輸出我們想要的內容了,如圖11-29所示,我們得到了程序輸出的數據。

圖11-29 UART數據輸出

至此,Patch固件調試的整個過程結束。如果想要查看其他的信息,重復上面的操作即可。

主站蜘蛛池模板: 从化市| 馆陶县| 祁东县| 宾川县| 巩义市| 牡丹江市| 侯马市| 灵武市| 东莞市| 海林市| 宁南县| 星子县| 周至县| 汤阴县| 阿克| 安顺市| 二手房| 贡觉县| 辽阳市| 凤山市| 鄂尔多斯市| 石渠县| 康马县| 平泉县| 朝阳市| 大连市| 鞍山市| 崇文区| 顺平县| 阿拉善盟| 余江县| 鸡东县| 鹰潭市| 屯留县| 栾城县| 麦盖提县| 碌曲县| 南宁市| 上栗县| 客服| 宜都市|