[Snort-sigs] False +ve for IMAP PCT Client_Hello overflow attempt: Sig ID 2517

Brian bmc at ...95...
Fri Mar 4 07:39:55 EST 2005


OK, so its taken me a while, but I have put together something I'd
like you to test with.  Please try this patch, which applies cleanly
to HEAD as of yesterday evening.

This patch adds "pre-tagging" to snort, configured on a global basis.
It is *massively* resource intensive, so don't use in a production
enviornment please!  To use "pre-tagging", after applying the patch,
add the following to your snort.conf:

    config max_presave_queue: 30

This configuration will copy the latest 30 packets of every flow into
memory.  When an alert is triggered, all of the packets in the queue
for the current flow are logged and removed from the queue.

Let me state this again.  This patch is *VERY* memory intensive.  You
might want to add a BPF to snort to trim down the traffic to just the
hosts that trigger this false positive.

After running this patch, please send me the resulting pcap so I can
figure out your false positive.  

Thanks,
Brian
-------------- next part --------------
diff -urN -x CVS -x Makefile.in current/etc/gen-msg.map snort-presave/etc/gen-msg.map
--- current/etc/gen-msg.map	2005-03-03 17:39:54.000000000 -0500
+++ snort-presave/etc/gen-msg.map	2005-03-03 17:58:32.000000000 -0500
@@ -4,6 +4,7 @@
 
 1 || 1 || snort general alert
 2 || 1 || tag: Tagged Packet
+2 || 2 || tag: Pre-Tagged Packet
 100 || 1 || spp_portscan: Portscan Detected
 100 || 2 || spp_portscan: Portscan Status
 100 || 3 || spp_portscan: Portscan Ended
diff -urN -x CVS -x Makefile.in current/src/decode.h snort-presave/src/decode.h
--- current/src/decode.h	2005-03-03 17:39:55.000000000 -0500
+++ snort-presave/src/decode.h	2005-03-02 17:15:45.000000000 -0500
@@ -1045,6 +1045,12 @@
     u_int32_t decode_flags; 
 } HttpUri;
 
