UDS Scanning#
Security Access and System States#
System States#
UDS |
GMLAN |
||
---|---|---|---|
|
DiagnosticSessionControl |
|
InitiateDiagnosticOperation |
|
ECUReset |
||
|
SecurityAccess |
|
SecurityAccess |
|
CommunicationControl |
|
DisableNormalCommunication |
|
RoutineControl |
||
|
RequestDownload |
||
|
TesterPresent |
|
TesterPresent |
|
ProgrammingMode |
Security Access#
A categorization of reverse-engineered security access functions delivered the following groups:
Simple Arithmetic Operations This group contains security access algorithms based on single arithmetic operations such as XOR, NOT, or ADD with a fixed value. Examples are given by the work of Dürrwang et al. and Nie et al. [Lab16, DBR+18]:
\[key = \neg seed\]Mathematical Operations The security access mechanism of one analyzed OEM relies on complex mathematical operations. To obtain a key for this ECU, one needs to know five different numeric values which act as a shared secret. With this secret, a random seed has to be multiplied in different ways to obtain a valid key. An example operation for this group can be the following: $\(key = (seed * secret1 + secret2) \bigoplus (seed * secret3 + secret4) \bigoplus secret5\)$
Proprietary XOR-Shift-Loop Security access algorithms for this group were analyzed in-depth by Van den Herrewegen et al. [VdHG18]. Their publication provides examples as well as a cryptographic analysis. TODO VWAG SA2 algorithm
Cryptographic Operations One analyzed OEM relies on cryptographic authentication mechanisms for its security access algorithms. The following equation shows an example:
\[key = RSA_{sign}(MD5(seed~|~salt), {private\_key})\]

