Hacking the Hyundai Tucson

The second part of the story is about how you can hack the official Hyundai Tucson 2020 firmware and stuff it with something not very useful. You can start read here.

Earlier, you learned how to hack the official Hyundai Tucson 2020 firmware and reverse engineer it. Then it seemed to me that you can simply modify the update file, archive it again with the same password and shove it into the machine. It turned out that everything is not so simple.

The update package is signed with an RSA key corresponding to the certificate daudio.x509.pem, and this signature is verified during update. This is part of the Android OTA update process, which is used to update the firmware of the entire device (not just car navigation). Unlike the RSA key for Ioniq 2021this key cannot be found on the network (at least I did not find it).

How in this case to get access to the ShGU (regular head unit)? I considered two options:

  • find a vulnerability in one of the applications;

  • find a vulnerability in the Linux kernel. SHGU is running Linux 3.1.10, so this is a real attack vector.

Alas, nothing happened. But I found new information that allowed me to root the MSU.

New ideas

I found out that Hyundai supplies the same firmware for different cars. My car had a so-called “Standard-class Gen5 navigation” that looks like this:

Although the word “navigation” appears in the title, in fact this is the firmware for the entire head unit. The same firmware is delivered to different Hyundai, KIA and Genesis models released between 2018 and 2021.

The head unit works on SoC Telechips TCC893X, and its SDK leaked to the Internet. There is a secret mechanism for launching recovery. To do this, you need to hold down the POWER button (this is the handle on the left) and the MAP button at startup:

I tried it on my car, and the following error appeared on the screen:

Obviously, some encrypted files on a USB drive are needed to start the recovery. A simple grep of these lines results in lk.rom file from the update package, which I have so far ignored. Let’s load it into Ghidra and see what happens.

Reverse lk.rom

LK means “little kernel“, a small open source kernel that is used in many embedded platforms. lk.rom loads lk.rom from address 0x82000000. By setting the correct start address in Ghidra, we can use printf and get a lot of useful debugging information. Checking “[DEBUG] U-Boot Recovery Button pushed .... \n” leads to:

It looks like recovery is part of u-boot and its entry point is the function 0x820589a8:

Pay attention to line 14. From it we can conclude that this function copies the u-boot code 0x80000000and launches it. PTR_DAT_82058a38start u-boot and PTR_DAT_82058a3c —firmware end address:

Using this information, we can extract the code u-boot lk.rom with the following command:

$ dd if=lk.rom skip=$((0x1055c)) count=$((0x57894-0x1055c)) bs=1 of=uboot.rom

And then parse uboot.rom as a separate binary with a starting address of 0x80000000 in Ghidra.

Reverse uboot.rom (part of lk.rom)

Okay, we see a lot of debug lines that help us understand what’s going on. Recovery looks for the following files on the USB drive:

  • security_force/encrypt_lk.rom

  • security_force/encrypt_boot.img

  • security_force/encrypt_system.img

  • security_force/encrypt_recovery.img

  • security_force/encrypt_splash.img

  • security_force/encrypt_partition.dat

There is also security_force/file_info, which contains the name, size, and CRC32 checksum for each of the files listed above. These files (except encrypt_partition.data) match the files we found in the update package:

They must be encrypted using the AES-128-CBC algorithm, with keys =”)1Zorxo^fAhGlh$#” and IV=”aoAkfwk+#1.6G{dE”. Only system.ext4 must be converted to a sparse image before encryption.

Patch system.ext4

Assuming that with the help of recovery we can flash everything we want, what will be the minimum patch for the official firmware, which will give us at least some access to the MCU? While searching for vulnerabilities in standard applications, I found a hidden engineering menu that includes ADB:

Flag mDispAdb can be switched by clicking 5 times on the bottom right corner of the 3rd page “Module Info”. But if present ADB_HIDE_FEATUREthis flag is ignored and visibility is always set to 8, which means GONE. Function ADB_HIDE installed by default, as seen in system.ext4:

$ cat /tmp/car/etc/permissions/com.hkmc.software.engineermode.adb_hide.xml 
<permissions>
    <feature name="com.hkmc.software.engineermode.adb_hide" />
</permissions>

Well, let’s remove this feature, create a recovery file and shove it into the car.

Yes, it worked! With this simple change, we successfully enabled ADB on the Kia Stinger 2020 and connected to it via USB.

Getting a root shell

Now that we have the ADB shell, how do we get root? It turns out that the stock firmware has a handy setuid binary called “amossu”:

$ ls -la bin/amossu
-rwsr-sr-x 1 root root 37216 Oct  6 08:29 bin/amossu

It works simply

setgid(0);
setuid(0);
execv("/system/bin/sh",__argv);

Instruments

I posted here program and instructions for creating custom firmware for cars with Gen5 firmware. So far, the whole process has been successfully tested on Kia Stringer 2020.

Final Thoughts

I hope this hack will allow you to create some interesting car mods. For example, I would like to see an application that records a video stream from a car’s camera and saves it to a flash drive. Of course, my ultimate goal remains to launch Doom on the screen of the SHGU. So I don’t say goodbye :).

If you have comments or feedback, you can leave them on Github.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *