No subject


Thu Nov 23 16:31:58 EST 2017


An RE like, say, `((((a{1,100}){1,100}){1,100}){1,100}){1,100}' will
(eventually)
run almost any  existing machine out of swap space.
 A basic but fast regex is better than a "full regex". It's faster! :)
If you can write a rule avoiding to use "full RE", you are welcome to
use "basic RE".
Of course, if a match can be checked without using any RE, you are
supposed to
*stay away* from RE, both basic and full.

 My point of view is that when I use snort in a net where there are some
Domino server,
snort fires an alert at every ".nsf" request, so I see snort logs
pointing to
almost any served page. (Domino yelds ".nsf" files like Apache yelds
".html")
A pattern like ".nsf/[^[:alpha:]]" would make the job. Removing the rule
not.
For people who do need fast performances, I suggest to make a main
config variable,
like a "full-regex yes/no" in snort.conf, so high speed will not be
affected by "full RE".

Bye
Giovanni



--------------E5573B2390DD2645F4595CE5
Content-Type: text/plain; charset=us-ascii;
 name="snort17-fullregex.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="snort17-fullregex.patch"

diff -ruN snort.orig/Makefile snort/Makefile
--- snort.orig/Makefile	Wed May  9 19:42:42 2001
+++ snort/Makefile	Wed May  9 23:16:45 2001
@@ -62,7 +62,7 @@
 host_alias = i686-pc-linux-gnu
 host_triplet = i686-pc-linux-gnu
 CC = gcc
-MAKEINFO = /home/giovanni/snort-1.7-orig/missing makeinfo
+MAKEINFO = /home/giovanni/snort-1.7/missing makeinfo
 PACKAGE = snort
 VERSION = 1.7
 extra_incl = -I/usr/include/pcap
@@ -86,8 +86,8 @@
 
 DEFS = -DHAVE_CONFIG_H -I. -I$(srcdir) -I.
 CPPFLAGS =  -I/usr/include -DENABLE_ODBC -I/usr/local/pgsql/include -DENABLE_POSTGRESQL
-LDFLAGS =  -L/usr/lib -L/usr/local/pgsql/lib
-LIBS = -lpcap -lm -lnsl  -lodbc -lpq
+LDFLAGS =  -L/usr/lib -L/usr/local/pgsql/lib -L./regex
+LIBS = -lpcap -lm -lnsl  -lodbc -lpq -lregex
 snort_OBJECTS =  snort.o log.o decode.o mstring.o rules.o plugbase.o \
 sp_pattern_match.o sp_tcp_flag_check.o sp_icmp_type_check.o \
 sp_icmp_code_check.o sp_ttl_check.o sp_ip_id_check.o sp_tcp_ack_check.o \
diff -ruN snort.orig/mstring.c snort/mstring.c
--- snort.orig/mstring.c	Tue Jan  2 09:06:00 2001
+++ snort/mstring.c	Wed May  9 19:22:47 2001
@@ -458,7 +458,7 @@
  *      failure (substr not in str)
  *
  ****************************************************************/
-int mSearch(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift)
+int mSearch(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift, PatternMatchData *idx)
 {
     int b_idx = plen;
 
@@ -523,7 +523,7 @@
  *      failure (substr not in str)
  *
  ****************************************************************/
-int mSearchCI(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift)
+int mSearchCI(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift, PatternMatchData *idx)
 {
     int b_idx = plen;
 
@@ -587,7 +587,7 @@
  *      failure (substr not in str)
  *
  ****************************************************************/
-int mSearchREG(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift)
+int mSearchREG(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift, PatternMatchData *idx)
 {
     int b_idx = plen;
     int literal = 0;
@@ -642,7 +642,7 @@
                      */
                     if(ret == (mSearchREG(&buf[b_idx--], b_idx,
                                           &ptrn[p_idx], p_idx,
-                                          skip, &shift[p_idx])) != 0)
+                                          skip, &shift[p_idx],NULL)) != 0)
                     {
                         printf("recurs: %i\n", ret);
                         return ret;
@@ -672,3 +672,68 @@
 
     return 0;
 }
+
+
+/****************************************************************
+ *
+ *  Function: mSearchFRE(char *, int, char *, int)
+ *
+ *  Purpose: Determines if a string contains a (full-regex)
+ *           substring matching is case sensitive
+ *
+ *  Parameters:
+ *      buf => data buffer we want to find the data in
+ *      blen => data buffer length
+ *      ptrn => pattern to find. Unused. It's been already compiled in regex function.
+ *      plen => length of the data in the pattern buffer. As for ptrn, we don't use it here.
+ *      skip => the B-M skip array. Unused
+ *      shift => the B-M shift array. Unused
+ *
+ *  Returns:
+ *      Integer value, 1 on success (str constains substr), 0 on
+ *      failure (substr not in str)
+ *
+ ****************************************************************/
+int mSearchFRE(char *buf, int blen, char *ptrn, int plen, int *skip, int *shift, PatternMatchData *idx)
+{
+    /*  We are in Full-REGEX mode.
+     *  We don't need to make a pattern check here,
+     *  regex will do the jab.
+     */
+
+    int err;
+    char tmpc;
+
+    if(plen == 0)
+        return 1;
+
+#define DEBUG
+
+    tmpc = buf[blen-2];
+    buf[blen-2]=0; /* before leaving, we'll fix it */
+#ifdef	DEBUG
+        fprintf(stdout, "Full-REGEX: buf='%s',buflen=%d, Expr='%s'.\n", buf,blen,ptrn);
+#endif
+
+
+    /* TODO: use REG_STARTEND , handle case insensitive */
+    err = regexec(idx->re, buf, 0, NULL, 0);
+    tmpc = buf[blen-2];
+    if (err) {
+#ifdef	DEBUG
+        fprintf(stdout, "No match.\n");
+#endif
+        return 0;
+    }
+    else {
+#ifdef	DEBUG
+        fprintf(stdout, "Match:.\n");
+        return 1;
+#endif
+    }
+
+
+
+    return 0;
+}
+
diff -ruN snort.orig/mstring.h snort/mstring.h
--- snort.orig/mstring.h	Tue Jan  2 09:06:00 2001
+++ snort/mstring.h	Wed May  9 19:26:03 2001
@@ -26,6 +26,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include "regex/regex.h"
+#include "sp_pattern_match.h"
 
 
 
@@ -33,9 +35,10 @@
 /*  P R O T O T Y P E S  *************************************************/
 char **mSplit(char *, char *, int, int *, char);
 int mContainsSubstr(char *, int, char *, int);
-int mSearch(char *, int, char *, int, int *, int *);
-int mSearchCI(char *, int, char *, int, int *, int *);
-int mSearchREG(char *, int, char *, int, int *, int *);
+int mSearch   (char *, int, char *, int, int *, int *, PatternMatchData *);
+int mSearchCI (char *, int, char *, int, int *, int *, PatternMatchData *);
+int mSearchREG(char *, int, char *, int, int *, int *, PatternMatchData *);
+int mSearchFRE(char *, int, char *, int, int *, int *, PatternMatchData *);
 int *make_skip(char *, int);
 int *make_shift(char *, int);
 
diff -ruN snort.orig/sp_pattern_match.c snort/sp_pattern_match.c
--- snort.orig/sp_pattern_match.c	Tue Jan  2 09:06:01 2001
+++ snort/sp_pattern_match.c	Wed May  9 19:31:40 2001
@@ -32,6 +32,7 @@
     RegisterPlugin("depth", PayloadSearchDepth);
     RegisterPlugin("nocase", PayloadSearchNocase);
     RegisterPlugin("regex", PayloadSearchRegex);
+    RegisterPlugin("full-regex", PayloadSearchFullRegex);
 
 #ifdef DEBUG
     printf("Plugin: PatternMatch Initialized!\n");
@@ -192,6 +193,68 @@
     return;
 }
 
+#define DEBUG_FULL_REGEX
+static char *eprint(int err)
+{
+	static char epbuf[100];
+	size_t len;
+
+	len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
+	assert(len <= sizeof(epbuf));
+	return(epbuf);
+}
+
+void PayloadSearchFullRegex(char *data, OptTreeNode * otn, int protocol)
+{
+    PatternMatchData *idx;
+    int i,err=0;
+    char erbuf[100];
+    const int copts = REG_EXTENDED+REG_NOSUB;
+    idx = (PatternMatchData *) otn->ds_list[PLUGIN_PATTERN_MATCH];
+
+#ifdef DEBUG_FULL_REGEX
+   printf("Here we are in PayloadSearchFullRegex with data='%s'\n",idx->pattern_buf);
+#endif
+
+
+    if(idx == NULL)
+    {
+        FatalError("ERROR Line %d => Please place \"content\" rules before full-regex modifier.\n", file_line);
+    }
+    while(idx->next != NULL)
+        idx = idx->next;
+
+    idx->search = mSearchFRE;
+
+    idx->re = (regex_t*) malloc(sizeof(regex_t));
+#ifdef DEBUG_FULL_REGEX
+   printf("Allocated bytes %d for regex, idx = %d\t now compiling ...\t",sizeof(regex_t),(int)idx);
+   fflush(stdout);
+#endif
+    if ((err=regcomp(idx->re, idx->pattern_buf , copts))) {
+        FatalError("ERROR Line %d: regular expressions compile error.\n", file_line);
+        fprintf(stderr, "error %s, %d/%d `%s'\n",eprint(err),
+                regerror(err, idx->re, erbuf, sizeof(erbuf)), sizeof(erbuf), erbuf);
+        exit(1);
+    }
+#ifdef DEBUG_FULL_REGEX
+   printf("done.\n");
+   fflush(stdout);
+#endif
+
+    i = idx->pattern_size;
+
+    /* TODO: What does the following lines do ? Can we remove'em ?
+       These actually comes from a cut and paste.
+    */
+    free(idx->skip_stride);
+    idx->skip_stride = make_skip(idx->pattern_buf, idx->pattern_size);
+
+    free(idx->shift_stride);
+    idx->shift_stride = make_shift(idx->pattern_buf, idx->pattern_size);
+
+    return;
+}
 
 
 void PayloadSearchRegex(char *data, OptTreeNode * otn, int protocol)
@@ -544,7 +607,7 @@
                     printf("testing pattern: %s\n", idx->pattern_buf);
 #endif
                     found = idx->search((char *)(p->data + idx->offset), sub_depth, idx->pattern_buf,
-                                        idx->pattern_size, idx->skip_stride, idx->shift_stride);
+                                        idx->pattern_size, idx->skip_stride, idx->shift_stride,idx);
 
                     if(!found)
                     {
@@ -562,13 +625,13 @@
                 if(idx->depth && (p->dsize-idx->offset> idx->depth))
                 {
                     found = idx->search((char *)(p->data + idx->offset), idx->depth, idx->pattern_buf,
-                                        idx->pattern_size, idx->skip_stride, idx->shift_stride);
+                                        idx->pattern_size, idx->skip_stride, idx->shift_stride, idx);
                 }
                 else
                 {
                     found = idx->search((char *)(p->data + idx->offset), p->dsize - idx->offset ,
                                         idx->pattern_buf, idx->pattern_size, idx->skip_stride,
-                                        idx->shift_stride);
+                                        idx->shift_stride, idx);
                 }
 
                 if(!found)
@@ -652,7 +715,7 @@
                     printf("testing pattern: %s\n", idx->pattern_buf);
 #endif
                     found = idx->search((char *)(p->data+idx->offset), sub_depth,idx->pattern_buf,
-                                        idx->pattern_size, idx->skip_stride, idx->shift_stride);
+                                        idx->pattern_size, idx->skip_stride, idx->shift_stride, idx);
 
                     if(!found)
                     {
@@ -672,13 +735,13 @@
                 if(idx->depth && (p->dsize-idx->offset> idx->depth))
                 {
                     found = idx->search((char *)(p->data+idx->offset), idx->depth, idx->pattern_buf,
-                                        idx->pattern_size, idx->skip_stride, idx->shift_stride);
+                                        idx->pattern_size, idx->skip_stride, idx->shift_stride, idx);
                 }
                 else
                 {
                     found = idx->search((char *)(p->data+idx->offset), p->dsize - idx->offset,
                                         idx->pattern_buf, idx->pattern_size, idx->skip_stride,
-                                        idx->shift_stride);
+                                        idx->shift_stride, idx);
                 }
 
                 if(!found)
