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

📄 rules.c

📁 网络入侵检测系统
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Id: rules.c,v 1.38 2001/01/26 19:03:07 roesch Exp $ *//*** Copyright (C) 1998,1999,2000,2001 Martin Roesch <roesch@clark.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.*/#include "rules.h"ListHead Alert;         /* Alert Block Header */ListHead Log;           /* Log Block Header */ListHead Pass;          /* Pass Block Header */ListHead Activation;    /* Activation Block Header */ListHead Dynamic;       /* Dynamic Block Header */RuleTreeNode *rtn_tmp;      /* temp data holder */OptTreeNode *otn_tmp;       /* OptTreeNode temp ptr */ListHead *head_tmp = NULL;  /* ListHead temp ptr */RuleListNode *RuleLists;struct VarEntry *VarHead = NULL;char *file_name;        /* current rules file being processed */int file_line;          /* current line being processed in the rules                         * file */int list_file_line;     /* current line being processed in the list                         * file */int rule_count;         /* number of rules generated */int head_count;         /* number of header blocks (chain heads?) */int opt_count;          /* number of chains */int do_detect;int dynamic_rules_present;int active_dynamic_nodes;extern KeywordXlateList *KeywordList;   /* detection/response plugin keywords */extern PreprocessKeywordList *PreprocessKeywords;   /* preprocessor plugin                             * keywords */extern PreprocessFuncNode *PreprocessList;  /* Preprocessor function list */extern OutputKeywordList *OutputKeywords;   /* Output plugin keyword list */extern OutputFuncNode *AlertList;   /* Alert function list */extern OutputFuncNode *LogList; /* log function list *//* Local Function Declarations */OutputFuncNode *AppendOutputFuncList(void (*) (Packet *, char *, void *), void *,                                     OutputFuncNode *);#ifdef BENCHMARKint check_count;        /* number of tests for a given rule to                         * determine a match */int cmpcount;           /* compare counter */#endif/**************************************************************************** * * Function: ParseRulesFile(char *, int) * * Purpose:  Read the rules file a line at a time and send each rule to *           the rule parser * * Arguments: file => rules file filename *            inclevel => nr of stacked "include"s * * Returns: void function * ***************************************************************************/FILE *rule_file;void ParseRulesFile(char *file, int inclevel){    FILE *thefp;        /* file pointer for the rules file */    char buf[STD_BUF];      /* file read buffer */    char *index;        /* buffer indexing pointer */    char *stored_file_name = file_name;    int stored_file_line = file_line;#ifdef DEBUG    printf("Opening rules file: %s\n", file);#endif    if(inclevel == 0)    {        if(!pv.quiet_flag)        {            printf("\n+++++++++++++++++++++++++++++++++++++++++++++++++++\n");            printf("Initializing rule chains...\n");        }        file_name = strdup(file);    }    /* open the rules file */    if((thefp = fopen(file, "r")) == NULL)    {        FatalError("ERROR: Unable to open rules file: %s\n", file);    }    /* clear the line buffer */    bzero((char *) buf, STD_BUF);    stored_file_line = file_line;    stored_file_name = file_name;    file_name = strdup(file);    file_line = 0;    rule_file = thefp;    /* loop thru each file line and send it to the rule parser */    while((fgets(buf, STD_BUF, thefp)) != NULL)    {        /*         * inc the line counter so the error messages know which line to         * bitch about         */        file_line++;        index = buf;#ifdef DEBUG2        printf("Got line %s (%d): %s", file_name, file_line, buf);#endif        /* advance through any whitespace at the beginning of the line */        while(*index == ' ' || *index == '\t')            index++;        /* if it's not a comment or a <CR>, send it to the parser */        if((*index != '#') && (*index != 0x0a) && (*index != ';') && (index != NULL))        {            ParseRule(index, inclevel);        }        bzero((char *) buf, STD_BUF);    }    if(file_name)        free(file_name);    file_name = stored_file_name;    file_line = stored_file_line;    if(inclevel == 0 && !pv.quiet_flag)    {        printf("%d Snort rules read...\n", rule_count);        printf("%d Option Chains linked into %d Chain Headers\n", opt_count, head_count);        printf("%d Dynamic rules\n", dynamic_rules_present);        printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");    }    rule_file = NULL;    fclose(thefp);    /* plug all the dynamic rules together */    if(dynamic_rules_present)    {        LinkDynamicRules();    }    if(inclevel == 0)    {#ifdef DEBUG        DumpRuleChains();#endif        IntegrityCheckRules();    }    return;}int CheckRule(char *str){    int len;    int got_paren = 0;    int got_semi = 0;    char *index;    len = strlen(str);    index = str + len - 1; /* go to the end of the string */    while((isspace((int)*index)))    {        if(index > str)            index--;        else            return 0;    }    /* the last non-whitspace character should be a ')' */    if(*index == ')')    {        got_paren = 1;        index--;    }    while((isspace((int)*index)))    {        if(index > str)            index--;        else            return 0;    }    /* the next to last char should be a semicolon */    if(*index == ';')    {        got_semi = 1;    }    if(got_semi && got_paren)    {        return 1;    }    else    {        /* check for a '(' to make sure that rule options are being used... */        for(index = str; index < str+len; index++)        {            if(*index == '(')            {                return 0;            }        }        return 1;    }    return 0;}void DumpRuleChains(){    RuleListNode *rule;    rule = RuleLists;    while(rule != NULL)    {        DumpChain(rule->RuleList->TcpList, rule->name, "TCP Chains");        DumpChain(rule->RuleList->UdpList, rule->name, "UDP Chains");        DumpChain(rule->RuleList->IcmpList, rule->name, "ICMP Chains");        rule = rule->next;    }}void IntegrityCheckRules(){    RuleListNode *rule;    rule = RuleLists;#ifdef DEBUG    if(!pv.quiet_flag)    {        printf("Performing Rule List Integrity Tests...\n");        printf("---------------------------------------\n");    }#endif    while(rule != NULL)    {        IntegrityCheck(rule->RuleList->TcpList, rule->name, "TCP Chains");        IntegrityCheck(rule->RuleList->UdpList, rule->name, "UDP Chains");        IntegrityCheck(rule->RuleList->IcmpList, rule->name, "ICMP Chains");        rule = rule->next;    }#ifdef DEBUG    if(!pv.quiet_flag)    {        printf("---------------------------------------\n\n");    }#endif}/**************************************************************************** * * Function: ParseRule(char *, int) * * Purpose:  Process an individual rule and add it to the rule list * * Arguments: rule => rule string *            inclevel => nr of stacked "include"s * * Returns: void function * ***************************************************************************/void ParseRule(char *prule, int inclevel){    char **toks;        /* dbl ptr for mSplit call, holds rule tokens */    int num_toks;       /* holds number of tokens found by mSplit */    int rule_type;      /* rule type enumeration variable */    char rule[PARSERULE_SIZE];    int protocol;    RuleTreeNode proto_node;    int i;#ifdef PARSERULE_BIFURCATE    int bid = 0;#endif#ifdef PARSERULE_REVERSED    char *tmp_tok_host, *tmp_tok_port; /* 2 tmps for clarity */#endif        /* chop off the <CR/LF> from the string */    strip(prule);    /* expand all variables */    bzero((void *)rule, sizeof(rule));    strncpy(rule, ExpandVars(prule), PARSERULE_SIZE-1);    /* break out the tokens from the rule string */    toks = mSplit(rule, " ", 10, &num_toks, 0);#ifdef PARSERULE_REVERSED    if(num_toks > 5 && (strncmp("<-", toks[4], 2) == 0))    {#ifdef DEBUG	printf("Reversing rule %s %s %s %s %s %s %s ( into )\n",	       toks[0],toks[1],toks[2],toks[3],toks[4],toks[5],toks[6]);#endif /* DEBUG */	/* Switch the src and dst port/ips and change the direction */	tmp_tok_host = toks[2];	tmp_tok_port = toks[3];	toks[2] = toks[5];	toks[3] = toks[6];	toks[5] = tmp_tok_host;	toks[6] = tmp_tok_port;	/* the == 0 makes sure this has room to copy */	strncpy (toks[4], "->", 2); #ifdef DEBUG	printf("Reversed rule: %s %s %s %s %s %s %s\n",	       toks[0],toks[1],toks[2],toks[3],toks[4],toks[5],toks[6]);#endif /* DEBUG */    }#endif /*  PARSERULE_REVERSED */#ifdef PARSERULE_BIFURCATE    if(num_toks > 5 && (bid = !strncmp("<>", toks[4], 2)))    {#ifdef DEBUG        printf("Generating bid rules for: %s %s %s %s %s %s %s\n",               toks[0],toks[1],toks[2],toks[3],toks[4],toks[5],toks[6]);#endif        strncpy (toks[4], "->", 2);    }    bidog:#endif    /* clean house */    bzero((char *) &proto_node, sizeof(RuleTreeNode));#ifdef DEBUG    printf("[*] Rule start\n");#endif    /* figure out what we're looking at */    rule_type = RuleType(toks[0]);#ifdef DEBUG    printf("Rule type: ");#endif    /* handle non-rule entries */    switch(rule_type)    {        case RULE_PASS:#ifdef DEBUG            printf("Pass\n");#endif            break;        case RULE_LOG:#ifdef DEBUG            printf("Log\n");#endif            break;        case RULE_ALERT:#ifdef DEBUG            printf("Alert\n");#endif            break;        case RULE_INCLUDE:#ifdef DEBUG            printf("Include\n");#endif            ParseRulesFile(toks[1], inclevel + 1);            return;        case RULE_VAR:#ifdef DEBUG            printf("Variable\n");#endif            VarDefine(toks[1], toks[2]);            return;        case RULE_PREPROCESS:#ifdef DEBUG            printf("Preprocessor\n");#endif            ParsePreprocessor(rule);            return;        case RULE_OUTPUT:#ifdef DEBUG            printf("Output Plugin\n");#endif            ParseOutputPlugin(rule);            return;        case RULE_ACTIVATE:#ifdef DEBUG            printf("Activation rule\n");#endif            break;        case RULE_DYNAMIC:#ifdef DEBUG            printf("Dynamic rule\n");#endif            break;        case RULE_CONFIG:#ifdef DEBUG            printf("Rule file config\n");#endif            ParseConfig(rule);            return;        case RULE_DECLARE:#ifdef DEBUG            printf("Rule type declaration\n");#endif            ParseRuleTypeDeclaration(rule);            return;        case RULE_UNKNOWN:#ifdef DEBUG            printf("Unknown rule type, might be declared\n");#endif            ParseDeclaredRuleType(rule);            return;        default:            printf("Invalid input: %s\n", prule);            return;    }    if(!CheckRule(prule))    {        ErrorMessage("[!] ERROR: Unterminated rule in file %s, line %d\n", file_name, file_line);        ErrorMessage("   (Snort rules must be contained on a single line, make sure\n");        FatalError("   there are no carriage returns before the end of this line)\n");        return;    }    proto_node.type = rule_type;    /* set the rule protocol */    protocol = WhichProto(toks[1]);    /* Process the IP address and CIDR netmask */    /* changed version 1.2.1 */    /*     * "any" IP's are now set to addr 0, netmask 0, and the normal rules are     * applied instead of checking the flag     */    /*     * if we see a "!<ip number>" we need to set a flag so that we can     * properly deal with it when we are processing packets     */    /* we found a negated address */    /* if( *toks[2] == '!' )         {         proto_node.flags |= EXCEPT_SRC_IP;         ProcessIP(&toks[2][1], &proto_node, SRC);     }     else     {*/    ProcessIP(toks[2], &proto_node, SRC);    /*}*/    /* check to make sure that the user entered port numbers */    /* sometimes they forget/don't know that ICMP rules need them */    if(!strncasecmp(toks[3], "->", 2) ||       !strncasecmp(toks[3], "<>", 2))    {        FatalError("ERROR %s:%d => Port value missing in rule!\n", file_name, file_line);

⌨️ 快捷键说明

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