Both the AT&T (SGH-I337) and Verizon (SCH-I545) models utilize the Qualcomm APQ8064T chipset. As described in my previous blog post on Motorola's bootloader, Qualcomm leverages software-programmable fuses known as QFuses to implement a trusted boot sequence. In summary, each stage of the boot process cryptographically verifies the integrity of the subsequent stage, with the trust root originating in QFuse values. After the early boot stages bootstrap various hardware components, Samsung's APPSBL ("Application Secondary Bootloader") is loaded and run. This bootloader differs between "locked" and "unlocked" variants of the Galaxy S4 in its enforcement of signature checks on the boot and recovery partitions.
A quick glance at aboot (adopting the name of the partition on which this bootloader resides) revealed that it is nearly identical to the open source lk ("Little Kernel") project, which undoubtedly saved me many hours of tedious reverse engineering. By locating cross-references to strings found in both lk and aboot, I was able to quickly identify the functions that implement signature verification and booting of the Linux kernel.
The central logic to load, verify, and boot the Linux kernel and ramdisk contained in either the boot or recovery partitions is implemented in the boot_linux_from_mmc() function. First, the function determines whether it is booting the main boot partition, containing the Linux kernel and ramdisk used by the Android OS, or the recovery partition, which contains the kernel and ramdisk used by the Android recovery subsystem. Then, the first page of the appropriate partition is read into physical memory from the eMMC flash storage:
if (!boot_into_recovery) {
index = partition_get_index("boot");
ptn = partition_get_offset(index);
if (ptn == 0) {
dprintf(CRITICAL, "ERROR: No boot partition found\n");
return -1;
}
}
else {
index = partition_get_index("recovery");
ptn = partition_get_offset(index);
if (ptn == 0) {
dprintf(CRITICAL, "ERROR: No recovery partition found\n");
return -1;
}
}
if (mmc_read(ptn + offset, (unsigned int *) buf, page_size)) {
dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
return -1;
}
This code is straight out of lk's implementation. Next, after performing some sanity-checking of the boot image, which contains a custom header format, the function loads the kernel and ramdisk into memory at the addresses requested in the boot image header:
hdr = (struct boot_img_hdr *)buf;
image_addr = target_get_scratch_address();
kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask) + 0x200;
imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
memcpy(image_addr, hdr, page_size);
offset = page_size;
/* Load kernel */
if (mmc_read(ptn + offset, (void *)hdr->kernel_addr, kernel_actual)) {
dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
return -1;
}
memcpy(image_addr + offset, hdr->kernel_addr, kernel_actual);
offset += kernel_actual;
/* Load ramdisk */
if (mmc_read(ptn + offset, (void *)hdr->ramdisk_addr, ramdisk_actual)) {
dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
return -1;
}
memcpy(image_addr + offset, hdr->ramdisk_addr, ramdisk_actual);
offset += ramdisk_actual;
This is still essentially identical to lk's implementation, with the addition of code to copy the individual pieces of the boot image to the image_addr location. Finally, the function performs signature verification of the entire image. If signature verification succeeds, the kernel is booted; otherwise, a tampering warning is displayed and the device fails to boot:
if (check_sig(boot_into_recovery))
{
if (!is_engineering_device())
{
dprintf("kernel secure check fail.\n");
print_console("SECURE FAIL: KERNEL");
while (1)
{
/* Display tampered screen and halt */
...
}
}
}
/* Boot the Linux kernel */
...
The is_engineering_device() function simply returns the value of a global variable that is set at an earlier stage in the boot process based on whether or not the chipset ID (an unchangeable hardware value) of the device indicates it is an engineering or production device.
Examining the check_sig() function in more detail revealed that aboot uses the open-source mincrypt implementation of RSA for signature validation. The bootloader uses an RSA-2048 public key contained in aboot to decrypt a signature contained in the boot image itself, and compares the resulting plaintext against the SHA1 hash of the boot image. Since any modifications to the boot image would result in a different SHA1 hash, it is not possible to generate a valid signed boot image without breaking RSA-2048, generating a specific SHA1 collision, or obtaining Samsung's private signing key.
The astute reader will have already noticed the design flaw present in the above program logic. Notice the order in which the steps are performed: first, aboot loads the kernel and ramdisk into memory at the addresses requested by the boot image header, and then signature validation is performed after this loading is complete. Because the boot image header is read straight from eMMC flash prior to any signature validation, it contains essentially untrusted data. As a result, it's possible to flash a maliciously crafted boot image whose header values cause aboot to read the kernel or ramdisk into physical memory directly on top of aboot itself!
Exploitation of this flaw proved to be fairly straightforward. I prepare a specially crafted boot image that specifies a ramdisk load address equal to the address of the check_sig() function in aboot physical memory. In my malicious boot image, I place shellcode where the ramdisk is expected to reside. I flash this image by leveraging root access in the Android operating system to write to the boot block device. When aboot reads the supposed ramdisk from eMMC flash, it actually overwrites the check_sig() function with my shellcode, and then invokes it. The shellcode simply patches up the boot image header to contain sane values, copies the actual kernel and ramdisk into appropriate locations in memory, and returns zero, indicating the signature verification succeeded. At this point, aboot continues the boot process and finally boots my unsigned kernel and ramdisk. Victory!
Thanks to ralekdev for the helpful exchange of ideas and suggestions.
Thank you very much for this. I won't be getting an SGS4, but in general I find it exponentially more valuable to have understanding and an exploit, than simply believing in magic.
ReplyDeleteThank D.R. for letting us know about the technical details. Awesome find with the Little Kernel OSP! Excellent security research.
ReplyDeleteThank you sir, you rock.
ReplyDeleteWell written and executed.
That's a great hack. Thank you for this.
ReplyDeleteIt is ridiculous how good you are at this stuff.
ReplyDeleteThanks from the entire SGS4 community!
Dan, as usual, you rock ;)
ReplyDeleteHopefully you are well compensated for your intelligence :)
ReplyDeleteVery nice! This is a great expoit and pretty easy one too :) good job on noticing the lk similarities.
ReplyDeletedoes this root the phone?
ReplyDeleteGood post . Thanks a lot.
ReplyDeletehey could you take a crack at the pantech bootloader for the flex
ReplyDeleteI will never be this smart.
ReplyDeletethe correct design would likely not solely involve verifying the signature on eMMC but also when copying into RAM calculating a SHA2 and comparing with the verified image. This will be to mitigate a TOCTOU style attack.
ReplyDeleteCould Samsung have signature-checked the boot header to make sure it doesn't load ontop of aboot, not overwriting checkSig()?
ReplyDeleteCan you do some hack to unlock iPhone 5? Thank you!
ReplyDeleteNice explanation,
ReplyDeleteCheers.
So we have learned today that it is otherwise POINTLESS for carriers and manufacturers to 'lock' their bootloaders, or roms, etc.
ReplyDeletethe lesson to be learned here: if you are designing something make it possible to 'lock' your ROM and bootloaders with cryptographic keys of extreme and lengthy strength. Otherwise, just GIVE USERS THE DARN KEYS FROM THE START!
Can you do the same thing to a iPad mini?
ReplyDeleteYES please. Thank you! Was so tired of touchwiz. NOW I can see why you waited until Verizons phone was out.
ReplyDeleteWould you elaborate more on how to Root SGs4? Thanks a million.
ReplyDeleteSo I'm curious, why couldn't this exploit be use to replace the aboot image with an image that is patched to always see the qfuse unblown? thus effectively unlocking the bootloader without needing loki to flash kernels and recoveries.
ReplyDeleteAnonymous:
ReplyDeleteI'm not sure what QFuse you're talking about, since whether a Galaxy S4's aboot is "unlocked" or not is not dependent on a QFuse.
You can't replace aboot itself because signatures are validated at each stage of the boot chain (pbl -> sbl1 -> sbl2 -> sbl3 -> aboot). Writing a tampered aboot would cause sbl3 to fail signature validation.
Dan I meant the QFuse for loading kernels or recoveries not a QFuse for aboot. But the second part of your reply answered my question. I thought maybe aboot would check the signature when loading a new aboot I didn't know it checked it every time you boot.
ReplyDeleteI like this blog and the statements which you have used in this blog.I found so many things in this page so i saved it in my favourite.
ReplyDeleteThanks for the info :)
ReplyDeleteAny chance you'll take a crack at any of their new firmwares?
ReplyDeleteI have brand new galaxy, "galaxy s4 lte-a(E330S)".
ReplyDeletebut your program can not find check function in its aboot.img
Is there any way to crack this?
I'd like to know what changed in the vzw update that killed this.
ReplyDeleteAny chance you can apply your talents to the LG Optimus L9. All dev attempts have failed.
ReplyDeleteVery informative post about Exploiting Samsung Galaxy S4 Secure Boot, Galaxy S4 users will once again be able to move apps to their SD car, assuming the apps allow the option. There has been a Secure Boot Image added for use with Knox, but the bootloader itself still isn't locked and is still easily rooted. Thanks for sharing.
ReplyDeleteI don't think he will. Everyone has given up on the new locks.
ReplyDeleteIt is possoble you turn a i9505 to i9505g?
ReplyDeleteI'd love to see this masterpiece working ;)
ReplyDeletePlease share your work at http://forum.xda-developers.com/
Great Work!
Thank you for the light in tunnel. Now we can override this Knox Crap.
ReplyDeleteCan you please share your ida pro aboot.mbn loader plugin?
ReplyDeletevery very clever nice to have a little insight into how it works,thanks for the info
ReplyDeleteI am having a "Samsung Galaxy S4-i337 AT&T" which i got as a gift from US.
ReplyDeleteModel no: SAMSUNG-SGH-I337
ANDROID VERSION: 4.2.2
BASEBAND VERSION: I337UCUAMDL
KERNAL VERSION: 3.4.0-453947
SE.INFRA@SEI-46#1
SAT APR 27 17:06:05 KST 2013
BUILD NO: JDQ39.I337UCUAMDL
IMEI : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (I AM HESITANT TO POST IT)
NETWORK UNLOCK CODE : 5XXXXXXX
Currently i am staying in India, When i put a new 3g BSNL sim card in it , phone asked for network unlock code, unfortunately i didn't know the importance of it and i entered some random numbers(more than 5 times) and now my network unlocking is permanently blocked by AT&T. I have contacted them they saying my phone is permanently locked and can use only with AT&T network sim card. I have tried to unlock with the method mentioned in XDA forums but unfortunately negative result. I have contacted Samsung , AT&T and BSNL service centers nobody could give a solution to my problem.
What can i do with my phone now to use it with BSNL sim card in India...
Thanks in advance.....all genius people out there help me please........
this post is last hope...
I‘am using S4(SC-04E,DCM) now, my nuild is SC04EOMUAMF2, I am trying to modify the "aboot.mbn", can you help to locate the entry point by IDA, or give me some tips about mbn file?
ReplyDeleteI have already locate the strings in mbn by IDA, but I can find cross-references.
Nice read Dan! I am a developer interesting in researching an MF3 bootloader exploit. Any tips?
ReplyDeleteGreat work Dan. I hate to be a noob (and I really should know the answer to this question..), but how did you figure out the aboot.mbn entry points? How big are the RAM/ROM sections, header, signature, and program? Are these features of ARM in general that I'm somehow missing, or is this specific to the partition? I've explored lk and still not finding a way to successfully disassemble the image. On another point, how would I know if the image is encrypted? I'm guessing I wouldn't see legible output when I run the binary through 'strings', correct?
ReplyDeleteCheers,
Mike
Thanks so much Dan, but i have a problem
ReplyDeleteWell, i try to make my patch, but i have the response:
[+] loki_patch v2.1
[-] Failed to find function to patch.
Using SCH-i545 4.3
Some news about this?
Dan, would you care to take a look a little at this thread on XDA and give us some feedback if the (accidental) presence of SECUREBOOT:NONE would be of any help in fully unlocking the N9005? Thank you very much!
ReplyDeletehttp://forum.xda-developers.com/showthread.php?p=48579747
Samsung ... naturally stupid
ReplyDeleteshould be used in their next commercials ....
Thank for sharing your idea about secure boot Galaxy S4
ReplyDeleteGalaxy S4 is the best model of all Notes and SX models
ReplyDeleteCan you do this for LG G2 kitkat version?
ReplyDeleteCan you please look into the Lg g flex
ReplyDeleteHey will it work for galaxy grand 2
ReplyDeletePlease do the same on Samsung Galaxy Note3 SM-N9005
ReplyDeletePlease help us out with the AT&T and Verizon note 3
ReplyDeleteDan is there a place I can download this unsigned image from, that you used to make your s4 boot?
ReplyDeleteUnlocking your AT&T HTC Aria by remote unlock code is 100% safe. These phones were built to accept unlock codes. It is the same method service providers will use to unlock their devices. Cellphone unlocking is also 100% legal and will not void warranty on your device.
ReplyDeletehttp://www.attphoneunlockingshop.us/
Hi Dan! How can I use this information to actually unfuse a smartphone? I'm programmer and enrolled in a Automation Engineering course, I already done some custom ROMs but I don't know the firsts steps that I need to take in order to break the secure boot. I must enter in shell (via adb), debug some kernel object (with gdb) and call this function? Or must I change the kernel source, put this function call, recompile the ROM and upload? Or I need to change the machine code of the ROM binaries to hack this? Or I need to do this via a JTAG? Or I need to pull a partition and save to a file, edit this binary file in machine code to force that call and update the partition with this edited file? I know how to do things like this, but I don't know how path I have to take.
ReplyDeletei have a s4 build i545vrufnk1 i have tried everything i could on line when in odin everything connects but when i try and start odin it fails any help would be great
ReplyDeleteDo you have a tool to unloki? I am trying to edit my boot, but it's got loki and I'm new to this. I compiled loki_tool but came to realize this is for patching when a mod is already ready.
ReplyDeleteHello, Dan,
ReplyDeletegreat exploit. Do you know can it be applied to NEC Terrain? Or other way around: do you know that it cannot by the different nature of the boot lock? For the moment it was a problem that even root (temporary) cannot write to partitions. I found a snaky way and CAN write, so I can flash whatever on the internal memory. I can provide I hope everything upon your request.
Now I'm waiting for my other guys to disasm and decompile the aboot binary. Everything suggests that the story is VERY similar or identical to your findings in S4, LG, etc. I hope to find the address of the important function myself.
Will you, however, be able to help by supporting (or correcting) my findings about the function address. My problem is that I'm quite new for arm, android, etc. I'm pc c/c++/assembler guy.
What might you need? aboot image I guess and the boot image (or atleast it first portion as the image itself is big, 10M), correct?
Thanks in advance, Alex alex-kas at altaray dot com