We will explain how we exploited Android firmware using an undocumented kernel API that was found by reverse-engineering Samsung’s “Hidden Factory Settings” app.
This API permits flashing unsigned firmware of Samsung’s touchscreen firmware.
The CVE affects all Samsung S7-S10 series using exynos chipset.
After reading project zero’s great article about exploiting WiFi firmware to gain RCE, I decided I should try to do some firmware exploration of my own.
SoC General Overview
Phones these days have much more than just 1 CPU that runs the Android OS, which makes them extremely complex systems.
Most Android phones have 10-30 different “computers” inside them, each with its own CPU, memory and storage.
All of these units are communicating over different hardware communication protocols like IPC, I2C and so on.
The main processing units in Android phones are:
AP / Application processor – This is the main CPU you know from the phone specs which communicates and manages all other processing units and runs the Android OS .
BP / Baseband Processor / Radio / Modem – The BP is responsible for converting all the cellular data received from radio waves to software usable information by implementing the LTE stack.
GPU – The graphics processing unit is responsible for handling all graphics related tasks
There are more processing units like wifi, Crypto, Camera ,Audio etc…
All this components together called “System on Chip” – SoC
Finding a Vulnerable Target
Android firmware exploitation is hard as we have very little prior knowledge of the firmware architecture and how the OS communicates with it.
Hence, using an information lead from the manufacturer can make the research tremendously easier.
After googling for the mentioned leads, a lot of forums mentioned Samsung’s touchscreen problem and how to fix it.
The method was relatively simple:
“First go to hidden settings by writing *#2663# in the phone app and then click on update FW”.
Finding How to Communicate with the Firmware
As mentioned before, using the manufacturer’s knowledge would be much easier than figuring everything by ourselves.
By running strace on the Android application, which is responsible for the firmware update, you can easily see that after clicking the update button the app writes to the following path
This path is part of the kernel’s sysfs mechanism.
sysfs is a pseudo file system provided by the Linux kernel that exports information about associated device drivers.
Here we can see how to communicate with the kernel from cmd file:
Writing function name e.g “fw_update” and then the parameter of “1” will result in a touch screen firmware update as used in the official factory settings app.
But in order to fully understand the functionality of the firmware update mechanisms we need to download the kernel and look at the device driver’s code.
After examining the kernel source code that handles the above command, the following comment unveiled very interesting functionality.
Apparently, when writing:
“echo -n "firmware_update:0" > /sys/class/sec/tsp/cmd”
The 0 parameter informs the kernel from which place to update the firmware from.
As the kernel’s code comment shows, passing 2 will cause the kernel to update the firmware from UMS (sdcard).
Further look in the kernel source will show the required path:
In order to check if we can flash unsigned / malformed firmware all we have to do is try and see what happens.
(In general it is better to only modify human readable strings, such a log message, to not break the program execution process, sadly I chose the dumber way)
The result printed in the kernel log (kmsg)
At this part of the research I wasn’t 100 percent sure it worked, but after trying to click on my personal device and seeing tons of IO errors in the kmsg (instead of just clicking), I understood I just flash malformed touchscreen firmware successfully, vuala!
Interesting note about fuzzing
When finding the cmd file API my first thought was “lets fuzz it and find some overflows!”
But the log clearly says the input is too long and dropped to prevent overflows.
This patch is due to vulnerability found by the same researcher of project zero’s article that inspired me to do the research.