/* * decoder.c * Job * * * A decoder for packets from the 'foo' binary. * * Options: decoder [-h] [-a] [-p] * * -p: the is a pcap dump. * -a: also print the ascii strings * -h: the contains 1 packet with pcap header * * option -h is braindead and buggy. * * Tip for compiling: you need to figure out where your * pcap includes and libs are (need -lpcap). On linux * I used the includes from tcpdump. * * My compile line: * gcc -I /usr/include/pcap -I ./linux-include/ -g decoder.c -o decoder -lpcap * * Todo: * * Adding the command parsing. Several commands are known: * * 1 - send some local info to the server? * 2 - reinitializes random IPs? * 3 - fork csh, execute the command and send the reply * 4 - fork and do something else (bounce?) * 5 - fork and do something else. * 6 - open a portdaemon/shell on port 61786 * 7 - * 8 - kill the last command forked. * 9 - * 10 - * 11 - * 12 - */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include char outbuf[2048]; static pcap_t *pd; extern int optind; extern int opterr; extern char *optarg; int doheader = 0; int doascii = 0; int dopcap = 0; /* * This is the reverse engineered decode routine from 'foo'. * Followed the register naming for readability with the disasm. */ decode(unsigned int len, unsigned char *inbuf, unsigned char *outbuf) { int eax, ebx, ecx, edx, i, j; unsigned char *localbuf; printf("starting decode of packet size %d\n",len); for(eax=0;eax<16;eax++) printf("%02X ",inbuf[eax]); printf("\n"); outbuf[0] = 0; ebx = len - 1; if (ebx<0) return(0); eax = (len+3)&0xFFFC; localbuf = malloc(eax); printf("local buf of size %d\n",eax); while(ebx>=0) { edx = ebx - 1; if (ebx>0) { eax = inbuf[ebx]; edx = inbuf[edx]; eax -= edx; } else eax = inbuf[0]; ecx = eax - 23; while( ecx<0 ) ecx += 0x100; if (len>0) { for(edx=0;edx1) { for(edx=1;edxcaplen; struct ether_header *ep; struct ip *ip; unsigned short n; printf("reading packet....\n"); ep = (struct ether_header *)p; p += sizeof(struct ether_header); caplen -= sizeof(struct ether_header); if (ntohs(ep->ether_type) != ETHERTYPE_IP) { printf("not an IP packet\n"); return; } ip = (struct ip *)p; p += sizeof(struct ip); if (ip->ip_p != 11) { fprintf(stderr,"no protocol 11\n"); return; } n = ntohs(ip->ip_len); printf("packet length %d. %x\n", n, ip->ip_len); printf("command %d.\n",*p); memset(outbuf,0,2038); decode(n-2, p+2, outbuf); } main(int argc, char *argv[]) { int fd, n, i, j; int op, cnt = -1; char inbuf[2048], ebuf[PCAP_ERRBUF_SIZE]; unsigned char *pcap_userdata = NULL; opterr = 0; while ((op = getopt(argc, argv, "hap")) != EOF) switch (op) { case 'h': ++doheader; break; case 'a': ++doascii; break; case 'p': ++dopcap; break; } if (optind == argc) { printf("need a filename as argument\n"); exit(1); } if (dopcap) { pd = pcap_open_offline(argv[optind], ebuf); if (pd == NULL) { perror(ebuf); exit(1); } if (pcap_loop(pd, cnt, (pcap_handler)printer, pcap_userdata) < 0) { (void)fprintf(stderr, "%s: pcap_loop: %s\n", argv[0], pcap_geterr(pd)); exit(1); } pcap_close(pd); exit(0); } if ((fd=open(argv[optind], O_RDONLY))<0) { perror("open"); exit(1); } if (doheader) { /* read tcpdump header */ n = read(fd,inbuf, 0x30); /* read linklevel header */ n = read(fd,inbuf, 14); /* read IP header */ n = read(fd,inbuf, 20); if (n<0) { perror("read"); exit(1); } if (inbuf[9]!=11) { fprintf(stderr,"no protocol 11\n"); exit(1); } } n = read(fd,inbuf, sizeof(inbuf)); memset(outbuf,0,2038); decode(n-2, inbuf+2, outbuf); return(0); }