diff -ruN snort.orig/sp_pattern_match.h snort/sp_pattern_match.h
--- snort.orig/sp_pattern_match.h	Tue Jan  2 09:06:01 2001
+++ snort/sp_pattern_match.h	Wed May  9 19:36:27 2001
@@ -21,8 +21,12 @@
 #define __SP_PATTERN_MATCH_H__
 
 
-#include "snort.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
 #include <ctype.h>
+#include <assert.h>
+#include "regex/regex.h"
 
 #define PLUGIN_PATTERN_MATCH   1
 
@@ -32,13 +36,16 @@
     int depth;              /* pattern search depth */
     u_int pattern_size;     /* size of app layer pattern */
     char *pattern_buf;      /* app layer pattern to match on */
-    int (*search)(char *, int, char *, int, int *, int *);  /* search function */
+    int (*search)(char *, int, char *, int, int *, int *, struct _PatternMatchData *);  /* search function */
     int *skip_stride; /* B-M skip array */
     int *shift_stride; /* B-M shift array */
+    regex_t *re;        /* regex structure */
     struct _PatternMatchData *next; /* ptr to next match struct */
 
 } PatternMatchData;
 
+#include "snort.h" /* now snort.h needs _PatternMatchData struct */
+
 void PayloadSearchInit(char *, OptTreeNode *, int);
 void PayloadSearchListInit(char *, OptTreeNode *, int);
 void ParseContentListFile(char *, OptTreeNode *, int);
@@ -50,6 +57,7 @@
 void PayloadSearchDepth(char *, OptTreeNode *, int);
 void PayloadSearchNocase(char *, OptTreeNode *, int);
 void PayloadSearchRegex(char *, OptTreeNode *, int);
+void PayloadSearchFullRegex(char *, OptTreeNode *, int);
 void NewNode(OptTreeNode *);
 
 

--------------E5573B2390DD2645F4595CE5--





More information about the Snort-devel mailing list