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

📄 spp_portscan.c

📁 该软件是一个有名的基于网络的入侵检测系统
💻 C
📖 第 1 页 / 共 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;
   
    ParseIP(toks[0], &homeNet, &homeNetMask);

    /* Now we use the default log directory if provided from the command line (-l). */   
    if (numToks == 4) 
    {
        if (pv.log_dir && (*toks[3] != '/'))
        {
            if (*(pv.log_dir + strlen(pv.log_dir) - 1) != '/')
            {
                logFileName = malloc(strlen(pv.log_dir) + strlen(toks[3]) + 1 + 1);
                strncpy(logFileName, pv.log_dir, strlen(pv.log_dir));
                strncat(logFileName, "/", 1);
                strncat(logFileName, toks[3], strlen(toks[3]));
            }
            else
            {
                logFileName = malloc(strlen(pv.log_dir) + strlen(toks[3]) + 1);
                strncpy(logFileName, pv.log_dir, strlen(pv.log_dir));
                strncat(logFileName, toks[3], strlen(toks[3]));
            }
        }
        else
        {
            logFileName = (char *)malloc(strlen(toks[3]) + 1);
            strncpy(logFileName, toks[3], strlen(toks[3]));
        }

#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;

    timeFormat = tLOCAL;  /* Alternatively, you can do tGMT (should be runtime setting) */
}


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)
    {
        strncpy(destinationAddress, inet_ntoa(currentDestination->daddr), 15);

        for (currentConnection = currentDestination->connectionsList; currentConnection;
                currentConnection = currentConnection->nextNode)
        {
            /* Apparently, through some stroke of genius and/or luck, timeval.tv_sec can be
               used just like time_t.  Sweet.  And stuff.
            */
            time = (timeFormat == tLOCAL) ? localtime(&currentConnection->timestamp.tv_sec)
                    : gmtime(&currentConnection->timestamp.tv_sec);
            switch (time->tm_mon)
            {
                case 0:
                    month = "Jan";
                    break;
                case 1:
                    month = "Feb";
                    break;
                case 2:
                    month = "Mar";
                    break;
                case 3:
                    month = "Apr";
                    break;
                case 4:
                    month = "May";
                    break;
                case 5:
                    month = "Jun";
                    break;
                case 6:
                    month = "Jul";
                    break;
                case 7:
                    month = "Aug";
                    break;
                case 8:
                    month = "Sep";
                    break;
                case 9:
                    month = "Oct";
                    break;
                case 10:
                    month = "Nov";
                    break;
                case 11:
                    month = "Dec";
                    break;
                default:
                    month = "MONTH IS INVALID!!";
                    break;
            }

            reservedBits = (currentConnection->scanType & sRESERVEDBITS) ? "RESERVEDBITS" : "";

#ifdef DEBUG
            printf("scanType = %x mask = %x result = (%x)\n", currentConnection->scanType, ~sRESERVEDBITS, currentConnection->scanType & ~sRESERVEDBITS);
#endif

            switch (currentConnection->scanType & ~sRESERVEDBITS)
            {
                case sUDP:
                    scanType = "UDP";
                    break;
                case sSYN:
                    scanType = "SYN";
                    break;
                case sFIN:
                    scanType = "FIN";
                    break;            
                case sSYNFIN:
                    scanType = "SYNFIN";
                    break;
                case sNULL:
                    scanType = "NULL";
                    break;
                case sXMAS:
                    scanType = "XMAS";
                    break;
                case sFULLXMAS:
                    scanType = "FULLXMAS";
                    break;
                case sVECNA:
                    scanType = "VECNA";
                    break;
                case sNOACK:
                    scanType = "NOACK";
                    break;
                case sNMAPID:
                    scanType = "NMAPID";
                    break;
                case sSPAU:
                    scanType = "SPAU";
                    break;
                case sINVALIDACK:
                    scanType = "INVALIDACK";
                    break;
                default:
                    /* This used to mean I screwed up, but now since any packet that has reserved bits set is
                       set as a scan it looks bad if "ERROR" shows up when the packet really has something
                       bizarre like "2****P**".
                    */

#ifdef DEBUG
                    printf("UNKNOWN: scanType = %x (%x)\n", currentConnection->scanType, currentConnection->scanType & ~sRESERVEDBITS);
#endif

                    scanType = "UNKNOWN";
                    break;
            }

            /* I have control of all data here, so this should be safe */
            sprintf(outBuf, "%s %2d %.2d:%.2d:%.2d %s:%d -> %s:%d %s %s %s\n", month, time->tm_mday, 
                    time->tm_hour, time->tm_min, time->tm_sec,
                    sourceAddress, currentConnection->sport, destinationAddress,
                    currentConnection->dport, scanType, currentConnection->tcpFlags, reservedBits);
            fwrite(outBuf, strlen(outBuf), 1, logFile);
        }
    }

    /* Now that we're done, flush the buffer to disk. */
    fflush(logFile);
}


/***** AlertIntermediateInfo() *****
  Log number of scan packets and types to standard alert mechanism.
*/
void AlertIntermediateInfo(SourceInfo* currentSource)
{
    char logMessage[160];

    sprintf(logMessage, MODNAME ": portscan status from %s: %d connections across %d hosts: TCP(%d), UDP(%d)%s",
            inet_ntoa(currentSource->saddr), currentSource->numberOfConnections, currentSource->numberOfDestinations,
            currentSource->numberOfTCPConnections, currentSource->numberOfUDPConnections, 
            (currentSource->stealthScanUsed) ? " STEALTH" : "");
    (*AlertFunc)(NULL, logMessage);
}


void ExtractHeaderInfo(Packet *p, struct in_addr *saddr, struct in_addr *daddr, 
        u_short *sport, u_short *dport)
{
    /* This function seems kinda silly now that I don't have to do protocol checks
       to use the proper protocol headers to get the port, but I think it still
       makes it easier and I don't have to worry about something changing later.
    */

    *sport = p->sp;
    *dport = p->dp;
    *saddr = p->iph->ip_src;
    *daddr = p->iph->ip_dst;
} 


/* Check if packet originated from a machine we have been told to ignore
   SYN and UDP "scans" from, presumably because it's a server.
*/
int IsServer(Packet *p)
{
    ServerNode *currentServer = serverList;

#ifdef DEBUG
    char sourceIP[16], ruleIP[16], ruleNetMask[16];
#endif
   
    while (currentServer)
    {
        /* Return 1 if the source addr is in the serverlist, 0 if nothing is found.
        */
        if (CheckAddrPort(currentServer->address, currentServer->netmask, 
                0, 0, p, ANY_SRC_PORT, CHECK_SRC))
        {

#ifdef DEBUG
            memset(sourceIP, '\0', 16);
            memset(ruleIP, '\0', 16);
            memset(ruleNetMask, '\0', 16);
            strncpy(sourceIP, inet_ntoa(p->iph->ip_src), 15);
            strncpy(ruleIP, inet_ntoa(*(struct in_addr*)&currentServer->address), 15);
            strncpy(ruleNetMask, inet_ntoa(*(struct in_addr*)&currentServer->netmask), 15);

            printf(MODNAME": IsServer():  Server %s found in %s/%s!\n", sourceIP, ruleIP, ruleNetMask);
#endif

            return(1);
        }

        currentServer = currentServer->nextNode;
    }

    return(0);
}


void SetupPortscanIgnoreHosts(void)
{
    RegisterPreprocessor("portscan-ignorehosts", PortscanIgnoreHostsInit);
}


void PortscanIgnoreHostsInit(u_char *args)
{
    CreateServerList(args);
}


/* Well, it seems we are ignoring more than just servers now.  We're also
   ignoring SYN and UDP scans from our own networks.  I guess this is okay.
   Most networks have a soft, chewy center, anyway.  Besides, this
   makes the coding easier! ;)
*/
void CreateServerList(u_char *servers)
{
    char **toks;
    int num_toks;
    int num_servers = 0;
    ServerNode *currentServer;

#ifdef DEBUG
    char ruleIP[16], ruleNetMask[16];
#endif

    currentServer = NULL;
    serverList = NULL;

    if (servers == NULL)
    {
        FatalError(MODNAME": ERROR: %s (%d)=> No arguments to portscan-ignorehosts preprocessor!\n", file_name, file_line);
    }

    /* tokenize the argument list */
    toks = mSplit(servers, " ", 31, &num_toks, '\\');

    /* convert the tokens and place them into the server list */
    for (num_servers = 0; num_servers < num_toks; num_servers++)
    {
        if (currentServer != NULL)
        {
            currentServer->nextNode = (ServerNode*)malloc(sizeof(ServerNode));
            currentServer = currentServer->nextNode;
        }
        else
        {
            currentServer = (ServerNode*)malloc(sizeof(ServerNode));
            serverList = currentServer;
        }

#ifdef DEBUG
        printf(MODNAME": CreateServerList(): Adding server %s\n", toks[num_servers]);
#endif

        ParseIP(toks[num_servers], &currentServer->address, &currentServer->netmask);

#ifdef DEBUG
        memset(ruleIP, '\0', 16);
        memset(ruleNetMask, '\0', 16);
        strncpy(ruleIP, inet_ntoa(*(struct in_addr*)&currentServer->address), 15);
        strncpy(ruleNetMask, inet_ntoa(*(struct in_addr*)&currentServer->netmask), 15);
        printf(MODNAME": CreateServerList(): Added server %s/%s\n", ruleIP, ruleNetMask);
#endif

        currentServer->nextNode = NULL;
    }

    free(toks);  /* ZDNOTE Does this really free the memory allocated to each token? */
}

⌨️ 快捷键说明

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