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

📄 sp_pattern_match.c

📁 Linux snort-2.4.4源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>**** 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$ */#include <errno.h>#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#ifdef DEBUG#include <assert.h>#endif#include "sp_pattern_match.h"#include "bounds.h"#include "rules.h"#include "plugbase.h"#include "debug.h"#include "mstring.h"#include "util.h" #include "parser.h"  /* why does parser.h define Add functions.. */#include "plugin_enum.h"#include "checksum.h"#include "inline.h"static void PayloadSearchInit(char *, OptTreeNode *, int);static void PayloadSearchListInit(char *, OptTreeNode *, int);static void ParseContentListFile(char *, OptTreeNode *, int);static void PayloadSearchUri(char *, OptTreeNode *, int);static void ParsePattern(char *, OptTreeNode *, int);static int CheckANDPatternMatch(Packet *, struct _OptTreeNode *, OptFpList *);static int CheckORPatternMatch(Packet *, struct _OptTreeNode *, OptFpList *);static int CheckUriPatternMatch(Packet *, struct _OptTreeNode *, OptFpList *);static void PayloadSearchOffset(char *, OptTreeNode *, int);static void PayloadSearchDepth(char *, OptTreeNode *, int);static void PayloadSearchNocase(char *, OptTreeNode *, int);static void PayloadSearchRegex(char *, OptTreeNode *, int);static void PayloadSearchDistance(char *, OptTreeNode *, int);static void PayloadSearchWithin(char *, OptTreeNode *, int);static void PayloadSearchRawbytes(char *, OptTreeNode *, int);static void PayloadReplaceInit(char *, OptTreeNode *, int);static PatternMatchData * ParseReplacePattern(char *, OptTreeNode *);int PayloadReplace(Packet *, struct _OptTreeNode *, OptFpList *, int                         depth);static int uniSearchReal(char *data, int dlen, PatternMatchData *pmd, int nocase);static PatternMatchData * NewNode(OptTreeNode *, int);void PayloadSearchCompile();int list_file_line;     /* current line being processed in the list file */int lastType = PLUGIN_PATTERN_MATCH;u_int8_t *doe_ptr;int detect_depth;       /* depth to the first char of the match */extern HttpUri UriBufs[URI_COUNT]; /* the set of buffers that we are using to match against				      set in decode.c */extern u_int8_t DecodeBuffer[DECODE_BLEN];extern char *file_name;extern int file_line;void SetupPatternMatch(){    RegisterPlugin("content", PayloadSearchInit);    RegisterPlugin("content-list", PayloadSearchListInit);    RegisterPlugin("offset", PayloadSearchOffset);    RegisterPlugin("depth", PayloadSearchDepth);    RegisterPlugin("nocase", PayloadSearchNocase);    RegisterPlugin("rawbytes", PayloadSearchRawbytes);    RegisterPlugin("regex", PayloadSearchRegex);    RegisterPlugin("uricontent", PayloadSearchUri);    RegisterPlugin("distance", PayloadSearchDistance);    RegisterPlugin("within", PayloadSearchWithin);    RegisterPlugin("replace", PayloadReplaceInit);    DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,                 "Plugin: PatternMatch Initialized!\n"););}void PayloadReplaceInit(char *data, OptTreeNode * otn, int protocol){    PatternMatchData *idx;    PatternMatchData *test_idx;    if(!InlineMode())        return;        idx = (PatternMatchData *) otn->ds_list[PLUGIN_PATTERN_MATCH];    if(idx == NULL)    {        FatalError("ERROR %s Line %d => Please place \"content\" rules "                   "before depth, nocase, replace or offset modifiers.\n",                   file_name, file_line);    }    test_idx = ParseReplacePattern(data, otn);#ifdef DEBUG    printf("idx (%p) pattern_size (%d) replace_size (%d)\n", test_idx, 		    test_idx->pattern_size, test_idx->replace_size);#endif    if (test_idx && test_idx->pattern_size != test_idx->replace_size)    {        FatalError("ERROR %s Line %d => The length of the replacement "                   "string must be the same length as the content string.\n",                   file_name, file_line);    }#ifdef DEBUG    printf("PayLoadReplaceInit Added to rule!\n");#endif}/*************************************************************************//*                                                                       *//*  Sigh.... this should be part of ParsePattern, but that can wait      *//*                                                                       *//*************************************************************************/PatternMatchData * ParseReplacePattern(char *rule, OptTreeNode * otn){    unsigned char tmp_buf[2048];    /* got enough ptrs for you? */    char *start_ptr;    char *end_ptr;    char *idx;    char *dummy_idx;    char *dummy_end;    char hex_buf[3];    u_int dummy_size = 0;    int size;    int hexmode = 0;    int hexsize = 0;    int pending = 0;    int cnt = 0;    int literal = 0;    int exception_flag = 0;    PatternMatchData *ds_idx;    /* clear out the temp buffer */    bzero(tmp_buf, 2048);    while(isspace((int)*rule))        rule++;    if(*rule == '!')    {        exception_flag = 1;    }    /* find the start of the data */    start_ptr = index(rule, '"');    if(start_ptr == NULL)    {        FatalError("ERROR %s Line %d => Replace data needs to be "                   "enclosed in quotation marks (\")!\n",                   file_name, file_line);    }    /* move the start up from the beggining quotes */    start_ptr++;    /* find the end of the data */    end_ptr = strrchr(start_ptr, '"');    if(end_ptr == NULL)    {        FatalError("ERROR %s Line %d => Replace data needs to be enclosed "                   "in quotation marks (\")!\n", file_name, file_line);    }    /* set the end to be NULL */    *end_ptr = '\0';    /* how big is it?? */    size = end_ptr - start_ptr;    /* uh, this shouldn't happen */    if(size <= 0)    {        FatalError("ERROR %s Line %d => Bad pattern length!\n",                   file_name, file_line);    }    /* set all the pointers to the appropriate places... */    idx = start_ptr;    /* set the indexes into the temp buffer */    dummy_idx = tmp_buf;    dummy_end = (dummy_idx + size);    /* why is this buffer so small? */    bzero(hex_buf, 3);    memset(hex_buf, '0', 2);    /* BEGIN BAD JUJU..... */    while(idx < end_ptr)    {        DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "processing char: %c\n", *idx););        switch(*idx)        {            case '|':		                    DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Got bar... "););		                if(!literal)                {			                    DEBUG_WRAP(DebugMessage(DEBUG_PARSER,					    "not in literal mode... "););		                        if(!hexmode)                    {                        DEBUG_WRAP(DebugMessage(DEBUG_PARSER, 						"Entering hexmode\n"););                        hexmode = 1;                    }                    else                    {			                            DEBUG_WRAP(DebugMessage(DEBUG_PARSER, 						"Exiting hexmode\n"););			                        hexmode = 0;                        pending = 0;                    }                    if(hexmode)                        hexsize = 0;                }                else                {                    DEBUG_WRAP(DebugMessage(DEBUG_PARSER, 					    "literal set, Clearing\n"););                    literal = 0;                    tmp_buf[dummy_size] = start_ptr[cnt];                    dummy_size++;                }                break;            case '\\':		                DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Got literal char... "););                if(!literal)                {                    DEBUG_WRAP(DebugMessage(DEBUG_PARSER, 					    "Setting literal\n"););		                        literal = 1;                }                else                {                    DEBUG_WRAP(DebugMessage(DEBUG_PARSER, 					    "Clearing literal\n"););		                        tmp_buf[dummy_size] = start_ptr[cnt];                    literal = 0;                    dummy_size++;                }                break;            default:                if(hexmode)                {                    if(isxdigit((int) *idx))                    {                        hexsize++;                        if(!pending)                        {                            hex_buf[0] = *idx;                            pending++;                        }                        else                        {                            hex_buf[1] = *idx;                            pending--;                            if(dummy_idx < dummy_end)                            {                                tmp_buf[dummy_size] = (u_char)                                    strtol(hex_buf, (char **) NULL, 16)&0xFF;                                dummy_size++;                                bzero(hex_buf, 3);                                memset(hex_buf, '0', 2);                            }                            else                            {                                FatalError("ERROR => ParsePattern() dummy "                                           "buffer overflow, make a smaller "                                           "pattern please! (Max size = 2048)\n");                            }                        }                    }                    else                    {                        if(*idx != ' ')                        {                            FatalError("ERROR Line %d => What is this "                                       "\"%c\"(0x%X) doing in your binary "                                       "buffer? Valid hex values only please! "                                       "(0x0 -0xF) Position: %d\n",                                       file_line, (char) *idx, (char) *idx, cnt);                        }                    }                }                else                {                    if(*idx >= 0x1F && *idx <= 0x7e)                    {                        if(dummy_idx < dummy_end)                        {                            tmp_buf[dummy_size] = start_ptr[cnt];                            dummy_size++;                        }                        else                        {                            FatalError("ERROR Line %d=> ParsePattern() dummy "                                       "buffer overflow!\n", file_line);                        }                        if(literal)                        {                            literal = 0;                        }                    }                    else                    {                        if(literal)                        {                            tmp_buf[dummy_size] = start_ptr[cnt];                            dummy_size++;			                                DEBUG_WRAP(DebugMessage(DEBUG_PARSER, 						    "Clearing literal\n"););			                                literal = 0;                        }                        else                        {                            FatalError("%s(%d)=> character value out "                                       "of range, only hex characters allowed in binary content buffers\n",                                       file_name, file_line);                        }                    }                }                break;				        } /* end switch */        dummy_idx++;        idx++;        cnt++;    }    /* ...END BAD JUJU */    /* error prunning */    if (literal) {        FatalError("%s(%d)=> backslash escape is not "		   "completed\n", file_name, file_line);    }    if (hexmode) {        FatalError("%s(%d)=> hexmode is not "		   "completed\n", file_name, file_line);    }    ds_idx = (PatternMatchData *) otn->ds_list[PLUGIN_PATTERN_MATCH];    while(ds_idx->next != NULL)        ds_idx = ds_idx->next;    if((ds_idx->replace_buf = (char *) calloc(dummy_size+1,                                                  sizeof(char))) == NULL)    {        FatalError("ERROR => ParsePattern() pattern_buf malloc filed!\n");    }    //memcpy(ds_idx->replace_buf, tmp_buf, dummy_size);    SafeMemcpy(ds_idx->replace_buf, tmp_buf, dummy_size,                ds_idx->replace_buf, (ds_idx->replace_buf+dummy_size+1));    ds_idx->replace_size = dummy_size;    DEBUG_WRAP(DebugMessage(DEBUG_PARSER, 			    "ds_idx (%p) replace_size(%d) replace_buf(%s)\n", ds_idx,			    ds_idx->replace_size, ds_idx->replace_buf););    return ds_idx;}int PayloadReplace(Packet *p, struct _OptTreeNode *otn,                         OptFpList *fp_list, int depth){    struct pseudoheader    {        u_int32_t sip, dip;        u_int8_t zero;        u_int8_t protocol;        u_int16_t len;    };    PatternMatchData *idx;    struct pseudoheader ph;    unsigned int ip_len;    unsigned int hlen;    //idx = (PatternMatchData *)otn->ds_list[PLUGIN_PATTERN_MATCH];    idx = (PatternMatchData *)fp_list->context;    if (depth >= 0)    {        //memcpy(p->data+depth, idx->replace_buf, strlen(idx->replace_buf));	SafeMemcpy( (p->data + depth), idx->replace_buf, strlen(idx->replace_buf),         p->data, (p->data + p->dsize + 1) );#ifdef GIDS        InlineReplace();#endif        /* calculate new checksum */        p->iph->ip_csum=0;        hlen = IP_HLEN(p->iph) << 2;        ip_len=ntohs(p->iph->ip_len);        ip_len -= hlen;        p->iph->ip_csum = in_chksum_ip((u_short *)p->iph, hlen);        if (p->tcph)        {            p->tcph->th_sum = 0;            ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);            ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);            ph.zero = 0;            ph.protocol = p->iph->ip_proto;            ph.len = htons((u_short)ip_len);            p->tcph->th_sum = in_chksum_tcp((u_short *)&ph,                                            (u_short *)(p->tcph), ip_len);        }        else if (p->udph)        {            p->udph->uh_chk = 0;            ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);            ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);            ph.zero = 0;            ph.protocol = p->iph->ip_proto;            ph.len = htons((u_short)ip_len);            p->udph->uh_chk = in_chksum_udp((u_short *)&ph,                                            (u_short *)(p->udph), ip_len);        }	else if (p->icmph)        {            p->icmph->csum = 0;	    ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);	    ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);	    ph.zero = 0;	    ph.protocol = p->iph->ip_proto;	    ph.len = htons((u_short)ip_len);	    p->icmph->csum = in_chksum_icmp((u_int16_t *)(p->icmph), ip_len);        }    }    return 1;}static inline int computeDepth(int dlen, PatternMatchData * pmd) {    /* do some tests to make sure we stay in bounds */    if((pmd->depth + pmd->offset) > dlen)    {

⌨️ 快捷键说明

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