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

📄 spp_frag3.c

📁 linux下IDS软件,来源于snort社团.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Id$ *//** * @file    spp_frag3.c * @author  Martin Roesch <roesch@sourcefire.com> * @date    Thu Sep 30 14:12:37 EDT 2004 * * @brief   Frag3: IP defragmentation preprocessor for Snort.  *//* ** Copyright (C) 2004 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. *//* * Notes:  * Frag3 sports the following improvements over frag2: *  - Target-based IP defragmentation, harder to evade *  - 8 Anomaly detection event types *  - Two separate memory management strategies to tailor *    performance for specific environments *  - Up to 250% faster than frag2. * *  The mechanism for processing frags is based on the Linux IP stack  *  implementation of IP defragmentation with proper amounts of paranoia *  and an IDS perspective applied.  Some of this code was derived from  *  frag2 originally, but it's basically unrecognizeable if you compare *  it to frag2 IMO. * *  I switched from using the UBI libs to using sfxhash and linked lists for  *  fragment management because I suspected that the management code was  *  the cause of performance issues that we were observing at Sourcefire  *  in certain customer situations.  Splay trees are cool and really hard *  to screw with from an attack perspective, but they also incur a lot  *  of overhead for managing the tree and lose the order of the fragments in  *  the FragTracker's fraglist, so I dropped them.  Originally the *  frag3 code was just supposed to migrate away from the splay tree system *  that I was using in frag2, but I figured since I was doing the work to *  pull out the splay trees I may as well solve some of the other problems *  we were seeing.   * *  Initial performance testing that I've done shows that frag3 can be as much *  as 250% faster than frag2, but we still need to do more testing and  *  optimization, we may be able to squeeze out some more performance. * *  Frag3 is also capable of performing "Target-based" IP defragmentation.   *  What this means practically is that frag3 can model the IP stack of a *  target on the network to avoid Ptacek-Newsham evasions of the IDS through *  sensor/target desynchronization.  In terms of implentation, this is *  reflected by passing a "context" into the defragmentation engine that has *  a specific configuration for a specific target type.  Windows can put *  fragments back together differently than Linux/BSD/etc, so we model that *  inside frag3 so we can't be evaded. * *  Configuration of frag3 is pretty straight forward, there's a global config *  that contains data about how the hash tables will be structured, what type *  of memory management to use and whether or not to generate alerts, then *  specific target-contexts are setup and bound to IP address sets.  Check *  the README file for specifics! *//*  I N C L U D E S  ************************************************/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <sys/types.h>#include <stdlib.h>#include <ctype.h>#include <rpc/types.h>#include "bounds.h"#include "generators.h"#include "log.h"#include "detect.h"#include "decode.h"#include "event.h"#include "util.h"#include "debug.h"#include "plugbase.h"#include "parser.h"#include "mstring.h"#include "checksum.h"#include "perf.h"#include "event_queue.h"#include "timersub.h"#include "fpcreate.h"#include "sfutil/sflsq.h"#include "sfutil/sfxhash.h"#include "snort.h"extern OptTreeNode *otn_tmp;/*  D E F I N E S  **************************************************//* flags for the FragTracker->frag_flags field */#define FRAG_GOT_FIRST      0x00000001#define FRAG_GOT_LAST       0x00000002#define FRAG_REBUILT        0x00000004#define FRAG_BAD            0x00000008#define FRAG_PRUNE_QUANTA   60          /* default frag timeout, 90-120 might                                          * be better values, can we do                                          * target-based quanta?                                         */#define FRAG_MEMCAP         4194304     /* default 4MB memcap */#define FRAG3_TTL_LIMIT      5          /* default TTL, unnecessary in                                          * tgt-based systems? */#define FRAG3_MIN_TTL        1          /* min acceptable ttl (should be 1?) *//* target-based defragmentation policy enums */#define FRAG_POLICY_FIRST       1#define FRAG_POLICY_LINUX       2#define FRAG_POLICY_BSD         3#define FRAG_POLICY_BSD_RIGHT   4#define FRAG_POLICY_LAST        5#define FRAG_POLICY_WINDOWS     6 /* Combo of FIRST & LAST, depending on                                   * overlap situation.                                   */#define FRAG_POLICY_SOLARIS     7 /* Combo of FIRST & LAST, depending on                                   * overlap situation.                                   *//* the twiddle is needed for architectures that force word-aligned memory * access  */#if defined (SOLARIS) || defined (SUNOS) || defined (__sparc__) || defined(__sparc64__) || defined (HPUX)#define SPARC_TWIDDLE       2#else#define SPARC_TWIDDLE       0#endif/* max packet size */#define DATASIZE (ETHERNET_HEADER_LEN+IP_MAXPACKET)/* max frags in a single frag tracker */#define DEFAULT_MAX_FRAGS   8192/* return values for CheckTimeout() */#define FRAG_TIME_OK            0#define FRAG_TIMEOUT            1/* return values for Frag3Insert() */#define FRAG_INSERT_OK          0#define FRAG_INSERT_FAILED      1#define FRAG_INSERT_REJECTED    2#define FRAG_INSERT_TIMEOUT     3#define FRAG_INSERT_ATTACK      4#define FRAG_INSERT_ANOMALY     5#define FRAG_INSERT_TTL         6/* return values for Frag3CheckFirstLast() */#define FRAG_FIRSTLAST_OK       0#define FRAG_LAST_DUPLICATE     1/* return values for Frag3Expire() */#define FRAG_OK                 0#define FRAG_TRACKER_TIMEOUT    1#define FRAG_LAST_OFFSET_ADJUST 2/* flag for detecting attacks/alerting */#define FRAG3_DETECT_ANOMALIES  0x01/*  D A T A   S T R U C T U R E S  **********************************//* global configuration data struct for this preprocessor */typedef struct {    u_int32_t max_frags;        /* max frags to track */    u_int32_t memcap;           /* memcap for frag3 */    u_int32_t static_frags;     /* static frag nodes to keep around */    u_int8_t use_prealloc;      /* flag to indicate prealloc nodes in use */} Frag3GlobalConfig;/* runtime context for a specific instance of an engine */typedef struct _Frag3Context{    u_int16_t frag_policy;  /* policy to use for target-based reassembly */    int32_t frag_timeout; /* timeout for frags in this policy */    u_int8_t min_ttl;       /* Minimum TTL to accept */    u_int8_t ttl_limit;     /* Size of ttls to avoid detection on */    char frag3_alerts;      /* Whether or not frag3 alerts are enabled */    IpAddrSet *bound_addrs; /* addresses bound to this context */} Frag3Context;/* struct to manage an individual fragment */typedef struct _Frag3Frag{    u_int8_t *data;     /* ptr to adjusted start position */    u_int16_t size;     /* adjusted frag size */    u_int16_t offset;   /* adjusted offset position */    u_int8_t *fptr;     /* free pointer */    u_int16_t flen;     /* free len, unneeded? */    struct _Frag3Frag *prev;    struct _Frag3Frag *next;    int ord;    char last;} Frag3Frag;/* key struct for the sfxhash */typedef struct _fragkey{    u_int32_t sip;      /* src IP */    u_int32_t dip;      /* dst IP */    u_int16_t id;       /* IP ID */    u_int8_t proto;     /* IP protocol */} FRAGKEY;/* Only track a certain number of alerts per session */#define MAX_FRAG_ALERTS  8/* tracker for a fragmented packet set */typedef struct _FragTracker{    u_int32_t sip;          /* src IP */    u_int32_t dip;          /* dst IP */    u_int16_t id;           /* IP ID */    u_int8_t protocol;      /* IP protocol */    u_int8_t ttl;           /* ttl used to detect evasions */    u_int8_t alerted;    u_int32_t frag_flags;   /* bit field */    u_int32_t frag_bytes;   /* number of fragment bytes stored, based                              * on aligned fragment offsets/sizes                             */    u_int32_t calculated_size; /* calculated size of reassembled pkt, based on                                 * last frag offset                                */    u_int32_t frag_pkts;   /* nummber of frag pkts stored under this tracker */    struct timeval frag_time; /* time we started tracking this frag */    Frag3Frag *fraglist;      /* list of fragments */    Frag3Frag *fraglist_tail; /* tail ptr for easy appending */    int fraglist_count;       /* handy dandy counter */    u_int32_t alert_gid[MAX_FRAG_ALERTS]; /* flag alerts seen in a frag list  */    u_int32_t alert_sid[MAX_FRAG_ALERTS]; /* flag alerts seen in a frag list  */    u_int8_t  alert_count;                /* count alerts seen in a frag list */    u_int32_t ip_options_len;  /* length of ip options for this set of frags */    u_int32_t ip_option_count; /* number of ip options for this set of frags */    u_int8_t *ip_options_data; /* ip options from offset 0 packet */    u_int32_t copied_ip_options_len;  /* length of 'copied' ip options */    u_int32_t copied_ip_option_count; /* number of 'copied' ip options */    Frag3Context *context;    int ordinal;} FragTracker;/* statistics tracking struct */typedef struct _Frag3Stats{    u_int32_t  total;    u_int32_t  overlaps;    u_int32_t  reassembles;    u_int32_t  prunes;    u_int32_t  timeouts;    u_int32_t  fragtrackers_created;    u_int32_t  fragtrackers_released;    u_int32_t  fragtrackers_autoreleased;    u_int32_t  fragnodes_created;    u_int32_t  fragnodes_released;    u_int32_t  discards;    u_int32_t  anomalies;    u_int32_t  alerts;} Frag3Stats;/*  G L O B A L S  **************************************************/static Frag3GlobalConfig global_config;  /* global configuration struct */static SFXHASH *f_cache;                 /* fragment hash table */static Frag3Frag *prealloc_frag_list;    /* head for prealloc queue */static char global_init_complete;   /* flag to signal f_cache initialization */ static u_int32_t mem_in_use;             /* memory in use, used for self pres */static u_int32_t prealloc_nodes_in_use;  /* counter for debug */static int ten_percent;                  /* holder for self preservation data */static Frag3Stats f3stats;               /* stats struct */static u_int8_t stats_registered;        /* make sure we only print stats once                                            per run */static Packet *defrag_pkt;               /* holder for prealloc'd defrag pkt *//* enum for policy names */static char *policy_names[] = { "no policy!",    "FIRST",    "LINUX",    "BSD",    "BSD_RIGHT",    "LAST",    "WINDOWS",    "SOLARIS"};/* * external globals for startup */extern char *file_name;             extern int file_line;                extern u_int snaplen;extern SFPERF sfPerf;/*  P R O T O T Y P E S  ********************************************/static void Frag3ParseGlobalArgs(u_char *);static void Frag3ParseArgs(u_char *, Frag3Context *);static FragTracker *Frag3GetTracker(Packet *, FRAGKEY *);static int Frag3NewTracker(Packet *p, FRAGKEY *fkey, Frag3Context *);static int Frag3Insert(Packet *, FragTracker *, FRAGKEY *, Frag3Context *);static void Frag3Rebuild(FragTracker *, Packet *);static int INLINE Frag3IsComplete(FragTracker *);static int Frag3HandleIPOptions(FragTracker *, Packet *);static void Frag3InitPkt();/* deletion funcs */static int Frag3Prune(FragTracker *);static struct timeval *pkttime;    /* packet timestamp */static void Frag3DeleteFrag(Frag3Frag *);static void Frag3RemoveTracker(void *, void *);static void Frag3DeleteTracker(FragTracker *);static int Frag3AutoFree(void *, void *);static int Frag3UserFree(void *, void *);/* fraglist handler funcs */static INLINE void Frag3FraglistAddNode(FragTracker *, Frag3Frag *, Frag3Frag *); static INLINE void Frag3FraglistDeleteNode(FragTracker *, Frag3Frag *);/* prealloc queue handler funcs */static INLINE Frag3Frag *Frag3PreallocPop();static INLINE void Frag3PreallocPush(Frag3Frag *);/* main preprocessor functions */void Frag3Defrag(Packet *, void *);void Frag3CleanExit(int, void *);void Frag3Restart(int, void *);void Frag3Init(u_char *);void Frag3GlobalInit(u_char *);#ifdef DEBUG_FRAG3/** * Print out a FragTracker structure * * @param ft Pointer to the FragTracker to print * * @return none */static void PrintFragTracker(FragTracker *ft){    LogMessage("FragTracker %p\n", ft);    if(ft)    {        LogMessage("        sip: 0x%08X\n", ft->sip);        LogMessage("        dip: 0x%08X\n", ft->dip);        LogMessage("         id: %d\n", ft->id);        LogMessage("      proto: 0x%X\n", ft->protocol);        LogMessage("        ttl: %d\n", ft->ttl);        LogMessage("    alerted: %d\n", ft->alerted);        LogMessage(" frag_flags: 0x%X\n", ft->frag_flags);        LogMessage(" frag_bytes: %d\n", ft->frag_bytes);        LogMessage("  calc_size: %d\n", ft->calculated_size);        LogMessage("  frag_pkts: %d\n", ft->frag_pkts);        LogMessage("  frag_time: %lu %lu\n", ft->frag_time.tv_sec,                 ft->frag_time.tv_usec);        LogMessage("   fraglist: %p\n", ft->fraglist);        LogMessage("    fl_tail: %p\n", ft->fraglist_tail);        LogMessage("fraglst cnt: %d\n", ft->fraglist_count);    }}/** * Print out a FragKey structure * * @param fkey Pointer to the FragKey to print * * @return none */static void PrintFragKey(FRAGKEY *fkey){    LogMessage("FragKey %p\n", fkey);    if(fkey)    {        LogMessage("    sip: 0x%08X\n", fkey->sip);        LogMessage("    dip: 0x%08X\n", fkey->dip);        LogMessage("     id: %d\n", fkey->id);        LogMessage("  proto: 0x%X\n", fkey->proto);    }

⌨️ 快捷键说明

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