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

📄 spp_portscan.c

📁 该源码是用C语言编写的,实现网络入侵检测系统的功能
💻 C
📖 第 1 页 / 共 4 页
字号:
				print_interface(pv.interfaces[0]), #else                                pv.interfaces[0], #endif                                inet_ntoa(scanList->lastSource->saddr));                    }                    else                    {                        sprintf(logMessage,                                 MODNAME ": PORTSCAN DETECTED from %s (STEALTH)",                                 inet_ntoa(scanList->lastSource->saddr));                    }                }                else                {                    if(pv.alert_interface_flag)                    {                        sprintf(logMessage, MODNAME                                 ": PORTSCAN DETECTED on %s from %s"                                " (THRESHOLD %ld connections exceeded in %ld seconds)",#ifdef WIN32				print_interface(pv.interfaces[0]), #else                                pv.interfaces[0], #endif                                 inet_ntoa(scanList->lastSource->saddr), maxPorts,                                (long int) (currTime.tv_sec -                                             scanList->lastSource->firstPacketTime.tv_sec));                    }                    else                    {                        sprintf(logMessage,                                 MODNAME ": PORTSCAN DETECTED from %s"                                " (THRESHOLD %ld connections exceeded in %ld seconds)",                                inet_ntoa(scanList->lastSource->saddr), maxPorts,                                (long int) (currTime.tv_sec -                                             scanList->lastSource->firstPacketTime.tv_sec));                    }                }                /* (*AlertFunc)(NULL, logMessage); */                CallAlertFuncs(NULL , logMessage, NULL);                /* CallLogFuncs(NULL , logMessage, NULL); */                scanList->lastSource->scanDetected = 1;                scanList->lastSource->reportTime = currTime;            }        }        /* See if there's anyone we can snitch on.  ;)  */        currentSource = scanList->listHead;        while(currentSource)        {            if(currentSource->scanDetected)            {                if(currentSource->reportTime.tv_sec + maxTime.tv_sec < currTime.tv_sec)                {                    if(currentSource->numberOfConnections == 0)                    {                        /* Portscan stopped.  Clear flag. */                        sprintf(logMessage, MODNAME ": End of portscan from %s: TOTAL time(%lds) hosts(%d) TCP(%d) UDP(%d)%s",                                inet_ntoa(currentSource->saddr),                                (long int) (currentSource->lastPacketTime.tv_sec - currentSource->firstPacketTime.tv_sec),                                currentSource->totalNumberOfDestinations,                                currentSource->totalNumberOfTCPConnections,                                currentSource->totalNumberOfUDPConnections,                                (currentSource->reportStealth) ? " STEALTH" : "");                        /* (*AlertFunc)(NULL, logMessage); */                        CallAlertFuncs(NULL , logMessage, NULL);                        /* CallLogFuncs(NULL , logMessage, NULL); */                        currentSource->scanDetected = 0;                    }                    else                    {                        /* This is where we do the real logging */                        if(logLevel & lFILE)                            LogScanInfoToSeparateFile(currentSource);                        if(logLevel & lEXTENDED)                            AlertIntermediateInfo(currentSource);                        currentSource->totalNumberOfTCPConnections += currentSource->numberOfTCPConnections;                        currentSource->totalNumberOfUDPConnections += currentSource->numberOfUDPConnections;                        ClearConnectionInfoFromSource(currentSource);                        currentSource->stealthScanUsed = 0;                        currentSource->reportTime = currTime;                    }                }            }            currentSource = currentSource->nextNode;        }    }}void ClearConnectionInfoFromSource(SourceInfo * currentSource){    DestinationInfo *currentDestination, *tmpDestination;    ConnectionInfo *currentConnection, *tmpConnection;    currentDestination = currentSource->destinationsList;    while(currentDestination)    {        currentConnection = currentDestination->connectionsList;        while(currentConnection)        {            tmpConnection = currentConnection;            currentConnection = currentConnection->nextNode;            if(tmpConnection->scanType == sUDP)            {                currentSource->numberOfUDPConnections--;#ifdef DEBUG                printf(MODNAME ": ClearConnectionInfoFromSource(): %s->numberOfUDPConnections-- (%d)\n",                       inet_ntoa(currentSource->saddr), currentSource->numberOfUDPConnections);#endif            }            else            {                currentSource->numberOfTCPConnections--;#ifdef DEBUG                printf(MODNAME ": ClearConnectionInfoFromSource(): %s->numberOfTCPConnections-- (%d)\n",                       inet_ntoa(currentSource->saddr), currentSource->numberOfTCPConnections);#endif            }            RemoveConnection(tmpConnection);            currentDestination->numberOfConnections--;            currentSource->numberOfConnections--;        }        tmpDestination = currentDestination;        currentDestination = currentDestination->nextNode;        RemoveDestination(tmpDestination);        currentSource->numberOfDestinations--;    }    currentSource->destinationsList = NULL;}void SetupPortscan(void){    RegisterPreprocessor("portscan", PortscanInit);}void PortscanInit(u_char * args){    ParsePortscanArgs(args);    scanList = CreateScanList();    /*     * We set serverList to NULL here so if portscan-ignorehosts is used it     * must be set after portscan.  This is necessary to make sure we don't     * check an empty list.     */    serverList = NULL;    AddFuncToPreprocList(PortscanPreprocFunction);}ScanType CheckTCPFlags(u_char th_flags){    u_char th_flags_cleaned;    ScanType scan = sNONE;    /*     * Strip off the reserved bits for the testing, but flag that a scan is     * being done.     */    th_flags_cleaned = th_flags & ~(R_RES1 | R_RES2);    if(th_flags != th_flags_cleaned)    {        scan = sRESERVEDBITS;    }    /*     * Most TCP packets will have the ACK bit set, so split that out quickly.     * Any scans which use ACK (like Full-XMAS) must be added to this part.     * Otherwise, it goes in the !ACK section. In addition, anything that is     * !ACK && !SYN eventually gets flagged as something.  This is to     * hopefully detect new stealth scan types.     */    if(th_flags_cleaned & R_ACK)    {        /*         * This is from ipt_unclean.c from the netfilter package.  We are         * allowing packets which are valid and flagging the rest as         * INVALIDACK, if it's not already listed as some other scan.         */        switch(th_flags_cleaned)        {            case (R_ACK):            case (R_SYN | R_ACK):            case (R_FIN | R_ACK):            case (R_RST | R_ACK):            case (R_ACK | R_PSH):            case (R_ACK | R_URG):            case (R_ACK | R_URG | R_PSH):            case (R_FIN | R_ACK | R_PSH):            case (R_FIN | R_ACK | R_URG):            case (R_FIN | R_ACK | R_URG | R_PSH):            case (R_RST | R_ACK | R_PSH):   /* Found through numerous false                             * alerts. */                /* Nothing.  This is legitimate traffic. */                break;            case (R_SYN | R_RST | R_ACK | R_FIN | R_PSH | R_URG):                scan |= sFULLXMAS;                break;            case (R_SYN | R_PSH | R_ACK | R_URG):                scan |= sSPAU;                break;            default:                scan |= sINVALIDACK;                break;        }    }    else    {        /*         * ZDNOTE This could/should be optimized, but just by having the         * check for SYN or RST being first makes this faster.  (Anything         * else is a scan and shouldn't be hit often.         */        switch(th_flags_cleaned)        {            case R_SYN:#ifdef DEBUG                printf("spp_portscan: SYN packet\n");#endif                scan |= sSYN;                break;            case R_RST:                /* Nothing.  This is legitimately tearing down a connection. */                break;            case R_FIN:                scan |= sFIN;                break;            case (R_SYN | R_FIN):                scan |= sSYNFIN;                break;            case 0:                scan |= sNULL;                break;            case (R_FIN | R_PSH | R_URG):                scan |= sXMAS;                break;            case R_URG:            case R_PSH:            case (R_URG | R_FIN):            case (R_PSH | R_FIN):            case (R_URG | R_PSH):                scan |= sVECNA;                break;            case (R_SYN | R_FIN | R_PSH | R_URG):                scan |= sNMAPID;                break;            default:                /*                 * We assume that anything down here w/out an ACK flag is some                 * sort of a scan or something.  Anyway, we'll flag it because if                 * it doesn't have an ACK it should have been only a SYN or RST                 * and be detected above.                 */                scan |= sNOACK;                break;        }    }    return(scan);}void ParsePortscanArgs(u_char * args){    char **toks;    int numToks;    char *logFileName;#ifdef DEBUG    printf(MODNAME ": ParsePortscanArgs(): %s\n", args);#endif    logLevel = lNONE;    if(!args)    {        FatalError(MODNAME ": ERROR: %s (%d) => portscan configuration format:  address/mask ports seconds [logfile]\n", file_name, file_line);    }    /* the '\\' sets the string escape delimiter - MFR */#ifdef WIN32     toks = mSplit(args, " ", 4, &numToks, 0);#else     toks = mSplit(args, " ", 4, &numToks, '\\');    /* ZDNOTE What does the                              * '\\' do? */#endif    if((numToks < 3) || (numToks > 4))    {        FatalError(MODNAME ": ERROR: %s (%d) => portscan configuration format:  address/mask ports seconds [logfile]\n", file_name, file_line);    }    maxPorts = atoi(toks[1]);    maxTime.tv_sec = atoi(toks[2]);    maxTime.tv_usec = 0;    PortscanParseIP(toks[0]);    /* ParseIP(toks[0], homeAddr); */    /*     * Now we use the default log directory if provided from the command line     * (-l).     */    if(numToks == 4)    {#ifdef WIN32       logFileName = (char *) calloc(strlen(toks[3]) + 1 + 1, 1);       strncpy(logFileName, toks[3], strlen(toks[3]));#else        if(pv.log_dir && (*toks[3] != '/'))        {            if(*(pv.log_dir + strlen(pv.log_dir) - 1) != '/')            {                logFileName = chrootdir == NULL ?                    (char *) calloc(strlen(pv.log_dir) + strlen(toks[3]) + 1 + 1, 1) :                    (char *) calloc(strlen(pv.log_dir) + strlen(toks[3]) + strlen(chrootdir) + 1 + 1, 1);                if(chrootdir)                    strncpy(logFileName, chrootdir, strlen(chrootdir) + 1);                strncat(logFileName, pv.log_dir, strlen(pv.log_dir) + 1);                strncat(logFileName, "/", 1);                strncat(logFileName, toks[3], strlen(toks[3]));            }            else            {                logFileName = chrootdir == NULL ?                    (char *) calloc(strlen(pv.log_dir) + strlen(toks[3]) + 1, 1) :                    (char *) calloc(strlen(pv.log_dir) + strlen(toks[3]) + strlen(chrootdir) + 1, 1);                if(chrootdir)                    strncpy(logFileName, chrootdir, strlen(chrootdir) + 1);                strncat(logFileName, pv.log_dir, strlen(pv.log_dir) + 1);                strncat(logFileName, toks[3], strlen(toks[3]));            }        }        else        {            logFileName = chrootdir == NULL ?                (char *) calloc(strlen(toks[3]) + 1, 1) :                (char *) calloc(strlen(toks[3]) + strlen(chrootdir) + 1, 1);            if(chrootdir)                strncpy(logFileName, chrootdir, strlen(chrootdir) + 1);            strncat(logFileName, toks[3], strlen(toks[3]) + 1);        }#endif#ifdef DEBUG        printf(MODNAME ": logFileName = %s\n", logFileName);#endif        logFile = fopen(logFileName, "a");        if(!logFile)            FatalError(MODNAME ": logfile open error (%s)\n", logFileName);        logLevel |= lFILE;    }    /* How about some error detecting? :) */    if(maxPorts == 0 || maxTime.tv_sec == 0)    {        FatalError(MODNAME ": ERROR: %s (%d) => portscan configuration format:  address/mask ports seconds [logfile]\n", file_name, file_line);    }    /*     * ZDNOTE Compile time settings.  Obviously needs to become runtime     * settings.     */    /*     * If you do not want every packet with reserved bits set (which     * shouldn't happen), just remove the "| sRESERVEDBITS" from the end of     * this line.  If you do that, you may wish to add a line to detect that     * in the rules file(s).     */    /*     * ZDNOTE If/when I add this to options, this would be "usfFnxXrvidI"     * scan detection.     */    scansToWatch = -1;      /* Watch for ALL scans */    /*     * scansToWatch = sUDP | sSYN | sFIN | sSYNFIN | sNULL | sXMAS |     * sFULLXMAS | sRESERVEDBITS | sVECNA | sNOACK | sNMAPID | sSPAU |     * sINVALIDACK;     */    /* can watch all scans but disable some by doing the following */    /* scansToWatch = ~(sRESERVEDBITS | sNMAPID ); */    /*     * ZDNOTE.  I'm a fascist and I want people to use my new feature, so I'm     * forcing everyone to default to my extended logging.  Mwua-ha-ha-ha!!!     */    logLevel |= lEXTENDED;    /* If you want to log packet contents, uncomment this line. */    /* logLevel |= lPACKET; */    /*     * If you want to change the number of bytes of packet data stored,     * change this value. This is the size of the payload and does not     * include the packet header. Set the value to -1 to log the complete     * packet contents.     */    packetLogSize = 100;    if(pv.use_utc == 1)    {        timeFormat = tGMT;        printf("Using GMT time\n");    }    else    {        timeFormat = tLOCAL;        printf("Using LOCAL time\n");    }}void LogScanInfoToSeparateFile(SourceInfo * currentSource){    DestinationInfo *currentDestination;    ConnectionInfo *currentConnection;    char *scanType;    char *reservedBits;    char *month;    struct tm *time;    char sourceAddress[16], destinationAddress[16];    char outBuf[160];       /* Don't need anywhere near this, but better                 * safe than sorry. */    memset(sourceAddress, '\0', 16);    memset(destinationAddress, '\0', 16);    /*     * Can't have two inet_ntoa() calls in a single printf because it uses a     * static buffer.  It's also faster to only do it twice instead of twice     * for each iteration.     */    strncpy(sourceAddress, inet_ntoa(currentSource->saddr), 15);    for(currentDestination = currentSource->destinationsList; currentDestination;       currentDestination = currentDestination->nextNode)    {

⌨️ 快捷键说明

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