|
[ANTI ANTI-SNIFFER PATCH]============================================[vecna] http://www.s0ftpj.org - Italian security/hacking group. HISTORY: Summer 2000: Thought of the patch November 2000: published code and italian file July 2001: I know that the code published on packetstorm cannot be understood, this invites me to write this readme file. This work is coded and tested under Linux kernel 2.2[.15|.16] FOCUS of this document is: i) Make possible patch to elude anti sniffer and some programs that use the series of technique explained by l0pht's studies. ii) Suggest possible techniques for secure sniffer discovery. Mac Address Check This is a old technique, consisting of send packets to valid ip address but with fake mac destination address, some stacks doesn't check datalink layer header and give packets at superior layer. Usually is implemented with ICMP echo request and arp request, but can be used with any kind of packets of any protocol. Simple you send erroneous packets and if you received some reply you are sure that source of reply is running in promiscuous mode. Fix Simple: the anti sniffer works because any stack will reply without checking the destination mac. It's simple to make a kernel patch for dropping any packets with a destination mac address different from network card mac address and different to "ff:ff:ff:ff:ff:ff" (used as mac broadcast). Implemented as kernel module for linux 2.2. DNS Resolver Check Some sniffers will try to resolve the sniffed IP to aid the user in indentification. This feature can be attacked by anti-sniffer check. The check appears as a SYN flood with random destinations, while reading the DNS requests made my the sniffing device. If you see DNS requests on the network while performing this, chances are, you have a sniffing device on the network. Fix DNS resolving is due to gethostbyname() resolve function. You must remove it from sniffer code (or disable it) and use a IP only format. In addition, if you want to resolve addresses anyway, you can always watch the network traffic of the target sniffer (if he is resolving). Network Latency Test - admin host start to pinging one network interface and trace the medium of him icmp echo reply - admin host start syn flood on the network for non-existent IP. - admin host check echo reply statistic after starting of flood. If the network interface has a heavy ping reply time increment it's due to hard network traffic, due to the flood, because network card is running in promiscuous mode, this anti sniffer check work over the physical law "more work -> more time". Fix Few time before anti anti sniffer patch, I've coded libvsk. Libvsk is a library suite for manipulating ongoing traffic working BEFORE the kernel using this concept: From userspace I set firewalling rules to DROP certain packets, From userspace I set datalink socket to read the packets that before raw socket layer kernel drop for my explicit request with firewall rules. With this library, you can code lots of nice applications related to network direction and similar things. For more info check http://www.s0ftpj.org and search libvsk and example spf.c, This is coded for kernel 2.2, after I've coded some applications working under kernel 2.2 2.4, I will port to *BSD with ipfw and solaris (or other system) with ipf, using system(3) than manually setsockopt/ioctl for add filtering rules (it's very hard filling certain structures)... For eluding network latency test I've coded a simple program that will drop any ICMP echo request before kernel reply, read some request and DELAY the reply. Admin knows that network run on prom. mode when he sees great increments on echo reply ... such 0.1 to 3.0 ... but if you set manually a delay such 3.0 in normal condition, when flood start cannot be view great increment, and btw never can be to 30 times (3.0 / 0.1) but lower that 1/0.5 times. THE CODE: - lodable module for source ethernet address check - - for more info read phrack 55 - 12 - /* # gcc -O6 -c aasp_lkmachk.c -I/usr/src/linux/include # insmod aasp_lkmachk.o device=eth0 # rmmod aasp_lkmachk Anti Anti Sniffer Patch (by vecna@s0ftpj.org) - MAC checker module */ #define MODULE #define __KERNEL__ #include <linux/config.h> #include <linux/module.h> #include <linux/version.h> #include <linux/netdevice.h> #include <net/protocol.h> #include <net/pkt_sched.h> #include <net/tcp.h> #include <net/ip.h> #include <linux/if_ether.h> #include <linux/ip.h> #include <linux/skbuff.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/file.h> #include <asm/uaccess.h> #define r_mac sk->mac.ethernet->h_dest /* received mac */ #define t_mac true->dev_addr /* true mac */ char *device; MODULE_PARM(device, "s"); struct device *true; struct packet_type aasp_ip, aasp_arp; int chk_mac_arp(struct sk_buff *sk, struct device *dev, struct packet_type *pt) { if( r_mac[0] ==r_mac[1] ==r_mac[2] ==r_mac[3] ==r_mac[4] ==r_mac[5] ==0xff) /* ARP broadcast */ goto end; if( (r_mac[0] !=t_mac[0]) || (r_mac[1] !=t_mac[1]) || (r_mac[2] !=t_mac[2]) || (r_mac[3] !=t_mac[3]) || (r_mac[4] !=t_mac[4]) || (r_mac[5] !=t_mac[5]) ) { /* ARP mac spoof detected */ sk->nh.arph->ar_hrd = 0; sk->nh.arph->ar_pro = 0; sk->nh.arph->ar_op = 0; goto end; } end: kfree_skb(sk); return(0); } int chk_mac_ip(struct sk_buff *sk, struct device *dev, struct packet_type *pt) { /* read #define(s) after #include(s) */ if( (r_mac[0] !=t_mac[0]) || (r_mac[1] !=t_mac[1]) || (r_mac[2] !=t_mac[2]) || (r_mac[3] !=t_mac[3]) || (r_mac[4] !=t_mac[4]) || (r_mac[5] !=t_mac[5]) ) { /* IP check - anti spoof detect! */ sk->nh.iph->tot_len = 0; sk->nh.iph->check = 0; } kfree_skb(sk); return(0); } int init_module(void) { if (device) { true =dev_get(device); if (true ==NULL) { printk("Did not find device %s!\n", device); return -EINVAL; } } else { printk("Usage: insmod aasp_lkmachk.o device=device name \n\n"); return -ENODEV; } printk("Mac checker module run on %s - by vecna@s0ftpj.org\n",device); printk("Full codes of Anti Anti Sniffer Patch can be" " downloadated at www.s0ftpj.org\n"); aasp_ip.dev = true; aasp_ip.type = htons(ETH_P_IP); aasp_ip.func = chk_mac_ip; aasp_arp.dev = true; aasp_arp.type = htons(ETH_P_ARP); aasp_arp.func = chk_mac_arp; dev_add_pack(&aasp_ip); dev_add_pack(&aasp_arp); return(0); } void cleanup_module(void) { dev_remove_pack(&aasp_ip); dev_remove_pack(&aasp_arp); printk("Anti Anti Sniffer Patch - MAC checker module unload\n"); } -- fake network latency test: /* Fucker Latency of test for Anti Anti Sniffer Patch */ #include "libvsk.h" /* www.s0ftpj.org for more info */ #include <errno.h> extern int errno; #define fatal(M) { \ perror(M); \ exit(0); \ } #define IPSIZE sizeof(struct iphdr) #define ICMPSIZE sizeof(struct icmphdr) #define IIPKTSIZE sizeof(struct iipkt) int check_dup(struct iipkt *); void build_reply(struct iipkt *, struct sockaddr_in *, struct iipkt *); unsigned short ip_s(unsigned short *, int); int main(int argc, char **argv) { int dlsfd, offset, forward, hdrincl =1, pkt_info[4], x; char ipdst[18], *rcvd =malloc(IIPKTSIZE); struct ifreq ifr; struct in_addr in; struct iipkt *reply =malloc(IIPKTSIZE); printf("\t Anti Anti Sniffer Patch for elude latency test\n"); printf("\t by vecna - vecna@s0ftpj.org - www.s0ftpj.org\n\n"); if(argc != 3) { printf( " usage %s interface fakedelay\n\n", argv[0]); exit(0); } printf(" running on background\n"); if(fork()) exit(0); pkt_info[0] =pkt_info[1] =ICMP_ECHO; pkt_info[2] =0; pkt_info[3] =0xFFFF; x =socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)); if(ioctl (x, SIOCGIFADDR, &ifr) < 0) fatal("unable to look local address"); memcpy((void *)&in, (void *)&ifr.ifr_addr.sa_data +2, 4); strcpy(ipdst, (char *)inet_ntoa(in)); close(x); dlsfd =set_vsk_param(NULL, ipdst, pkt_info, argv[1], IPPROTO_ICMP, IO_IN, IP_FW_INSERT, 0, 0); if(dlsfd < 0) fatal("set_vsk: IP_FW_INSERT"); if((offset =get_offset(dlsfd, argv[1])) <0) fatal("get device offset"); if((forward = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) fatal("forward socket - SOCK_RAW"); if((x = setsockopt(forward, IPPROTO_IP, IP_HDRINCL, &hdrincl, sizeof(hdrincl))) == -1) fatal("setsockopt - IP_HDRINCL"); while(1) { struct iipkt *packet; static int last_id; read(dlsfd, rcvd, IIPKTSIZE); (char *)packet = rcvd + offset; if(check_dup(packet)) continue; if(check_packet(packet, IPPROTO_ICMP)) { struct sockaddr_in sin; build_reply(packet, &sin, reply); usleep(atoi(argv[2])); x =sendto(forward, (char *)reply, ntohs(reply->ip.tot_len), 0, (struct sockaddr *)&sin, sizeof(struct sockaddr) ); if(x < 0) fatal("sendto on forwarding packet"); } memset(packet, 0, IIPKTSIZE); } free(rcvd); /* never here */ } void build_reply(struct iipkt *packet, struct sockaddr_in *sin, struct iipkt *reply) { memcpy((void *)reply, (void *)packet, IIPKTSIZE); reply->ip.id =getpid() & 0xffff ^ packet->ip.id; reply->ip.saddr =packet->ip.daddr; reply->ip.daddr =packet->ip.saddr; reply->ip.check =ip_s((u_short *)&reply->ip, IPSIZE); reply->icmp.type =ICMP_ECHOREPLY; reply->icmp.checksum =0x0000; reply->icmp.checksum =ip_s((u_short *)&reply->icmp, ntohs(packet->ip.tot_len) - IPSIZE ); /* setting sockaddr_in stuctures */ sin->sin_port =htons(0); sin->sin_family = AF_INET; sin->sin_addr.s_addr = reply->ip.daddr; } int check_dup(struct iipkt *packet) { static int last_id; int id =htons(packet->ip.id); if(id ==htons(last_id)) return 1; last_id =packet->ip.id; return 0; } u_short ip_s(u_short *ptr, int nbytes) { register long sum = 0; u_short oddbyte; register u_short answer; while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } if (nbytes == 1) { oddbyte = 0; *((u_char *) &oddbyte) = *(u_char *)ptr; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return(answer); } -- Ideas for new anti sniffer (or anti anti anti sniffer :) ? Make the same work used on network latency test but use for check TCP packets, for network statistic, also tcp can be used, think to SYN packets for port 0, any host reply with RST+ACK, you may use time of RST+ACK reply for trace network statistic and for viewing REAL network congestion statistic after start the flood. BTW: this system cannot be accurate for some things how ... - local and remote load average network undependent ... - your local network device congestion due to your flood - network driver, ram, cpu, kind of device - runnng of program working on datalink/raw layer - other ? Using network restriction is a good idea for detect prom. cards, this can be tested with systems on your network that you admin yourself or your friends ... or other cases such LAN party is easy put network card without ip address and with arp filtering (for drop any arp broadcast), this mean that you may sniff without problem :) /* Editors Note: Sorry about the translation vecna, I was tired! */