project zeus "You will not be informed of the meaning of Project Zeus until the time is right for you to know the meaning of Project Zeus."

Archives Current Posts April 2010 May 2010 August 2010 September 2012 February 2013 March 2013 April 2013 May 2013 June 2013 December 2013 March 2014 January 2015 Posts Re-visiting the Exynos Memory Mapping Bug Re-visiting the Exynos Memory Mapping Bug On December 15, 2012, a member of the XDA Developer Forums going by the handle "alephzain" published a vulnerability affecting all Android devices using the Samsung Exynos chipset and running Android 4.0 (Ice Cream Sandwich) or greater. Affected devices include the extremely popular international variant of the Galaxy S3 (the North American version is not affected because it uses a Qualcomm chipset instead), and Exynos variants of the Galaxy S2, Galaxy Note, Galaxy Note 2, and Galaxy Tab.





The vulnerability allows any unprivileged user to read and write to arbitrary physical memory on an affected device by mmap()-ing a file descriptor to the world-writable device file at /dev/exynos-mem. Alephzain's exploit utilizes this capability by mapping the kernel address space, modifying a format string used by the kptr_restrict security feature in order to disable it, and finally modifying the .text segment of the kernel itself in order to trigger a privilege escalation payload and gain root privileges. The original exploit is available on



On February 2, 2013, alephzain published an APK version of his exploit, which he called

Analyzing Framaroot First, I decompiled the Framaroot APK to Java using dex2jar and jad (other toolchains exist, but this works fine for me). Taking a look at com.alephzain.framaroot.FramaActivity revealed the following logic:



public native String[] Check(); public native long Launch(String s); protected void onCreate(Bundle bundle) { ... String as[] = Check(); if(as.length == 0) { /* Device not affected, exit */ ... } else { ... /* Device affected, launch new thread to exploit */ LaunchThread launchthread = new LaunchThread(adapterview.getItemAtPosition(i).toString()); launchthread.start(); ... } }

The above code first invokes the Check() native method to probe for the existence of a supported vulnerability, and if successful, launches a new thread that invokes the native Launch() method. These methods are both implemented in a bundled dynamic library, lib/armeabi/libframalib.so.



Reverse engineering the Check() method in the bundled library revealed that alephzain had defined a structure containing information for each supported target. This structure looks something like the following:



struct target { char *tag; char *device_name; int fd; int flags; unsigned long offset; unsigned long size; unsigned long start_offset; unsigned long device_len; int (*)(void) func1; int (*)(void) func2; }; Multiple Exploit Targets A global array of targets contains four of these structures, with tags "Sam", "Gimli", "Merry", and "Frodo" (I guess alephzain is a Lord of the Rings fan). The device_name field contains an encoded representation of a vulnerable device file (for example, /dev/exynos-mem). The Check() function iterates through each target, decodes its device file name using a simple XOR cipher, and checks for the existence of a world-writable device file of that name as follows:



struct *target; struct stat st; char file[32]; char *key; /* Simplified... */ key = get_key(); for (i = 0; i < 4; i++) { memset(file, 0, 32); target = targets[i]; idx = 0; for (j = 0; j < target->device_len; j++) { file[j] = (key[idx] + 1) ^ *(target->device_name + j); idx = (idx + 1) % 4; } if ((stat(file, &st) != -1) && (st.st_mode & (S_IROTH|S_IWOTH))) { /* Target found */ ... } ... }

Rather than going through the trouble of reversing the above XOR cipher, it's also possible to install the Framaroot APK, launch the application, attach GDB to the process, place a breakpoint right before the call to stat(), and inspect the r0 register. Doing so yields the names of the device files exploited by this library: /dev/exynos-mem, /dev/s5p-smem, and /dev/DspBridge. While the first of these vulnerable devices was disclosed with the original Exynos exploit, the latter two were previously unpublished.

Same Bug, Different Devices Inspecting affected kernel code reveals that /dev/s5p-smem is another world-writable device file on Exynos Android phones running ICS or greater. The code is implemented in arch/arm/mach-exynos/secmem-allocdev.c in Exynos kernel trees. This device file functions identically to /dev/exynos-mem in that it allows unprivileged users to map arbitrary physical memory. Fortunately, Samsung's latest update to fix the issues with /dev/exynos-mem modified the file permissions on the s5p-smem device file so that it is no longer world-accessible, mitigating the vulnerability.



The second new device is more of the same: yet another device file that allows unprivileged users to map arbitrary physical memory. This bug appears in kernels for devices using the TI OMAP3 chipset, which includes a number of popular older devices, such as the Motorola Droid, Droid 2, and Droid X. For reference, the affected code is implemented in drivers/dsp/bridge/rmgr/drv_interface.c and even includes a helpful comment:



/* This function maps kernel space memory to user space memory. */ static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) { u32 status; vma->vm_flags |= VM_RESERVED | VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot); if (status != 0) status = -EAGAIN; return status; }

As in the other examples, this code maps an arbitrary range of physical frames specified by the offset argument to mmap() into the user's address space.



Unlike the Exynos vulnerabilities, which were quickly patched by Samsung, most devices affected by this OMAP vulnerability no longer receive carrier updates, so it is likely that this bug will remain exploitable indefinitely on all affected devices.

Samsung's Incomplete Fix So far, we've discovered three variants of the same bug, all of which are exploited in Framaroot. So what's Framaroot's fourth target?



Looking at the patch Samsung released to address the original Exynos flaw reveals the answer. In drivers/char/exynos_mem.c, we see the addition of the following lines:



int exynos_mem_mmap(struct file *filp, struct vm_area_struct *vma) { struct exynos_mem *mem = (struct exynos_mem *)filp->private_data; bool cacheable = mem->cacheable; dma_addr_t start = 0; u32 pfn = 0; u32 size = vma->vm_end - vma->vm_start; if (vma->vm_pgoff) { start = vma->vm_pgoff << PAGE_SHIFT; pfn = vma->vm_pgoff; } else { start = mem->phybase << PAGE_SHIFT; pfn = mem->phybase; } if (!cma_is_registered_region(start, size)) { pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited

", __func__, size, start); return -EINVAL; } ... }

Presumably, this new function ensures that the requested mmap() region is safe to map to userland. The cma_is_registered_region() function is implemented in mm/cma.c:



bool cma_is_registered_region(phys_addr_t start, size_t size) { struct cma_region *reg; cma_foreach_region(reg) { if ((start >= reg->start) && ((start + size) <= (reg->start + reg->size))) return true; } return false; }

This function iterates over registered CMA regions, and attempts to check that the requested mapping falls within one of the allowed regions.



However, this code contains a fairly obvious integer overflow in the check: what happens if (start + size) overflows its 32-bit representation, wrapping around to a smaller number? As a result, it's possible to provide pgoff and size values to mmap() that circumvent this check and map arbitrary kernel memory once again.



Quickly disassembling the Launch() function in alephzain's native library shows that Framaroot employs this tactic to sidestep Samsung's fix. After running the device name decoding loop again, Launch() opens the affected device file and invokes mmap() with arguments provided by the target structure:



target = targets[idx]; target->fd = = open(file, O_RDWR); if ( target->fd == -1 ) { return -1; } addr = mmap(0, target->size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, target->fd, target->offset);

Examining Framaroot's fourth target reveals a size value of 0x50000000 and an offset value of 0xfffff000 . These values will pass the above check due to the integer overflow, and map a large chunk of physical memory outside the allowed CMA region, allowing overwriting kernel memory.



At the time of this blog post, this fourth vulnerability remains unpatched on the latest Samsung Galaxy S3 build, and presumably affects the rest of the Exynos models as well. On December 15, 2012, a member of the XDA Developer Forums going by the handle "alephzain" published a vulnerability affecting all Android devices using the Samsung Exynos chipset and running Android 4.0 (Ice Cream Sandwich) or greater. Affected devices include the extremely popular international variant of the Galaxy S3 (the North American version is not affected because it uses a Qualcomm chipset instead), and Exynos variants of the Galaxy S2, Galaxy Note, Galaxy Note 2, and Galaxy Tab.The vulnerability allows any unprivileged user to read and write to arbitrary physical memory on an affected device by-ing a file descriptor to the world-writable device file at. Alephzain's exploit utilizes this capability by mapping the kernel address space, modifying a format string used by thesecurity feature in order to disable it, and finally modifying thesegment of the kernel itself in order to trigger a privilege escalation payload and gain root privileges. The original exploit is available on XDA . Shortly after the publication of this vulnerability, Samsung released updates for several of its devices, including the Galaxy S3.On February 2, 2013, alephzain published an APK version of his exploit, which he called Framaroot . Examining this APK revealed that alephzain had added exploits for additional vulnerabilities besides the original Exynos flaw.First, I decompiled the Framaroot APK to Java using dex2jar and jad (other toolchains exist, but this works fine for me). Taking a look atrevealed the following logic:The above code first invokes thenative method to probe for the existence of a supported vulnerability, and if successful, launches a new thread that invokes the nativemethod. These methods are both implemented in a bundled dynamic library,Reverse engineering themethod in the bundled library revealed that alephzain had defined a structure containing information for each supported target. This structure looks something like the following:A global array of targets contains four of these structures, with tags "Sam", "Gimli", "Merry", and "Frodo" (I guess alephzain is a Lord of the Rings fan). Thefield contains an encoded representation of a vulnerable device file (for example,Thefunction iterates through each target, decodes its device file name using a simple XOR cipher, and checks for the existence of a world-writable device file of that name as follows:Rather than going through the trouble of reversing the above XOR cipher, it's also possible to install the Framaroot APK, launch the application, attach GDB to the process, place a breakpoint right before the call to, and inspect theregister. Doing so yields the names of the device files exploited by this library:, and. While the first of these vulnerable devices was disclosed with the original Exynos exploit, the latter two were previously unpublished.Inspecting affected kernel code reveals thatis another world-writable device file on Exynos Android phones running ICS or greater. The code is implemented inin Exynos kernel trees. This device file functions identically toin that it allows unprivileged users to map arbitrary physical memory. Fortunately, Samsung's latest update to fix the issues withmodified the file permissions on thedevice file so that it is no longer world-accessible, mitigating the vulnerability.The second new device is more of the same: yet another device file that allows unprivileged users to map arbitrary physical memory. This bug appears in kernels for devices using the TI OMAP3 chipset, which includes a number of popular older devices, such as the Motorola Droid, Droid 2, and Droid X. For reference, the affected code is implemented inand even includes a helpful comment:As in the other examples, this code maps an arbitrary range of physical frames specified by theargument tointo the user's address space.Unlike the Exynos vulnerabilities, which were quickly patched by Samsung, most devices affected by this OMAP vulnerability no longer receive carrier updates, so it is likely that this bug will remain exploitable indefinitely on all affected devices.So far, we've discovered three variants of the same bug, all of which are exploited in Framaroot. So what's Framaroot's fourth target?Looking at the patch Samsung released to address the original Exynos flaw reveals the answer. In, we see the addition of the following lines:Presumably, this new function ensures that the requestedregion is safe to map to userland. Thefunction is implemented inThis function iterates over registered CMA regions, and attempts to check that the requested mapping falls within one of the allowed regions.However, this code contains a fairly obvious integer overflow in the check: what happens ifoverflows its 32-bit representation, wrapping around to a smaller number? As a result, it's possible to provideandvalues tothat circumvent this check and map arbitrary kernel memory once again.Quickly disassembling thefunction in alephzain's native library shows that Framaroot employs this tactic to sidestep Samsung's fix. After running the device name decoding loop again,opens the affected device file and invokeswith arguments provided by the target structure:Examining Framaroot's fourth target reveals avalue ofand anvalue of. These values will pass the above check due to the integer overflow, and map a large chunk of physical memory outside the allowed CMA region, allowing overwriting kernel memory.At the time of this blog post, this fourth vulnerability remains unpatched on the latest Samsung Galaxy S3 build, and presumably affects the rest of the Exynos models as well. Labels: Android, Privilege Escalation, Vulnerabilities 5 comments: Subscribe to Post Comments [Atom] << Home