Saturday, May 23, 2015

How a $30 Phone Caused Me a Headache & Write Protection Woes.

How a $30 Phone Caused Me a Headache & Write Protection Woes.

A few months ago while I was playing cards in my Physics class, my friend Quincy Jones comes up to me and said

“Hey, I have a crappy old ZTE phone my grandma gave me, and I know that you like messing around with this kind of stuff. You want it?”

Heck Yeah! Should be fun. Quick/Easy to root, then work on getting TWRP ported, etc. Right? No.

To begin, this phone runs ZTE’s (in my opinion horridly ugly) Jelly Bean 4.1.2. It is labeled Z796C, which, after a quick google search, is called the ZTE Majesty on Straight Talk Wireless (The carrier would later cause me multiple headaches, but we’ll get to that. Upon googling “ZTE Majesty Root” I was greeted by a SINGLE thread about the phone. No big surprise, it’s not a well sold device. The thread was about 8 pages of people complaining about how it hadn’t been rooted. They all said they had tried “every method”, which, at the time, I didn’t believe.

This phone runs 4.1.2, which means that, in theory, this device is vulnerable to hundreds of different local (and even some remote) code execution (root) exploits.

To begin, I tried SafeRoot (originally intended for 4.3), which seemed to succeed, but upon reboot, no root. Huh.

Onto attempt two, Cydia Impactor (Master Key Bug), and although it seemed to work, upon reboot, no root. This should have keyed me off to the problem, but it didn’t.

Onto what should have been my go to for attempt one, TowelRoot. Downloaded the APK and installed, Bang. Root. Or so I thought.

After TowelRoot displayed its success message, I left the app and jumped over to SuperSU, which said that the SU Binary needed to be updated. Sure. I click “Yes”, and left to go for a run.

Got back about 30 minutes later, and it still displayed the “Installing…” prompt! I closed the app, and plugged it into my Surface Pro 3, and pulled up an ADB Shell.


Wow. That’s painfully generic.

I then ran “SU” which returned:

/system/bin/sh: su: not found

Huh? I thought I had root? Maybe I was wrong. Reran TowelRoot, and it rebooted, which is TowelRoot’s way of telling you you aren’t vulnerable/it failed. What the Heck?

I then rebooted the device. Pulled up TowelRoot, and ran it. It reported success. Popped open SuperSU and decided to not update the binary, and just use the one that TowelRoot installs. Seemed like everything was fine. I opened that same ADB shell and ran SU. To which I was greeted with an SuperSU prompt, to which I agreed. Boom.

root@android:/ #

Wow. That’s still painfully generic.

Started surfing around to find where the different partitions lie.

root@android:/ # cat /proc/partitions

root@android:/ # ls -al /dev/block/platform/msm_sdcc.3/by-name

Returns: /dev/block/platform/msm_sdcc.3/by-name: No such file or directory

What? No “By-name” function on a JB era device? That sucks.

root@android:/ # cat /proc/mtd

Returns: dev:    size   erasesize  name

Ugh. No partition listing that sucks.

I tried a few more common methods that I won’t waste time outlining, all you need tt know is that none of them worked.

Next plan of action for me would normally be to examine the Recovery.img and get an fstab, which displays all of a devices mount points. Bad news… after a search, there are no fastboot images for this device! No problem, I’ll just dump the recovery.img from Fastboot. Here we go:

PS C:\Users\Nolen> adb reboot bootloader

I then waited, the ZTE splash screen came up, and then it came up with the Android Boot Logo! What the Heck? I then found out from a quick google search that all Straight Talk phones have Fastboot disabled. This particulat phone also lacks a “Download Mode” to replace Fastboot like what LG does. Wow. This not only prevents disaster recovery, but just made a seemingly easy job much, MUCH harder.

Where to go from here? Not sure honestly. So, I set to work researching it. Couldn’t really find anything relating to the topic.

About 30 minutes into brainstorming, the device randomly rebooted.

When it rebooted, I got back on an ADB shell:

root@android:/ # su

Returned: /system/bin/sh: su: not found

This means war.

Huh!?!?!?! We had Root! Ugh. What’s going on!

For those who haven’t figured it out yet, it was now apparent that not only the phone has Write Protection on /system (prevents writing to a live system, can only be written to from recovery), but also has some form of temp root detector that shuts down root after a certain period of time.

So, I gained temp-root via TowelRoot again, and began brainstorming how to get a partition map again.

Then it hit me.

Recovery knows how to mount the partitions! So, I need to get it to mount all the partition in recovery… Factory Reset!

root@android:/ # reboot recovery

Then, from recovery, I initiated a cache wipe, and then a Factory Data Reset.

After they completed, I reboot to system.

root@android:/ # cat /cache/recovery/last_log

Yay! A partition map!

Now to use an old trick found by Justin Case (@Jcase) to help temporarily remove Write Protection.

We write the boot partition to the recovery partition, and then reboot to recovery, because the recovery partition (when booted) has permission to mount /system read-write. 

Well, now onto the fun stuff.

We back up our boot partition:

root@android:/# dd if= /dev/block/mmcblk0p8 of=/sdcard/boot.img

Now we back up our recovery partition:

root@android:/# dd if= /dev/block/mmcblk0p16 of=/sdcard/recovery.img

Now we write the contents of the boot partition to the recovery partition

root@android:/# dd if= /dev/block/mmcblk0p8 of=/dev/block/mmcblk0p16

Here we go! *crosses fingers*

PS C:\Users\Nolen> adb reboot recovery

Upon reboot, it seems completely normal. All data is intact, and system is booted sucessfully as expected.

Now to test it. We have to first regain temp-root with TowelRoot, then ADB Shell:

root@android:/# mount –o remount,rw /system

Returns: mount –o remount,rw /system

Success! We have RW access to /system!

Now onto perma-root.

Just open up SuperSU and it will ask to Update the SU Binary, select yes, and wait. About 30 seconds later, it displayed the “Success! It is recommended you reboot now.” Message, I then went in and converted SuperSU to a /system app. Then I rebooted to the normal boot image.

I expected the following; to have root access, but to be unable to remount /system due to write protection.

However, upon reboot:


root@android:/# mount –o remount,rw /system

Returns: mount –o remount,rw /system

What? How are we still able to remount system RW? To make sure I wasn’t still booted to the recovery partition, I ran:

root@android:/# dd if= /sdcard/recovery.img of=/dev/block/mmcblk0p16

root@android:/# reboot

Now to test again:


root@android:/# mount –o remount,rw /system

Returns: mount –o remount,rw /system

What? Now I am really confused… but I can live with it! We defeated ZTE Write protection permanently! Even if by accident.

Interesting Notes: After booting the stock kernel from recovery, instead of the

Sunday, May 10, 2015

Breaking Samsung's Security

Problem: The Verizon Galaxy S4 is bootloader locked.

Well, what exactly is a Locked Bootloader? A locked bootloader checks for a digital signature on certain images/partitions on the device. This prompted me to begin to research ways to work around this.

The Verizon Galaxy S4 (hereon referred to as VZW S4) checks the integrity of signatures on all of the following partitions;

-          Boot (boot.img)

-          TrustZone (TZ.img)

-          Aboot  (aboot.mbn)

-          RPM (RPM.mbn)

-          SBL1 (sbl1.mbn)

-          SBl2 (sbl2.mbn)

-          SBl3 (sbl3.mbn)

-          The Partition Map (JFLTE_USA_VZW.pit)

-          Recovery (recovery.img)

-          Modem
-          NON-HLOS

 Partitions not checked:

-          System (/system, only checked during OTA Update)

-          Persdata (/Data)

-          Cache (/cache)

-          Hidden.img

Basic Understanding of the boot sequence:


Where to start? There are many vantage points to be taken.

1.      One was described in a recent leak: There is a QFUSE on device under the label of TESTBIT. By reverse engineering a Verizon Galaxy S4 (SCH-i545) VRUFNK1 aboot.mbn in IDA, we can follow the decompiled functions down to the function that calls to check the value of TESTBIT in memory.

We can also deduce from here that the value of TESTBIT’s shadow in memory is 0x700438+0x4000. Though, it is worth noting that aboot does not check TESTBIT’s shadow, it checks the base fuse, which makes overwriting the shadow in memory almost entirely useless.

With this info, we can use JTAG to set the fuse value and boot an MDK aboot. This allows us to use a Loki like attack to boot a custom recovery and kernel.

The only way to permanently blow the fuse would be to use a flaw/vulnerability in TrustZone blow the base fuse to our desired value. Dan Rosenberg's QSEE exploit could easily be leveraged. We could even likely apply M0nk's work on the 8974 to get TZ shellcode, and over-write the fuse value in the shared-cache.

Another fuse that would work similarly would be the Commercial bit, however, this fuse has proven extremely hard to find. Though I am sure it exists. This would be the fuse that is read out by aboot, and dictates whether or not the developer edition checks are enforced. Though, from my findings in aboot, some form of CID hash (at the minimum) spoof would also have to be present.

Theoretically Vulnerable Devices:

-          Galaxy S4 (All QCOM Variants) Method: Downgrade to Pre-Knox Bootloader, or to exploitable firmware, i.e. MDK (SCH-i545), MDL (SGH-i337)

-          Note 3 (All QCOM Variants) NOTE: Note 3 has no Loki vulnerable Bootloader, meaning this only disables roll back for these devices.

-          Galaxy S5 (All QCOM Variants) NOTE: Galaxy S5 has no Loki vulnerable Bootloader, meaning this only disables roll back for these devices.

-          Galaxy S3 (All QCOM Variants) Method: Downgrade to “African-Sock-Monkey” leaked Insecure (Unlocked) Bootloader

Likelihood: (WITH JTAG ONLY)  0/10 – EDIT: The TESTBIT check function looks for 0x20, and the ones digit of the increment fuse is already blown to 0x01, meaning if we blew 0x20 to the fuse, it would return 0x21 and brick.*, still working on Commercial BIT - FAILED -- Could still work with the advent of M0nk's shellcode escalation? Still researching.

Likelihood: (WITHOUT JTAG) 0/10, would require a TrustZone Exploit to blow TESTBIT (Dan's TZ, and I can count the amount of public TrustZone Exploits I have seen in my career on two hands (5 HTC Specific, 3 Motorola Specific, 2 Generic TrustZone)

2.       Another method was described in a recent leak: There is a special hardware protected partition on the eMMC called “RPMB” (Not to be confused with RPM.mbn), that stores the roll back information on the QCOM Galaxy S4 variants. This can be theoretically restored to a blank state by removing the eMMC and hooking it up (using the correct pin outs) to a Linux Machine, which would then have to issue several (confidential/not-public knowledge) Toshiba eMMC Vendor Commands to wipe RPMB (or write the lowest known firmware value to it). After placing the eMMC back in the device, the device could theoretically downgrade to any previous firmware.

It is worth noting that all devices released by Samsung after the Galaxy S4 blow a physical QFUSE to signify rollback, meaning that they are not vulnerable (i.e. Note 3, Galaxy S5).

Theoretically Vulnerable Devices:

-          Galaxy S4 (All QCOM Variants) Method: Downgrade to Pre-Knox Bootloader, or to exploitable firmware, i.e. MDK (SCH-i545), MDL (SGH-i337)

-          Galaxy S3 (All QCOM Variants) Method: Downgrade to “African-Sock-Monkey” leaked Insecure (Unlocked) Bootloader

Likelihood:  4/10, would work if we had the correct pin-out for our eMMC, and the Toshiba Vendor Commands, but getting our hands on the latter is unlikely. – Still under research

3.       Yet another method is described below:

KEXEC is a tool used to overwrite the Linux kernel in memory with a new kernel, and then execute the new kernel without ever taking the system down for full reboot (hardware always remains live). It has become increasingly more common to see KEXEC implementations to bypass android device Bootloader security, as many times, it is far simpler than finding a vulnerability that would allow a full unlock.

KEXEC must be loaded in as a kernel module to work correctly. So, to even attempt a KEXEC bring up, we first need root access and the ability to load custom (un-signed) kernel modules. I will be speaking about the Verizon Galaxy S4 almost exclusively here, although this theoretically applies to most Samsung devices.

First step is root, easily attained on all >4.4.4 devices via the Futex bug (originally by Comex, though ported to android by George Hotz in the form of TowelRoot.apk), and as long as the device in question hasn’t been upgraded to Android 5.0 yet, you can always just roll back to a Futex vulnerable firmware and root. We then install BusyBox, and SafeStrap (A boot hijack that allows us to flash ROM’s, and access a terminal before any partitions are mounted originally by HashCode, updated by Muniz_ri), this gives us a base for KEXEC work/debugging, and a place to optimally execute it. Next is un-signed kernel modules, on the S4, the process that checks to see if kernel module signatures are require is called KLSM. There is a known exploit by Jeboo that was initially created for 4.3 (MK2) called BypassLKSM, that was later ported to 4.4.2 (NC5) by Surge1223, and then later to 4.4.2 (NK1) by myself and Demetulth.
EDIT: VZW S4 has Lollipop (5.0.1, OC1), researching BypassLKSM addresses now…
-EDIT 2: Found them.

Now, we build our version of KEXEC using the NC5 kernel source (As Samsung has yet to release the NK1 kernel source 5 months after release, GPL violation? Big time)

Now to actually execute KEXEC! We then boot up to safestrap (a recovery boot hijack, and at that, a special version with devmem2 & viewmem), push the built KEXEC modules, ramdisk, and vmlinuz (kernel) to the root of the device, connect the device to your computer via USB, and run  commands with similar syntax(s) to these:

Adb shell


Insmod kexec_arm.ko

Insmod kexec_machine.ko

Insmod Kexec.ko

Lsmod       #Expected output should list all 3 modules listed above

kexec -l /stock_nk1_zImage --ramdisk=/ramdisk.cpio.gz --append="($cat $cmdline)" --atags-file=/atags

unmount –a #My recommendation would be to unmounts all partitions manually

(In a separate terminal)ADB Shell su –c “dmesg”

(In the first terminal) kexec- e

After the system attempts to soft-boot the kernel (and inevitably fails), we have to pull a last_kmesg, and look at the DMESG we got in the second terminal we pulled up earlier. We then try to debug the problems it is having. Right now, we are hanging at being unable to flush the kernel caches correctly & at the correct time in the KEXEC sequence, as well as the kernel being corrupted in purgatory.

Likelihood:  7/10, will work if we can debug all of the issues, not a question of “if”, as it is “how”, and “when– Still under research.

4.       An alternative idea was to mask TESTBIT in memory using JTAG to disable rollback, and then KEXEC to boot to Download Mode and attempt to do so without emptying the memory. This failed in our attempts, because for one reason or another, we were unable to keep the memory from reverting the value of TESTBIT to the pre-masked version.

Likelihood:  1/10, failed miserably, if we could find a way to retain memory contents after the softboot to Download Mode, it could work.

5.       Another proposed method of attack was using KEXEC Hardboot (a way to KEXEC to a new kernel from a full reboot) – This posed extremely similar results to KEXEC, but provided no logs whatsoever, as last_kmesg had been cleared upon reboot, and the DMESG was of no use, as it just stated that the system went down for reboot, so we had no method to debug it.

Likelihood:  1/10, failed miserably in testing, no way to debug it due to lack of logs.

6.       A proposed method, that has yet to come to fruition, is the potential for a vulnerability in QCOM Download Mode (See the referenced bootchain.pdf earlier in the article for explanation), as it allows you to boot an SBL1 (as long as it is signed and within rollback), from the SD Card. This mode can only be accessed if SBL1 is damaged/not signed/not present.

Likelihood:  1/10, failed miserably in testing, no documentation provided for QCOM mode, hard to work with.

7.        Similar to the above method, is the potential for a vulnerability in QCOM Download Mode itself, and the way it boots SBL1 from the SD Card (via debrick.img).

Likelihood:  3/10, requires more research, no documentation provided for QCOM mode, hard to work with, and would require specially crafted debrick.img. – Still under research

8.       Another proposed potential vantage point is a vulnerability in ODIN that would allow us to modify protected partitions of the device.

Likelihood:  1/10, almost complete chance, would require reverse engineering of ODIN, and a special kind of vulnerability.

9.       Yet another method is to reverse engineer how developer edition devices aboot is signed, though, even if we deduced the algorithm, we would still need access to Samsung’s RSA & Private Key (likely could only happen via a leak).

Likelihood:  0.000000001/10, would require Samsung’s RSA & Private key to be leaked, which is almost impossible.

10.   Another idea to be considered is finding a way to write the CID of the device, allowing us to boot another (developer edition) devices signed, unlocked aboot.

Likelihood:  6/10, Can definitely work, but would be highly illegal, as we legally can’t spoof our device’s CIDs, falls under the same category as IMEI/ESN spoofing, but is much harder to do.

12.   On final idea to consider is that there is a mode known only as “Factory Mode”, this is the mode wherein the manufacturer writes the CID, partition layout, fuse values, etc. It basically serves as a “God-Mode” for the device, but can only be accessed once, and then it is permanently disabled. If we could find a way to get the device to revert to this mode, anything would be possible.

Likelihood:  0.00000000000000001/10, would require a godsend of a vulnerability, would likely have to be at PBL level, and would likely affect all QCOM devices if found.