📄 sf_snort_detection_engine.c
字号:
/* * sf_snort_detection_engine.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation. You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * 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. * * Copyright (C) 2005-2008 Sourcefire Inc. * * Author: Steve Sturges * Andy Mullican * * Date: 5/2005 * * Dyanmic Rule Engine */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <string.h>#include <ctype.h>#include <sys/types.h>#include <stdarg.h>#include "debug.h"#include "sf_snort_packet.h"#include "sf_snort_plugin_api.h"#include "sf_dynamic_meta.h"#include "sf_dynamic_engine.h"#define MAJOR_VERSION 1#define MINOR_VERSION 9#define BUILD_VERSION 15#define DETECT_NAME "SF_SNORT_DETECTION_ENGINE"#ifdef WIN32#define PATH_MAX MAX_PATH#else#include <sys/param.h>#include <limits.h>#endifDynamicEngineData _ded;#define STD_BUF 1024NORETURN void DynamicEngineFatalMessage(const char *format, ...){ char buf[STD_BUF]; va_list ap; va_start(ap, format); vsnprintf(buf, STD_BUF, format, ap); va_end(ap); buf[STD_BUF - 1] = '\0'; _ded.fatalMsg("%s", buf); exit(1);}extern int BoyerContentSetup(Rule *rule, ContentInfo *content);extern int PCRESetup(Rule *rule, PCREInfo *pcreInfo);extern int ValidateHeaderCheck(Rule *rule, HdrOptCheck *optData);extern void ContentSetup(void);extern int ByteExtractInitialize(Rule *rule, ByteExtract *extractData);extern int LoopInfoInitialize(Rule *rule, LoopInfo *loopInfo);ENGINE_LINKAGE int InitializeEngine(DynamicEngineData *ded){ int i; if (ded->version < ENGINE_DATA_VERSION) { return -1; } _ded.version = ded->version; _ded.altBuffer = ded->altBuffer; for (i=0;i<MAX_URIINFOS;i++) { _ded.uriBuffers[i] = ded->uriBuffers[i]; } _ded.ruleRegister = ded->ruleRegister; _ded.flowbitRegister = ded->flowbitRegister; _ded.flowbitCheck = ded->flowbitCheck; _ded.asn1Detect = ded->asn1Detect; _ded.dataDumpDirectory = ded->dataDumpDirectory; _ded.logMsg = ded->logMsg; _ded.errMsg = ded->errMsg; _ded.fatalMsg = ded->fatalMsg; _ded.getPreprocOptFuncs = ded->getPreprocOptFuncs; _ded.setRuleData = ded->setRuleData; _ded.getRuleData = ded->getRuleData; _ded.debugMsg = ded->debugMsg;#ifdef HAVE_WCHAR_H _ded.debugWideMsg = ded->debugWideMsg;#endif _ded.debugMsgFile = ded->debugMsgFile; _ded.debugMsgLine = ded->debugMsgLine; _ded.pcreStudy = ded->pcreStudy; _ded.pcreCompile = ded->pcreCompile; _ded.pcreExec = ded->pcreExec; return 0;}ENGINE_LINKAGE int LibVersion(DynamicPluginMeta *dpm){ dpm->type = TYPE_ENGINE; dpm->major = MAJOR_VERSION; dpm->minor = MINOR_VERSION; dpm->build = BUILD_VERSION; strncpy(dpm->uniqueName, DETECT_NAME, MAX_NAME_LEN); return 0;}/* * Function: CheckCompatibility * Return values: 0 -- no compatibility issue detected; 1 -- otherwise. */ENGINE_LINKAGE int CheckCompatibility(DynamicPluginMeta *meta, DynamicPluginMeta *lib){ int ret = 0; /* types match */ if(((void *)meta != NULL ) && ((void *)lib != NULL) && (lib->type == meta->type)) { /* names match */ if (!strcmp(meta->uniqueName, lib->uniqueName) ) { if (((meta->major == 1) && (meta->minor >= 7)) || (meta->major > 1)) { if( (lib->major == 1) && (lib->minor < 7 )) { ret = 1; } } } } return( ret );}/* Variables to check type of InitializeEngine and LibVersion */ENGINE_LINKAGE InitEngineLibFunc initEngineFunc = &InitializeEngine;ENGINE_LINKAGE LibVersionFunc libVersionFunc = &LibVersion;/* Evaluates the rule -- indirect interface, this will be * called from the SpecialPurpose detection plugin as * CheckRule (void *, void *); */static int CheckRule(void *p, void *r){ Rule *rule = (Rule *)r; if (!rule->initialized) { _ded.errMsg("Dynamic Rule [%d:%d] was not initialized properly.\n", rule->info.genID, rule->info.sigID); return RULE_NOMATCH; } ContentSetup(); /* If there is an eval func, use it, this is a 'hand-coded' rule */ if (rule->evalFunc) return rule->evalFunc((SFSnortPacket *)p); else return ruleMatch(p, rule);}static int HasOption (void *r, enum DynamicOptionType optionType, int flowFlag){ Rule *rule = (Rule *)r; RuleOption *option; int i; if ((!rule) || (!rule->initialized)) { return 0; } for (i=0,option = rule->options[i];option != NULL; option = rule->options[++i]) { if (option->optionType == optionType) { if (!flowFlag) return 1; if ( (optionType == OPTION_TYPE_FLOWFLAGS) && (option->option_u.flowFlags->flags & flowFlag) ) return 1; } } return 0;}static int GetFPContent(void *r, int buf, FPContentInfo** contents, int maxNumContents){ Rule *rule = (Rule *)r; int i, j = 0; RuleOption *option; int numContents = 0; for (i=0,option = rule->options[i];option != NULL; option = rule->options[++i]) { if (option->optionType == OPTION_TYPE_CONTENT) { if ((option->option_u.content->flags & CONTENT_FAST_PATTERN) && (((option->option_u.content->flags & (CONTENT_BUF_URI | CONTENT_BUF_POST | CONTENT_BUF_HEADER | CONTENT_BUF_METHOD)) && (buf == FASTPATTERN_URI)) || (!(option->option_u.content->flags & (CONTENT_BUF_URI | CONTENT_BUF_POST | CONTENT_BUF_HEADER | CONTENT_BUF_METHOD)) && (buf == FASTPATTERN_NORMAL)) )) { FPContentInfo *content = (FPContentInfo *)calloc(1, sizeof(FPContentInfo)); if (content == NULL) { DynamicEngineFatalMessage("Failed to allocate memory\n"); } content->content = (char *)option->option_u.content->patternByteForm; content->length = option->option_u.content->patternByteFormLength; content->noCaseFlag = (char)(option->option_u.content->flags & CONTENT_NOCASE); contents[j++] = content; numContents++; } } if (numContents >= maxNumContents) break; } return numContents;}static int DecodeContentPattern(Rule *rule, ContentInfo *content){ int pat_len; const u_int8_t *pat_begin = content->pattern; const u_int8_t *pat_idx; const u_int8_t *pat_end; char tmp_buf[2048]; char *raw_idx; char *raw_end; int tmp_len = 0; int hex_encoding = 0; int hex_len = 0; int pending = 0; int char_count = 0; int escaped = 0; char hex_encoded[3]; /* First, setup the raw data by parsing content */ /* XXX: Basically, duplicate the code from ParsePattern() * in sp_pattern_match.c */ pat_len = strlen((const char *)content->pattern); pat_end = pat_begin + pat_len; /* set the indexes into the temp buffer */ raw_idx = tmp_buf; raw_end = (raw_idx + pat_len); /* why is this buffer so small? */ memset(hex_encoded, 0, 3); memset(hex_encoded, '0', 2); pat_idx = pat_begin; /* Uggh, loop through each char */ while(pat_idx < pat_end) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "processing char: %c\n", *pat_idx);); switch(*pat_idx) { case '|': DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Got bar... ");); if(!escaped) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "not in literal mode... ");); if(!hex_encoding) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Entering hexmode\n");); hex_encoding = 1; } else { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Exiting hexmode\n");); /* ** Hexmode is not even. */ if(!hex_len || hex_len % 2) { DynamicEngineFatalMessage("Content hexmode argument has invalid " "number of hex digits for dynamic rule [%d:%d].\n", rule->info.genID, rule->info.sigID); } hex_encoding = 0; pending = 0; } if(hex_encoding) hex_len = 0; } else { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "literal set, Clearing\n");); escaped = 0; tmp_buf[tmp_len] = pat_begin[char_count]; tmp_len++; } break; case '\\': DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Got literal char... ");); if(!escaped) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting literal\n");); escaped = 1; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Clearing literal\n");); tmp_buf[tmp_len] = pat_begin[char_count]; escaped = 0; tmp_len++; } break; case '"': if (!escaped) { DynamicEngineFatalMessage("Non-escaped '\"' character in dynamic rule [%d:%d]!\n", rule->info.genID, rule->info.sigID); } /* otherwise process the character as default */ default: if(hex_encoding) { if(isxdigit((int) *pat_idx)) { hex_len++; if(!pending) { hex_encoded[0] = *pat_idx; pending++; } else { hex_encoded[1] = *pat_idx; pending--; if(raw_idx < raw_end) { tmp_buf[tmp_len] = (u_char) strtol(hex_encoded, (char **) NULL, 16)&0xFF; tmp_len++; memset(hex_encoded, 0, 3); memset(hex_encoded, '0', 2); } else { DynamicEngineFatalMessage("ParsePattern() buffer overflow, " "make a smaller pattern please for dynamic " "rule [%d:%d]! (Max size = 2048)\n", rule->info.genID, rule->info.sigID);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -