?? spp_rpc_decode.c
字號:
/*** 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 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.*//* $Id$ *//* spp_rpc_decode * * Purpose: * * This preprocessor normalizes the RPC requests from remote machines by * converting all fragments into one continous stream. * This is very useful for doing things like defeating hostile attackers * trying to stealth themselves from IDSs by fragmenting the request so the * string 0186A0 is broken up. * * Arguments: * * This plugin takes a list of integers representing the TCP ports that the * user is interested in having normalized * * Effect: * * Changes the data in the packet payload and changes * p->dsize to reflect the new (smaller) payload size. * * Comments: * */#ifdef HAVE_CONFIG_H #include "config.h" #endif#include <sys/types.h>#include <stdlib.h>#include <ctype.h>#ifdef HAVE_STRINGS_H #include <strings.h> #endif#include "decode.h"#include "plugbase.h"#include "parser.h"#include "log.h"#include "debug.h"#include "util.h"#include "mstring.h"#include "snort.h"#include "detect.h"#include "log.h"#include "generators.h"#include "event_queue.h"#include "profiler.h"#include "bounds.h"#include "strlcatu.h"extern char *file_name;extern int file_line;extern int do_detect;extern u_int8_t DecodeBuffer[DECODE_BLEN];#define OPT_ALERT_FRAGMENTS "alert_fragments"#define OPT_ALERT_MULTIPLE_REQUESTS "no_alert_multiple_requests"#define OPT_ALERT_LARGE_FRAGMENTS "no_alert_large_fragments"#define OPT_ALERT_INCOMPLETE "no_alert_incomplete"#define TEXT_ALERT_MULTIPLE_REQUESTS "alert_multiple_requests"#define TEXT_ALERT_LARGE_FRAGMENTS "alert_large_fragments"#define TEXT_ALERT_INCOMPLETE "alert_incomplete"#define RPC_CLASS DECODE_CLASS /* use the same classification as the other decoder alerts */typedef struct _RpcDecodeData{ char alert_fragments; /* Alert when we see ANY fragmented RPC requests */ char alert_incomplete; /* Alert when we don't see all of a request in one packet */ char alert_multi; /* Alert when we see multiple requests in one packet */ char alert_large; /* Alert when we see multiple requests in one packet */} RpcDecodeData;static RpcDecodeData rpcpreprocdata; /* Configuration Set */static char RpcDecodePorts[65536/8];#ifdef PERF_PROFILINGPreprocStats rpcdecodePerfStats;#endifvoid RpcDecodeInit(char *);void RpcDecodeInitIgnore(char *);void PreprocRpcDecode(Packet *, void *);void SetRpcPorts(char *);int ConvertRPC(Packet *);/* * Function: SetupRpcDecode() * * Purpose: Registers the preprocessor keyword and initialization * function into the preprocessor list. * * Arguments: None. * * Returns: void function * */void SetupRpcDecode(void){ /* link the preprocessor keyword to the init function in the preproc list */ RegisterPreprocessor("rpc_decode", RpcDecodeInit); DEBUG_WRAP(DebugMessage(DEBUG_RPC,"Preprocessor: RpcDecode in setup...\n"););}/* * Function: RpcDecodeInit(char *) * * Purpose: Processes the args sent to the preprocessor, sets up the * port list, links the processing function into the preproc * function list * * Arguments: args => ptr to argument string * * Returns: void function * */void RpcDecodeInit(char *args){ DEBUG_WRAP(DebugMessage(DEBUG_RPC,"Preprocessor: RpcDecode Initialized\n");); bzero(&rpcpreprocdata,sizeof(RpcDecodeData)); /* turn on the following alerts by default */ rpcpreprocdata.alert_multi = 1; rpcpreprocdata.alert_incomplete = 1; rpcpreprocdata.alert_large = 1; /* parse the argument list into a list of ports to normalize */ SetRpcPorts((char *)args); /* Set the preprocessor function into the function list */ AddFuncToPreprocList(PreprocRpcDecode, PRIORITY_APPLICATION, PP_RPCDECODE);#ifdef PREF_PROFILING RegisterPreprocessorProfile("rpcdecode", &rpcdecodePerfStats, 0, &totalPerfStats);#endif}/* * Function: SetRpcPorts(char *) * * Purpose: Reads the list of port numbers from the argument string and * parses them into the port list data struct * * Arguments: portlist => argument list * * Returns: void function * */void SetRpcPorts(char *portlist){ char portstr[STD_BUF]; char **toks; int is_reset = 0; int num_toks; int num; if(portlist == NULL || *portlist == '\0') { portlist = "111 32771"; } /* tokenize the argument list */ toks = mSplit(portlist, " ", 31, &num_toks, '\\'); LogMessage("rpc_decode arguments:\n"); /* convert the tokens and place them into the port list */ for(num = 0; num < num_toks; num++) { if(isdigit((int)toks[num][0])) { char *num_p = NULL; /* used to determine last position in string */ long t_num; t_num = strtol(toks[num], &num_p, 10); if(*num_p != '\0') { FatalError("ERROR %s(%d) => Port Number invalid format: %s\n", file_name, file_line, toks[num]); } else if(t_num < 0 || t_num > 65535) { FatalError("ERROR %s(%d) => Port Number out of range: %ld\n", file_name, file_line, t_num); } /* user specified a legal port number and it should override the default port list, so reset it unless already done */ if(!is_reset) { bzero(&RpcDecodePorts, sizeof(RpcDecodePorts)); portstr[0] = '\0'; is_reset = 1; } /* mark this port as being interesting using some portscan2-type voodoo, and also add it to the port list string while we're at it so we can later print out all the ports with a single LogMessage() */ RpcDecodePorts[(t_num/8)] |= 1<<(t_num%8); strlcat(portstr, toks[num], STD_BUF - 1); strlcat(portstr, " ", STD_BUF - 1); } else if(!strcasecmp(OPT_ALERT_MULTIPLE_REQUESTS,toks[num])) { rpcpreprocdata.alert_multi = 0; } else if(!strcasecmp(OPT_ALERT_INCOMPLETE,toks[num])) { rpcpreprocdata.alert_incomplete = 0; } else if(!strcasecmp(OPT_ALERT_LARGE_FRAGMENTS,toks[num])) { rpcpreprocdata.alert_large = 0; } else if(!strcasecmp(OPT_ALERT_FRAGMENTS,toks[num])) { rpcpreprocdata.alert_fragments = 1; } else { FatalError("ERROR %s(%d) => Unknown argument to rpc_decode " "preprocessor: \"%s\"\n", file_name, file_line, toks[num]); } } mSplitFree(&toks, num_toks); /* print out final port list */ LogMessage(" Ports to decode RPC on: %s\n", portstr); LogMessage(" %s: %s\n", OPT_ALERT_FRAGMENTS, rpcpreprocdata.alert_fragments ? "ACTIVE": "INACTIVE"); LogMessage(" %s: %s\n", TEXT_ALERT_LARGE_FRAGMENTS, rpcpreprocdata.alert_large ? "ACTIVE": "INACTIVE"); LogMessage(" %s: %s\n", TEXT_ALERT_INCOMPLETE, rpcpreprocdata.alert_incomplete ? "ACTIVE": "INACTIVE"); LogMessage(" %s: %s\n", TEXT_ALERT_MULTIPLE_REQUESTS, rpcpreprocdata.alert_multi ? "ACTIVE": "INACTIVE");} /* * Function: PreprocRpcDecode(Packet *) * * Purpose: Inspects the packet's payload for fragment records and * converts them into one infragmented record. * * Arguments: p => pointer to the current packet data struct * * Returns: void function * */void PreprocRpcDecode(Packet *p, void *context){ int ret = 0; /* return code for ConvertRPC */ PROFILE_VARS; DEBUG_WRAP(DebugMessage(DEBUG_RPC,"rpc decoder init on %d bytes\n", p->dsize);); /* check to make sure we're talking TCP and that the TWH has already completed before processing anything */ if(!PacketIsTCP(p)) { DEBUG_WRAP(DebugMessage(DEBUG_RPC,"It isn't TCP session traffic\n");); return; } if((snort_runtime.capabilities.stateful_inspection == 1) && (p->packet_flags & PKT_FROM_SERVER)) { DEBUG_WRAP(DebugMessage(DEBUG_RPC,"This is from a server\n");); return;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -