📄 spp_portscan.c
字号:
/*** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>** Copyright (C) 1999,2000,2001 Patrick Mullen <p_mullen@linuxrc.net>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//* $Id$ *//* Snort Portscan Preprocessor Plugin by Patrick Mullen <p_mullen@linuxrc.net> Version 0.2.14*/#include <sys/types.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#ifndef WIN32 #include <sys/time.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>#endif /* !WIN32 */#include <time.h>#include "rules.h"#include "log.h"#include "util.h"#include "debug.h"#include "generators.h"#include "detect.h"#include "log.h"#include "plugbase.h"#include "parser.h"#include "mstring.h"#include "snort.h"void PortscanInit(u_char *);void ParsePortscanArgs(u_char *);void PortscanPreprocFunction(Packet *, void *);void ExtractHeaderInfo(Packet*, struct in_addr*, struct in_addr*, u_short*, u_short*);void PortscanIgnoreHostsInit(u_char*);#define MODNAME "spp_portscan"/*BUGS:I dare say the connection information reported at the end of a scan is wildly inaccurate. Search for "ZDNOTE CONNECTION INFORMATION" for more details.TODO:configuration filescans to multiple networkslog scan packet contents- Once a host has been determined to be scanning, automatically log packets from that host to reduce memory requirements.documentationfunction descriptionsdistributed portscans*//* Definitions for scan types */struct spp_timeval{ time_t tv_sec; time_t tv_usec;};typedef enum _scanType{ sNONE = 0, sUDP = 1, sSYN = 2, sSYNFIN = 4, sFIN = 8, sNULL = 16, sXMAS = 32, sFULLXMAS = 64, sRESERVEDBITS = 128, sVECNA = 256, sNOACK = 512, sNMAPID = 1024, sSPAU = 2048, sINVALIDACK = 4096} ScanType;/* Definitions for log levels */typedef enum _logLevel{ lNONE = 0, lFILE = 1, lEXTENDED = 2, lPACKET = 4} LogLevel;/* Structures for keeping track of connection information. */typedef struct _connectionInfo{ ScanType scanType; u_short sport; u_short dport; struct spp_timeval timestamp; char tcpFlags[9]; /* Eight flags and a NULL */ u_char *packetData; struct _connectionInfo *prevNode; struct _connectionInfo *nextNode;} ConnectionInfo;typedef struct _destinationInfo{ struct in_addr daddr; int numberOfConnections; ConnectionInfo *connectionsList; struct _destinationInfo *prevNode; struct _destinationInfo *nextNode;} DestinationInfo;typedef struct _sourceInfo{ struct in_addr saddr; int numberOfConnections; int numberOfDestinations; int numberOfTCPConnections; int numberOfUDPConnections; /* * ZDNOTE CONNECTION INFORMATION The totals statistics are generally * inaccurate and for general information of the severity of a scan, * rather than a hard and fast count of what was scanned. To provide 100% * accurate statistics, the architecture would have to be heavily * modified. This should probably be done anyway, but not today. * * Ways these counts will be inaccurate: 1) Hosts is incorrect if a host is * rescanned after all connection information is cleared 2) Connections * counts are incorrect if same ports are rescanned after they have * already been reported. 3) Probably more. This is a little more * difficult to do reliably than I realized. Ah, well. */ int totalNumberOfTCPConnections; int totalNumberOfUDPConnections; int totalNumberOfDestinations; struct spp_timeval firstPacketTime; struct spp_timeval lastPacketTime; int reportStealth; int stealthScanUsed; int scanDetected; struct spp_timeval reportTime; /* last time we reported on this * source's activities */ DestinationInfo *destinationsList; u_int32_t event_id; struct _sourceInfo *prevNode; struct _sourceInfo *nextNode;} SourceInfo;typedef struct _scanList{ SourceInfo *listHead; SourceInfo *lastSource; long numberOfSources; /* must be as large as address space */} ScanList;typedef struct _serverNode /* for keeping track of our network's servers */{ IpAddrSet *address; /* * u_long address; u_long netmask; */ char ignoreFlags; struct _serverNode *nextNode;} ServerNode;typedef struct _CPConfig{ u_int32_t classification; u_int32_t priority;} CPConfig;/** FUNCTION PROTOTYPES **//* Add connection information */int NewScan(ScanList *, Packet *, ScanType);ConnectionInfo *NewConnection(Packet *, ScanType);ConnectionInfo *AddConnection(ConnectionInfo *, Packet *, ScanType);DestinationInfo *NewDestination(Packet *, ScanType);DestinationInfo *AddDestination(DestinationInfo *, Packet *, ScanType);SourceInfo *NewSource(Packet *, ScanType);SourceInfo *AddSource(SourceInfo *, Packet *, ScanType);/* Remove connection information */void ExpireConnections(ScanList *, struct spp_timeval, struct spp_timeval);void RemoveConnection(ConnectionInfo *);void RemoveDestination(DestinationInfo *);void RemoveSource(SourceInfo *);void ClearConnectionInfoFromSource(SourceInfo *);/* Logging functions */void LogScanInfoToSeparateFile(SourceInfo *);void AlertIntermediateInfo(SourceInfo *);/* Miscellaneous functions */ScanList *CreateScanList(void);ScanType CheckTCPFlags(u_char);int IsServer(Packet *);/* For portscan-ignorehosts */IpAddrSet *PortscanAllocAddrNode();void PortscanParseIP(char *);void CreateServerList(u_char *);IpAddrSet *PortscanIgnoreAllocAddrNode(ServerNode *);void PortscanIgnoreParseIP(char *, ServerNode *);/* Global variables */ScanList *scanList;ServerNode *serverList;ScanType scansToWatch;CPConfig configdata;/*u_long homeNet, homeNetMask;*/IpAddrSet *homeAddr;char homeFlags;struct spp_timeval maxTime;long maxPorts;LogLevel logLevel;enum _timeFormat{ tLOCAL, tGMT} timeFormat;FILE *logFile;int packetLogSize; /* Number of data bytes to log per scan * packet *//* external globals from rules.c */extern u_int32_t event_id;ConnectionInfo *NewConnection(Packet * p, ScanType scanType){ ConnectionInfo *newConnection = (ConnectionInfo *) malloc(sizeof(ConnectionInfo)); newConnection->prevNode = NULL; newConnection->nextNode = NULL; newConnection->scanType = scanType; /* * timestamp provided by libpcap. This is available realtime and during * -r playback */ newConnection->timestamp.tv_sec = p->pkth->ts.tv_sec; newConnection->timestamp.tv_usec = p->pkth->ts.tv_usec; /* The ports are already supposed to be in host order from decode.c */ newConnection->sport = p->sp; newConnection->dport = p->dp; switch(p->iph->ip_proto) { case IPPROTO_TCP: CreateTCPFlagString(p, newConnection->tcpFlags); /* ZDNOTE PACKET LOGGING */ if(logLevel & lPACKET) { /* * Determine buffer size = header size + lower(datasize, * packetLogSize) */ /* Allocate memory */ /* Copy data */ } break; case IPPROTO_UDP: strncpy(newConnection->tcpFlags, "\0", 1); /* ZDNOTE PACKET LOGGING */ if(logLevel & lPACKET) { /* * Determine buffer size = header size + lower(datasize, * packetLogSize) */ /* Allocate memory */ /* Copy data */ } break; default: /* This should never happen because it's already filtered. */ FatalError(MODNAME ": NewConnection(): Invalid protocol! (%d)\n", p->iph->ip_proto); break; } return(newConnection);}ConnectionInfo *AddConnection(ConnectionInfo * currentConnection, Packet * p, ScanType scanType){ if(currentConnection->nextNode) FatalError(MODNAME ": AddConnection(): Not at end of connection list!"); currentConnection->nextNode = NewConnection(p, scanType); currentConnection->nextNode->prevNode = currentConnection; return(currentConnection->nextNode);}DestinationInfo *NewDestination(Packet * p, ScanType scanType){ DestinationInfo *newDestination = (DestinationInfo *) malloc(sizeof(DestinationInfo)); newDestination->prevNode = NULL; newDestination->nextNode = NULL; newDestination->daddr = p->iph->ip_dst; newDestination->connectionsList = NewConnection(p, scanType); newDestination->numberOfConnections = 1; return(newDestination);}DestinationInfo *AddDestination(DestinationInfo * currentDestination, Packet * p, ScanType scanType){ if(currentDestination->nextNode) FatalError(MODNAME ": AddDestination(): Not at end of destination list!"); currentDestination->nextNode = NewDestination(p, scanType); currentDestination->nextNode->prevNode = currentDestination; return(currentDestination->nextNode);}SourceInfo *NewSource(Packet * p, ScanType scanType){ SourceInfo *newSource = (SourceInfo *) malloc(sizeof(SourceInfo)); newSource->prevNode = NULL; newSource->nextNode = NULL; newSource->saddr = p->iph->ip_src; newSource->numberOfConnections = 1; newSource->firstPacketTime.tv_sec = p->pkth->ts.tv_sec; newSource->firstPacketTime.tv_usec = p->pkth->ts.tv_usec; newSource->lastPacketTime.tv_sec = p->pkth->ts.tv_sec; newSource->lastPacketTime.tv_usec = p->pkth->ts.tv_usec; if(scanType == sUDP) { newSource->numberOfUDPConnections = 1; newSource->numberOfTCPConnections = 0; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME ": NewSource(): %s->numberOfUDPConnections = 1, TCP = 0\n", inet_ntoa(newSource->saddr));); } else { newSource->numberOfTCPConnections = 1; newSource->numberOfUDPConnections = 0; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME ": NewSource(): %s->numberOfTCPConnections = 1, UDP = 0\n", inet_ntoa(newSource->saddr));); } newSource->totalNumberOfTCPConnections = 0; newSource->totalNumberOfUDPConnections = 0; newSource->stealthScanUsed = 0; /* This needs to be set elsewhere */ newSource->scanDetected = 0; newSource->destinationsList = NewDestination(p, scanType); newSource->numberOfDestinations = 1; newSource->totalNumberOfDestinations = 1; newSource->reportStealth = 0; /* This needs to be set elsewhere */ return(newSource);}SourceInfo *AddSource(SourceInfo * currentSource, Packet * p, ScanType scanType){ if(currentSource->nextNode) FatalError(MODNAME ": AddSource(): Not at end of source list!"); currentSource->nextNode = NewSource(p, scanType); currentSource->nextNode->prevNode = currentSource; return(currentSource->nextNode);}void RemoveConnection(ConnectionInfo * delConnection){ /* * If there is a prev and/or next node, make them point to the proper * places. Otherwise, just delete this node. */ if(delConnection->prevNode || delConnection->nextNode) { if(delConnection->prevNode) { delConnection->prevNode->nextNode = delConnection->nextNode; } else if(delConnection->nextNode) { delConnection->nextNode->prevNode = NULL; } if(delConnection->nextNode) { delConnection->nextNode->prevNode = delConnection->prevNode; } else if(delConnection->prevNode) { delConnection->prevNode->nextNode = NULL; } } free(delConnection);}void RemoveDestination(DestinationInfo * delDestination){ /* * If there is a prev and/or next node, make them point to the proper * places. Otherwise, just delete this node. */ if(delDestination->prevNode || delDestination->nextNode) { if(delDestination->prevNode) { delDestination->prevNode->nextNode = delDestination->nextNode; } else if(delDestination->nextNode) { delDestination->nextNode->prevNode = NULL; } if(delDestination->nextNode) { delDestination->nextNode->prevNode = delDestination->prevNode; } else if(delDestination->prevNode) { delDestination->prevNode->nextNode = NULL; } } free(delDestination);}void RemoveSource(SourceInfo * delSource){ /* * If there is a prev and/or next node, make them point to the proper * places. Otherwise, just delete this node. */ if(delSource->prevNode || delSource->nextNode) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -