Pangu jailbreak installs unlicensed code on millions of devices

The iPhone jailbreak Pangu for iOS 7.1-8.1 installs unlicensed code on millions of iDevices.

Introduction

For years iPhone jailbreaking has been a very controversial topic. Considered illegal by some including the vendor, customers had to fight in court to get a DCMA exception that finally ruled iPhone jailbreaking legal. However jailbreaking is still considered shady and many believe that the primary purpose of jailbreaking is to install pirated software copies. At the same time the jailbreaking community is trying hard to fight this stigma and jailbreak release groups like The iPhone Dev Team, Chronic-dev teams and finally the evad3rs tried their best to provide jailbreaking software that was clean from 3rd party code that would infringe on other people's copyright.

This all changed about five months ago, when a team of Chinese called PanguTeam released a shady jailbreak that relied on enterprise code-signing certificates, used vulnerabilities that were shared with them in the confidence that they would not be leaked and installed the 25pp app store that allegedly supports software piracy. But not only that they also took our code, incorporated it into their untether and distributed it to millions of iDevices without having a license that would allow this.

Pangu has basically managed to turn every single jailbreaker into a software pirate, because everyone is running the installed untether binary on their device that incorporates unlicensed code.

Kernelpatcher

We at SektionEins offer iOS Kernel Exploitation Trainings were we teach interested 3rd parties like security researchers and people who want to release the next public jailbreak. Throughout this course we give the students access to various internally developed tools and explain how they function directly on the source code of said tools. We provide these tools to the students in order for them to be able to perform research and work with new iOS releases. We welcome that people use what they learned from us to release their own public jailbreaks, but at no time during the course we give students the permission or a software license that would allow them to distribute our code as part of such a jailbreak to the general public.

One of these tools is for example called kernelpatcher / patcher70 or just patcher. It is a tool that takes a decrypted iOS kernel binary, searches for various code addresses inside the binary and then applies a number of patches to the code in order to disable kernel security features or to add new functionality. It incorporates some pieces of open source code made freely available by others that are not covered by a viral license like GPL. However a large part of the code is actually written by ourselves in order to adjust it to new kernel versions and to add new features. One of its features is also that it searches for slackspace inside the kernel and writes a debugging system call into it. We use this debugging system call throughout the training to give students the ability to play with the kernel without having to give them access additional real kernel vulnerabilities. The code of the kernelpatcher is furthermore shared with the students to explain to them in detail what patches need to be applied to the kernel to successfully disable the code-signing and other security features.

Like all of the other tools this one is shared with the students for the work in the course and for their research back home. At no point in time the students get a license to distribute this code freely to the world or to install it inside an untether binary on all jailbroken iDevices in the world.

Within the kernelpatcher there is a number of functions that were written by ourselves and mostly make sense in the context of the iOS kernel exploitation training. Therefore it is very easy to identify that someone uses this code in his product. One of such functions is called find_coredump(). The original idea behind this function was to find the unused coredump() function in the iOS 6 kernel. The space of that function would then be used by the kernelpatcher to store the code for the new debugging systemcall. Since iOS 7 the coredump() function has disappeared from the kernel this is why we replaced the find_coredump() function with the following hard coded code:

uint32_t find_coredump(uint32_t region, uint8_t* kdata, size_t ksize)
{
    // Find location of the "/cores/core.%d" string.
    uint8_t* corename = memmem(kdata, ksize, "/private/var/cores/%N.core", sizeof("/private/var/cores/%N.core"));
    if(!corename)
        return 0;

    return 0x950; /* hard coded in the mach-o header */

    ... some other original code for iOS 6 that will not get compiled due to the return ...
}

As you can see the function searches for some string that is part of iOS kernels, but does not really use it and instead returns a hardcoded value. Because it is code that does not make sense it means it is very easy to identify in a compiled binary (if not optimized out).

Pangu Untether

When you use the Pangu 8 jailbreak (or the Pangu 7 jailbreak before) it will install a so called untether binary on your device. This binary is responsible for exploiting the boot process over and over again every time you reboot the system. In Pangu 8 this binary is called xuanyuansword and is stored in the root directory of the device.

The binary we were looking into is from version 1.0.1 of the Pangu 8 jailbreak and has the sha1 hash: c69b532bfe835ce8f98b82fe36a415aa675b7b2f

If you now load this binary into a disassembler like IDA and jump to offset 0x2956c you will see the following.

__text:0002956C ; =============== S U B R O U T I N E =======================================
__text:0002956C
__text:0002956C
__text:0002956C sub_2956C
__text:0002956C                 PUSH            {R7,LR}
__text:0002956E                 MOVW            R3, #(:lower16:(aPrivateVarCore - 0x2957E)) ; "/private/var/cores/%N.core"
__text:00029572                 MOV             R0, R1
__text:00029574                 MOVT.W          R3, #(:upper16:(aPrivateVarCore - 0x2957E)) ; "/private/var/cores/%N.core"
__text:00029578                 MOV             R1, R2
__text:0002957A                 ADD             R3, PC  ; "/private/var/cores/%N.core"
__text:0002957C                 MOV             R7, SP
__text:0002957E                 MOV             R2, R3
__text:00029580                 MOVS            R3, #0x1B
__text:00029582                 BLX             _memmem
__text:00029586                 CMP             R0, #0
__text:00029588                 IT NE
__text:0002958A                 MOVNE.W         R0, #0x950
__text:0002958E                 POP             {R7,PC}
__text:0002958E ; End of function sub_2956C

Everybody who is familiar with ARM assembly will immediately see that this is the compiled version of the watermarking function find_coredump() which proves that Pangu incorporates code shared with them during our training and distributes it to the whole world without having a license that would allow this. Ironically this watermark function, which is the easiest to detect, was left inside the binary and distributed although it is not being called at all. However other functions from the same codebase are called and this is just one example of Pangu using unlicensed code.

It also needs to be noted that it has been reported that now parts of the Pangu 8 untether binary are heavily obfuscated to hide the code. It is therefore possible that other code is used that is hidden by layers of obfuscation and therefore harder to prove.

Stefan Esser