📄 spp_stream4.c
字号:
/* $Id$ *//*** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>** Copyright (C) 2003-2005 Sourcefire, Inc.**** 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.*//* spp_stream4 * * Purpose: Stateful inspection and tcp stream reassembly in Snort * * Arguments: * * Effect: * * Comments: * * Any comments? * *//* * 04 Feb 2005: SAS Updated to handle favor_old and favor_new options. * favor_new traverses the tree in the opposite * direction and builds the stream using newer packets. * Also added checks for: * - PAWS (Timestamp option is set and 0) on an * establiahed session and ACK in the packet. Win32 * uses 0 Timestamp on Syn-only packets. * - Checks for NULL TCP flags in established session. * After the TWHS, all packets should have at least * ACK, RST, or FIN. * - Checks for overlaps (larger than an option * specified overlap_limit) in the reassembled stream. * When the overlap limit is reached, that side of the * stream is flushed and an evasion alert is raised. * * 08 Feb 2005: AJM Update ACK when server sends RST, which enables client * stream to be reassembled upon flush. * - Also enable client reassembly upon client RST. * - Reset session alert count after flushing rebuilt packet. * * 28 Feb 2005: SAS Update to use hash table to Session storage. Added new * files snort_stream_session.{c,h} that contain the sfxhash * interfaces. * - Added max_sessions configuration option. Impacts the * meaning of memcap in that memcap now only relates to the * memory consumed by stored packets, not memory for session * structure. * * 07 Mar 2005: JRB/SAS Add user configurable flushpoints. Added options: * flush_behavior, flush_base, flush_seed, flush_range to * stream4_reassemble preproc config. * * 31 Mar 2005: SAS Added server_inspect_limit option to limit the * amount of data that goes through rules inspection on * the server side. The counter is reset when a client * packet is seen (ie, a request). *//* I N C L U D E S ************************************************/#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifndef DEBUG #ifndef INLINE #define INLINE inline #endif#else #ifdef INLINE #undef INLINE #endif #define INLINE #endif /* DEBUG */#include <sys/types.h>#include <stdlib.h>#include <string.h>#include <errno.h>#ifndef WIN32#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#endif /* WIN32 */#include <time.h>#include <rpc/types.h>#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include "bounds.h"#include "decode.h"#include "event.h"#include "debug.h"#include "util.h"#include "plugbase.h"#include "parser.h"#include "mstring.h"#include "checksum.h"#include "log.h"#include "generators.h"#include "detect.h"#include "perf.h"#include "timersub.h"#include "ubi_SplayTree.h"#include "snort.h"#include "stream.h"#include "spp_stream4.h"#include "snort_packet_header.h"#include "event_queue.h"#include "inline.h"#include "sfghash.h"#include "snort_stream4_session.h"/* D E F I N E S **************************************************//* normal TCP states */#define CLOSED 0#define LISTEN 1#define SYN_RCVD 2#define SYN_SENT 3#define ESTABLISHED 4#define CLOSE_WAIT 5#define LAST_ACK 6#define FIN_WAIT_1 7#define CLOSING 8#define FIN_WAIT_2 9#define TIME_WAIT 10/* extended states for fun stuff */#define NMAP_FINGERPRINT_2S 30#define NMAP_FINGERPRINT_NULL 31#define NMAP_FINGERPRINT_UPSF 32#define NMAP_FINGERPRINT_ZERO_ACK 33#define ACTION_NOTHING 0x00000000#define ACTION_FLUSH_SERVER_STREAM 0x00000001#define ACTION_FLUSH_CLIENT_STREAM 0x00000002#define ACTION_DROP_SESSION 0x00000004#define ACTION_ACK_SERVER_DATA 0x00000008#define ACTION_ACK_CLIENT_DATA 0x00000010#define ACTION_DATA_ON_SYN 0x00000020#define ACTION_SET_SERVER_ISN 0x00000040#define ACTION_COMPLETE_TWH 0x00000080#define ACTION_ALERT_NMAP_FINGERPRINT 0x00000100#define ACTION_INC_PORT 0x00000200#define FROM_SERVER 0#define FROM_CLIENT 1#define PRUNE_QUANTA 30 /* seconds to timeout a session */#define STREAM4_MEMORY_CAP 8388608 /* 8MB */#define STREAM4_MAX_SESSIONS 8192 /* 8k */#define STREAM4_CLEANUP 5 /* Cleanup 5 sessions at a time */#define STREAM4_CACHE_PERCENT 0.1 /* Or cleanup 0.1 % sessions at a time */#define STREAM4_TTL_LIMIT 5 /* default for TTL Limit */#define DEFAULT_STREAM_TRACKERS 256000 /* 256k sessions by default */#define STATS_HUMAN_READABLE 1#define STATS_MACHINE_READABLE 2#define STATS_BINARY 3#define STATS_MAGIC 0xDEAD029A /* magic for the binary stats file */#define REVERSE 0#define NO_REVERSE 1#define METHOD_FAVOR_NEW 0x01#define METHOD_FAVOR_OLD 0x02/* # of packets that we accept on an unestab conn */#define UNESTABLISHED_MAX_PCOUNT 300/* what pcap can hold is how this limit comes about -- cmg */#define MAX_STREAM_SIZE (IP_MAXPACKET - IP_HEADER_LEN - TCP_HEADER_LEN - ETHERNET_HEADER_LEN) /* Macros to deal with sequence numbers - p810 TCP Illustrated vol 2 */#define SEQ_LT(a,b) ((int)((a) - (b)) < 0)#define SEQ_LEQ(a,b) ((int)((a) - (b)) <= 0)#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)#define SEQ_GEQ(a,b) ((int)((a) - (b)) >= 0)#define SEQ_EQ(a,b) ((int)((a) - (b)) == 0)#define NO_CHK_SEQ 0#define CHK_SEQ 1/* these are needed in snort versions before 2.0build something */#ifndef SNORT_20extern char *file_name;extern int *file_line;#endif /* SNORT_20 *//* We must twiddle to align the offset the ethernet header and align the IP header on solaris -- maybe this will work on HPUX too.*/#if defined (SOLARIS) || defined (SUNOS) || defined (__sparc__) || defined(__sparc64__) || defined (HPUX)#define SPARC_TWIDDLE 2#else#define SPARC_TWIDDLE 0#endif/* values for the smartbits detector/self perservation */#define SELF_PRES_THRESHOLD 50#define SELF_PRES_PERIOD 90#define SUSPEND_THRESHOLD 200#define SUSPEND_PERIOD 30#define OPS_NORMAL 0#define OPS_SELF_PRESERVATION 1#define OPS_SUSPEND 2#define MAXSIZE_IP 65535#define MAX_TRACKER_AMOUNT (MAX_STREAM_SIZE + 4000)/* Support dynamic flush points */#define FCOUNT 64#define STREAM4_FLUSH_BASE 512#define STREAM4_FLUSH_RANGE 1213#define FLUSH_BEHAVIOR_RANDOM -1#define FLUSH_BEHAVIOR_DEFAULT 0#define FLUSH_BEHAVIOR_LARGE 1/* Old flushpoints, for backward compat. Use flush_behavior default */static u_int32_t old_flush_points[FCOUNT] = { 128, 217, 189, 130, 240, 221, 134, 129, 250, 232, 141, 131, 144, 177, 201, 130, 230, 190, 177, 142, 130, 200, 173, 129, 250, 244, 174, 151, 201, 190, 180, 198, 220, 201, 142, 185, 219, 129, 194, 140, 145, 191, 197, 183, 199, 220, 231, 245, 233, 135, 143, 158, 174, 194, 200, 180, 201, 142, 153, 187, 173, 199, 143, 201 };static u_int32_t new_flush_points[FCOUNT] = { 1280, 2176, 1895, 1303, 2402, 2211, 1340, 1298, 2500, 2320, 1413, 1313, 1444, 1776, 2015, 1305, 2130, 1190, 1377, 1492, 1380, 2100, 1373, 1029, 750, 444, 874, 551, 401, 390, 1801, 1898, 2260, 2601, 642, 485, 619, 929, 794, 340, 445, 1911, 497, 883, 399, 2201, 2431, 2145, 433, 735, 543, 658, 1174, 2042, 1200, 1800, 2015, 1142, 1530, 487, 673, 899, 743, 2101 };#ifdef DEBUGstatic char *state_names[] = { "CLOSED", "LISTEN", "SYN_RCVD", "SYN_SENT", "ESTABLISHED", "CLOSE_WAIT", "LAST_ACK", "FIN_WAIT_1", "CLOSING", "FIN_WAIT_2", "TIME_WAIT"};#endif/* D A T A S T R U C T U R E S **********************************/typedef struct _OverlapData{ u_int32_t seq_low; u_int32_t seq_hi;} OverlapData;typedef struct _BuildData{ Stream *stream; u_int8_t *buf; u_int32_t total_size; /* u_int32_t build_flags; -- reserved for the day when we generate 1 stream event and log the stream */} BuildData;typedef struct _BinStats{ u_int32_t start_time; u_int32_t end_time; u_int32_t sip; u_int32_t cip; u_int16_t sport; u_int16_t cport; u_int32_t spackets; u_int32_t cpackets; u_int32_t sbytes; u_int32_t cbytes;} BinStats;typedef struct _StatsLog{ FILE *fp; char *filename;} StatsLog;typedef struct _StatsLogHeader{ u_int32_t magic; u_int32_t version_major; u_int32_t version_minor; u_int32_t timezone;} StatsLogHeader;typedef struct _S4Emergency{ long end_time; char old_reassemble_client; char old_reassemble_server; char old_reassembly_alerts; int old_assurance_mode; char old_stateful_mode; u_int32_t new_session_count; int status;} S4Emergency;typedef struct _StreamKey{ u_int32_t sip; u_int32_t cip; u_int16_t sport; u_int16_t cport;} STREAM_KEY;typedef Session *SessionPtr;StatsLog *stats_log;/* splay tree root data */#ifndef USE_HASH_TABLEstatic ubi_trRoot s_cache;static ubi_trRootPtr RootPtr = &s_cache;int GetSessionCount();#endifu_int32_t safe_alloc_faults;/* we keep a stream packet queued up and ready to go for reassembly */Packet *stream_pkt;/* G L O B A L S **************************************************/extern int do_detect;/* external globals from rules.c */FILE *session_log;Stream4Data s4data;u_int32_t stream4_memory_usage;u_int32_t ps_memory_usage;/* stream4 emergency mode counters... */S4Emergency s4_emergency;/* List of Dynamic flushpoints */u_int32_t flush_points[FCOUNT];/* P R O T O T Y P E S ********************************************/void *SafeAlloc(unsigned long, int, Session *);void ParseStream4Args(char *);void Stream4InitReassembler(u_char *);void ReassembleStream4(Packet *, void *);#if !defined(USE_HASH_TABLE) && !defined(USE_SPLAY_TREE)Session *GetSession(Packet *);#endifSession *CreateNewSession(Packet *, u_int32_t, u_int32_t);void DropSession(Session *);void DeleteSession(Session *, u_int32_t);void DeleteSpd(ubi_trRootPtr);int GetDirection(Session *, Packet *);void Stream4ShutdownFunction(int, void *);void Stream4CleanExitFunction(int, void *);void Stream4RestartFunction(int, void *);void PrintSessionCache();int CheckRst(Session *, int, u_int32_t, Packet *);int PruneSessionCache(u_int32_t, int, Session *);void StoreStreamPkt(Session *, Packet *, u_int32_t);void FlushStream(Stream *, Packet *, int);void InitStream4Pkt();int BuildPacket(Stream *, u_int32_t, Packet *, int);int CheckPorts(u_int16_t, u_int16_t);void PortscanWatch(Session *, u_int32_t);void PortscanDeclare(Packet *);void AddNewTarget(ubi_trRootPtr, u_int32_t, u_int16_t, u_int8_t);void AddNewPort(ubi_trRootPtr, u_int16_t, u_int8_t);int LogStream(Stream *);void WriteSsnStats(BinStats *);void OpenStatsFile();static int RetransTooFast(struct timeval *old, struct timeval *new);void Stream4Init(u_char *);void PreprocFunction(Packet *);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -