Nmap Announce mailing list archives

Re: Promiscuous mode detection


From: Eric Estabrooks <estabroo () ispn com>
Date: Thu, 04 Mar 1999 17:03:56 -0600

A program was posted to comp.security.unix that supposedly made the
corrupted ping packet that hosts in promiscius mode responded too.  I
haven't looked at it yet but I have attached the post and a follow to
the post that included some patches.

Eric
 estabroo () ispn com
Newsgroups: comp.security.unix
Subject: Re: Where can I get a good sniffer?
Date: Fri, 22 Jan 1999 09:45:16 +0000
Sender: Richard Jones <rich () arctor annexia org>
Message-ID: <cbh987.qqs.ln () gw annexia org>
References: <01be40dd$3c937780$0501010a@pyxis> <788tgu$avf$1 () jtjm2 trinhall cam ac uk>
NNTP-Posting-Host: annexia.demon.co.uk
X-NNTP-Posting-Host: annexia.demon.co.uk:212.228.121.204
X-Trace: news.demon.co.uk 916998523 nnrp-04:7194 NO-IDENT annexia.demon.co.uk:212.228.121.204
X-Complaints-To: abuse () demon net
User-Agent: tin/pre-1.4-981114 ("The Watchman") (UNIX) (Linux/2.2.0-final (i686))
Xref: news.ispn.net comp.security.unix:44796

Julian T. J. Midgley <jtjm2 () jtjm2 trinhall cam ac uk> wrote:
: In article <01be40dd$3c937780$0501010a@pyxis>,
: Joao Repas Goncalves <repas () mail telepac pt> wrote:
:>Does anyone now a site where I can download a sniffer for Windows?
:>I would like to look at what is going on my net, and check its security.
:>The protocols running on it are TCP/IP (and its services) and SNA.

: I have the inverse problem.  We would like to be able to detect
: ethernet cards running in promiscuous mode on our network.  After some
: research, I discovered a couple of references to theoretical means by
: which a promiscuous mode card might be detected (over the network),
: but no mention of any programs/scripts which actually implemented
: either of these methods.

: If anyone knows of such a program, I would be grateful for its name
: and a URL.

Try asking this guy: johna _at_ llnl.gov (John Allen)