+typedef struct _SAVE_PACKET
+{
+    struct pcap_pkthdr pkth;
+    void *pkt;
+} SAVE_PACKET;
+
 typedef struct _Packet
 {
     struct pcap_pkthdr *pkth;   /* BPF data */
diff -urN -x CVS -x Makefile.in current/src/detect.c snort-presave/src/detect.c
--- current/src/detect.c	2005-03-03 17:39:55.000000000 -0500
+++ snort-presave/src/detect.c	2005-03-03 17:47:34.000000000 -0500
@@ -50,6 +50,9 @@
 #include "event_queue.h"
 #include "stream.h"
 #include "inline.h"
+#include "sfeventq.h"
+
+#include "preevent_queue.h"
 
 /* XXX modularization violation */
 #include "preprocessors/spp_stream4.h"
@@ -146,6 +149,10 @@
     */
     CheckTagging(p);
 
+    /* log the presaved queue if we are going to alert... */
+    if (pv.max_presave_queue && sfeventq_has_events())
+        LogPresavedQueue(p);
+
     retval = SnortEventqLog(p);
     SnortEventqReset();
 
@@ -159,6 +166,10 @@
     if(retval && p->ssnptr)
         AlertFlushStream(p);
 
+    /* we only need to save a packet if we didn't alert on it */
+    if(pv.max_presave_queue && !retval)
+        SaveFlowPacket(p);
+
     /**
      * See if we should go ahead and remove this flow from the
      * flow_preprocessor -- cmg
diff -urN -x CVS -x Makefile.in current/src/generators.h snort-presave/src/generators.h
--- current/src/generators.h	2005-03-03 17:39:55.000000000 -0500
+++ snort-presave/src/generators.h	2005-03-03 17:59:15.000000000 -0500
@@ -24,6 +24,7 @@
 
 #define GENERATOR_TAG                 2
 #define    TAG_LOG_PKT                1
+#define    PRETAG_LOG_PKT             2
 
 #define GENERATOR_SPP_PORTSCAN      100
 #define     PORTSCAN_SCAN_DETECT        1
diff -urN -x CVS -x Makefile.in current/src/Makefile.am snort-presave/src/Makefile.am
--- current/src/Makefile.am	2005-03-03 17:39:54.000000000 -0500
+++ snort-presave/src/Makefile.am	2005-03-03 17:31:10.000000000 -0500
@@ -45,7 +45,7 @@
 smalloc.h \
 snort_packet_header.h \
 event_queue.c event_queue.h \
-inline.c inline.h
+inline.c inline.h preevent_queue.c preevent_queue.h
 
 snort_LDADD = output-plugins/libspo.a \
 detection-plugins/libspd.a            \
diff -urN -x CVS -x Makefile.in current/src/parser.c snort-presave/src/parser.c
--- current/src/parser.c	2005-03-03 17:39:55.000000000 -0500
+++ snort-presave/src/parser.c	2005-03-03 11:23:04.000000000 -0500
@@ -3241,6 +3241,33 @@
     return;
 }
 
+void ProcessMaxPreQueueSize(char **args, int nargs)
+{
+    int i;
+    char *pcEnd;
+
+    if(nargs)
+    {
+        i = strtol(args[0], &pcEnd, 10);
+        if(*pcEnd || i < 0)
+        {
+            FatalError("%s(%d) => Invalid argument to 'max_presave_queue'. "
+                       "Must be a positive integer.\n",
+                       file_name, file_line);
+        }
+        else if (i > 10) 
+        {
+            LogMessage("WARNING %s (%d) => max pre-queued packet size is set "
+                      "to %d. Are you sure you want to do this?\n", file_name, 
+                      file_line, i);
+        }
+        
+        pv.max_presave_queue = (unsigned int)i;
+    }
+
+    return;
+}
+
 void ProcessEventQueue(char **args, int nargs)
 {
     int iCtr;
@@ -3479,6 +3506,15 @@
         mSplitFree(&config_decl,num_config_decl_toks);
         return;
     }
+    else if(!strcasecmp(config, "max_presave_queue"))
+    {
+        toks = mSplit(args, ", ",20, &num_toks, 0);
+        ProcessMaxPreQueueSize(toks, num_toks);
+        mSplitFree( &toks, num_toks );
+        mSplitFree(&rule_toks,num_rule_toks);
+        mSplitFree(&config_decl,num_config_decl_toks);
+        return;
+    }
     else if(!strcasecmp(config, "event_queue"))
     {
         toks = mSplit(args, ", ", 20, &num_toks, 0);
diff -urN -x CVS -x Makefile.in current/src/preevent_queue.c snort-presave/src/preevent_queue.c
--- current/src/preevent_queue.c	1969-12-31 19:00:00.000000000 -0500
+++ snort-presave/src/preevent_queue.c	2005-03-03 17:59:11.000000000 -0500
@@ -0,0 +1,168 @@
+/**
+ * @file   preevent_queue.c
+ * @author Brian Caswell <bmc at ...435...>
+ * @date   Thu Mar  3 17:19:16 EST 2005
+ * 
+ * @brief  store a queue of packets so we can do "prepacket" tagging
+ * 
+ * This is a wrapper around SetEvent,CallLogFuncs,CallEventFuncs 
+ */
+
+#include <pcap.h>
+
+#include "snort.h"
+#include "log.h"
+#include "generators.h"
+#include "detect.h"
+#include "sflsq.h"
+#include "preevent_queue.h"
+#include "flow.h"
+
+
+static SAVE_PACKET * GetSavePacket (Packet *p);
+static void TrimFlowQueue (SF_QUEUE *queue, unsigned int max_size);
+
+extern grinder_t grinder;
+extern u_int32_t event_id;
+
+/** 
+ *  * If we have not alerted, add a copy of this packet to the flow.
+ *   * 
+ *    * @param p packet
+ *     */
+void SaveFlowPacket(Packet *p)
+{
+    FLOW     *fp;
+    FLOWDATA *flowdata;
+    SF_QUEUE *queue;
+
+    SAVE_PACKET *sp = NULL;
+
+    /* no p?  how did we get here */
+    if (!p)
+        return;
+
+    if(!p->flow)
+        return;
+
+    fp = (FLOW *)p->flow;
+
+
+    flowdata = &(fp->data);
+
+    /* no flowdata? */
+    if(!flowdata)
+        return;
+
+    queue = flowdata->presave_queue;
+
+    if (!queue)
+        return;
+
+    if (pv.max_presave_queue) {
+        TrimFlowQueue(queue, (pv.max_presave_queue - 1));
+        sp = GetSavePacket(p);
+        if (sp != NULL) {
+            sfqueue_add(queue, sp);
+        }
+    }
+}
+
+/* trim the queue to be the max size of the queue */
+void TrimFlowQueue (SF_QUEUE *queue, unsigned int max_size)
+{
+    SAVE_PACKET * sp = NULL;
+
+    unsigned int size = 0;
+
+    size = sfqueue_count(queue);
+    if (queue && size) {
+        while (size > max_size) {
+            sp = sfqueue_remove(queue);
+            if (sp) {
+                if (sp->pkt) {
+                    free(sp->pkt);
+                }
+                free (sp);
+            }
+            size--;
+        }
+    }
+}
+
+/* create a copy of the pcap packet */
+SAVE_PACKET * GetSavePacket (Packet *p)
+{
+    SAVE_PACKET * sp = NULL;
+
+    sp = malloc(sizeof(SAVE_PACKET));
+    if (!sp) {
+        return NULL;
+    }
+
+    memcpy(&(sp->pkth), p->pkth, sizeof(sp->pkth));
+
+    /* copy the packet payload */
+    sp->pkt = malloc(sp->pkth.caplen);
+    if (!sp->pkt) {
+        free(sp);
+        return NULL;
+    }
+
+    memcpy(sp->pkt, p->pkt, sp->pkth.caplen);
+
+    return sp; 
+}
+
+void LogPresavedQueue(Packet *p)
+{
+    Event event;
+    FLOW     *fp;
+    FLOWDATA *flowdata;
+    SF_QUEUE *queue;
+
+    SAVE_PACKET *sp = NULL;
+
+    /* no p?  how did we get here */
+    if (!p)
+        return;
+
+    /* no flow? */
+    if(!p->flow)
+        return;
+
+    fp = (FLOW *)p->flow;
+
+    flowdata = &(fp->data);
+
+    /* no flowdata?!? */
+    if(!flowdata)
+        return;
+
+    queue = flowdata->presave_queue;
+
+    if (!queue)
+        return;
+
+    while ((sp = sfqueue_remove(queue)) != NULL) {
+        if (sp) {
+            /* XXX - log event */
+            if (sp->pkt) {
+                Packet newp;
+
+                (*grinder) (&newp, &(sp->pkth), sp->pkt);
+
+                SetEvent(&event, GENERATOR_TAG, PRETAG_LOG_PKT, 1, 1, 1,
+                        event_id + 1);
+
+                event.ref_time.tv_sec = sp->pkth.ts.tv_sec;
+                event.ref_time.tv_usec = sp->pkth.ts.tv_usec;
+
+                CallLogFuncs(&newp, "Pre-Tagged Packet", NULL, &event);
+                free(sp->pkt);
+                ClearDumpBuf();
+            }
+            free(sp);
+        }
+    }
+}
diff -urN -x CVS -x Makefile.in current/src/preevent_queue.h snort-presave/src/preevent_queue.h
--- current/src/preevent_queue.h	1969-12-31 19:00:00.000000000 -0500
+++ snort-presave/src/preevent_queue.h	2005-03-03 17:33:52.000000000 -0500
@@ -0,0 +1,11 @@
+#ifndef _PREEVENT_QUEUE_H
+#define _PREEVENT_QUEUE_H
+
+#include "log.h"
+#include "detect.h"
+#include "decode.h"
+
+void SaveFlowPacket(Packet *p);
+void LogPresavedQueue(Packet *p);
+
+#endif /* _PREEVENT_QUEUE_H */
diff -urN -x CVS -x Makefile.in current/src/preprocessors/flow/flow_cache.c snort-presave/src/preprocessors/flow/flow_cache.c
--- current/src/preprocessors/flow/flow_cache.c	2005-03-03 17:39:55.000000000 -0500
+++ snort-presave/src/preprocessors/flow/flow_cache.c	2005-03-02 17:54:58.000000000 -0500
@@ -162,6 +162,10 @@
 {
     FLOWKEY *key;
     FLOWKEY search_key;
+    FLOWDATA *flowdata;
+    SF_QUEUE *queue;
+    SAVE_PACKET *sp;
+
     
     if(!flowcachep || !flowpp || !(*flowpp))
     {
@@ -179,6 +183,26 @@
         return FLOW_NOTFOUND;
     }
 
+    flowdata = &((*flowpp)->data);
+    if (flowdata) {
+        queue = flowdata->presave_queue;
+
+        if (queue) {
+            unsigned int count = sfqueue_count(queue);
+            while (count > 0) {
+                sp = sfqueue_remove(queue);
+                if (sp) {
+                    if (sp->pkt) {
+                        free(sp->pkt);
+                    }
+                    free(sp);
+                }
+                count--;
+            }
+            sfqueue_free(queue);
+        }
+    }
+
     /* we've successfully removed the node from the table */
     
     *flowpp = NULL;
@@ -197,6 +221,12 @@
         return 1;
     }
 
+    flowp->data.presave_queue = sfqueue_new();
+    if (!flowp->data.presave_queue) {
+        flowp->data.presave_queue = NULL;
+        return 1;
+    }
+
     return 0;
 }
 
