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

📄 sp_respond2.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id$ *//*** Copyright (C) 2002-2004 Jeff Nathan <jeff@snort.org>** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>** Copyright (C) 1999,2000,2001 Christian Lademann <cal@zls.de>**** 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.*//* Snort sp_respond2 Detection Plugin *   by Jeff Nathan <jeff@snort.org> *   Version 1.0.2 * * Purpose: * * Perform active response on packets matching conditions specified * in Snort rules. * * * Arguments: * * To enable link-layer response, specify the following in snort.conf *   config flexresp2_interface: <interface>  * * To configure the number of TCP response attempts, specify the following in  * snort.conf (the maximum is 20) *   config flexresp2_attempts: <attempts>  * * To configure the response cache memcap, specify the following in snort.conf *   config flexresp2_memcap: <memcap>  * * To configure the number of rows in the response cache , specify the  * following in snort.conf *   config flexresp2_rows: <rows>  * * Effect: * * Shutdown hostile network connections by falsifying TCP resets or ICMP * unreachable packets * * * Acknowledgements: * * Improvements inspired by Dug Song's tcpkill.  Thanks Dug. * * * Comments: * * sp_respond2 uses libdnet rather than libnet and supports link-layer  * injection so you can specify the network interface responses will be sent  * from (and bypass the kernel routing table).  This allows multi-homed  * systems to use Snort's flexible response system (sp_respond was broken in  * this regard). * * Resetting TCP connections with a passive NIDS is depends on speed, * and prediction.  sp_respond2 attempts to brute force active response by  * trying to predict changes in the sequence number and ack number of  * an active connection while trying to shut it down.   * * Finally, * sp_respond2 does NOT utilize TCP flags to determine whether or not * a packet should be considered valid.  This is primarily due to * inconsistencies in establishing TCP connections.  Reference: * http://www.securityfocus.com/archive/1/296122/2002-10-19/2002-10-25/2 * * * Bugs: * * All software has bugs.  When you find a bug read the BUGS document  * in the doc directory of the Snort source distribution for instructions * on submitting a bug report. * * Enjoy, * * -Jeff */#ifdef HAVE_CONFIG_H#include "config.h"#endif#if defined(ENABLE_RESPONSE2) && !defined(ENABLE_RESPONSE)#include <dnet.h>#include "decode.h"#include "rules.h"#include "plugbase.h"#include "parser.h"#include "debug.h"#include "util.h"#include "log.h"#include "mstring.h"#include "plugin_enum.h"#include "snort.h"#include "checksum.h"#include "bounds.h"#include "sfxhash.h"#define IPIDCOUNT 8192              /* number of randomly generated IP IDs */#define CACHETIME 2                 /* dampening interval */ #define MODNAME   "sp_respond2"     /* plugin name */#define DEFAULT_ROWS 1024#define DEFAULT_MEMCAP (1024 * 1024)typedef struct _RespondData{    u_int response_flag;} RespondData;/* response cache data structure */typedef struct _RESPKEY{    u_int32_t sip;                      /* source IP */    u_int32_t dip;                      /* dest IP */    u_int16_t sport;                    /* source port/ICMP type */    u_int16_t dport;                    /* dest   port/ICMP code */    u_int8_t  proto;                    /* IP protocol */    u_int8_t  _pad[3];                  /* empty bits for word alignment */} RESPKEY;typedef struct _RESPOND2_CONFIG{    int rows;                           /* response cache size (in rows) */    int memcap;                         /* response cache memcap */    u_int8_t respond_attempts;          /* respond attempts per trigger */    ip_t *rawdev;                       /* dnet(3) raw IP handle */    eth_t *ethdev;                      /* dnet(3) ethernet device handle */       rand_t *randh;                      /* dnet(3) rand handle */} RESPOND2_CONFIG;extern PV pv;static void *ip_id_pool = NULL;         /* random IP ID buffer */static u_int32_t ip_id_iterator;        /* consumed IP IDs */static void *tcp_pkt = NULL;            /* TCP packet memory placeholder */static void *icmp_pkt = NULL;           /* ICMP packet memory placeholder */static u_int8_t link_offset;            /* offset from L2 to L3 header */static u_int8_t alignment;              /* force alignment ?? */SFXHASH *respcache = NULL;              /* cache responses to prevent loops */static RESPKEY response;static RESPOND2_CONFIG config;/* API functions */static void Respond2Init(char *data, OptTreeNode *otn, int protocol);static void Respond2Restart(int signal, void *data);static int ParseResponse2(char *type);/* CORE respond2 functions */static int Respond2(Packet *p, RspFpList *fp_list);static INLINE void SendReset(const int mode, Packet *p, RESPOND2_CONFIG *conf);static INLINE void SendUnreach(const int code, Packet *p,         RESPOND2_CONFIG *conf);static INLINE int IsRSTCandidate(Packet *p);static INLINE int IsUNRCandidate(Packet *p);static INLINE int IsLinkCandidate(Packet *p);static INLINE u_int16_t RandID(RESPOND2_CONFIG *conf);static INLINE u_int8_t CalcOriginalTTL(Packet *p);/* UTILITY functions */static void PrecacheTCP(void);static void PrecacheICMP(void);static void GenRandIPID(RESPOND2_CONFIG *conf);static void SetLinkInfo(void);static void SetRespAttempts(RESPOND2_CONFIG *conf);static void SetRespCacheRows(RESPOND2_CONFIG *conf);static void SetRespCacheMemcap(RESPOND2_CONFIG *conf);/* HASH functions */static int respcache_init(SFXHASH **cache, RESPOND2_CONFIG *conf);static INLINE int dampen_response(Packet *p);static INLINE int respkey_make(RESPKEY *hashkey, Packet *p);/* ######## API section ######## *//** * Initialize respond2 plugin * * @return void function */void SetupRespond2(void){    RegisterPlugin("resp", Respond2Init, OPT_TYPE_ACTION);    GenRandIPID(&config);  /* generate random IP ID cache */    return;}/** * Respond2 initialization function * * @param data argument passed to the resp keyword * @param otn pointer to an OptTreeNode structure * @param protocol Snort rule protocol (IP/TCP/UDP) * * @return void function */static void Respond2Init(char *data, OptTreeNode *otn, int protocol) {    static int setup = 0;    RespondData *rd = NULL;    if (!(protocol & (IPPROTO_ICMP | IPPROTO_TCP | IPPROTO_UDP)))        FatalError("%s: %s(%d): Can't respond to IP protocol rules.\n",                 MODNAME, file_name, file_line);    rd = (RespondData *)SnortAlloc(sizeof(RespondData));    if (!setup)    {        SetLinkInfo();      /* setup link-layer pointer arithmetic info */        SetRespAttempts(&config);       /* configure # of TCP attempts */        SetRespCacheRows(&config);      /* configure # of rows in cache */        SetRespCacheMemcap(&config);    /* configure response cache memcap */        if ((respcache_init(&respcache, &config)) != 0)            FatalError("%s: Unable to allocate hash table memory.\n", MODNAME);        /* Open raw socket or network device before Snort drops privileges */        if (link_offset)        {            if (config.ethdev == NULL)     /* open link-layer device */            {                if ((config.ethdev = eth_open(pv.respond2_ethdev)) == NULL)                    FatalError("%s: Unable to open link-layer device: %s.\n",                             MODNAME, pv.respond2_ethdev);            }            DEBUG_WRAP(                    DebugMessage(DEBUG_PLUGIN, "%s: using link-layer "                            "injection on interface %s\n", MODNAME,                            pv.respond2_ethdev);                    DebugMessage(DEBUG_PLUGIN, "%s: link_offset = %d\n",                             MODNAME, link_offset);                            );        }        else        {            if (config.rawdev == NULL)   /* open raw device if necessary */            {                if ((config.rawdev = ip_open()) == NULL)                    FatalError("%s: Unable to open raw socket.\n",                             MODNAME);            }        }        setup = 1;        DEBUG_WRAP(                DebugMessage(DEBUG_PLUGIN, "%s: respond_attempts = %d\n",                         MODNAME, config.respond_attempts);                DebugMessage(DEBUG_PLUGIN, "Plugin: Respond2 is setup\n");        );    }    rd->response_flag = ParseResponse2(data);        AddRspFuncToList(Respond2, otn, (void *)rd);    /* Restart and CleanExit function are identical */    AddFuncToCleanExitList(Respond2Restart, &config);    AddFuncToRestartList(Respond2Restart, &config);    return;}/** * respond2 signal handler * re-initializes packet memory and close device handles *  * @param data pointer to a RESPOND2_CONFIG data structure * * @return void function */static void Respond2Restart(int signal, void *data){    RESPOND2_CONFIG *conf = (RESPOND2_CONFIG *)data;    /* device and raw IP handles */    if (conf->rawdev != NULL)        conf->rawdev = ip_close(conf->rawdev);    if (conf->ethdev != NULL)        conf->ethdev = eth_close(conf->ethdev);    /* free packet memory */    if (tcp_pkt != NULL)    {        tcp_pkt -= alignment;        free(tcp_pkt);        tcp_pkt = NULL;    }    if (icmp_pkt != NULL)    {        icmp_pkt -= alignment;        free(icmp_pkt);        icmp_pkt = NULL;    }    /* free IP ID pool and close random handle */    if (ip_id_pool != NULL)    {        free(ip_id_pool);        ip_id_pool = NULL;        /* reset iterator */        ip_id_iterator = 0;    }    if (conf->randh != NULL)        conf->randh = rand_close(conf->randh);    /* destroy the response dampening hash table */    if (respcache != NULL)    {        sfxhash_delete(respcache);        respcache = NULL;    }    return;}/** * Determine how to handle hostile connection attempts * * @param type string of comma-separated response modifiers * * @return integer describing the type of response action on a matching packet */static int ParseResponse2(char *type){    char **toks;    int response_flag = 0;    int num_toks;    static int make_tcp = 0;    static int make_icmp = 0;    int i;    while (isspace((int) *type))        type++;    if (!type || !(*type))        return 0;    toks = mSplit(type, ",", 6, &num_toks, 0);    if (num_toks < 1)        FatalError("ERROR %s (%d): Bad arguments to respond2: %s.\n", file_name,                file_line, type);    i = 0;    while (i < num_toks)    {        if (!strcasecmp(toks[i], "reset_source"))        {            response_flag |= RESP_RST_SND;            if (!make_tcp)                make_tcp = 1;            i++;        }        else if (!strcasecmp(toks[i], "reset_dest"))        {            response_flag |= RESP_RST_RCV;            if (!make_tcp)                make_tcp = 1;            i++;        }        else if (!strcasecmp(toks[i], "reset_both"))        {            response_flag |= (RESP_RST_RCV | RESP_RST_SND);            if (!make_tcp)                make_tcp = 1;            i++;        }        else if (!strcasecmp(toks[i], "icmp_net"))        {            response_flag |= RESP_BAD_NET;            if (!make_icmp)                make_icmp = 1;            i++;        }        else if (!strcasecmp(toks[i], "icmp_host"))        {            response_flag |= RESP_BAD_HOST;            if (!make_icmp)                make_icmp = 1;            i++;        }        else if (!strcasecmp(toks[i], "icmp_port"))        {            response_flag |= RESP_BAD_PORT;            if (!make_icmp)                make_icmp = 1;            i++;        }

⌨️ 快捷键说明

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