]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dns: improve response name parsing 943/head
authorVictor Julien <victor@inliniac.net>
Fri, 18 Apr 2014 18:25:22 +0000 (20:25 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 18 Apr 2014 19:07:00 +0000 (21:07 +0200)
Improve parsing of names with multiple pointers following each other.

src/app-layer-dns-common.c
src/app-layer-dns-udp.c

index c1555b54b6308cd321403ad903cb5fbbe24338b9..0814634b08b83b102f5d01a6a7f6a3177cfe3153 100644 (file)
@@ -587,7 +587,8 @@ static uint16_t DNSResponseGetNameByOffset(const uint8_t * const input, const ui
     }
 
     while (length != 0) {
-        if (length & 0xc0) {
+        int cnt = 0;
+        while (length & 0xc0) {
             uint16_t offset = ((length & 0x3f) << 8) + *(qdata+1);
             qdata = (const uint8_t *)input + offset;
 
@@ -598,6 +599,11 @@ static uint16_t DNSResponseGetNameByOffset(const uint8_t * const input, const ui
 
             length = *qdata;
             SCLogDebug("qry length %u", length);
+
+            if (cnt++ == 100) {
+                SCLogDebug("too many pointer iterations, loop?");
+                goto bad_data;
+            }
         }
         qdata++;
 
index 1d293c32b91d02b6f9c3dc0e580922cab547dd73..a56cfa37c2731feb74cb47d8a9f684e70ba1b1e4 100644 (file)
@@ -459,7 +459,77 @@ end:
     return (result);
 }
 
+static int DNSUDPParserTest02 (void) {
+    int result = 0;
+    uint8_t buf[] = {
+        0x6D,0x08,0x84,0x80,0x00,0x01,0x00,0x08,0x00,0x00,0x00,0x01,0x03,0x57,0x57,0x57,
+        0x04,0x54,0x54,0x54,0x54,0x03,0x56,0x56,0x56,0x03,0x63,0x6F,0x6D,0x02,0x79,0x79,
+        0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,
+        0x02,0xC0,0x0C,0xC0,0x31,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,
+        0x31,0xC0,0x3F,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x3F,0xC0,
+        0x4D,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x4D,0xC0,0x5B,0x00,
+        0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x5B,0xC0,0x69,0x00,0x05,0x00,
+        0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x69,0xC0,0x77,0x00,0x05,0x00,0x01,0x00,
+        0x00,0x0E,0x10,0x00,0x02,0xC0,0x77,0xC0,0x85,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,
+        0x10,0x00,0x02,0xC0,0x85,0x00,0x00,0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    };
+    size_t buflen = sizeof(buf);
+    Flow *f = NULL;
+
+    f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53);
+    if (f == NULL)
+        goto end;
+    f->proto = IPPROTO_UDP;
+    f->alproto = ALPROTO_DNS;
+    f->alstate = DNSStateAlloc();
+
+    int r = DNSUDPResponseParse(f, f->alstate, NULL, buf, buflen, NULL);
+    if (r != 1)
+        goto end;
+
+    result = 1;
+end:
+    UTHFreeFlow(f);
+    return (result);
+}
+
+static int DNSUDPParserTest03 (void) {
+    int result = 0;
+    uint8_t buf[] = {
+        0x6F,0xB4,0x84,0x80,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x03,0x57,0x57,0x77,
+        0x0B,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x03,0x55,0x55,0x55,
+        0x02,0x79,0x79,0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00,
+        0x0E,0x10,0x00,0x02,0xC0,0x10,0xC0,0x34,0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,
+        0x00,0x04,0xC3,0xEA,0x04,0x19,0xC0,0x34,0x00,0x02,0x00,0x01,0x00,0x00,0x0E,0x10,
+        0x00,0x0A,0x03,0x6E,0x73,0x31,0x03,0x61,0x67,0x62,0xC0,0x20,0xC0,0x46,0x00,0x02,
+        0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x06,0x03,0x6E,0x73,0x32,0xC0,0x56,0xC0,0x52,
+        0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x04,0x0A,0xC0,0x68,
+        0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x05,0x14,0x00,0x00,
+        0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+    };
+    size_t buflen = sizeof(buf);
+    Flow *f = NULL;
+
+    f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53);
+    if (f == NULL)
+        goto end;
+    f->proto = IPPROTO_UDP;
+    f->alproto = ALPROTO_DNS;
+    f->alstate = DNSStateAlloc();
+
+    int r = DNSUDPResponseParse(f, f->alstate, NULL, buf, buflen, NULL);
+    if (r != 1)
+        goto end;
+
+    result = 1;
+end:
+    UTHFreeFlow(f);
+    return (result);
+}
+
 void DNSUDPParserRegisterTests(void) {
        UtRegisterTest("DNSUDPParserTest01", DNSUDPParserTest01, 1);
+       UtRegisterTest("DNSUDPParserTest02", DNSUDPParserTest02, 1);
+       UtRegisterTest("DNSUDPParserTest03", DNSUDPParserTest03, 1);
 }
 #endif