TUCoPS :: Linux :: Discontinued :: antsnif.txt

Anti-Anti-Sniffer Patch


[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! */

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH