📄 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 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 "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 7#define BUILD_VERSION 1#define DETECT_NAME "SF_SNORT_DETECTION_ENGINE"#ifdef WIN32#define PATH_MAX MAX_PATH#else#include <sys/param.h>#include <limits.h>#endif#define DEBUG_WRAP(x)DynamicEngineData _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; 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;}/* 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 *); */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);}int HasFlow(void *r){ 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 == OPTION_TYPE_FLOWFLAGS) { return 1; } } return 0;}int HasFlowBits(void *r){ 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 == OPTION_TYPE_FLOWBIT) { return 1; } } return 0;}int HasContent(void *r){ 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 == OPTION_TYPE_CONTENT) { return 1; } } return 0;}int HasByteTest(void *r){ 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 == OPTION_TYPE_BYTE_TEST) { return 1; } } return 0;}int HasPCRE(void *r){ 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 == OPTION_TYPE_PCRE) { return 1; } } return 0;}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)) && (buf == FASTPATTERN_URI)) || (!(option->option_u.content->flags & (CONTENT_BUF_URI | CONTENT_BUF_POST)) && (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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -