TUCoPS :: SunOS/Solaris :: nitwit.c

Nitwit.c - Identify Ethernet sniffers running on your hosts





/***

 ***

 *** author   : beavis & butthead 

 ***

 *** nitwit.c : checks for a vnode with major/minor similar 

 ***            to /dev/nit. i.e. reports if there is a sunsniffer.

 ***

 *** compile  : cc -o nitwit nitwit.c -lkvm

 ***

 *** include  : all header files about disclaimers and that kind of rubbish.

 ***

 *** "bugs"   : it checks 'kmem' for such vnodes therefore there is no

 ***            guarantee that it will cue for all sniffers.

 ***            the intruder might have modified 'kmem' already.

 ***

 *** advntges : better than cert's 'cpm' because the sniffer can be

 ***            reading in normal (non promiscuous) mode from /dev/nit

 ***            and nittie.c will sense this.

 ***

 ***/

                   



#include <stdio.h> 

#include <errno.h>

#include <nlist.h>

#include <pwd.h>



#include <sys/time.h>

#include <kvm.h>



#define KERNEL

#include <sys/file.h>

#include <fcntl.h>

#include <sys/proc.h>

#undef KERNEL



/* the following lines are stollen from <sys/vnode.h> */



enum vtype 	{ VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VBAD, VFIFO };



struct vnode {

	u_short		v_flag;			/* vnode flags (see below) */

	u_short		v_count;		/* reference count */

	u_short		v_shlockc;		/* count of shared locks */

	u_short		v_exlockc;		/* count of exclusive locks */

	struct vfs	*v_vfsmountedhere; 	/* ptr to vfs mounted here */

	struct vnodeops	*v_op;			/* vnode operations */

	union {

		struct socket	*v_Socket;	/* unix ipc */

		struct stdata	*v_Stream;	/* stream */

		struct page	*v_Pages;	/* vnode pages list */

	} v_s;

	struct vfs	*v_vfsp;		/* ptr to vfs we are in */

	enum vtype	v_type;			/* vnode type */

	dev_t		v_rdev;			/* device (VCHR, VBLK) */

	long		*v_filocks;		/* File/Record locks ... */

	caddr_t		v_data;			/* private data for fs */

};



/* down to here */





#define NIT_MAJ     0x2800

#define MAJ_MASK    0xff00

#define MIN_MASK    0x00ff

#define FALSE       0

#define TRUE        1



#define k_read(x, y, l) \

           if (kvm_read(kd, (unsigned long)x, (char *)y, (unsigned)l) < 0) \

              { perror("kvm_read"); exit(1); }



int    cnt = 0;

kvm_t *kd;



int CheckFile(pUsrFile)

struct file *pUsrFile;

{

   struct vnode vn;



   if ((pUsrFile->f_count == 0) || (pUsrFile->f_data == NULL))

      return FALSE;

   

   k_read(pUsrFile->f_data, &vn, sizeof(struct vnode));



   if ((vn.v_type == VCHR) && ((vn.v_rdev & MAJ_MASK) == NIT_MAJ)) {

      printf("open NIT with major/minor: %d / %d\n",

             ((vn.v_rdev >> 8) & MIN_MASK), (vn.v_rdev & MIN_MASK));

      

      printf("NIT open() flags: %s%s\n", 

             (((pUsrFile->f_flag) & _FREAD) ? "READ " : ""),

             (((pUsrFile->f_flag) & _FWRITE) ? "WRITE" : ""));

      

      return TRUE;

   }

   return FALSE;



}



void userSearch(userProc)

struct proc *userProc;

{



#define MAX_CWD_LEN 1024



   int            flg;

   char         **usrArg;

   struct file  **ppFile, *pCurFile, curFile;

   struct user   *pUsrEnv;

   struct passwd *pUsrInfo;

   struct ucwd    usrCurDir;

   char           szCD[MAX_CWD_LEN];



   

   pUsrEnv = kvm_getu(kd, userProc);

   ppFile = pUsrEnv->u_ofile;



   if (ppFile) do {

      

      k_read(ppFile++, &pCurFile, sizeof(struct file *));



      if (pCurFile == NULL)

         continue;



      k_read(pCurFile, &curFile, sizeof(struct file));

      

      if (flg = CheckFile(&curFile)) {

         cnt++;



         pUsrInfo = getpwuid(userProc->p_uid);

         if (pUsrInfo)

            printf("user: %s (%s)\n", pUsrInfo->pw_name, pUsrInfo->pw_gecos);

         else

            printf("userid: %d\n", userProc->p_uid);

      

         k_read(pUsrEnv->u_cwd, &usrCurDir, sizeof(struct ucwd));

         k_read(usrCurDir.cw_dir, szCD, MAX_CWD_LEN);

         printf("starting dir: %s\n", (szCD[0] ? szCD: "/"));



         kvm_getcmd(kd, userProc, pUsrEnv, &usrArg, NULL);

         if (usrArg) {

            printf("program:");

            while (*usrArg != NULL) printf(" %s", *usrArg++);

            puts("");

         }

         else

            puts("can not find program's args");

            

         printf("pid: %d\n", userProc->p_pid);

         

         puts("---");

      }

   } while (pCurFile && !flg);

}





main(argc, argv)

int    argc;

char **argv;

{

   struct proc *pCurProc;

 

   if (!(kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL))) {

      perror("kvm_open");  

      exit(1);

   }

   

   kvm_setproc(kd);

   while ((pCurProc = kvm_nextproc(kd)) != NULL) 

      userSearch(pCurProc);

   

   if (!cnt)

      puts("can not sense anyone reading from the NIT");

   else

      printf("total: %d process%s using NIT\n", cnt, (cnt == 1 ? "" : "es"));



   kvm_close(kd);

}


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