隨著感測器技術、無線通訊技術的迅速發展,越來越多物聯網產品滲透進我們生活的方方面面。
但無處不在的物聯網裝置也可能成為無所不在的安全隱患。
其中,裝置中晶片韌體的安全性是最不容忽視的問題之一。晶片韌體相當於是裝置內部儲存的裝置“驅動程式”,任何作業系統都要通過韌體才能按照標準的裝置驅動實現特定的執行動作。因此晶片韌體的安全與否,直接決定了作業系統能否正常執行。
記憶體保護晶片作為守衛所有裝置資料和安全的最後一道防線,應當引起所有安全工程師和開發者的高度重視。
下面就讓我們來回顧看雪2020第四屆安全開發者峰會上《敲開晶片記憶體保護的最後一扇“門”》的精彩內容。
演講嘉賓
付鵬飛,阿里雲安全IoT平臺高階安全工程師,主要負責阿里雲IoT平臺億萬級裝置連線雲平臺的安全。曾任職知道創宇,聯想全球安全實驗室的安全研究員主要方向為IoT安全,硬體安全。
演講內容
以下為速記全文:
大家下午好,我是來自阿里雲IoT安全的付鵬飛,今天帶來的議題是《敲開晶片記憶體保護的最後一扇“門”》,主要是針對於開啟讀保護後,晶片的一個防護突破吧。
自我介紹這塊主持人已經說了,我個人平時比較喜歡DIY硬體,議題中也會提到很多自己設計的工具。對於這些工具,我是有開源的想法的,現在還在走流程,最後會開源給大家,讓大家一起使用。
今天議題主要會講四個方面。第一部分是常見晶片韌體的提取,主要會介紹EEPROM、Flash之類的常規記憶體晶片的正常提取,還會介紹一下MCU和SOC的基本架構。第二部分是晶片記憶體保護攻擊方法,主要是通過晶片Flash呼叫的過程,根據各個過程中暴露出來的弱點對其攻擊方法進行描述。第三部分為大家介紹一個比較低成本的側通道攻擊方案,還有一些我自己設計的工具。第四部分是晶片記憶體防護方案,主要會說一下市面上比較常見的幾種方案。
一.常見晶片韌體提取
第一個就是常見記憶體晶片的韌體提取,這張表主要是把現在常見的幾種晶片的提取過程和提取工具都列了一下。其中,EEPROM和Flash都有常見的提取工具。而MCU和SOC之間,當它沒有開始讀保護的時候,也有一些特定的程式設計器讓大家可以把韌體提取出來。
今天主要給大家講的就是在開啟讀保護的情況下,如何讀取MCU和SOC這兩類晶片的方法。
這是我自己設計的一個工具,主要是適配樹莓派和一些開源軟體。它主要會覆蓋硬體協議UART、I2C、JATG、SPI等,使用這些硬體協議的晶片都可以用這個工具去做一個記憶體的提取。
這是現階段比較常見的MCU主要架構,大家可以看到它的整個架構都是以匯流排控制為基礎去控制各個資源單位的。黃色部分就是一個整體Flash呼叫過程,主要是通過SWD或JTAG進行核心呼叫,核心通過地址匯流排和資料匯流排,進行匯流排的一個呼叫,匯流排再去呼叫整個flash。這就是一個基本的過程。
這是SOC的主要架構。SOC的本質實際上就是在MCU的周圍有一些特定場景的設計,主要的應用場景來自於藍芽和Wifi晶片。現在市面上比較常見的整合晶片一般都是SOC架構的。
MCU和SOC記憶體保護的主要方式是配置字加密,主要是從記憶體中選擇一個欄位,通過配置這個欄位起到記憶體保護的作用。這個欄位主要的功能會禁止我們除錯,也會禁止除Flash正常執行程式外的其他Flash操作,並關閉所有非正常執行的Flash指令。
二.晶片記憶體保護攻擊方法
在第二部分我會重點給大家說明一下我們如何繞過讀保護,在晶片整個Flash呼叫過程中存在哪些問題,以及我們可以用哪些方法把Flash裡面的資訊提取出來。
整個Flash的呼叫過程,主要分成三個方面,除錯介面、資料匯流排和匯流排控制。
第一方面除錯介面這塊,我們用到的主要方法是通過除錯匯流排的仲裁利用。關鍵除錯介面資訊主要是針對於SWD、JTAG除錯匯流排的一個問題。
這是SWD匯流排的基本架構,大家可以看到,在DAP匯流排中會有三條匯流排去對核心進行呼叫,進行呼叫的時候主要是對JTAG和記憶體的呼叫。在呼叫的過程中,如果記憶體是第一個觸發呼叫狀態的話,會從記憶體中拉取部分記憶體資料出來,所以我們主要是要觀察針對於除錯介面的監控,並判斷晶片啟動之後,連線協議連進去之後要幹什麼,是訪問記憶體還是要進行除錯。
這是我針對於此設計的一個工具。這個是硬體工具,主要相容開源的J-Link最新版V9,還覆蓋JTAG、SWD等晶片匯流排的除錯,並可以進行SWD等協議的自主開發和除錯。
自主開發這一塊,我們最需要注意的幾個點是,首先要列印詳細的報錯日誌。因為在詳細的報錯日誌中,我們發現有一款晶片在進行除錯的時候,晶片啟動並訪問記憶體的時候,它會從記憶體裡面攜帶出一部分記憶體的資料出來,利用這個就可以不斷從記憶體中調取資料,不斷觸發裝置發生中斷。
其次,我們還要修改SWD初始化狀態。因為只有修改初始化狀態才能改變它仲裁的規則還有讀取系統的配置,能幫助我們更好地去下斷點。
然後,還要注意Flash的鎖定提前觸發,這主要是為了監控即時匯流排的仲裁。每次要保證匯流排訪問記憶體是第一個觸達的,就可以把整個思路利用起來。我們重啟裝置之後,會進行一個除錯協議的初始化,在協議初始化的時候,保證每次匯流排都是率先去訪問記憶體的。此時它就會把記憶體的一段資料帶出來,不斷迴圈的過程就會把整個Flash裡面的記憶體資料都攜帶出來。
第二方面主要是針對資料匯流排這一塊。我們的核心在訪問匯流排控制這塊主要是地址匯流排和資料匯流排這兩部分。
但是有些晶片在設計初期就缺失了一部分的協議控制。比如說這一塊,我們看到這一塊晶片的整個系統設計。大家可以看到在匯流排控制這塊,只有資料主線到達了匯流排控制,地址匯流排是可以直接訪問Flash的,這就造成了我們訪問Flash的時候有兩種途徑的存在。
配置自加密就是讀保護作用在匯流排控制這個區域會把地址匯流排的訪問路徑開啟。我們就可以利用這個從核心到地址匯流排,再到Flash控制器再到Flash,把整個Flash一個位元組一個位元組地提取出來。
這是地址匯流排上復位向量的利用。它是一個ARM架構下中斷的向量表,我們每次都可以精準觸發晶片產生中斷,通過PC指證的方式從Flash記憶體裡面把記憶體的資料匯出來。然後,這是整個實現的POC,就是如何去觸發晶片異常的POC。
第三種方式就是匯流排控制這一塊存在的問題。匯流排控制這塊,由於許可權控制不乾淨,會有一些異常的暫存器暴露出來,我們通過去觀察暫存器的狀態,去檢視暫存器數值的變化。具體的方法是這樣的,使用偵錯程式訪問控制許可權,跳到受保護記憶體的一個指令,然後執行該指令。指令會把受保護的資料攜帶到CPU暫存器中,可以用偵錯程式把CPU暫存器裡面的資料讀取出來,每次精準地跳到Flash裡面指定的一個記憶體地址裡,就可以把整個Flash資料一步一步遷移出來。
這是一步一步除錯晶片的過程。主要是我們初始的時候會重置CPU,重置後檢視初始化暫存器的值以後單步執行程式碼,因為每次單步執行,暫存器都會發生變化。我們去對比暫存器的變化,就能檢視到控制許可權不足的暫存器,最後通過這個暫存器把所有的記憶體值反推出來。這是我們實現的一個POC的結果。
需要注意的是,整個Flash的調取過程中,三個關鍵的部分都會存在一定的風險。這種風險的存在主要是因為某些廠商許可權控制不完善,和設計上存在缺陷導致的。那有沒有一種通用的方法去幫我們更簡便地繞過這種讀保護呢?這裡肯定會提到大家經常用到的側通道攻擊。
三.低成本側通道晶片攻擊
側通道攻擊最主要的是尋找攻擊點。在晶片的攻擊點中,大家可以看到,這是晶片Bootloader啟用啟動的一個流程。在它啟動過程中,大家可以看到2、3步會判斷我這個晶片是否啟動了讀保護,判斷是否可以去除錯這個晶片。
整個啟用的過程實際上就是一個硬體初始化的過程,在2、3步的時候,我們是否可以直接從第1步跳到第4步?這樣我們就可以跳過讀保護的判斷,直接進入晶片除錯的過程。
如果把剛才的流程圖反映在實際側通道功耗的攻擊上,可以看到黃色線是晶片復位重啟的過程,綠色的線就是功耗的過程,在我標紅色位置的地方可以看到綠色線有明顯的功耗變化,這是我們的一個注入點,用到的方法主要是VCC注入,學術上叫電壓故障注入,主要的特點是使用超壓或欠壓的方式,讓CPU處在一個短暫的休眠期。
因為超壓和欠壓,整個CPU會執行不正常。在啟動過程中有短暫的執行不正常的話,側通道防護做得不好的晶片會忽略掉這個,並且會按照硬體初始化的狀態繼續往下走,就會存在跳過的風險。而VCC注入的整個過程的時間要控制在百納秒之內,但一般我們都是控制在微秒的。
VCC注入第一個關鍵點是要進行電源域的確認,確認核心的供電方式。核心的供電方式決定於我們注入的點在哪。我們使用晶片本身的供電的話,一般注入不會成功,因為晶片本身供電會有其它資源重啟的過程,而不是說單作用於核心。所以我們確實需要關注一下電源域的確認過程,主要是要收集資料表,確認電源域的情況,特別是核心電源域的情況,確認電源穩壓器引腳,並確定VCC注入點和功率觀察的引腳。
至於我們在攻擊之前要準備的東西的話,主要要準備的是控制器。控制器這塊推薦大家使用FPGA,或者其它的開源硬體也可以,但是要注意的是工作頻率,因為你注入的控制器的工作頻率一定要大於等於被注入的工作頻率。比如說我這個晶片被注入的工作頻率是16兆,我們注入的控制器就要大於等於16兆,我們要比控制的晶片跑得快,只有跑得快才能搶先把錯誤的資訊注入進去。
還有引腳切換非常重要。我剛才說過,我們主要的攻擊途徑就是過壓或欠壓,過壓、欠壓的控制方式就是引腳切換,而且實際上整個的控制核心就是在這一塊,能起到切換電壓的作用。
但是需要特別注意的是千萬不要用晶片本身的引腳直接去切換供電。做過嵌入式開發的都知道,我們是可以用程式碼去控制晶片的高電平或低電平的。那個高電頻或低電頻,它的功率不夠,而且電流非常小,千萬不要用引腳直接去控制,而是要用一個轉換器去轉換,利用穩壓器去供電。還有訊號發生器主要是去誘發晶片注入的過程。而示波器主要是觀察注入的情況。
拋開這些,為什麼說低成本呢?訊號發生器、穩壓器、示波器,這些都可以不要,事實上我們用控制器和引腳切換就可以達到目的。
這是我自己設計的一個注入板,主要的能力是進行VCC的注入分析,也可以進行自主的二次研究,主要覆蓋線性啟動晶片的VCC注入攻擊。我看了一下,市面上佔比比較大的晶片都是可以用這種方法的。
這是整個低成本側通道攻擊的架構圖。訊號發生器主要作用是啟動延時,晶片覆蓋之後會觸發訊號發生器,訊號發生器會把觸發的指令發給示波器,示波器再把訊號的結果反饋到注入系統。剛才說了注入系統可以用FPGA,也可以用我們自己設計的都可以,只要是大於等於你被注入的MCU和SOC晶片的工作頻率就可以。
大家可以看到,在這一塊主要的核心在穩壓器。一般我們用的是低壓,就是欠壓的方式,在1.250左右。一般不用過壓的方式,因為容易把晶片燒掉。而PC這一塊主要作用是進行自動化的控制。
大家可以從這張圖看到,當我們真正地發生注入的波形的時候,會看到下面功率的明顯變化。這是一個注入成功的波形,黃色部分發生注入成功的時候,綠色部分功耗的位置會有明顯功耗的變化。
我們在進行自動化控制的時候,最主要的關鍵點在於設定毛刺的延遲和寬度、測試範圍、晶片復位初始化、觸發毛刺的效果,還有就是連線偵錯程式的時候要始終去檢視是否已經可以除錯記憶體了,一旦發現已經可以除錯記憶體了,證明我們已經把讀保護越過了。還有就是在崩潰的時候如何合理的去重置晶片,一般我們會把復位引腳直接拉低,拉低再拉高,對它進行復位。但是這種方式一般效果不會很好,所以我們會直接斷電,斷電之後效果好一些。
上面我介紹了四種方法。我把這四種方法全部整合到一個PCB板上了,它主要是覆蓋了現在市面上常見的一些QFP48和32封裝的晶片,可以進行自動化的分析。剛才提到的是BGA封裝的,BGA封裝的只是我們要把QFP這個封裝的換掉,換成BGA的。這個也是可以覆蓋的,只是多一道程式罷了。還有就是它也支援USB除錯以及晶片韌體的二次開發和修改,主要覆蓋常用的MCU和SOC的晶片。
四.晶片記憶體防護方案
第四部分我介紹一下晶片記憶體防護方案,主要介紹嵌入式開發時比較常用的一些。沒有給大家介紹一些比較成型的產品,是因為這種產品一般都不是開發所設計的,開發還是比較關注於我們如何快速地去做這個事情。
第一個方案針對晶片本身訊號離散的特性。因為我們整個板子上會用到電容器、電阻、二級管這些類比電路、數位電路的器件,一般在不焊接上去的時候,它的訊號是離散的,一旦放在了板子上它的訊號有時候是有規律可尋的,是穩定的,可以通過這種訊號的方式對晶片進行加密。它的優點在於使用簡單、成本低,缺點是場景比較特殊,因為我們需要去找晶片本身具有離散特性的器件。
第二個方案就是針對晶片本身序列號不可篡改。這個序列號本身不可逆且唯一,對序列號的加密方式優點在於沒有成本,缺點在於加密程度不高。
第三種方式是現在大家比較認可的,而且安全程度比較高一點的,就是用硬體邊界的方式進行隔離,加一塊SE在裡面,主要對資料流和業務流進行一個隔離。這種方式主要的優點是可以實現以晶片為邊界的硬體隔離,缺點就是成本太高。
最後,這是我們一個還在不斷優化的方案,主要是使用低成本序列號的加密驗證方式,去對不同的資料和業務流程進行分塊的軟體隔離方法進行一個加密,最後再進行MCU的驗證。這樣既能節約成本,又能提高加密強度,還能實現軟體之間的相互隔離。
那麼我今天的演講就到這裡,謝謝大家!
本屆峰會議題回顧
2020看雪SDC議題回顧 | 逃逸IE瀏覽器沙箱:在野0Day漏洞利用復現
2020 看雪SDC議題回顧 | LightSpy:Mobile間諜軟體的狩獵和剖析
2020 看雪SDC議題回顧 | DexVmp最新進化:流式編碼
2020 看雪SDC議題回顧 | Android WebView安全攻防指南2020
2020 看雪SDC議題回顧 | 生物探針技術研究與應用
2020 看雪SDC議題回顧 | 世界知名工控廠商密碼保護機制突破之旅
……
更多議題回顧盡情期待!!
注意:關注看雪學院公眾號(ikanxue)回覆“SDC”,即可獲得本次峰會演講ppt!
其他議題演講PPT,經講師同意後會陸續放出,請大家持續關注看雪論壇及看雪學院公眾號!
- End -