I had some code which detected promiscuous mode
on ethernet cards by sending out goofy looking ping
packets (ethernet dest wrong, but IP dest right). The
code worked OK, but I never got round to doing a
`releaseable' version. However, he took the code and
AFAIK he put together a cleaned up version. My
horrible hacky version is attached.

Rich.

----------------------------------------------------------------------
/* Test if a host is in promiscuous mode.
 * Copyright (C) 1998 Richard W.M. Jones (rjones () orchestream com)
 * This program is GPL. It is derived from a program by
 * Paul Gortmaker (called bogon.c), also under GPL.
 *
 * It works as follows: send out a ICMP echo request to the host
 * in question, but wrap the echo request in a bogus ethernet packet.
 * If the host is acting normally, it will ignore the bogus packet.
 * If the host is listening to the network in promiscuous mode, then
 * it will pick up the packet and push it up to the IP layer which
 * will respond to the ping. This is obviously not foolproof, since
 * you could modify your kernel to disallow responses to echo requests.
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <malloc.h>
#include <string.h>

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#include <net/if.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <asm/checksum.h>

#define PACKET_SIZE 1024

// Bogus ethernet MAC address.
unsigned char bogus[ETH_ALEN] = { 0, 0x60, 0x97, 0xb4, 0x34, 0x82 };
unsigned char us[ETH_ALEN];

struct ifreq ifreq;
struct ethhdr *eth_pkt;
struct iphdr *ip_pkt;
struct icmphdr *icmp_pkt;

int fd, i, j;
unsigned char *packet;

struct in_addr ip_dest;
struct hostent *dest_name;

struct in_addr ip_source;

// Set the ethernet interface here.
#define INTERFACE "eth0"
struct sockaddr interface = { AF_INET, INTERFACE };

void 
main (int argc, char **argv)
{
  if (argc != 2)
    {
      fprintf (stderr, "Usage: promisc destination\n");
      exit (1);
    }

  dest_name = gethostbyname (argv [1]);
  if (dest_name == NULL) { perror (argv [1]); exit (1); }

  ip_dest = *(struct in_addr *) (dest_name->h_addr);
  printf ("Destination IP address: %s\n", inet_ntoa (ip_dest));

  fd = socket (AF_INET, SOCK_PACKET, htons (ETH_P_802_3));
  if (fd == -1)
    {
      perror ("socket");
      exit (1);
    }

  strcpy (ifreq.ifr_name, INTERFACE);
  if (ioctl (fd, SIOCGIFHWADDR, &ifreq) < 0)
    {
      perror ("SIOCGIFHWADDR");
      exit (1);
    }

  memcpy (us, ifreq.ifr_hwaddr.sa_data, ETH_ALEN);

  printf ("My ethernet address: ");
  for (i = 0; i < ETH_ALEN; i++)
    printf (" %X", us[i]);
  printf ("\n");

  strcpy (ifreq.ifr_name, INTERFACE);
  if (ioctl (fd, SIOCGIFADDR, &ifreq) < 0)
    {
      perror ("SIOCGIFADDR");
      exit (1);
    }

  memcpy (&ip_source, &((struct sockaddr_in *) &ifreq.ifr_ifru.ifru_addr)->sin_addr,
          sizeof (struct sockaddr_in));

  printf ("My IP address: %s\n", inet_ntoa (ip_source));

  packet = (char *) malloc (PACKET_SIZE);
  if (packet == NULL)
    {
      perror ("malloc");
      exit (1);
    }

  memset (packet, 0, PACKET_SIZE);

  /* Fill out the ethernet header. */
  eth_pkt = (struct ethhdr *) packet;
  memcpy (eth_pkt->h_dest, bogus, ETH_ALEN);
  memcpy (eth_pkt->h_source, us, ETH_ALEN);
  eth_pkt->h_proto = htons (ETH_P_IP);

  /* Fill out the IP header. */
  ip_pkt = (struct iphdr *) (packet + sizeof (struct ethhdr));
  ip_pkt->ihl = 5;              /* Header length / 4.  Always 5 if no opts. */
  ip_pkt->version = 4;          /* IP version.         Always 4.            */
  ip_pkt->tos = 0;              /* Type of service.    8 bits.              */
                                /* Total length.       Bytes, up to 64K.    */
  ip_pkt->tot_len = htons (PACKET_SIZE - sizeof (struct ethhdr));
  ip_pkt->id = 0;               /* Identification.                          */
  ip_pkt->frag_off = 0;         /* Fragment offset.                         */
  ip_pkt->ttl = 64;             /* Time to live.       8 bits.              */
  ip_pkt->protocol = IPPROTO_ICMP; /* Protocol.         IPPROTO_xxx          */
                                /* Source address.     IP address.          */
  ip_pkt->saddr = ip_source.s_addr;
                                /* Destination address.IP address.          */
  ip_pkt->daddr = ip_dest.s_addr;

  /* Compute the IP header checksum. */
  ip_pkt->check = 0;
  ip_pkt->check = ip_fast_csum ((unsigned char *) ip_pkt, ip_pkt->ihl);

  /* Construct the echo request. */
  icmp_pkt = (struct icmphdr *) (packet + sizeof (struct ethhdr)
                                 + sizeof (struct iphdr));
  icmp_pkt->type = ICMP_ECHO;
  icmp_pkt->code = 0;
  icmp_pkt->checksum = ip_fast_csum ((unsigned char *) icmp_pkt,
                                     sizeof (struct icmphdr));

  /* Send 10 packets. */
  for (j = 0; j < 10; j++)
    {
      i = sendto (fd, packet, PACKET_SIZE, 0,
                  &interface, sizeof (struct sockaddr));

      if (i < 0)
        {
          perror ("sendto");
          exit (1);
        }
    }
  printf ("sent %d bytes %d times.\n", i, j);

  exit (0);
}


-- 
-      Richard Jones. Linux contractor London and SE areas.        -
-    Very boring homepage at: http://www.annexia.demon.co.uk/      -
- You are currently the 1,991,243,100th visitor to this signature. -
-    Original message content Copyright (C) 1998 Richard Jones.    -

--------------FA28785ACE8B8D49B0E1072D--

Newsgroups: comp.security.unix
Subject: Re: Where can I get a good sniffer?
Date: Fri, 22 Jan 1999 14:22:36 +0000
Sender: Richard Jones <rich () arctor annexia org>
Message-ID: <cj1a87.gat.ln () gw annexia org>
References: <01be40dd$3c937780$0501010a@pyxis> <788tgu$avf$1 () jtjm2 trinhall cam ac uk> <cbh987.qqs.ln () gw annexia 
org> <789q7p$bls$1 () jtjm2 trinhall cam ac uk>
NNTP-Posting-Host: annexia.demon.co.uk
X-NNTP-Posting-Host: annexia.demon.co.uk:212.228.121.204
X-Trace: news.demon.co.uk 917015160 nnrp-07:21733 NO-IDENT annexia.demon.co.uk:212.228.121.204
X-Complaints-To: abuse () demon net
User-Agent: tin/pre-1.4-981114 ("The Watchman") (UNIX) (Linux/2.2.0-final (i686))
Xref: news.ispn.net comp.security.unix:44805

Julian T. J. Midgley <jtjm2 () jtjm2 trinhall cam ac uk> wrote:
: In article <cbh987.qqs.ln () gw annexia org>,
: Many thanks,

: I'll contact John Allen, and give your code a try in the meantime.

: All the best,

: Julian Midgley

You need to apply the following patches
to actually get the hacky version to compile :-)

Rich.

--- /mnt/cdrom/c/promisc.c      Thu Jan 29 13:28:52 1998
+++ promisc.c   Tue Nov 10 17:53:01 1998
@@ -28,11 +28,22 @@
 #include <netinet/ip.h>
 #include <netinet/in.h>
 #include <netinet/ip_icmp.h>
+
+/* Hack for kernel >= 2.1 */
+#if defined(linux)
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
+typedef unsigned short __u16;
+typedef unsigned int __u32;
+#define VERIFY_WRITE 0
+#endif
+#endif
+
 #include <asm/checksum.h>
 
 #define PACKET_SIZE 1024
 
-// Bogus ethernet MAC address.
+/* Bogus ethernet MAC address. */
 unsigned char bogus[ETH_ALEN] = { 0, 0x60, 0x97, 0xb4, 0x34, 0x82 };
 unsigned char us[ETH_ALEN];
 
@@ -49,11 +60,11 @@
 
 struct in_addr ip_source;
 
-// Set the ethernet interface here.
+/* Set the ethernet interface here. */
 #define INTERFACE "eth0"
 struct sockaddr interface = { AF_INET, INTERFACE };
 
-void 
+int
 main (int argc, char **argv)
 {
   if (argc != 2)
@@ -155,6 +166,8 @@
          perror ("sendto");
          exit (1);
        }
+
+      sleep (1);
     }
   printf ("sent %d bytes %d times.\n", i, j);
 


-- 
-      Richard Jones. Linux contractor London and SE areas.        -
-    Very boring homepage at: http://www.annexia.demon.co.uk/      -
- You are currently the 1,991,243,100th visitor to this signature. -
-    Original message content Copyright (C) 1998 Richard Jones.    -

--------------3BA5FD5D2CF0FA66D22DC198--


Current thread: