/* decoder.c - Decode traffic to/from the Honeynet project's "the-binary" DoS agent. Copyright (c) 2002 Chris Eagle This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * A quick and dirty decoder for the-binary traffic * minimal effort is expedend to indicate what the purpose of the * captured command may be, but the command is displayed in * its decoded format. In cases where the maximum amount of useful * information in the packet is know, the displayed packet is truncated * */ #include #include #include #include #include #include #include #include #define BUF_SIZE 202 #define STATUS_BYTE 25 #define STATE_BYTE 26 #define PAYLOAD 14 + 20 char *commands[] = {"status request", "set ip list", "exec1", "dns flood 1", "icmp/udp flood", "open root shell", "exec2", "kill job", "dns flood 2", "tcp syn flood 1", "tcp syn flood 2", "dns flood 3"}; int lengths[] = {4, 45, 64, 32, 32, 4, 64, 4, 32, 32, 32, 32}; void sub23decode(unsigned char *buf, int len) { int i; unsigned char offset = 23, prev = 0; for (i = 0; i < len; i++, offset += 23) { prev += buf[i] = buf[i] - prev - offset; } } void dump(unsigned char *pkt, int len) { int i = 0; int j = 0; for (i = 0; i < len; i += 16) { for (j = 0; j < 16; j++) { if (i + j >= len) { fprintf(stdout, " "); } else { fprintf(stdout, "%2.2x ", pkt[i + j]); } } fprintf(stdout, " "); for (j = 0; j < 16; j++) { if (i + j >= len) break; if (isprint(pkt[i + j])) { fprintf(stdout, "%c", pkt[i + j]); } else { fprintf(stdout, "."); } } fprintf(stdout, "\n"); } fprintf(stdout, "\n----------------------------------------------------------------\n\n"); } void printHeader(int dir, struct ip *ipHdr) { static char *tag[] = {"(agent)", "(handler)"}; char source[32]; strcpy(source, inet_ntoa(ipHdr->ip_src)); fprintf(stderr, "%s %s -> %s %s", source, tag[3 - dir], inet_ntoa(ipHdr->ip_dst), tag[dir - 2]); } int main(int argc, char **argv) { pcap_t *handle; /* Session handle */ char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */ struct pcap_pkthdr header; /* The header that pcap gives us */ const u_char *packet; /* The actual packet */ u_char *data; if (argc < 2) { fprintf(stderr, "Error: please specify a device to capture on\n"); exit(1); } handle = pcap_open_live(argv[1], 800, 1, 0, errbuf); if (!handle) { fprintf(stderr, "Error: failed to init pcap session for %s\n", argv[1]); exit(1); } fprintf(stderr, "\n"); while (packet = pcap_next(handle, &header)) { struct ip *ipHdr = (struct ip *) (packet + 14); if (header.len > 200 && ipHdr->ip_p == 11) { data = (char*) packet + PAYLOAD; sub23decode(data + 2, header.caplen - PAYLOAD); printHeader(data[0], ipHdr); if (data[0] == 2) { //command to agent fprintf(stderr, ": %s\n", commands[data[3] - 1]); dump(data, lengths[data[3] - 1]); } else { if (data[3] == 1 && data[4] == 7) { fprintf(stderr, ": status reply, "); if (data[5]) { fprintf(stderr, "active - %d\n", data[6]); } else { fprintf(stderr, "idle\n"); } dump(data, 16); } else { fprintf(stderr, "\n"); dump(data, header.caplen - PAYLOAD); } } } } /* And close the session */ pcap_close(handle); return(0); }