⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spp_portscan.c

📁 该软件是一个有名的基于网络的入侵检测系统
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
** Copyright (C) 1998,1999,2000 Martin Roesch <roesch@clark.net>
** Copyright (C) 1999,2000 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: spp_portscan.c,v 1.19 2000/07/07 12:00:25 fyodor Exp $ */
/* Snort Portscan Preprocessor Plugin
    by Patrick Mullen <p_mullen@linuxrc.net>
    Version 0.2.14
*/


#define MODNAME "spp_portscan"

#include "spp_portscan.h"
#include "rules.h"
#include "log.h"

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

/*
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 file
scans to multiple networks
log scan packet contents
- Once a host has been determined to be scanning, automatically log packets from
  that host to reduce memory requirements.
documentation
function descriptions
distributed portscans

*/

struct spp_timeval
{
   time_t tv_sec;
   time_t tv_usec;
};


/* Definitions for scan types */
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;
    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 */
{
    u_long address;
    u_long netmask;
    struct _serverNode *nextNode;
}  ServerNode;


/** 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 */
void CreateServerList(u_char*);

/* Global variables */
ScanList *scanList;
ServerNode *serverList;
ScanType scansToWatch;
u_long homeNet, homeNetMask;
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 char *file_name;
extern int file_line;


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;

#ifdef DEBUG
        printf(MODNAME": NewSource(): %s->numberOfUDPConnections = 1, TCP = 0\n", inet_ntoa(newSource->saddr));
#endif

    }
    else
    {
        newSource->numberOfTCPConnections = 1;
        newSource->numberOfUDPConnections = 0;

#ifdef DEBUG
        printf(MODNAME": NewSource(): %s->numberOfTCPConnections = 1, UDP = 0\n", inet_ntoa(newSource->saddr));
#endif

    }

    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) 
        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -