#include #include #include #include extern char* optarg; extern int optind; int ETHHDRSIZE = 0; /* The reverse of packet_encode */ void packet_decode(int input_size, char* input, char* output) { int c; for (c=input_size-1; c > 0; c--) { output[c] = input[c] - input[c-1] - 0x17; } output[0] = input[0] - 0x17; } /* Proces captured pcap packet */ void process_pcap(u_char *temp1, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) { struct iphdr* ip; unsigned char packet[1000]; if (!pkt_data) return; ip = (struct iphdr*)(pkt_data + ETHHDRSIZE); if (ip->protocol == 0x0B) { if (ntohs(ip->tot_len) < 200) { printf("Undersized 0x0B packet, %d bytes\n", ip->tot_len); return; } switch (pkt_data[ETHHDRSIZE+20]) { case 2: packet_decode(ntohs(ip->tot_len)-22, (char*)&pkt_data[ETHHDRSIZE+22], (char*)packet); switch (packet[1]) { case 1: printf("status\n"); break; case 2: printf("init: type=%d control_ip=%u.%u.%u.%u\n", packet[2], packet[3], packet[4], packet[5], packet[6]); break; case 3: printf("exec_output: \"%s\"\n", &packet[2]); break; case 4: printf("dns_smurf: "); if (packet[8] == 0) printf("victim=%u.%u.%u.%u ", packet[2], packet[3], packet[4], packet[5]); else printf("victim=%s ", &packet[9]); if (packet[6] && packet[7]) printf("s_port=%u ", ((int)packet[6] << 8) + packet[7]); printf("\n"); break; case 5: if (packet[2]) printf("udp_flood: "); else printf("icmp_flood: "); printf("src=%u.%u.%u.%u ", packet[4], packet[5], packet[6], packet[7]); if (packet[12] == 0) printf("dst=%u.%u.%u.%u ", packet[8], packet[9], packet[10], packet[11]); else printf("dst=%s ", &packet[13]); if (packet[2]) printf("d_port=%d ", packet[3]); printf("\n"); break; case 6: printf("bind_shell\n"); break; case 7: printf("exec: \"%s\"\n", &packet[2]); break; case 8: printf("kill\n"); break; case 9: printf("dns_smurf: "); if (packet[9]) printf("victim=%u.%u.%u.%u ", packet[2], packet[3], packet[4], packet[5]); else printf("victim=%s ", &packet[10]); if (packet[7] && packet[8]) printf("s_port=%d ", ((int)packet[7] << 8) + packet[8]); printf("sleep_after=%d\n", packet[6]); break; case 10: printf("syn_flood: "); if (packet[8]) printf("src=%u.%u.%u.%u ", packet[9], packet[10], packet[11], packet[12]); else printf("src=random "); if (packet[13] == 0) printf("dst=%u.%u.%u.%u ", packet[2], packet[3], packet[4], packet[5]); else printf("dst=%s ", &packet[14]); printf("d_port=%d\n", ((int)packet[6] << 8) + packet[7]); break; case 11: printf("syn_flood: "); if (packet[8]) printf("src=%u.%u.%u.%u ", packet[9], packet[10], packet[11], packet[12]); else printf("src=random "); if (packet[14] == 0) printf("dst=%u.%u.%u.%u ", packet[2], packet[3], packet[4], packet[5]); else printf("dst=%s ", &packet[15]); printf("d_port=%d ", ((int)packet[6] << 8) + packet[7]); printf("sleep_after=%d\n", packet[13]); break; case 12: printf("dns_flood: "); if (packet[6] || packet[7] || packet[8] || packet[9]) printf("src=%u.%u.%u.%u ", packet[6], packet[7], packet[8], packet[9]); else printf("src=random "); if (packet[13] == 0) printf("dst=%u.%u.%u.%u ", packet[2], packet[3], packet[4], packet[5]); else printf("dst=%s ", &packet[14]); if (packet[11] || packet[12]) printf("s_port=%d ", ((int)packet[11] << 8) + packet[12]); else printf("src=random "); printf("sleep_after=%d\n", packet[10]); break; default: printf("Unknown request code %d\n", packet[1]); return; } break; case 3: packet_decode(ntohs(ip->tot_len)-22, (char*)&pkt_data[ETHHDRSIZE+22], (char*)packet); if ((packet[1] == 1) && (packet[2] = 7)) { printf("Status reply: "); if (packet[3] == 0) printf("idle\n"); else { switch (packet[4]) { case 4: printf("dns_smurf\n"); break; case 5: printf("udp_flood or icmp_flood\n"); break; case 6: printf("bind_shell\n"); break; case 9: printf("dns_smurf with sleep_interval\n"); break; case 10: printf("syn_flood\n"); break; case 11: printf("syn_flood with sleep_interval\n"); break; default: printf("unknown code %d\n", packet[4]); break; } } } else if (packet[2] != 0) printf("reply:\n%s\n", &packet[2]); else printf("reply end\n"); break; case 4: packet_decode(ntohs(ip->tot_len)-22, (char*)&pkt_data[ETHHDRSIZE+22], (char*)packet); printf("reply followup:\n%s\n", &packet[2]); break; default: printf("Unknown packet signature %d\n", pkt_data[ETHHDRSIZE+20]); break; } } return; } int main(int argc, char* argv[]) { struct pcap* pcapd; char ebuf[256]; char dumpfile[256]; char iface[32] = "any"; int datalink; int arg; int o_dumpfile = 0; int o_help = 0; while ((arg = getopt(argc, argv, "i:r:")) != EOF) { switch (arg) { case 'i': strcpy(iface, optarg); /* don't suid this program :-) */ break; case 'r': o_dumpfile = 1; strcpy(dumpfile, optarg); break; default: o_help = 1; } } if (o_help || (optind < argc)) { printf("the-binary Traffic Decoder\n"); printf("Syntax: the-binary [options]\n"); printf(" -i Listens on a interface\n"); printf(" -r Reads in a tcpdump file\n"); exit(1); } if (o_dumpfile) { pcapd = pcap_open_offline(dumpfile, ebuf); if (!pcapd) { printf("pcap_open_offline: cannot open file %s\n%s\n", dumpfile, ebuf); exit(1); } } else { pcapd = pcap_open_live(iface, 1518, 1, 200, ebuf); if (!pcapd) { printf("pcap_open_live: cannot open device %s\n%s\n", iface, ebuf); exit(1); } } datalink = pcap_datalink(pcapd); switch (datalink) { case DLT_NULL: ETHHDRSIZE = 4; break; case DLT_EN10MB: case DLT_EN3MB: ETHHDRSIZE = 14; break; case DLT_PPP: ETHHDRSIZE = 4; break; case DLT_RAW: ETHHDRSIZE = 0; break; case DLT_LINUX_SLL: ETHHDRSIZE = 16; break; default: printf("pcap_datalink: unknown interface type\n"); exit(1); } pcap_loop(pcapd, 0, process_pcap, NULL); return 0; }