diff -urN -x CVS -x Makefile.in current/src/preprocessors/flow/flow.h snort-presave/src/preprocessors/flow/flow.h
--- current/src/preprocessors/flow/flow.h	2005-03-03 17:39:55.000000000 -0500
+++ snort-presave/src/preprocessors/flow/flow.h	2005-03-02 16:15:51.000000000 -0500
@@ -7,6 +7,7 @@
 #include "flow_print.h"
 #include "flow_packet.h"
 #include "bitop.h"
+#include "sflsq.h"
 
 #define FROM_INITIATOR 1
 #define FROM_RESPONDER 2
@@ -19,6 +20,7 @@
 {
     BITOP boFlowbits;
     unsigned char flowb[1];
+    SF_QUEUE *presave_queue;
 } FLOWDATA;
 
 typedef enum {
diff -urN -x CVS -x Makefile.in current/src/sfutil/sfeventq.c snort-presave/src/sfutil/sfeventq.c
--- current/src/sfutil/sfeventq.c	2005-03-03 17:39:55.000000000 -0500
+++ snort-presave/src/sfutil/sfeventq.c	2005-03-03 13:49:45.000000000 -0500
@@ -169,6 +169,24 @@
     return event;
 }
 
+
+/*
+**  NAME
+**    sfeventq_has_events::
+*/
+/**
+**  return if there are events currently in the queue
+**
+**  @return  int 
+*/
+int *sfeventq_has_events(void)
+{
+    if(s_eventq.cur_events > 0) 
+        return 1;
+        
+    return 0;
+}
+
 /*
 **  NAME
 **    sfeventq_reset::
diff -urN -x CVS -x Makefile.in current/src/sfutil/sfeventq.h snort-presave/src/sfutil/sfeventq.h
--- current/src/sfutil/sfeventq.h	2005-03-03 17:39:55.000000000 -0500
+++ snort-presave/src/sfutil/sfeventq.h	2005-03-03 16:38:44.000000000 -0500
@@ -7,5 +7,5 @@
 int   sfeventq_action(int (*action_func)(void *event, void *user), void *user);
 int   sfeventq_init(int max_nodes, int log_nodes, int event_size, 
                     int (*sort)(void *, void *));
-
+int   sfeventq_has_events(void);
 #endif
diff -urN -x CVS -x Makefile.in current/src/snort.h snort-presave/src/snort.h
--- current/src/snort.h	2005-03-03 17:39:55.000000000 -0500
+++ snort-presave/src/snort.h	2005-03-03 10:56:51.000000000 -0500
@@ -151,6 +151,7 @@
 /* struct to contain the program variables and command line args */
 typedef struct _progvars
 {
+    unsigned int max_presave_queue;
     int stateful;
     int line_buffer_flag;
     int checksums_mode;


More information about the Snort-sigs mailing list