[PATCH] snort hex strings and libipt_string.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The attached patch adds an option "--hex-string" to the string match
module to allow snort-style hex strings to be specified on the
command line.  This is useful because there are many signatures that
consist of non-printable characters and without this patch there is
no way to easily tell iptables to search for them.

E.x:

iptables -I INPUT 1 -p udp --dport 53 -m string --hex-string
"31 c0 b0 02 cd 80 85 c0 75 4c eb 4c 5e b0" -j LOG --log-prefix
"DNS EXPLOIT x86 linux overflow attempt "

(This is my first patch to iptables so let me know if I need to do
anything differently).

Thanks,

--Mike

Michael Rash
http://www.cipherdyne.com
Key fingerprint = 4EE3 816C 413A 41AA 72C8  4463 70C3 783C 1B91 F85E
--- iptables-1.2.7a/extensions/libipt_string.c.old	Wed May 29 09:08:16 2002
+++ iptables-1.2.7a/extensions/libipt_string.c		Sun Feb 16 22:52:16 2003
@@ -31,6 +31,7 @@
 
 static struct option opts[] = {
 	{ "string", 1, 0, '1' },
+	{ "hex-string", 1, 0, '2' },
 	{0}
 };
 
@@ -48,6 +49,31 @@
 	else exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
 }
 
+static void
+parse_hex_string(const unsigned char *s, struct ipt_string_info *info)
+{
+    int slen, schar, sindex=0, i;
+    char hextmp[3];
+    slen = strlen(s);
+    if(slen <= 3*(BM_MAX_NLEN)) { /* hex input like "71 61 7a" */
+        for (i=0; i<slen; i+=3) {
+            hextmp[0] = s[i];
+            hextmp[1] = s[i+1];
+            if (s[i+2] == ' ' || s[i+2] == '\0') {
+                hextmp[2] = '\0';
+                if (! sscanf(hextmp, "%x", &schar))
+                    exit_error(PARAMETER_PROBLEM, "Invalid hex char `%c'", s[i]);
+                info->string[sindex] = (char) schar;
+                sindex++;
+            } else {
+                exit_error(PARAMETER_PROBLEM, "Enter hex chars separated by spaces");
+            }
+        }
+    } else {
+        exit_error(PARAMETER_PROBLEM, "HEX STRING too long `%s'", s);
+    }
+}
+
 /* Function which parses command options; returns true if it
    ate an option */
 static int
@@ -67,7 +93,14 @@
                 stringinfo->len=strlen((char *)&stringinfo->string);
 		*flags = 1;
 		break;
-
+    case '2':
+        check_inverse(optarg, &invert, &optind, 0);
+        parse_hex_string(argv[optind-1], stringinfo);
+        if (invert)
+            stringinfo->invert = 1;
+        stringinfo->len=strlen((char *)&stringinfo->string);
+        *flags = 1;
+        break;
 	default:
 		return 0;
 	}

[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux