Hardware Security
Basics and Components of Hardware
Electrical Fundamentals
Voltage
- Difference in electric potential between two points
- Could be thought of as water pressure in two locations, where water will flow from high to low pressure areas
- Pushes current through a circuit, measured in Volts (V)
- Electrons flow through the device from the negative to the positive
- This is how data is communicated, via differences in voltage
- For example, a 1 could be 3.3V and a 0 could be 0V
Ground
- Very important, acts as an unmoving reference
- Typically the lowest voltage line in a circuit (with exceptions for things like audio processing and motor controls)
- If something is 5V, it’s 5V with respect to ground
- This can differ between devices, so we need to connect the ground of our tools and devices so they have the same reference point
- Look for metal on a board, that’ll usually be ground, or sometimes USB connector
Current
- Flow of electrical energy from one point to another
- Like the amount of water flowing through a pipe
- Measured in Amperes (A or I)
Resistance
- Opposition to the flow of electric current
- Like the size of the pipe which water flows through
- Measured in Ohms (Ω)
Ohm’s Law
Power
- The rate at which energy is transferred
- Total flow rate of water out of a pipe
- Measured in Watts (W), calculated as P = V x I
Safety
- Always power off devices before connecting/disconnecting components
- Make sure to check wires and components for damage
- Work away from water
- Don’t short circuits (connect voltage and ground)
- Connect power in proper orientation (check polarity markings)
- Don’t connect to wall outlets/high voltage sources
- Don’t touch exposed conductors
- Make sure to match voltage levels of tools and items
Component Identification
Diodes
- A type of semi-conductor that’s used to control the direction of current
- Like LEDs (light-emitting diodes) or photodiodes, which sense light
Resistors
- Limits current flow
- Usually labeled with R
Capacitors
- Stores energy in electrical potential
- Usually labeled with C
- Resists changes in voltage (if we drop power, they’ll slowly discharge, and vice versa)
Inductors
- Stores energy in electromagnetic fields
- Resists change in current
Transistors
- Semiconductor device used to amplify/switch electrical signals
- Little rectangles with three pins, most commonly 2 on one side and 1 on the other
Integrated Circuits
- Can do dedicated tasks, simple or complex
- A little rectangle with lots of pins on each side
- Can do data storage, microcontroller tasks, power regulation, etc.
- We can figure out what it does by matching the shape and searching up the datasheet with the pinout
- Try to look for datasheets on Digikey or Mouser and not random sus 3rd party sites
- Not only will they have pinouts, but also pin functions
- Similarly, we can find the base memory address for flash memory (which we’d like to dump)
- Use the little circle to orient the chip the same way as shown on the datasheet
- Sites to search chips by logo: FCCID.io (many corporations must upload information, which we can search by FCC ID), retrosix.wiki, elnec.com, or ecadata.de
- We can get the FCCID on the board or online (e.g.
{device_name} FCC ID or site:{vendor_site} FCC ID)
Printed Circuit Boards (PCBs)
- Fiberglass layer (substrate) with copper on top and then a solder-mask/paintpcb
Throughholes
- Pins that can be accessed from the front and back of the board
Connectors
- Sections with pins inside to plug into
- Described based on pitch, which is the distance between the centers of pins (usually 2.54mm)
- Test points - pads used for production programming/validation/troubleshooting
- Labeled with TP, will look like little exposed copper/tin pads
Testing a board
Checking voltages
- Set multimeter to DC V 20 (to measure up to 20 volts)
- This is on the left side, AC is on the right (but this will rarely be necessary)
- Then connect black lead (ground) into COM section (common reference AKA ground) and the red lead into the voltage/ohm/amperage section
- Tap the black probe to ground and then use the red probe to check voltages
Testing continuity
- Board should not be powered during continuity testing (else we risk shorting the circuit)
- Set the multimeter to the Wifi looking thing
- This will send current through one of the probes and will check if receiving it through the other probe
- This will tell us if the things we test are connected together
- For example, we could check to see which pin a test pad is connected to
- Put black cable in COM and red cable in the voltage/ohm/amperage section
- Then touch probes to two locations
- We might have to
UART
- Universal Asynchronous Receiver-Transmitter
- Hardware communication protocol allowing serial data exchange between devices without a shared clock signal (done via a Baud rate)
- Active-high vs. active-low:
- Active-high - idling at 0V and sending data at higher voltage
- Active-low - idling at higher voltage and sending data at 0V
Identification
- 3 pins, ground, Receive, and Transmit, indicate UART
- When connecting devices, Rx goes to Tx and Tx goes to Rx
- One device transmits data and the other receives data
- These can often be mislabeled, so often when debugging first step is to swap these
- Frame:
- Start bit, data bits, parity bit, and 1-2 required stop bits
- Data is usually 8 bits, with least significant bit sent first
- Can figure out Rx and Tx by tracing pins to the chip and checking the pinout
- We can also just connect it to the logic analyzer and see where the data comes from (all data out will come from the board’s Tx pin)
- Baud rate is a predefined speed of data measured in bits per second
- Common values: 115.2k, 9.6k (90% of baud rates), 57.6k, 19.2k, 4.8k
- Generally running through these 5 will result in a good chance of talking to the device
- Can also perform a measurement with a logic analyzer and calculate the baud rate
- https://github.com/devttys0/baudrate/blob/master/baudrate.py
- Uses
python2, so curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py, python2 get-pip.py, python2 -m pip install pyserial
- For an even simpler scan,
ls /dev/cu.usb* and then pass the device:
import serial, time
port = '/dev/{device}'
for baud in [4800, 9600, 19200, 38400, 57600, 115200]:
try:
s = serial.Serial(port, baud, timeout=2)
time.sleep(0.1)
s.reset_input_buffer()
data = s.read(256)
s.close()
if data:
print(f'{baud}: {len(data)}B hex={data[:30].hex()}')
else:
print(f'{baud}: (no data)')
except Exception as e:
print(f'{baud}: ERROR {e}')
- Parity start/stop bit is configured to off (99% of the time), even, or odd
- Either 1 or 2 stop bits
Reading data
- Use a logic analyzer to connect to the pins
- Connect either ground pin to ground
- Take other two TX/RX and connect to channel 0 and 1
- Open up Logic2 application to view the data
- Hovering over the “smallest slice” in Logic2 will show us the baud rate, given by the
width
- Settings in the top right to configure if we get buffer errors and such
- Move to analyzer tab (2nd on right side) and select
Async Serial
- Enter baud rate, channel with activity, and guess the scheme (usually 8bits, no parity, 1 stop bit)
- After saving, we can view the hex data above the captured data
- Right click data and change to ASCII to read plaintext
- This is better for signal analysis, rather than something like UART to USB
Interacting with UART
- Can vary wildly based on tools
- USB to UART is pretty standard - hook it up and then use
screen /dev/ttyUSB0 {baud_rate} to receive the data
- We can detach from screen with
CTRL a then d, and reattach with screen -r, or CTRL A then K to kill the screen
-
| Using PiFex - Connect board Tx to PiFex IO15 |
RX |
TCK, Rx to IO14 |
TX |
TMS, and GND to GND |
- Then, connect with
screen /dev/ttyS0 {baud_rate}
- If we’re on a device that doesn’t have screen and we need to interact with a USB device, we can use echo and cat
stty -F /dev/ttyUSB0 115200 raw -echo
echo -ne '{command}\r' > /dev/ttyUSB0
cat /dev/ttyUSB0
- Might initially show an empty window, but we can try sending data blindly or power cycling/resetting the device
- If we get hit with an auth page, we can use
pyserial to try and brute force over a serial connection
SPI
Information
- Serial Peripheral Interface
- Very common with flash memory chips, sensors, displays, and SD cards
- Characteristics:
- Synchronous - clock signal is shared and controlled by the controller device
- Controller/peripheral architecture - single controller with multiple peripherals
- No frame structure - transmits data without start/stop/parity
Using SPI
- No spec for SPI, so each device has implementation details
- Datasheet will contain implementation details
- Watch for the Clock Polarity (CPOL) and Clock Phase (CPHA)
- These describe when lines should be sampled/toggled
- Quite often mode 0, where polarity and phase are set to 0
- Worst-case, these can be brute-forced (only four combinations between 00, 01, 10, and 11)
- Will usually not have a pinout, so we use pcbytes kits or micrograbbers to create a pin out
- We can also use a SOIC clip to try and clip onto a flash chip
- Is a bus, so multiple devices can use the same shared wires
- SCK - shared clock
- MOSI/COPI (master-out slave-in/central-out peripheral-in)
- Essentially transmit from the controller
- We’ll see a request coming from the controller on this line
- MISO/CIPO (master-in slave-out/central-in peripheral-out)
- Essentially receive on the controller
- We’ll see the peripheral device’s response to the controller’s request on this line
- Multiple peripherals are handled by multiple chip select (CS) lines
- Can also be called slave select lines (SS)
- These are not shared between peripherals, controller will send out an active low signal over CS lines to signify when it’s a peripheral’s turn to discuss
Analyzing SPI on a Logic Analyzer
- We’ll have to zoom in pretty far, since it’s a very fast protocol
- Look for challenge response to identify MISO/MOSI, but sometimes it could just be the controller sending data
- This would be pretty common when sending data to flash, for example
- Choose
SPI in analysis, set MOSI/MISO/Clock channels, set polarity/phase to 0, and data should be shown
Using the CH341a, SPI SOIC-8 clip, and Raspberry pi
- Pinout is super common, CH341a/SOIC-8 clip will assume it
- SOIC-8 red wire is pin 1, which is the CS pin. Make sure red wire lines up pin 1 on both the chip itself and on the CH341A
- Half circle on right side of CH341A will show which set of 8 has pin 1 - then we just set it up so the numbers are facing the front of the stick
- Then plug into raspberry pi and do below
Extracting SPI Flash Memory
- Peripherals don’t usually verify controller authenticity
- Since we have datasheets, we can often just talk to the flash chips directly
- Will usually use the same pinout as SPI
- Need to be careful about voltages necessary, as we can easily fry the chip giving 5V to a 3.3V chip
- Sometimes, the controller can try to talk to the flash as the same time as us
- We can attempt to hold the controller in reset or wait until the controller isn’t talking
- Can just hold the reset button the entire time, but dumping could be very slow, so this isn’t smart
- Instead, we can connect the microcontroller’s reset pin to ground or 3.3V
- Alternatively, we can attempt to remove and resolder the SPI flash
- Also, we can often run into bit corruptions
- Thus, dump three times and hash until we have a match
- After we’re connected to the chip, we’ll use
flashrom to dump the contents
sudo flashrom -p {programmer} -r {outfile}.bin
programmer can be something like ch341a_spi for the clip
- If using raspberry pi instead of CH341A, we’d specify
linux_spi:dev=/dev/spidev0.0,spispeed=8000 as the programmer
- Then, we can just
xxd {bin_file} | head -n {lines_to_output} to read it
I2C
- Used for inter-chip communication
- Has
SDA and SCL pins, using address-based communication
- Logic2 can analyze after identifying the pins
Using/Exploiting Debug Interfaces
- These aid engineers during development and should not be present in production
- Common ones are JTAG/SWD, and sometimes UART
SWD/JTAG
- Core capabilities: halt/resume execution, memory read/write, registry manipulation, hardware breakpoint management, and access to real-time variables
- Can be used to bypass security checks, memory exploration, and dumping firmware
- Will usually be either JTAG or SWD on a board
SWD Overview
- ARM Serial Wire Debug protocol
- SWDIO (data input/output) and SWCLK (clock) signals
- Debug Access Port (DAP architecture)
- Connect
GND to GND on the pi, 3.3 to 3.3, SWDCLK to IO9|SDI|SCLK, SWDIO to IO11|CLK|SWDIO
- Then, run
sudo openocd -f raspberrypi-native.cfg-swd -f stm32f1x.cgf
- We can then connect via telnet to
localhost 4444, after which we can perform lots of actions
- Dump memory with
dump_image {out_file}.bin {starting_address_of_flash} {number_of_bytes_to_dump}
- We can find where internal flash memory is based on the microcontroller’s datasheet
- Then grep/strings for interesting info
Joint Test Action Group (JTAG) Overview
- Signals: TCK (test clock), TMS (test mode select), TDI (test data in), TDO (test data out)
- Lots of different pinouts (usually 2x4 to 2x10)
- Can also look for a cluster of test pads with 4 and 4 pins around it, as this is very indicative of tag connect
- They’ve removed the headers but they have cables that can press down and connect
- State machine under the hood
- We start in a reset mode, and every clock cycle we check our
TMS pin value. If it’s 1, we stay, but if it’s 0, we move to run test idle
- The rest of JTAG works like this
Interacting with JTAG
- Make sure to figure out the pinout first
- Connect ground to ground, 3.3 to 3.3, and then figure out if any of the other JTAG pins are 3.3 or ground before brute-forcing
- go-jtagenum is a good tool for bruteforcing
- Connect ground, then connect the rest of the pins to all the IO pins, and then run the tool with each of the pins mapped
go-jtagenum -pins '{ "io2": 2, "io3": 3, "io14": 14, {etc.}}' -command scan_idcode -delay-tck 50
- Then do
-command scan_bypass with no delay-tck to double check what each of the pins can be
- JTAGulator is also pretty good for this
- A debugger is the best for interacting with JTAG, such as Segger Jlink (but that’s pretty expensive)
- For hardware interaction, can use JTAG adapters, Pifex, or Bus Pirate
- Connect GND to GND, 3.3V to 3.3V,
IO2 | SDA | TDI on pifex to TDI, IO3 | SCL | TDO to TDO, IO14 | TX | TMS to TMS, and IO15 | RX | |TCK to TCK on board
- We can then run
openocd command to dump
sudo openocd -f raspberrypi-native.cfg-swd -f stm32f1x.cfg
- This is a pretty common config file
- If on a pi, we may need to use
sysfsgpio-raspberrypi.cfg as the config file due to some linux kernel shit
- We can then
telnet into the locally-opened port on 4444 to access the shell
- Should immediately run
halt after getting into the shell
- Getting the initial memory address from the datasheet is really important, as we can use it to dump
dump_image internal.bin 0x0{starting_address} 30000
- 30000 is a good number for dumping
- Then, do it again and compare the hashes
Debugging with JTAG
- Run
halt inside the 4444 service opened by openocd
- This will halt execution and put us in debug-mode
reg to view registers
- Back on the pi, we can use
gdb-multiarch for a gdb session to step through execution
- We can then use
openocd’s gdb service, which is hosted locally on 3333
- Run
target remote 127.0.0.1:3333 within GDB
- To continue execution (after setting desired breakpoints from Ghidra) we should continue, or
c
- Then, once we hit our breakpoint, we can read/set memory as necessary and such
- Then, since we aren’t debugging an executable, we’ll need to use memory addresses
- Referring back to the datasheet, we know internal flash starts at
0x08000000
- We can dump 30000 bytes starting there into a binary file, and have Ghidra analyze it
- Ghidra process:
- Import the bin file, and select the architecture of the chip
- For example,
ARM:LE:32:Cortex:default
- Don’t analyze it yet, as we need to set the base address
- Go to Window -> Memory Map
- Click the home icon in the top right
- Set the base address
- Now we can analyze the bin file
- Go to Analysis -> Auto-analyze
- Profit!
JTAG and UART at the Same Time
- Since they use overlapping pins on the pifex (namely IO14 and IO15), we can move them around
- Still use UART
RX -> IO14 TX and TX -> IO15 RX on the board
- Move JTAG
TCK to IO10 and TMS to IO9
- Then need to edit
sysfsgpio-raspberrypi.cfg to modify remapped pins
- Change
sysfsgpio jtag_nums 15 14 2 3 to sysfsgpio jtag_nums 10 9 2 3
JTAG protection mechanisms
- Fuse bits and lock bits
- Physical fuse within the chip
- Apply a voltage between two pins for a certain amount of time, which will blow a fuse and disable JTAG
- This is a pretty good control
- Read-out protection levels
- Have RDP levels, such as 0, where everything is accessible, and gets less accessible up to level 2
- Can be glitched down
- Debug interface disable methods
- Software-level methods to disable results for interacting with debugging interface
- Different for each vendor, but can be broken depending on implementation
Firmware Analysis
Binwalk Analysis
- Binwalk is pretty good at figuring out what the underlying file system is
- Common FS formats: SquashFS, JFFS2, ext4, and UBIFS
- There are custom tools to extract the files, but binwalk can do it automatically
- If we want to do it ourselves, find the header and size and use
dd
- Once inside, want to check for:
- Debug info:
/sys, /proc, /dev, /debug
- Logs:
/var/log, /tmp/log, /logs, /data/logs
- Update files:
/tmp/update, /mnt/flash, /firmware, /factory, /backup
- Update scripts:
/bin, /sbin, /usr/local/bin, /usr/sbin
- Network configurations:
/etc/network/interfaces, /etc/wpa_supplicant.conf, /etc/hostapd.conf, /etc/dnsmasq.conf, /etc/hosts
- Look for passwords to crack (
/etc/shadow, /etc/ssl/certs, /etc/ssl/private, /etc/keys)
- Initialization scripts in
/etc/init.d
Firmware Manipulation
- Tools like firmware analysis toolkit can unpack/repack firmware
- Can also do firmware emulation
Reflashing
- Get another session and write to memory rather than reading
- On RTOS, will need to repackage changes back into the initial format (e.g. packing a filesystem back into SquashFS)
- Flashrom can handle reflashing
- Reflashing can occur via UART, SPI, JTAG, USB, or even over-the-air (OTA) methods
Radio
Terminnology
- Antennas: piece of wire to receive radio waves
- Usually tunes for a range of frequencies
- There is an ideal length for specific frequencies
- Calculators exist to find the best length, but best starteers are the ANT-500 (Great Scott Gadgets) and the RTL-SDR kit dipole antenna
- Demodulation: extracting information from the wave
- Decoding: understanding the information being sent
- Bandwitdh: how wide a band a radio can perceive at once
- 2 MegaHertz will be able to see 2 MHz around the central frequency
- Gain: how amplified the signal is
- Signal: data being sent
Using the Flipper
- Pros: Easy to use, good community support
- Cons: bad interface, and limited frequencies
Software-Defined Radios
- Very modular, allows control via software
- RTL-SDR is the cheapest solid option, at ~$50
- Upper range options: HackRF at ~$360 (a bit outdated) or BladeRF 2.0 Micro xA4 at ~$540
- Tools:
- Waterfall viewers, like SRF++ or GQRX
- Allows viewing signals over time
- Decoders
- Analyzers
- Universal Radio Hacker (go-to)
Decoders
- RTL_433
- Can decode over 280 protocols
- Just give it a set of frequencies, which it will hop between, and will print results if signal is known
- POCSAG
- Pager system, often used by outdated hospitals
- pipe rtl_fm into multimon-ng
Universal Radio Hacker
- Can capture and replay signals, in addition to decoding
- Support fuzz testing, etc.
- Just need to select a connected device, along w frequency, sample, bandwidth, gain, etc.
- Good idea to crop the signal down to the signal, that way the majority of the capture isn’t just noise
- In the Interpretation page, the
Autodetect parameters button can help, using heuristics to find parameters
- When decoding, we can program the decoder using the dropdown and the
..., for example using a substitution cipher to replace 100 with 0 and 101 with 1
Automotive Hacking
CAN Bus
- Most common network used in vehicles, introduced in 1986
- Robust, but slow. Up to 1MBit/s, usually 500 or 125 Kbit/s
- Up to 8 bytes of payload
- Can-FD - newer standard with 64 bytes of payload @ 8MBit/s
- No guarantees on timing, thus MITM attacks are trivial without security implemented
- Cabana is an excellent GUI tool for viewing CAN traffic
- Will be a bit difficult to understand what ECUs are talking on the bus we’re on if we don’t have the DBCs
- Installation is a bit wack:
- Clone the entire openpilot repo:
git clone --depth 1 https://github.com/commaai/openpilot.git && cd openpilot && git submodule update --init --depth 1
- Install deps:
apt-get install -y qtbase5-dev qtbase5-dev-tools qttools5-dev-tools libqt5charts5-dev libqt5svg5-dev libqt5x11extras5-dev libqt5opengl5-dev libgles-dev libglvnd-dev libegl-dev build-essential
- Install uv:
curl -LsSf https://astral.sh/uv/install.sh | sh && source ~/.local/bin/env && uv sync --frozen --all-extras
- Build:
scons -j4 tools/cabana/_cabana cereal/messaging/bridge
Network Topology
- Cars usually have multiple busses networked together
- These could be for powertrain, body, convenience, etc.
- Gateway to separate busses and ODB-II port
- The ODB-II (ODB2) port is a 16 pin connector usually located in the driver side footwell under the dashboard
- Mostly used for diagnostics and data monitoring
- Modern cars sometimes use (automotive) ethernet alongside CAN
- Useful for video steams, software updates, etc.
Unified Diagnostic Service (UDS)
- (ISO 14299) used for diagnostic communication, every ECU in the car supports this
- Talks over CAN, sort of in the sense that TCP/IP talks over ethernet
- However, because CAN also supports messages, this would be as if a server could perform actions sent to it via its MAC address and its IP address
- Has very nice primitives for car hacking
- Can be used to diagnose problems in the workshop, like reading sensor data or actuator tests
- The actuator converts electrical signals into physical force, such as powered locks, seats, AC, throttle control
UDS Request & Response
- Contains a Service ID (SID) as the first byte, optional subfunction ID (or
$) as the second, and the payload itself
- Subfunctions could be start/stop/read
- A positive response will have the SID + 0x40 (@) as the first byte, then the same subfunction ID, and the payload
- A negative response will have 0x7E as the first byte, then the SID as the second, then the error code as the third byte, no payload
- Common error codes are 0x11 (service not supported), 0x13 (incorrect length or format), and 0x35 (invalid key)
Common UDS SIDs
- SID $10 (diagnostic session control)
- The subfunction ID could be 0x1 (default session), 0x2 (programming session), or 0x3 (extended diagnostics)
- SID $22 (read data by identifier)
- SID $23 (read memory by address)
- Allows reading of RAM, sometimes whole flash
- Byte 0 is SID, byte 1 is the Address/Length format, byte 2 is the big endian memory address to start from, and then bytes 2+N are the memory size to read
- Usually disabled or the ranges are limited
- SID $27 (security access)
- The subfunction ID either says whether we’re requesting a seed (1, 3, …) or sending the key (2, 4, …)
- Normal way to authenticate a tester to an ECU, challenge/response
- Requests a seed (no payload), perform some operation on the seed, send the key as payload
- Usually symmetric crypto with XOR, custom linear-feedback shift register (lfsr), AES
- Future of auth is SID $29 with PKI
- SID $31 (routine control)
- Subroutines are start/stop/results
- Erase flash, compute checksum
- SIDs $34/$35 (download/upload)
- This is from the ECU’s perspective, so download would mean the tester provides the thing, like a software update
- SID $36 (transfer data)
Custom Data IDs (DIDs)
- OEM can create custom DIDs which are not part of an ISO spec
- These could be basically anything, and are worth probing
- Ranges:
- 0xA800–0xACFF
- 0xB000–0xB1FF
- 0xC000–0xC2FF
- 0xCF00–0xEFFF
- 0xF010–0xF0FF
- 0xF1F0–0xF2FF
- For example, one on my car allows reading 15 bytes of a buffer without authentication
- DIDs can be stacked, as well, meaning you can query multiple DIDs at once
- For example, you could query the VIN and the serial number in one SID $22 command
- This also allows for moving the pointer within the output buffer, so if one of the DIDs allows for reading the buffer (as it does in my car) you can increment the starting address with this technique
Memory Layout
- Usually the bootloader, application code, data/calibration lookup tables
- There’s usually not a signature check on boot, since it would take too long
Firmware Updates
- ECU powers on, bootloader does check and jumps into application code
- Person then requests programming session via UDS ($10 0x02) which goes back into the bootloader
- Issue a routine control “Erase memory” ($31 0x01 FF00)
- Tell it to request download with $34 and then send the data with $36
- Finally, check signatures/checksum ($31 0x01 FF01)
Reverse Engineering FW updates
- Most common microcontrollers are Power PC NXP/FreeScale, V850 Renesas, and TriCore Infineon
- These have safety requirements (ASIL) and aren’t really resistant to modern attacks like fault injection
- Might get lucky with JTAG/UART
- Can often download software from microcontroller website to allow interfacing with debug port
- Becoming locked more often
- Ghidra is solid, but be sure to disable “Create Address Tables” due to false positives
- Ghidra’s entropy map is good for finding missed code, since there often aren’t headers labeling code
- The blue color shows code
- Look for diagnostic protocols, like Universal Measurement and Calibration protocl (XCP) or CAN Calibration Protocl (CCP) handlers
- These usually have read/write memory open
- Look for functions that return multiple matching error codes
- CCP: 0x30, 0x32, 0x33
- XCP: 0x22, 0x25, 0x29
- Look for UDS handlers
- Use hard-coded error codes again, like 0x12, 0x13, 0x22, 0x33
- Find CAN registers
- Try to find information related to CAN messages
- See if we can find a CAN table or anywhere CAN parsing occurs
- Look at global variables
- Super common, make sure to label them
- Map out large structs in Ghidra
- There can be copies of massive structs created across layers of application, which are referenced quite a lot
- Can export to C/C++ from Ghidra and search through resulting code
Secure on Board Communication (SecOC)
- AUTOSAR Standard
- Message sent by known ECU
- Message contents have not been altered
- Rollback protection
- Low overhead
- Chosen chiper (AES CMAC)
- Signing process
- Secret symmetric key will be used by sender, which is used with a payload and a freshness value to calculate a MAC
- Payload, freshness value, and MAC are all sent as the total payload
- Receiver then takes the payload, freshness value, and shared key to calculate the MAC and compare the results
- Freshness value
- Trip counter which increments every time a power-on happens
- Message counter which increases after each message from a certain ID
- Reset counter which is periodically increased by gateway
- Truncated freshness value which is lower part of message and reset counters
- Bits:
- 48-32 - trip counter
- 32-12 - reset counter
- 12-4 - message counter
- 6-2 - truncated freshness value
- 4-2 - reset flag
Key Management
- We’re very interested in the
ECU_MASTER_KEY, which really only the manufacturer knows per VIN/SN
- They can allow requesting of keys via some HTTP service they provide
- M2 is a key encrypted with the master key with AES, so getting the key doesn’t allow MITM
- M2 also contains a counter, preventing replay attacks
Mitigations
- Hardware Security Model (HSM) handles CMAC
Misc
- Sometimes, we’ll only want to power a section of the board, like a daughterboard