Introduction
Nowadays, the automobile industry is integrating many new features into connected vehicles where there is increasing interaction between ECUs connected over in-vehicle communication protocols. This enormous flow of data needs to be validated in the context of security to check if any potential vulnerabilities may lead to some compromise of core functionalities. To find those real-time vulnerabilities over CAN UDS protocol, a black box Fuzz Testing approach is developed. The central idea of fuzz testing is development of a fuzzer. It consists of a positive test suit, altered and fuzzing criteria, and generates and feeds invalid inputs to the System Under Test (SUT). The behavior of the SUT is monitored, and anomalies are reported. Fuzz testing can be performed to find vulnerabilities on different interfaces and ECUs. The process involves getting the IDs and sessions from SUT to perform fuzzing. Afterwards the creation of a positive test suit with valid CAN messages is done. Further alteration of valid input request is carried out; altered inputs are provided to the SUT, and its responses are analyzed for crash or halt. By providing invalid input to the system, the behavior of the ECU is observed. The erroneous responses of ECU (vulnerabilities) are found and reported. These requests and responses are stored in a file and analyzed.
Unified Diagnostic Services – ISO 14229
The Unified Diagnostic Services (UDS) standard, also known as [1] ISO-14229, is an application protocol interface used in road vehicles for diagnostics, debugging, and configuration of ECUs. UDS defines how messages should be formatted but not how they should be implemented (although the standard suggests some good practices); that’s why it is an interface. Figure 1 shows the structure and types of diagnostic messages. The UDS client is usually a tester unit meant to be connected to a vehicle diagnostic port. The UDS server is usually a device or “Name of ECU” Electronic Control Unit (ECU) within the vehicle that is connected to the CAN bus (accessible by the diagnostic port).
Each functionality of the standard is grouped within the concept of a service. A service is a type of request that has some parameters. Here are some examples of how functionalities are grouped within service identifiers:
- ECU Reset – 0x11
- Diagnostic Session Control – 0x10
- Tester Present – 0x3E
- Read Data by identifier – 0x22
The security level is a status that the client gains by unlocking features within the server by providing a security key. UDS is designed to allow up to 64 security levels that are, in the end, Boolean flags set in the server. These security levels, and what they unlock, are not defined by UDS but will be by the ECU manufacturer. A security level can unlock a whole service, a sub-function or access to a specific value. For instance, writing the Vehicle Identification Number (VIN) may require a specific security level that is different from what is needed to write the maximum speed or override the vehicle IOs.
Unlocking security levels is not allowed in the default session. To gain some privileges, the client must first switch to a non-default session that enables the SecurityAccess service. Only then may the client execute the handshake that will unlock the wanted feature. Usually, when privileges are gained, they will expire after a short period of time defined by the ECU manufacturer. A keep-alive message will keep the security level unlocked and the session active; these keep-alive messages are sent with service TesterPresent.
The payload that must be sent to unlock a security level is not defined by UDS; UDS defines how to proceed with the key exchange. This process consists of 2 exchanges of request/response between the client and the server. It goes as follows:
First, the client requests for a seed to unlock a specific security level (identified by a number). This seed is usually a random value that the client must use in order to compute the key. It is meant to prevent someone from recording the CAN bus message exchange and then gaining privileges by blindly sending what was recorded. In cryptography terms, the seed is a nonce used to avoid replay attacks.
Once the client gets the seed, it must compute a key using an algorithm that is defined by the ECU manufacturer and known by the server.
The client then sends the key to the server, the server verifies it and, if it matches the server’s value, the security level is unlocked, and a positive message is responded to the client.
The security algorithm can be any algorithm. The lack of algorithm definition in the UDS standard leaves some room for good security design but also for poor design – it’s up to the manufacturer. Yes, some manufacturers implement security through obscurity, while some others will go for a more robust pre-shared key scheme.
Process Flow
The aim of this experiment was to generalize the fuzzer algorithm such that it can be used for all ECUs using UDS over CAN according to UDS protocol [1] . As we are performing black box fuzz testing, we gained a basic understanding of the system. In the reconnaissance phase, we had undertaken the task of system understanding. This was followed by generating a positive test suite based on the results of the reconnaissance phase. An alteration was implemented, and outputs were classified based on a set of criteria. We further explain each phase of fuzz testing in detail. Figure 2 presents a Fuzz Testing process.
System under Test
The process started by identifying the UDS over CAN port/ OBD-II port and proceed with a hardware setup. For the hardware set up, we supplied the correct voltage, connected the SUT with our laptop using a USB 2 CAN protocol converter. For the purpose of setting criteria, monitoring, altering, and analyzing the packets, we have developed CAPL scripts.
Reconnaissance
It is very important to find the diagnostic arbitration Id in order carry out fuzz testing successfully. Identifying arbitration Id is an important step in communicating with the ECU via diagnostics over CAN. We developed a script that identified the arbitration id by developing a CAPL script. The CANoe-CAPL script to play with the 8 byte data field of the CAN frame. We sequentially alternate the arbitration id field up to 11 bits (for standard CAN frame), keeping other data fields constant. Similarly, identification of which services have been implemented on the ECUs and the service Ids and the sub-function Ids is carried out.
Positive Test Case Generation and defining fuzz criteria
This step involves generating valid UDS requests. For this purpose, we had to study the UDS protocol standard [1] and UDS Over CAN standard [2] . It defines application layer Unified Diagnostic Services requirements. We studied this ISO and generated a positive test suit. The positive test suite is automatically generated by the fuzzer. The algorithm automatically generates a positive test suite which is used to observe the behavior of the ECU and define fuzzing criteria.
Systematic alteration in CAN Packets and related analysis
Mutation-based fuzz testing is a very effective approach to improve the security and reliability of protocol implementations. The alteration-based fuzzer, works on valid data and applies random changes to it. That technique can reach deep into the message processing at the target. Alteration of the valid input request is carried out. Altered inputs are provided to the SUT, and SUT’s responses are analyzed for crash or halt. By providing invalid input to the system, the behavior of the ECU is observed. The erroneous responses of ECU (vulnerabilities) are found and reported. These requests and responses are stored in a file and analyzed. During analysis, a generated list of vulnerable messages is highlighted.
Alteration of a message length byte, sub-function byte without and without SPR-bit set, and data length code (DLC) has been performed. Alteration for services without sub-function also have been performed. This process is done for services in both default and non-default sessions. This is because some services are implemented in default sessions, while some are implemented in non-default sessions.
Experimental Set-up
The setup consists of the system under test. Figure 3 shows an experimental setup for Fuzz Testing. There fuzz testing on several third-party ECUs have been performed. The SUT is connected to the Vector CAN Interface. This is connected to our PC, which acts as a tester. The fuzzer scripts are run on CANoe-CAPL on the PC.
Conclusion
At the end of the Fuzz Testing process, a list of vulnerabilities is generated, which are responses that are neither negative nor positive according to [1] ISO 14229-1. This is achieved by developing data analysis-based algorithms for the report module. The algorithm applies data analysis techniques on positive test suite and ECU response for identifying anomalies that are then reported in an excel sheet. All the valid responses are also logged, and the anomalies are highlighted. Figure 4 shows the anomalies highlighted in yellow. The report consists of arbitration id, sessions, mutated payload and DLC, and the result.