/********************************************************************** * file: disect4.c * Authors: Rachel Greenstadt John Giffin * * Description: * * Large amounts of code taken from Martin Casso's sample * libpcap code, largely disect2.c * Large amounts of this code were taken from tcpdump source * namely the following files.. * * print-ether.c * print-ip.c * ip.h * tcp.h * * Compile with: * make * * Usage: * disect4 (# of packets) "filter string" * **********************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include /* tcpdump header (ether.h) defines ETHER_HDRLEN) */ #ifndef ETHER_HDRLEN #define ETHER_HDRLEN 14 #endif typedef u_int32_t tcp_seq; /* struct tcptimestamp{ u_int8_t th_kind; u_int8_t th_len; u_int32_t th_value; u_int32_t th_echoreply; }; */ /* * TCP header. * Per RFC 793, September, 1981. */ struct tcpfoo { u_int16_t th_sport; /* source port */ u_int16_t th_dport; /* destination port */ tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ u_int8_t th_offx2; /* data offset, rsvd */ #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) u_int8_t th_flags; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 u_int16_t th_win; /* window */ u_int16_t th_sum; /* checksum */ u_int16_t th_urp; /* urgent pointer */ u_int8_t th_kind; u_int8_t th_len; u_int32_t th_tsvalue; u_int32_t th_echoreply; }; int B[256]; char *skey; int keylen; /* looking at ethernet headers */ void my_callback(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet) { /* handle tcp packets (since we're filtering that's what * we ought to be getting) */ const struct tcpfoo* tcp; u_int length = pkthdr->len; int index; int key; int tsbit; char shain[28]; char md[SHA1HashSize]; int i=0; int j=0; int q; //u_int hlen,off,version; //int i; /* jump past the ethernet and ip headers */ tcp = (struct tcpfoo*)(packet+sizeof(struct ether_header)+sizeof(struct iphdr)); length -= (sizeof(struct ether_header) + sizeof(struct iphdr)); if (length < sizeof(struct tcpfoo)) { printf("truncated tcp %d",length); } index = get_index(ntohs(tcp->th_sport), ntohs(tcp->th_dport), ntohl(tcp->th_seq),skey, keylen); key = get_key_bit(ntohs(tcp->th_sport), ntohs(tcp->th_dport), ntohl(tcp->th_seq), ntohl(tcp->th_ack), ntohs(tcp->th_win), ntohs(0), ntohl(tcp->th_tsvalue)&0xfffffffe, ntohl(tcp->th_echoreply), skey, keylen); tsbit = ntohl(tcp->th_tsvalue) & 1; B[index] = key ^ tsbit; /* Now we need to pack up our array into a nice byte array for * testing with a nice 32 bit int to compare the output of sha1 */ for (i=0; i<32;i++) { shain[i] = 0; } for (i=0; i<32;i++) { for (j=0; j<8;j++) { shain[i] = shain[i] | (B[8*i+j]<=32 && shain[q] <= 126) { fprintf(stdout, "%c", shain[q]); } else { fprintf(stdout, "\\%d", shain[q]); } } fprintf(stdout,"\n"); SHA1(md, shain, 28); /* Check if our block works, reset the array if it does */ if (md[0] == shain[28] && md[1] == shain[29] && md[2] == shain[30] && md[3] == shain[31]) { fprintf(stdout, "We've got a block.\n"); fprintf(stdout, "%s\n", shain); fflush(stdout); for (q=0; q<256; q++) { B[q]=0; } } } int main(int argc, char **argv) { char *dev; char errbuf[PCAP_ERRBUF_SIZE]; pcap_t* descr; struct bpf_program fp; /* hold compiled program */ bpf_u_int32 maskp; /* subnet mask */ bpf_u_int32 netp; /* ip */ u_char* args = NULL; /* Options must be passed in as a string because I am lazy */ if(argc != 5) { printf("Usage: %s numpackets \"options\" key keylen\n", argv[0]); exit(1); } skey = argv[3]; keylen = atoi(argv[4]); /* grab a device to peak into... */ dev = pcap_lookupdev(errbuf); if (dev == NULL) { fprintf(stderr, "pcap_lookupdev failed: %s\n", errbuf); exit(1); } /* ask pcap for the network address and mask of the device */ pcap_lookupnet(dev,&netp,&maskp,errbuf); /* open device for reading. NOTE: defaulting to * promiscuous mode*/ descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf); if (descr == NULL) { printf("pcap_open_live(): %s\n", errbuf); exit(1); } /* Lets try and compile the program.. non-optimized */ if (pcap_compile(descr, &fp, argv[2], 0, netp) == -1) { fprintf(stderr,"Error calling pcap_compile with filter code ``%s''\n", argv[2]); exit(1); } /* set the compiled program as the filter */ if(pcap_setfilter(descr, &fp) == -1) { fprintf(stderr,"Error setting filter\n"); exit(1); } /* ... and loop */ pcap_loop(descr,atoi(argv[1]),my_callback,args); fprintf(stdout,"\nfinished\n"); return 0; }