[Snort-devel] Several fixes for Inline Mode to Snort

Bradley A. Plank bplank at ...2952...
Mon Dec 10 09:50:06 EST 2007


Snort Developers,

I'd like to help out with the Snort project, please accept these
modifications in the 2.7.0.x and 2.8.0.x development branches.  I've been
doing development for quite some time and would like to help with future
Snort issues.  Contact me if you would like help with using Snort under
FreeBSD, inline mode, or anything really that needs attention with the Snort
project.

See the following diffs to make inline mode work correctly for a few cases:
[ All fixes/modifications are marked with 'ifdef FIX_B_PLANK']
[ All feature additions are marked by 'ifdef FEATURE_B_PLANK']

[*** Need a way to know if the packet was 'dropped' or 'rejected' for better
logging ***]

Index: src/decode.h
===================================================================
@@ -568,8 +568,13 @@
 #define PKT_STREAM_TWH       0x00001000
 #define PKT_IGNORE_PORT      0x00002000  /* this packet should be ignored,
based on port */
 #define PKT_PASS_RULE        0x00004000  /* this packet has matched a pass
rule */
+
+#ifdef FIX_B_PLANK
+#define PKT_INLINE_REJECT    0x08000000  /* this packet has matched a
reject rule */
+#endif /* FIX_B_PLANK */
+
 #define PKT_STATELESS        0x10000000  /* Packet has matched a stateless
rule */
-#define PKT_INLINE_DROP      0x20000000
+#define PKT_INLINE_DROP      0x20000000  /* this packet has matched a drop
rule */
 #define PKT_OBFUSCATED       0x40000000  /* this packet has been obfuscated
*/
 #define PKT_NO_DETECT        0x80000000  /* this packet should not be
preprocessed */

[*** Need to reject packet and mark as such before logging what was done
***]

Index: src/detect.c
===================================================================
@@ -1546,9 +1546,12 @@
                "        <!!>Ignoring! \"%s\"\n",
                otn->sigInfo.message););
 
+#ifdef FIX_B_PLANK
+    InlineReject(p);
+#endif /* FIX_B_PLANK */
+
     // Let's log/alert, drop the packet, and mark it for reset.
     CallAlertFuncs(p, otn->sigInfo.message, otn->rtn->listhead, event);
-
     CallLogFuncs(p, otn->sigInfo.message, otn->rtn->listhead, event);
 
     /*
@@ -1568,7 +1571,9 @@
                "   => Alert packet finished, returning!\n"););
     */
 
+#ifndef FIX_B_PLANK
     InlineReject(p);
+#endif /* FIX_B_PLANK */
 
     return 1;
 }

[ *** Fix possible use of a NULL pointer when initializing the reject
response packet *** ]
[ *** Mark a packet as rejected for improved logging *** ]

Index: src/inline.c
===================================================================
@@ -426,15 +426,24 @@
     int size = 0;
     int payload_len = 0;
 
+#ifndef FIX_B_PLANK
     iph = (IPHdr *)l_tcp;
 
     proto = tmpP->iph->ip_proto;
     iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr;
     iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr;
