/************************************************************** Function: do_tcpPurpose: Process this TCP packet if it is important. ***************************************************************/ void do_tcp(ep, pkt) struct ethhdr *ep; u_char *pkt; { struct tcphdr *thdr; u_short sport, dport;
thdr = (struct tcphdr *) pkt; if(thdr->th_flags & TH_RST) /* RST generates no response */ return; /* Therefore can't be used to scan. */ sport = ntohs(thdr->th_sport); dport = ntohs(thdr->th_dport);
if(thdr->th_flags & TH_SYN) { if(Gsaddr == Gdaddr && sport == dport) { Gsi->land.atktime = Gtimein; Gsi->land.saddr = Gsaddr; memcpy(Gsi->land.eaddr, ep->h_source, ETH_ALEN); } } addtcp(sport, dport, thdr->th_flags, ep->h_source); }
/********************************************************************** Function: addtcp
Purpose: Add this TCP packet to our list. **********************************************************************/ void addtcp(sport, dport, flags, eaddr) u_short sport; u_short dport; u_char flags; u_char *eaddr; { struct pktin *pi, *last, *tpi;
/* See if this packet relates to other packets already received. */
for(pi = Gsi->tcpin; pi; pi = pi->next) { if(pi->saddr == Gsaddr && pi->dport == dport) { if(flags == TH_SYN) addfloodinfo(pi, sport); else if((flags & TH_FIN) (flags & TH_ACK)) rmfloodinfo(pi, sport); return; } last = pi; } /* Must be new entry */
if((tpi = (struct pktin *)malloc(sizeof(struct pktin))) == NULL) { perror("Malloc"); exit(-1); } memset(tpi, 0, sizeof(struct pktin)); memcpy(tpi->eaddr, eaddr, ETH_ALEN); tpi->saddr = Gsaddr; tpi->sport = sport; tpi->dport = dport; tpi->timein = Gtimein; if(flags == TH_SYN) addfloodinfo(tpi, sport); if(Gsi->tcpin) last->next = tpi; else Gsi->tcpin = tpi; }
/***************************************************************** Function: addfloodinfo
Purpose: Add floodinfo information **************************************************************/ void addfloodinfo(pi, sport) struct pktin *pi; u_short sport; { struct floodinfo *fi;
fi = (struct floodinfo *)malloc(sizeof(struct floodinfo)); if(fi == NULL) { perror("Malloc of floodinfo"); exit(-1); } memset(fi, 0, sizeof(struct floodinfo)); fi->sport = sport; fi->next = pi->fi; pi->fi = fi; }
/********************************************************************** Function: rmfloodinfo
Purpose: Removes floodinfo information **********************************************************************/ void rmfloodinfo(pi, sport) struct pktin *pi; u_short sport; { struct floodinfo *fi, *prev = NULL;
for(fi = pi->fi; fi; fi = fi->next) { if(fi->sport == sport) break; prev = fi; } if(fi == NULL) return; if(prev == NULL) /* First element */ pi->fi = fi->next; else prev->next = fi->next; free(fi); }
/********************************************************************** Function: do_udp
Purpose: Process this udp packet.
Currently teardrop and all its derivitives put 242 in the IP id field. This could obviously be changed. The truly paranoid might want to flag all fragmented UDP packets. The truly adventurous might enhance the code to track fragments and check them for overlaping boundaries. **********************************************************************/ void do_udp(ep, pkt) struct ethhdr *ep; u_char *pkt; { struct udphdr *uhdr; u_short sport, dport;
uhdr = (struct udphdr *) pkt; if(Gid == 242 && Gisfrag) /* probable teardrop */ { Gsi->teardrop.saddr = Gsaddr; memcpy(Gsi->teardrop.eaddr, ep->h_source, ETH_ALEN); Gsi->teardrop.atktime = Gtimein; } sport = ntohs(uhdr->source); dport = ntohs(uhdr->dest); addudp(sport, dport, ep->h_source); }
/************************************************************ Function: addudp
Purpose: Add this udp packet to our list. *************************************************************/ void addudp(sport, dport, eaddr) u_short sport; u_short dport; u_char *eaddr; { struct pktin *pi, *last, *tpi;
for(pi = Gsi->udpin; pi; pi = pi->next) { if(pi->saddr == Gsaddr && pi->dport == dport) { pi->timein = Gtimein; return; } last = pi; } /* Must be new entry */
if((tpi = (struct pktin *)malloc(sizeof(struct pktin))) == NULL) { perror("Malloc"); exit(-1); } memset(tpi, 0, sizeof(struct pktin)); memcpy(tpi->eaddr, eaddr, ETH_ALEN); tpi->saddr = Gsaddr; tpi->sport = sport; tpi->dport = dport; tpi->timein = Gtimein; if(Gsi->udpin) last->next = tpi; else Gsi->udpin = tpi; }
/********************************************************************** Function: do_icmp
Purpose: Process an ICMP packet.
We assume there is no valid reason to receive a fragmented ICMP packet. **********************************************************************/ void do_icmp(ep, pkt) struct ethhdr *ep; u_char *pkt; { struct icmphdr *icmp;
icmp = (struct icmphdr *) pkt; if(Gisfrag) /* probable ICMP attack (i.e. Ping of Death) */ { Gsi->icmpfrag.saddr = Gsaddr; memcpy(Gsi->icmpfrag.eaddr, ep->h_source, ETH_ALEN); Gsi->icmpfrag.atktime = Gtimein; } if(icmp->type == ICMP_ECHOREPLY) Gsi->icmpcnt++; return; }
/************************************************************ Function: clear_pkt
Purpose: Delete and free space for any old packets. ***************************************************************/ void clear_pktin(si) struct scaninfo *si; { struct pktin *pi; struct floodinfo *fi, *tfi; time_t t, t2;
t = time((time_t *)0); while(si->tcpin) { t2 = t - si->tcpin->timein; if(t2 > Gtimer) { pi = si->tcpin; fi = pi->fi; while(fi) { tfi = fi; fi = fi->next; free(tfi); } si->tcpin = pi->next; free(pi); } else break; } while(si->udpin) { t2 = t - si->udpin->timein; if(t2 > Gtimer) { pi = si->udpin; si->udpin = pi->next; free(pi); } else break; } }
/**************************************************************** Function: print_info
Purpose: Print out any alerts. **************************************************************/ void print_info() { struct pktin *pi; struct addrlist *tcplist = NULL, *udplist = NULL, *al; struct floodinfo *fi; char buf[1024], *eaddr, abuf[32]; int i;
strcpy(abuf, anetaddr(Gsi->addr)); if(Greportlevel == REPORTALL Greportlevel == REPORTDOS) { if(Gsi->teardrop.atktime) { eaddr = ether_ntoa(Gsi->teardrop.eaddr); sprintf(buf, "Possible teardrop attack from %s (%s) against %s", anetaddr(Gsi->teardrop), eaddr, abuf); syslog(LOG_ALERT, buf); memset(&Gsi->teardrop, 0, sizeof(struct atk)); } if(Gsi->land.atktime) { eaddr = ether_ntoa(Gsi->land.eaddr); sprintf(buf, "Possible land attack from (%s) against %s", eaddr, abuf); syslog(LOG_ALERT, buf); memset(&Gsi->land, 0, sizeof(struct atk)); } if(Gsi->icmpfrag.atktime) { eaddr = ether_ntoa(Gsi->icmpfrag.eaddr); sprintf(buf, "ICMP fragment detected from %s (%s) against %s", anetaddr(Gsi->icmpfrag), eaddr, abuf); syslog(LOG_ALERT, buf); memset(&Gsi->icmpfrag, 0, sizeof(struct atk)); } if(Gsi->icmpcnt > Gicmplimit) { sprintf(buf, "ICMP ECHO threshold exceeded, smurfs up. I saw %d packets\n", Gsi->icmpcnt); syslog(LOG_ALERT, buf); Gsi->icmpcnt = 0; } } for(pi = Gsi->tcpin; pi; pi = pi->next) { i = 0; for(fi = pi->fi; fi; fi = fi->next) i++; if(Greportlevel == REPORTALL Greportlevel == REPORTDOS) { if(i > Gsynflood) { eaddr = ether_ntoa(pi->eaddr); sprintf(buf, "Possible SYNFLOOD from %s (%s), against %s. I saw %d packets\n", anetaddr(pi->saddr), eaddr, abuf, i); syslog(LOG_ALERT, buf); } } for(al = tcplist; al; al = al->next) { if(pi->saddr == al->saddr) { al->cnt++; if(pi->sport == 80) al->wwwcnt++; break; } } if(al == NULL) /* new address */ { al = (struct addrlist *)malloc(sizeof(struct addrlist)); if(al == NULL) { perror("Malloc address list"); exit(-1); } memset(al, 0, sizeof(struct addrlist)); al->saddr = pi->saddr; al->cnt = 1; if(pi->sport == 80) al->wwwcnt = 1; al->next = tcplist; tcplist = al; } } if(Greportlevel == REPORTALL Greportlevel == REPORTSCAN) { for(al = tcplist; al; al = al->next) { if((al->cnt - al->wwwcnt) > Gportlimit al->wwwcnt > Gwebcount) { sprintf(buf, "Possible TCP port scan from %s (%d ports) against %s\n", anetaddr(al->saddr), al->cnt, abuf); syslog(LOG_ALERT, buf); } }
for(pi = Gsi->udpin; pi; pi = pi->next) { for(al = udplist; al; al = al->next) { if(pi->saddr == al->saddr) { al->cnt++; break; } } if(al == NULL) /* new address */ { al = (struct addrlist *)malloc(sizeof(struct addrlist)); if(al == NULL) { perror("Malloc address list"); exit(-1); } memset(al, 0, sizeof(struct addrlist)); al->saddr = pi->saddr; al->cnt = 1; al->next = udplist; udplist = al; } } for(al = udplist; al; al = al->next) { if(al->cnt > Gportlimit) { sprintf(buf, "Possible UDP port scan from %s (%d ports) against %s\n", anetaddr(al->saddr), al->cnt, abuf); syslog(LOG_ALERT, buf); } } }
while(tcplist) { al = tcplist->next; free(tcplist); tcplist = al; } while(udplist) { al = udplist->next; free(udplist); udplist = al; } }
/*********************************************************** Function: anetaddr
Description:
Another version of the intoa function. ************************************************************/
char *anetaddr(addr) u_long addr; { u_long naddr; static char buf[16]; u_char b[4]; int i;
naddr = ntohl(addr); for(i = 3; i >= 0; i--) { b[i] = (u_char) (naddr & 0xff); naddr >>= 8; } sprintf(buf, "%d.%d.%d.%d", b[0], b[1], b[2], b[3]); return(buf); }
/********************************************************** Function: initdevice
Description: Set up the network device so we can read it.
******************************************************/ initdevice(fd_flags, dflags) int fd_flags; u_long dflags; { struct ifreq ifr; int fd, flags = 0;
if((fd = socket(PF_INET, SOCK_PACKET, htons(0x0003))) < 0) { perror("Cannot open device socket"); exit(-1); }
/* Get the existing interface flags */
strcpy(ifr.ifr_name, Gdevice); if(ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { perror("Cannot get interface flags"); exit(-1); }
ifr.ifr_flags = IFF_PROMISC; if(ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { perror("Cannot set interface flags"); exit(-1); } return(fd); }
/********************************************************* Function: readdevice
Description: Read a packet from the device.
**************************************************************/ u_char *readdevice(fd, pktlen) int fd; int *pktlen; { int cc = 0, from_len, readmore = 1; struct sockaddr from; static u_char pktbuffer[PKTLEN]; u_char *cp;
while(readmore) { from_len = sizeof(from); if((cc = recvfrom(fd, pktbuffer, PKTLEN, 0, &from, &from_len)) < 0) { if(errno !
复制本页网址和标题,发送给你QQ/Msn的好友一起分享
上一篇:入侵检测工具Watcher 一
下一篇:如何将多个文件捆绑成一个可执行文件