Fig. 56 Automatically reverse-engineered system state graph of an ECU. Reset through power cycle is represented by the red dotted lines. Blue lines indicate Security Access (SA) authentication. Diagnostic Session Control (DSC) transitions are shown by the green lines. TP stands for Tester Present.#
Extracting information from log files#
Ecu utility allows to analyze log files
verbose
prints packet and statelogging
creates a log with timestamps and packetsstore_supported_responses
creates a list of all answered responses. This can be used to create an EcuAnsweringMachine on the fly.
from scapy.all import *
load_contrib("isotp")
load_contrib("automotive.uds")
load_contrib("automotive.uds_ecu_states")
load_contrib("automotive.uds_logging")
load_contrib("automotive.ecu")
with PcapReader("ecu_trace.pcap.gz") as sock:
udsmsgs = sniff(session=ISOTPSession, session_kwargs={"use_ext_addr":False, "basecls":UDS}, count=50, opened_socket=sock)
ecu = Ecu(store_supported_responses=False)
ecu.update(udsmsgs)
<UDS service=DiagnosticSessionControl |<UDS_DSC diagnosticSessionType=extendedDiagnosticSession |>>
<UDS service=DiagnosticSessionControlPositiveResponse |<UDS_DSCPR diagnosticSessionType=extendedDiagnosticSession sessionParameterRecord='\x002\x01\\xf4' |>>
session3 <UDS service=RoutineControl |<UDS_RC routineControlType=startRoutine routineIdentifier=0x203 |>>
session3 <UDS service=RoutineControlPositiveResponse |<UDS_RCPR routineControlType=startRoutine routineIdentifier=0x203 |>>
session3 <UDS service=TesterPresent |<UDS_TP subFunction=128 |>>
session3 <UDS service=ControlDTCSetting |<UDS_CDTCS DTCSettingType=130 DTCSettingControlOptionRecord='\\xff\\xff\\xff' |>>
session3 <UDS service=NegativeResponse |<UDS_NR requestServiceId=ControlDTCSetting negativeResponseCode=requestCorrectlyReceived-ResponsePending |>>
session3 <UDS service=ControlDTCSettingPositiveResponse |<UDS_CDTCSPR DTCSettingType=off |>>
session3 <UDS service=CommunicationControl |<UDS_CC controlType=129 communicationType0=ISOSAEReserved communicationType1=0 communicationType2=Disable/Enable specific subnet |>>
session3 <UDS service=TesterPresent |<UDS_TP subFunction=128 |>>
session3 <UDS service=DiagnosticSessionControl |<UDS_DSC diagnosticSessionType=programmingSession |>>
session3 <UDS service=NegativeResponse |<UDS_NR requestServiceId=DiagnosticSessionControl negativeResponseCode=requestCorrectlyReceived-ResponsePending |>>
session3 <UDS service=DiagnosticSessionControlPositiveResponse |<UDS_DSCPR diagnosticSessionType=programmingSession sessionParameterRecord='\x002\x01\\xf4' |>>
session2 <UDS service=SecurityAccess |<UDS_SA securityAccessType=17 |>>
session2 <UDS service=SecurityAccessPositiveResponse |<UDS_SAPR securityAccessType=17 securitySeed='\x00\x03.i' |>>
session2 <UDS service=SecurityAccess |<UDS_SA securityAccessType=18 securityKey='Բf\\x82' |>>
session2 <UDS service=SecurityAccessPositiveResponse |<UDS_SAPR securityAccessType=18 |>>
security_level18session2 <UDS |>
security_level18session2 <UDS service=WriteDataByIdentifier |<UDS_WDBI dataIdentifier=0xf15a |<Raw load='\x18\x10\x08\x00\x00\x01\x00\x16/' |>>>
security_level18session2 <UDS |>
security_level18session2 <UDS service=WriteDataByIdentifierPositiveResponse |<UDS_WDBIPR dataIdentifier=0xf15a |>>
security_level18session2 <UDS |>
security_level18session2 <UDS service=RequestDownload |<UDS_RD dataFormatIdentifier=noCompressionNoEncryption memorySizeLen=4 memoryAddressLen=1 memoryAddress1=0xa memorySize4=0x100 |>>
security_level18session2 <UDS service=0x0 |>
security_level18session2 <UDS service=RequestDownloadPositiveResponse |<UDS_RDPR memorySizeLen=2 reserved=0 maxNumberOfBlockLength='\x0f\\xf9' |>>
req_download{'service': 52}security_level18session2 <UDS service=TesterPresent |<UDS_TP subFunction=128 |>>
req_download{'service': 52}security_level18session2 <UDS service=TransferData |<UDS_TD blockSequenceCounter=1 |>>
req_download{'service': 52}security_level18session2 <UDS |>
req_download{'service': 52}security_level18session2 <UDS service=TransferData |<UDS_TD blockSequenceCounter=1 transferRequestParameterRecord='\x19\\xb1B\\xe2\\xael\\xabOik>\\x9c\\xb28#1q\x1ev\\x8fk\\x92\\xe0Y\\xc7\\xd7\\xef\\xf6\x1c0\\xf0P\\xe9\\xb7#\x1e\x01\\xb0/\\xe5\\x82\\xf4=|\\xf3\\xd9\\xdb/\\x9a\\xac\\xea\\xbc"ߣф\\x83\\xad\\xc0\\xbb\\x9b\\xf6\x00#\\xb3sV0\x1c\x1a$-&\\xc1^XkI\\xe1\\xbbS\x14\\xaf@\\xf3a\\xb4\x14\\xab\x17!\x16Yҹ@::O\\xfb\\xcd\x14l\\xd3Œ\\xbe\\xec[\\x828\\xb3\\xfb\n̸(\\x92\x1f8\\x8b\ts\\xb6k>f\\x9d\x00\\x8d\\xf7S1v\\x9egx\x05\\xfa\x12\\xdb\x18Y\\xc0\\x9f\\xf6\\xbf\\xea\x11Z\\xb9\\x93\\x87\\x81`\\xb2\x14\\xfa\\x97D\\xc3\\xd7[\\x81PlN5C\\xa4\x18\\xe9\\xd6XV9\\xf5P)\x11\\xca7\\x9d8\\xd0w\\xf9\\xb0\\xda\\xe5\\x98+:\\x89(\\xd7\\xc7\x1d\\xd9\\xc9\\xeaYe%\\xd4\\xef\\xfd\\x85\x11\\x95g/:"\\x81\\xfe\\xa8\\xde\x19\\xc2:aH\\xf8\\xdcߋS\\xa0\\xd4\\xc0\\xaf\t\x03\\xf3\\x90\x06\\xc5\x0f\\x92g\\xfd3~\\xa6\\x9bK_\\xc6\\xc0\\x90\\x92A;\'' |>>
req_download{'service': 52}security_level18session2 <UDS service=TransferDataPositiveResponse |<UDS_TDPR blockSequenceCounter=1 |>>
req_download{'service': 52}security_level18session2 <UDS service=TesterPresent |<UDS_TP subFunction=128 |>>
req_download{'service': 52}security_level18session2 <UDS service=RequestTransferExit |>
req_download{'service': 52}security_level18session2 <UDS service=RequestTransferExitPositiveResponse |>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS |>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS service=RoutineControl |<UDS_RC routineControlType=startRoutine routineIdentifier=0x202 |<Raw load="t\\xdb\\xf3EW\tBEM\\xc4\\xf6Уh\x11-PqY\\xc5ܨg\\xaaI4;\x13\\xf1+#e\\xa9'x\\xf0\\xe2I<xGt\n\\xc57\x7fmDe\\xf1!\x7f\\x91\\x89\\x83}\x12\x11\\xde\x1aSE\\x91\x0c]\\xcdf\\x80_\\xa9\\xf7+\\xe6u$\\xa5^\\xa3Т\x1a\x0eN\\xde/\x14\x19A\\xa2\x18bx!!\\xac\\xfaC.\\xd2\\xfcƂ\\xee!\\xb4\x1a\\xe1\x16\\x82D\\x82a!\\x8d\\xf5\\x86aJ\\xb9\\xb9\\xb5\\xcc4`m\\xb5V3" |>>>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS service=RoutineControlPositiveResponse |<UDS_RCPR routineControlType=startRoutine routineIdentifier=0x202 |<Raw load='\x00' |>>>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS service=RoutineControl |<UDS_RC routineControlType=startRoutine routineIdentifier=0xff00 |<Raw load='\x01\x05' |>>>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS service=RoutineControlPositiveResponse |<UDS_RCPR routineControlType=startRoutine routineIdentifier=0xff00 |<Raw load='\x00' |>>>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS |>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS service=RequestDownload |<UDS_RD dataFormatIdentifier=noCompressionNoEncryption memorySizeLen=4 memoryAddressLen=1 memoryAddress1=0x5 memorySize4=0x4 |>>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS |>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS service=RequestDownloadPositiveResponse |<UDS_RDPR memorySizeLen=2 reserved=0 maxNumberOfBlockLength='\x0f\\xf9' |>>
download_complete{'service': 52}req_download{'service': 52}security_level18session2 <UDS service=TesterPresent |<UDS_TP subFunction=128 |>>
download_complete{'service': 52}req_download{'service': 52}security_level18session2 <UDS service=TransferData |<UDS_TD blockSequenceCounter=1 transferRequestParameterRecord='0321' |>>
download_complete{'service': 52}req_download{'service': 52}security_level18session2 <UDS service=TransferDataPositiveResponse |<UDS_TDPR blockSequenceCounter=1 |>>
download_complete{'service': 52}req_download{'service': 52}security_level18session2 <UDS service=TesterPresent |<UDS_TP subFunction=128 |>>
download_complete{'service': 52}req_download{'service': 52}security_level18session2 <UDS service=RequestTransferExit |>
download_complete{'service': 52}req_download{'service': 52}security_level18session2 <UDS service=RequestTransferExitPositiveResponse |>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS |>
download_complete{'service': 52}req_downloadsecurity_level18session2 <UDS service=RoutineControl |<UDS_RC routineControlType=startRoutine routineIdentifier=0x202 |<Raw load='\r_Q\x0e\\x9e\\xfd>ꐝf3\\xa680]\\xe0x\\xcd8\\xcat\x1f\\x82s\\x99zk(\x127#\\xb0X\\xa3\\xff\\x83\\xa9DkƵކxT\\xb0.V\\xbb\\xb6\\xaf\\xbe!\\xb9\\xbe\\xef\\xb1\\xcd\r^K\\xa5\\x96\\xf0z\\xe6\x15q\x15)U\\xcdsF\\xffR\\xbc\x0e\\xe5\x1b^\\xf9̋ҩ\\xb4\\xb1\\xd1!\\xf5\\xd6U]\\xccU\x0c\\xbf\\xe5\\xfe\\x81\\x84\\xeau]\\x85\\x8cۄ\x0c\\x87\\xe8\\xe01뉻\\xcae-\\xe4\\xe8\\xe3n\x11p&' |>>>
Attacks on UDS and GMLAN#
UDS |
GMLAN |
Type |
Descriptions and references for the combination of flaw types with UDS/GMLAN services |
---|---|---|---|
|
|
dos-flood |
These commands will change the session of an ECU. This command’s actual impact can reach from no effect in the functionality to the execution of a different firmware or the ECUs bootloader. Miller & Valasek and Nie et al. used this service to disable (DoS) individual ECUs [SN17, MV16]. |
|
dos-flood |
During a reset, an ECU is unavailable. Researchers from Keen Labs were able to trigger this function at any speed of a vehicle. Unavailability of safety-critical ECUs in extreme driving conditions can cause serious dangers [CWZ19]. |
|
|
|
infoleak |
These commands can be used to gather internal information about an ECU. This can be used to obtain static information (VIN, software versions, etc.), dynamic information to understand the internal behavior of an ECU, or even to extract the entire firmware [PC18]. |
|
|
crypt |
Van den Herrewegen et al. and Dürrwang et al. demonstrated impacts of weak cryptographic implementations [DBR+18, VdHG18]. |
pass |
Miller & Valasek revealed many hard-coded cryptographic secrets inside an ECUs firmware [MV13]. |
||
rand |
Nie et al. analyzed weak security access implementations and showed the lack of random seed creation [SN17]. |
||
|
|
dos-flood |
This service grants the total bandwidth of the CAN bus to only one ECU. Attackers can prevent ECUs from communicating, which causes a DoS of the attacked ECU [KoscherCzeskisRoesner+10]. |
|
int-overflow |
his service specification describes two possible use-cases, clearing of non-volatile memory and changing of calibration values [ISOCSecretary12]. Both use-cases can be used to cause program flow corruptions, e. g. integer- or buffer-overflows. |
|
buf |
See above. Identical to int-overflow. |
||
|
|
int-overflow |
Identifiers can be any payload. The protocol specifications are very generic for these commands. If a data-identifier is mapped to numeric values, it might be possible that these values can trigger execution errors, such as integer overflows. |
phys |
Cai et al. demonstrated the manipulation of the driver’s seat position through this service [CWZ19]. |
||
buf |
Payloads can contain complex data, e. g. certificates or ring buffer contents. Increasing data size and complexity leads to more likelihood of security flaws in interpreters and parsers. Additionally, writable memory areas allow attackers to place exploit code into known and defined memory sections. |
||
|
phys |
Miller & Valasek demonstrated the control of a vehicle’s pre-collision system seat belt functionality. This proves the possibility to trigger physical actions through this service [MV13]. |
|
|
dos-flood |
Miller & Valasek identified sub-functions that allow the erase of an ECUs memory. Such an operation would brick an ECU and lead to the entire vehicle’s unavailability [MV16]. |
|
buf |
RoutineControl jobs accept individual payloads with various lengths. The more complex data leads to a higher likelihood of implementation flaws. Cai et al. demonstrated an insecure implementation, combined with a TOCTOU attack, which led to code execution [CWZ19]. |
||
phys |
RoutineControl jobs can be used to control actuators on a vehicle. Miller & Valasek were able to kill a vehicle’s engine [MV13]. Dürrwang et al. showed the deployment of airbags through insecure implementations of RoutineControl jobs [DBR+18]. |
||
infoleak |
The sub-function |
||
|
|
upload |
These commands are intended to initiate a software update. Miller & Valasek and Van den Herrewegen et al. demonstrated arbitrary code execution by abusing this command [MV16, VdHG18]. |
|
infoleak |
This command could be used to leak internal information of an ECU. |
|
|
|
buf |
These commands are part of the update process. An implementation flaw is unlikely; nevertheless, buffer overflow vulnerabilities are potentially possible. |
|
dos-flood |
Allows the modification of communication parameters. Attackers can prevent an ECU from communicating by providing an invalid configuration. |
|
|
phys |
Koscher et al. demonstrated the possibility of triggering physical actions on ECUs [KoscherCzeskisRoesner+10]. |
|
dos-flood |
The GMLAN standard describes the possibility to trigger an ECU reset [GMW18]. |
Scanning#
Scapy contains a powerful scanner library for automotive protocols
UDS_Scanner
orGMLAN_Scanner
are the executors ofTestCases
Enumerators
derive fromTestCases
Every enumerator scans a different UDS or GMLAN service
Since some services generate new states, the specific enumerators evaluate an ECUs response and generate a system state graph.
Example#
from scapy.all import *
conf.contribs['CANSocket'] = {'use-python-can': False}
conf.contribs['ISOTP'] = {'use-can-isotp-kernel-module': True}
from scapy.contrib.isotp import *
from scapy.contrib.automotive.uds_scan import *
sock = ISOTPNativeSocket("can0", tx_id=0x6f1, rx_id=0x610, ext_address=0x10, rx_ext_address=0xf1, basecls=UDS)
s = UDS_Scanner(sock, test_cases=[UDS_ServiceEnumerator])
s.scan(timeout=10)
s.show_testcases()
============================================================
Available services and negative response per state
------------------------------------------------------------
128 requests were sent, 128 answered, 0 unanswered Statistics per state
-------------------+---------+----------+
| all | session1 |
-------------------+---------+----------+
answertime_avg | 0.00077 | 0.00077 |
answertime_avg_nr | 0.00077 | 0.00077 |
answertime_avg_pr | - | - |
answertime_max | 0.0012 | 0.0012 |
answertime_max_nr | 0.0012 | 0.0012 |
answertime_max_pr | - | - |
answertime_min | 0.0007 | 0.0007 |
answertime_min_nr | 0.0007 | 0.0007 |
answertime_min_pr | - | - |
num_answered | 128 | 128 |
num_negative_resps | 128 | 128 |
num_unanswered | 0 | 0 |
-------------------+---------+----------+
128 negative responses were received
These negative response codes were received 0x11 0x13 0x7f
NRC 0x11: serviceNotSupported received 111 times
NRC 0x13: incorrectMessageLengthOrInvalidFormat received 10 times
NRC 0x7f: serviceNotSupportedInActiveSession received 7 times
The following negative response codes are blacklisted:
['generalReject', 'serviceNotSupported']
---------------------------------+-------------------------------------------+
| session1 |
---------------------------------+-------------------------------------------+
0x10: DiagnosticSessionControl | NR: incorrectMessageLengthOrInvalidFormat |
0x11: ECUReset | NR: incorrectMessageLengthOrInvalidFormat |
0x14: ClearDiagnosticInformation | NR: incorrectMessageLengthOrInvalidFormat |
0x19: ReadDTCInformation | NR: incorrectMessageLengthOrInvalidFormat |
0x22: ReadDataByIdentifier | NR: incorrectMessageLengthOrInvalidFormat |
0x27: SecurityAccess | NR: serviceNotSupportedInActiveSession |
0x28: CommunicationControl | NR: serviceNotSupportedInActiveSession |
0x2e: WriteDataByIdentifier | NR: incorrectMessageLengthOrInvalidFormat |
0x31: RoutineControl | NR: incorrectMessageLengthOrInvalidFormat |
0x34: RequestDownload | NR: serviceNotSupportedInActiveSession |
0x35: RequestUpload | NR: serviceNotSupportedInActiveSession |
0x36: TransferData | NR: serviceNotSupportedInActiveSession |
0x37: RequestTransferExit | NR: serviceNotSupportedInActiveSession |
0x3e: TesterPresent | NR: incorrectMessageLengthOrInvalidFormat |
0x85: ControlDTCSetting | NR: serviceNotSupportedInActiveSession |
0x86: ResponseOnEvent | NR: incorrectMessageLengthOrInvalidFormat |
0xbf: 0xbf | NR: incorrectMessageLengthOrInvalidFormat |
---------------------------------+-------------------------------------------+
General Motors Worldwide (GMW). General Motors Local Area Network Enhanced Diagnostic Test Mode Specification. Standard GMW3110, General Motors Worldwide (GMW), 2018.
Zhiqiang Cai, Aohui Wang, and Wenkai Zhang. 0-days & Mitigations: roadways to Exploit and Secure Connected BMW Cars. In BlackHat USA, 1–37. Aug 2019. https://i.blackhat.com/USA-19/Thursday/us-19-Cai-0-Days-And-Mitigations-Roadways-To-Exploit-And-Secure-Connected-BMW-Cars-wp.pdf.
Jürgen Dürrwang, Johannes Braun, Marcel Rumez, Reiner Kriesten, and Alexander Pretschner. Enhancement of Automotive Penetration Testing with Threat Analyses Results. SAE International Journal of Transportation Cybersecurity and Privacy, 1(2):91–112, 11 2018. doi:10.4271/11-01-02-0005.
Tencent Keen Security Lab. Car Hacking Research: Remote Attack Tesla Motors. 2016. https://keenlab.tencent.com/en/2016/09/19/Keen-Security-Lab-of-Tencent-Car-Hacking-Research-Remote-Attack-to-Tesla-Cars/.
Dr. Charlie Miller and Chris Valasek. Adventures in Automotive Networks and Control Units. DEF CON 21 Hacking Conference. Las Vegas, NV: DEF CON, August 2013. http://illmatics.com/car_hacking.pdf.
Dr. Charlie Miller and Chris Valasek. Advanced can injection techniques for vehicle networks. In BlackHat USA. Aug 2016. http://illmatics.com/can%20message%20injection.pdf.
Ramiro Pareja and Santiago Cordoba. Fault injection on automotive diagnostic protocols. 2018. https://www.riscure.com/uploads/2018/06/Riscure_Whitepaper_Fault_injection_on_automotive_diagnostic_protocols.pdf.
Yuefeng Du Sen Nie, Ling Liu. FREE-FALL: HACKING TESLA FROM WIRELESS TO CAN BUS. 2017. https://www.blackhat.com/docs/us-17/thursday/us-17-Nie-Free-Fall-Hacking-Tesla-From-Wireless-To-CAN-Bus-wp.pdf.
Jan Van den Herrewegen and Flavio D. Garcia. Beneath the Bonnet: A Breakdown of Diagnostic Security, pages 305–324. Volume 11098 of Lecture Notes in Computer Science. Springer International Publishing, 2018. URL: http://link.springer.com/10.1007/978-3-319-99073-6_15, doi:10.1007/978-3-319-99073-6_15.
ISO Central Secretary. Road vehicles – Unified diagnostic services (UDS) – Part 3: Unified diagnostic services on CAN implementation (UDSonCAN). Standard ISO 14229-3:2012, International Organization for Standardization, Geneva, CH, 2012. URL: https://www.iso.org/standard/55284.html.
K. Koscher, A. Czeskis, F. Roesner, S. Patel, T. Kohno, S. Checkoway, D. McCoy, B. Kantor, D. Anderson, H. Shacham, and S. Savage. Experimental Security Analysis of a Modern Automobile. In 2010 IEEE Symposium on Security and Privacy, volume, 447–462. May 2010. doi:10.1109/SP.2010.34.