+#endif /* FIX_B_PLANK */
 
     switch(proto)
     {
         case IPPROTO_TCP:
+#ifdef FIX_B_PLANK
+	    if ( l_tcp == NULL )
+	    {
+		LogMessage("Cached TCP reset packet not initialized.\n");
+	    }
+	    else
+#endif /* FIX_B_PLANK */
             if (!tmpP->frag_flag)
             {
                 size = IP_H + TCP_H;
@@ -469,6 +478,13 @@
             break;
 
         case IPPROTO_UDP:
+#ifdef FIX_B_PLANK
+	    if ( l_icmp == NULL )
+	    {
+		LogMessage("Cached ICMP unreachable packet not
initialized.\n");
+	    }
+            else
+#endif /* FIX_B_PLANK */
             if (!tmpP->frag_flag)
             {
                 iph = (IPHdr *)l_icmp;
@@ -491,6 +507,10 @@
 
                 iph->ip_len = htons(size);
                         
+#ifdef FIX_B_PLANK
+		//printf("Send UDP ICMP unreachable in IP-mode.\n");
+#endif /* FIX_B_PLANK */
+
                 /* calculate checksums */
                 if (libnet_do_checksum(l_icmp, IPPROTO_ICMP, size - IP_H)
== -1)
 	        {
@@ -806,6 +826,11 @@
     //printf("InlineReject(): rejecting\n");
     iv.reject = 1;
     iv.drop = 1;
+
+#ifdef FIX_B_PLANK
+    p->packet_flags |= PKT_INLINE_REJECT;
+#endif /* FIX_B_PLANK */
+
     tmpP = p;
     return 0;
 }

[ *** Fix bug for custom defined rule types in Snort inline mode *** ]

Index: src/parser.c
===================================================================
@@ -5705,8 +5746,20 @@
     {
         type = RuleType(toks[1]);
         /* verify it is a valid ruletype */
+#ifdef FIX_B_PLANK
+#ifdef GIDS
         if((type != RULE_LOG) && (type != RULE_PASS) && (type !=
RULE_ALERT) &&
-           (type != RULE_ACTIVATE) && (type != RULE_DYNAMIC))
+           (type != RULE_ACTIVATE) && (type != RULE_DYNAMIC) &&
+	   (type != RULE_DROP) && (type != RULE_REJECT) &&
+	   (type != RULE_SDROP))
+#else
+	if((type != RULE_LOG) && (type != RULE_PASS) && (type != RULE_ALERT)
&&
+	   (type != RULE_ACTIVATE) && (type != RULE_DYNAMIC))
+#endif /* GIDS */
+#else
+	if((type != RULE_LOG) && (type != RULE_PASS) && (type != RULE_ALERT)
&&
+	   (type != RULE_ACTIVATE) && (type != RULE_DYNAMIC))
+#endif /* FIX_B_PLANK */
         {
             FatalError("%s(%d): Invalid type for rule type declaration:
%s\n", file_name, file_line, toks[1]);
         }

[ *** Cleanly unmark packet, similar to drop case *** ]

Index: src/fpdetect.c
===================================================================
--- src/fpdetect.c	(.../cots/freebsd/services/snort/snort-2.7.0)
(revision 12154)
+++ src/fpdetect.c	(.../sdf/source/GB-OS/services/snort/snort-2.7.0)
(revision 12154)
@@ -357,6 +357,10 @@
 
     p->packet_flags &= ~PKT_INLINE_DROP;
 
+#ifdef FIX_B_PLANK
+    p->packet_flags &= ~PKT_INLINE_REJECT;
+#endif /* FIX_B_PLANK */
+
     otn_tmp = NULL;
 
     return 0;

[ *** Response packet must be initialized so a reject response will work in
FreeBSD (using IPFW) *** ]

Index: src/snort.c
===================================================================
@@ -825,6 +842,15 @@
         SnortEventqInit();
         
 #ifdef GIDS
+#ifdef FIX_B_PLANK
+        if (InlineMode())
+        {
+            if (!(pv.test_mode_flag && pv.disable_inline_init_flag))
+            {
+                InitInlinePostConfig();
+            }
+        }
+#else
 #ifndef IPFW
         if (InlineMode())
         {
@@ -834,6 +860,7 @@
             }
         }
 #endif /* IPFW */
+#endif /* FIX_B_PLANK */
 #endif /* GIDS */
     }

[ *** Feature addition for improved logging in WELF format, with inline
drop/reject info *** ]

Index: src/output-plugins/spo_alert_syslog.c
===================================================================
@@ -68,6 +68,10 @@
 
 #include "snort.h"
 
+#ifdef FEATURE_B_PLANK
+#include "generators.h"
+#endif /* FEATURE_B_PLANK */
+

@@ -503,6 +511,7 @@
  */
 extern OptTreeNode *otn_tmp;
 void AlertSyslog(Packet *p, char *msg, void *arg, Event *event)
+#ifdef FEATURE_B_PLANK
 {
     char sip[16];
     char dip[16];
@@ -515,6 +524,141 @@
 
     event_string[0] = '\0';
 
+    if ( p && p->iph ) {
+	const char *pszPktAction = NULL;
+
+	/* Log message is in WELF format */
+	/* Event message */
+        if ( msg != NULL ) {
+	    if ( SnortSnprintf(event_string,
+			       SYSLOG_BUF,
+			       "<WELF>msg=\"IPS: %s\"",
+			       msg) != SNORT_SNPRINTF_SUCCESS )
+		return;
+        } else {
+	    if ( strlcat(event_string, "ALERT", SYSLOG_BUF) >= SYSLOG_BUF )
+                return;
+        }
+
+	if ( p->packet_flags & PKT_INLINE_REJECT ) {
+	    pszPktAction = "reset";
+
+	} else if ( p->packet_flags & PKT_INLINE_DROP ) {
+	    pszPktAction = "drop";
+
+	} else if ( (p->packet_flags & PKT_PASS_RULE) ||
+		    (GENERATOR_SNORT_ENGINE == event->sig_generator) ) {
+	    pszPktAction = "pass";
+	}
+
+	/* Event action */
+	if ( pszPktAction != NULL ) {
+	    if ( SnortSnprintf(event_data,
+			       STD_BUF,
+			       " action=%s",
+			       pszPktAction) != SNORT_SNPRINTF_SUCCESS )
+		return;
+
+	    if ( strlcat(event_string, event_data, SYSLOG_BUF) >= SYSLOG_BUF
)
+		return;
+	}
+
+        if ( event != NULL ) {
+	    if ( GENERATOR_SNORT_ENGINE == event->sig_generator ) {
+		if ( SnortSnprintf(event_data,
+				   STD_BUF,
+				   " rule_id=%lu rule_rev=%lu",
+				   (unsigned long)event->sig_id,
+				   (unsigned long)event->sig_rev) !=
SNORT_SNPRINTF_SUCCESS )
+		    return;
+	    } else {
+		if ( SnortSnprintf(event_data,
+				   STD_BUF,
+				   " generator=%lu-%lu",
+				   (unsigned long)event->sig_generator,
+				   (unsigned long)event->sig_id) !=
SNORT_SNPRINTF_SUCCESS )
+		    return;
+	    }
+
+	    if ( strlcat(event_string, event_data, SYSLOG_BUF) >= SYSLOG_BUF
)
+		return;
+        }
+
+        if ( otn_tmp != NULL ) {
+            if ( otn_tmp->sigInfo.classType ) {
+                if ( otn_tmp->sigInfo.classType->name ) {
+                    if ( SnortSnprintf(pri_data,
+				       STD_BUF,
+				       " classification=\"%s\"", 
+                                       otn_tmp->sigInfo.classType->name) !=
SNORT_SNPRINTF_SUCCESS )
+                        return;
+                }
+
+                if( strlcat(event_string, pri_data, SYSLOG_BUF) >=
SYSLOG_BUF)
+                    return ;
+            }
+        }
+
+        if ( strlcpy(sip, inet_ntoa( p->iph->ip_src ), sizeof( sip )) >=
sizeof(sip) )
+            return;
+
+        if ( strlcpy(dip, inet_ntoa( p->iph->ip_dst ), sizeof( dip )) >=
sizeof(dip) )
+            return;
+
+        if ( (p->iph->ip_proto != IPPROTO_TCP &&
+              p->iph->ip_proto != IPPROTO_UDP) || p->frag_flag ) {
+            if ( SnortSnprintf(ip_data,
+			       STD_BUF,
+			       " proto=%i/ip src=%s dst=%s",
+			       p->iph->ip_proto,
+                               sip,
+			       dip) != SNORT_SNPRINTF_SUCCESS )
+		return;
+        } else {
+	    if( SnortSnprintf(ip_data,
+			      STD_BUF,
+			      " proto=%i/%s src=%s srcport=%i dst=%s
dstport=%i",
+			      p->dp,
+			      ( p->iph->ip_proto == IPPROTO_UDP ) ? "udp" :
"tcp",
+			      sip,
+			      p->sp,
+			      dip,
+			      p->dp) != SNORT_SNPRINTF_SUCCESS )
+		   return;
+        }
+
+        if ( strlcat(event_string, ip_data, SYSLOG_BUF) >= SYSLOG_BUF )
+            return;
+
+	if ( LOG_ALERT == data->priority ) {
+	    if ( strlcat(event_string, " attribute=\"alarm\"", SYSLOG_BUF)
>= SYSLOG_BUF ) {
+		return;
+	    }
+
+	    syslog( LOG_WARNING, "%s", event_string );
+	} else {
+	    syslog( data->priority, "%s", event_string );
+	}
+
+    } else {
+        syslog( data->priority, "%s", msg == NULL ? "ALERT!" : msg );
+    }
+
+    return;
+}
+#else
+{
+    char sip[16];
+    char dip[16];
+    char pri_data[STD_BUF];
+    char ip_data[STD_BUF];
+    char event_data[STD_BUF];
+#define SYSLOG_BUF  1024
+    char event_string[SYSLOG_BUF];
+    SyslogData *data = (SyslogData *)arg;
+
+    event_string[0] = '\0';
+
     if(p && p->iph)
     {
         if (strlcpy(sip, inet_ntoa(p->iph->ip_src), sizeof(sip)) >=
sizeof(sip))
@@ -635,10 +779,9 @@
     }
 
     return;
-
 }
+#endif /* FEATURE_B_PLANK */
 
-
 void AlertSyslogCleanExit(int signal, void *arg)
 {
     SyslogData *data = (SyslogData *)arg;







More information about the Snort-devel mailing list