#include "util-profiling.h"
#include "rust.h"
-#ifdef UNITTESTS
-static void DetectDnsResponseRegisterTests(void);
-#endif
-
static int detect_buffer_id = 0;
typedef struct PrefilterMpm {
int list_id;
sigmatch_table[DETECT_DNS_RESPONSE].desc = "DNS response sticky buffer";
sigmatch_table[DETECT_DNS_RESPONSE].url = "/rules/dns-keywords.html#dns-response-rrname";
sigmatch_table[DETECT_DNS_RESPONSE].Setup = DetectSetup;
-#ifdef UNITTESTS
- sigmatch_table[DETECT_DNS_RESPONSE].RegisterTests = DetectDnsResponseRegisterTests;
-#endif
sigmatch_table[DETECT_DNS_RESPONSE].flags |= SIGMATCH_NOOPT;
sigmatch_table[DETECT_DNS_RESPONSE].flags |= SIGMATCH_INFO_STICKY_BUFFER;
detect_buffer_id = DetectBufferTypeGetByName(keyword);
}
-
-#ifdef UNITTESTS
-
-#include "app-layer.h"
-#include "app-layer-parser.h"
-#include "detect-engine-alert.h"
-#include "detect-engine-build.h"
-#include "flow.h"
-#include "flow-util.h"
-#include "flow-var.h"
-#include "util-unittest.h"
-#include "util-unittest-helper.h"
-
-/** \test google.com match query name field in response */
-static int DetectDnsResponseTest01(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x10, 0x31, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* questions: 1 */
- 0x00, 0x00, /* answer_rrs: 0 */
- 0x00, 0x00, /* authority_rrs: 0 */
- 0x00, 0x00, /* additional_rr: 0 */
- /* Query */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01,
- };
- // clang-format on
-
- Flow f;
- void *dns_state = NULL;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response query name match\"; "
- "dns.response.rrname; content:\"google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
-
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- dns_state = f.alstate;
- FAIL_IF_NULL(dns_state);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/** \test google.com match answer name field in response */
-static int DetectDnsResponseTest02(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x11, 0x32, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x00, /* questions: 0 */
- 0x00, 0x01, /* answer_rrs: 1 */
- 0x00, 0x00, /* authority_rrs: 0 */
- 0x00, 0x00, /* additional_rr: 0 */
- /* Answer */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
- 0x01, 0x2c, 0x00, 0x04, 0x7f, 0x00,
- 0x00, 0x01,
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response answer name match\"; "
- "dns.response.rrname; content:\"google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/** \test google.com match authority name field in response */
-static int DetectDnsResponseTest03(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x12, 0x33, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x00, /* questions: 0 */
- 0x00, 0x00, /* answer_rrs: 0 */
- 0x00, 0x01, /* authority_rrs: 1 */
- 0x00, 0x00, /* additional_rr: 0 */
- /* Authority */
- /* name = google.com*/
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x06, /* type: SOA */
- 0x00, 0x01, /* Class: IN*/
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x37, /* Data length: 55 */
- /* primary name server: ns1.google.com */
- 0x03, 0x6e, 0x73, 0x31, 0x06, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
- 0x63, 0x6f, 0x6d, 0x00, 0x06, 0x61,
- 0x6e, 0x64, 0x72, 0x65, 0x69, 0x06,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x0b,
- 0xff, 0xb4, 0x5f, 0x00, 0x00, 0x0e,
- 0x10, 0x00, 0x00, 0x2a, 0x30, 0x00,
- 0x01, 0x51, 0x80, 0x00, 0x00, 0x0e,
- 0x10,
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response authority name match\"; "
- "dns.response.rrname; content:\"google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/** \test ns1.google.com match additional name field in response */
-static int DetectDnsResponseTest04(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x13, 0x34, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* questions: 1 */
- 0x00, 0x01, /* answer_rrs: 1 */
- 0x00, 0x00, /* authority_rrs: 0 */
- 0x00, 0x01, /* additional_rr: 1 */
- /* Query name = google.com */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01,
- /* Answer name = google.com (0xc00c pointer to query) */
- 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04,
- 0x7f, 0x00, 0x00, 0x01,
- /* Additional: name = ns1.google.com (0xc00c pointer to query) */
- 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x0c,
- 0x00 ,0x01 ,0x00, 0x01 ,0x00 ,0x00,
- 0x01, 0x2c, 0x00, 0x04, 0x7f, 0x00,
- 0x00, 0x01,
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response additional name match\"; "
- "dns.response.rrname; content:\"ns1.google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/** \test mail.google.com match answer data field in response (MX type) */
-static int DetectDnsResponseTest05(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0xb7, 0xf6, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* num query */
- 0x00, 0x01, /* num answer */
- 0x00, 0x01, /* num authority */
- 0x00, 0x01, /* num additional */
- /* Query */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, /* google.com */
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x0f, 0x00, 0x01,
- /* Answer */
- 0xc0, 0x0c, /* reference to Query name google.com bytes*/
- 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00,
- 0x01, 0x2c, 0x00, 0x09, 0x00, 0x0a,
- /* MX record: mail.google.com */
- 0x04, 0x6d, 0x61, 0x69, 0x6c,
- 0xc0, 0x0c, /* google.com reference to Query name bytes */
- /* Authority */
- 0xc0, 0x0c, 0x00, 0x06, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x23,
- 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x0c,
- 0x06, 0x61, 0x6e, 0x64, 0x72, 0x65,
- 0x69, 0xc0, 0x0c, 0x0b, 0xff, 0xb4,
- 0x5f, 0x00, 0x00, 0x0e, 0x10, 0x00,
- 0x00, 0x2a, 0x30, 0x00, 0x01, 0x51,
- 0x80, 0x00, 0x00, 0x0e, 0x10,
- /* Additional */
- 0xc0, 0x3d, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04,
- 0x7f, 0x00, 0x00, 0x01,
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response answer data match\"; "
- "dns.response.rrname; content:\"mail.google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/**
- * \test ns2.google.com match 2nd answer data field in response.
- * This verifies multiple records of one type are parsed.
- */
-static int DetectDnsResponseTest06(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x53, 0x19, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* num queries */
- 0x00, 0x02, /* num answers */
- 0x00, 0x00, /* num authority */
- 0x00, 0x00, /* num additional */
- /* Query */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, /* google.com */
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x02, /* Type: NS */
- 0x00, 0x01, /* Class: IN */
- /* Answer 1/2 */
- 0xc0, 0x0c, /* Name: google.com (pointer to query bytes) */
- 0x00, 0x02, /* Type: NS */
- 0x00, 0x01, /* Class: IN*/
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x06, /* Data length: 6 */
- /* ns1.google.com (google.com pointer to query bytes)*/
- 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x0c,
- /* Answer 2/2 */
- 0xc0, 0x0c, /* Name: google.com (pointer to query bytes) */
- 0x00, 0x02, /* Type: NS */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x06, /* Data length: 6 */
- /* ns2.google.com (google.com pointer to query bytes)*/
- 0x03, 0x6e, 0x73, 0x32, 0xc0, 0x0c,
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response 2nd answer data match\"; "
- "dns.response.rrname; content:\"ns2.google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/** \test ns1.google.com match authority data field in response (SOA) */
-static int DetectDnsResponseTest07(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x61, 0xb7, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* num queries */
- 0x00, 0x00, /* num answers */
- 0x00, 0x01, /* num authority */
- 0x00, 0x00, /* num additional */
- /* Query, name: www.google.com */
- 0x03, 0x77, 0x77, 0x77, 0x06, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
- 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
- 0x00, 0x01,
- /* Authority */
- 0xc0, 0x10, /* Name: google.com (pointer to query bytes) */
- 0x00, 0x06, /* Type: SOA */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x23, /* Data length: 35 */
- /* Primary name server: ns1.google.com */
- 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x10, /* 0xc010 pointer to query */
- 0x06, 0x61, 0x6e, 0x64, 0x72, 0x65,
- 0x69, 0xc0, 0x10, 0x0b, 0xff, 0xb4,
- 0x5f, 0x00, 0x00, 0x0e, 0x10, 0x00,
- 0x00, 0x2a, 0x30, 0x00, 0x01, 0x51,
- 0x80, 0x00, 0x00, 0x0e, 0x10,
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response authority data match\"; "
- "dns.response.rrname; content:\"ns1.google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/** \test ns2.google.com match second additional data field in response (NS) */
-static int DetectDnsResponseTest08(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x50, 0x42, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* num queries */
- 0x00, 0x01, /* num answers */
- 0x00, 0x01, /* num authority */
- 0x00, 0x02, /* num additional */
- /* Query, name: google.com */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01, /* Type: A, Class: IN */
- /* Answer */
- 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04,
- 0x7f, 0x00, 0x00, 0x01,
- /* Authority */
- 0xc0, 0x0c, 0x00, 0x06, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x23,
- /* NS: ns1.google.com */
- 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x0c,
- 0x06, 0x61, 0x6e, 0x64, 0x72, 0x65,
- 0x69, 0xc0, 0x0c, 0x0b, 0xff, 0xb4,
- 0x5f, 0x00, 0x00, 0x0e, 0x10, 0x00,
- 0x00, 0x2a, 0x30, 0x00, 0x01, 0x51,
- 0x80, 0x00, 0x00, 0x0e, 0x10,
- /* Additional 1/2 */
- 0xc0, 0x0c, /* name: google.com (pointer to query) */
- 0x00, 0x02, /* Type: NS */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x02, /* Data length: 2 */
- 0xc0, 0x38, /* Pointer to ns1.google.com in Authority */
- /* Additional 2/2 */
- 0xc0, 0x0c, /* name: google.com (pointer to query) */
- 0x00, 0x02, /* Type: NS */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x06, /* Data length: 6 */
- /* ns2.google.com (google.com pointer to query) */
- 0x03, 0x6e, 0x73, 0x32, 0xc0, 0x0c,
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response additional data match\"; "
- "dns.response.rrname; content:\"ns2.google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/** \test google.com match query name field in response (TCP) */
-static int DetectDnsResponseTest09(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x00, 28, /* tcp len */
- 0x10, 0x31, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* questions: 1 */
- 0x00, 0x00, /* answer_rrs: 0 */
- 0x00, 0x00, /* authority_rrs: 0 */
- 0x00, 0x00, /* additional_rr: 0 */
- /* Query */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01,
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_TCP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
- p->flowflags |= FLOW_PKT_TOCLIENT | FLOW_PKT_ESTABLISHED;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response query name match tcp\"; "
- "dns.response.rrname; content:\"google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
-
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-/** \test multi tx (mail,ns2).google.com response matching */
-static int DetectDnsResponseTest10(void)
-{
- // clang-format off
- /* Query 1/2 */
- uint8_t buf1[] = {
- 0xa1, 0xc4, 0x01, 0x20, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, /* google.com */
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x0f, 0x00, 0x01, /* Type: MX, Class: IN */
- };
- /* Response 1/2 */
- uint8_t buf2[] = {
- 0xa1, 0xc4, 0x85, 0x80, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- /* Query */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x0f, 0x00, 0x01,
- /* Answer data: mail.google.com */
- 0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x09,
- 0x00, 0x0a, 0x04, 0x6d, 0x61, 0x69,
- 0x6c, 0xc0, 0x0c, 0xc0, 0x0c,
- };
- /* Query 2/2 */
- uint8_t buf3[] = {
- 0xc1, 0xc5, 0x01, 0x20, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, /* google.com */
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01, /* Type: A, Class: IN */
- };
- /* Response 2/2 */
- uint8_t buf4[] = {
- 0xc1, 0xc5, 0x85, 0x80, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x02,
- /* Query */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, /* google.com */
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01,
- /* Answer */
- 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04,
- 0x7f, 0x00, 0x00, 0x01,
- /* Authority */
- 0xc0, 0x0c, 0x00, 0x06, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x23,
- 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x0c, /* ns1.google.com */
- 0x06, 0x61, 0x6e, 0x64, 0x72, 0x65,
- 0x69, 0xc0, 0x0c, 0x0b, 0xff, 0xb4,
- 0x5f, 0x00, 0x00, 0x0e, 0x10, 0x00,
- 0x00, 0x2a, 0x30, 0x00, 0x01, 0x51,
- 0x80, 0x00, 0x00, 0x0e, 0x10,
- /* Additional 1/2 */
- 0xc0, 0x0c, 0x00, 0x02, 0x00,
- 0x01, 0x00, 0x00, 0x01, 0x2c, 0x00,
- 0x02, 0xc0, 0x38, /* ns1.google.com */
- /* Additional 2/2 */
- 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x06,
- 0x03, 0x6e, 0x73, 0x32, 0xc0, 0x0c, /* ns2.google.com */
- };
- // clang-format on
-
- Flow f;
- Packet *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- /* Query 1/2 to server */
- p1 = UTHBuildPacketReal(
- buf1, sizeof(buf1), IPPROTO_UDP, "192.168.1.5", "192.168.1.1", 41424, 53);
- /* Response 1/2 to client */
- p2 = UTHBuildPacketReal(
- buf2, sizeof(buf2), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
- /* Query 2/2 to server */
- p3 = UTHBuildPacketReal(
- buf3, sizeof(buf3), IPPROTO_UDP, "192.168.1.5", "192.168.1.1", 41424, 53);
- /* Response 2/2 to client */
- p4 = UTHBuildPacketReal(
- buf4, sizeof(buf4), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
- f.alproto = ALPROTO_DNS;
-
- p1->flow = &f;
- p1->flags |= PKT_HAS_FLOW;
- p1->flowflags |= FLOW_PKT_TOSERVER;
- p1->pcap_cnt = 1;
-
- p2->flow = &f;
- p2->flags |= PKT_HAS_FLOW;
- p2->flowflags |= FLOW_PKT_TOCLIENT;
- p2->pcap_cnt = 1;
-
- p3->flow = &f;
- p3->flags |= PKT_HAS_FLOW;
- p3->flowflags |= FLOW_PKT_TOSERVER;
- p3->pcap_cnt = 1;
-
- p4->flow = &f;
- p4->flags |= PKT_HAS_FLOW;
- p4->flowflags |= FLOW_PKT_TOCLIENT;
- p4->pcap_cnt = 1;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response multi tx answer match\"; "
- "dns.response.rrname; content:\"mail.google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response multi tx additional match\"; "
- "dns.response.rrname; content:\"ns2.google.com\"; nocase; sid:2;)");
- FAIL_IF_NULL(s);
- s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
- "(msg:\"Test dns response multi tx additional match\"; "
- "dns.query; content:\"google.com\"; nocase; sid:3;)");
- FAIL_IF_NULL(s);
-
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(
- NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf1, sizeof(buf1));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
-
- /* should not match */
- FAIL_IF(PacketAlertCheck(p1, 1));
- /* should not match */
- FAIL_IF(PacketAlertCheck(p1, 2));
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p1, 3));
-
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf2, sizeof(buf2));
- FAIL_IF_NOT(r == 0);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p2, 1));
- /* should not match */
- FAIL_IF(PacketAlertCheck(p2, 2));
- /* should not match */
- FAIL_IF(PacketAlertCheck(p2, 3));
-
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf3, sizeof(buf3));
- FAIL_IF_NOT(r == 0);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
-
- /* should not match */
- FAIL_IF(PacketAlertCheck(p3, 1));
- /* should not match */
- FAIL_IF(PacketAlertCheck(p3, 2));
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p3, 3));
-
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf4, sizeof(buf4));
- FAIL_IF_NOT(r == 0);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p4);
-
- /* should not match */
- FAIL_IF(PacketAlertCheck(p4, 1));
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p4, 2));
- /* should not match */
- FAIL_IF(PacketAlertCheck(p4, 3));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p1);
- UTHFreePacket(p2);
- UTHFreePacket(p3);
- UTHFreePacket(p4);
-
- PASS;
-}
-
-/** \test google.com and ns2.google.com response matching, pcre */
-static int DetectDnsResponseTest11(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x50, 0x42, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* num queries */
- 0x00, 0x01, /* num answers */
- 0x00, 0x01, /* num authority */
- 0x00, 0x02, /* num additional */
- /* Query, name: google.com */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01, /* Type: A, Class: IN */
- /* Answer */
- 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04,
- 0x7f, 0x00, 0x00, 0x01,
- /* Authority */
- 0xc0, 0x0c, 0x00, 0x06, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x23,
- /* NS: ns1.google.com */
- 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x0c,
- 0x06, 0x61, 0x6e, 0x64, 0x72, 0x65,
- 0x69, 0xc0, 0x0c, 0x0b, 0xff, 0xb4,
- 0x5f, 0x00, 0x00, 0x0e, 0x10, 0x00,
- 0x00, 0x2a, 0x30, 0x00, 0x01, 0x51,
- 0x80, 0x00, 0x00, 0x0e, 0x10,
- /* Additional 1/2 */
- 0xc0, 0x0c, /* name: google.com (pointer to query) */
- 0x00, 0x02, /* Type: NS */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x02, /* Data length: 2 */
- 0xc0, 0x38, /* Pointer to ns1.google.com in Authority */
- /* Additional 2/2 */
- 0xc0, 0x0c, /* name: google.com (pointer to query) */
- 0x00, 0x02, /* Type: NS */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x06, /* Data length: 6 */
- /* ns2.google.com (google.com pointer to query) */
- 0x03, 0x6e, 0x73, 0x32, 0xc0, 0x0c,
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
- "(msg:\"Test dns response pcre match\"; "
- "dns.response.rrname; content:\"google\"; nocase; "
- "pcre:\"/ns2\\.google\\.com$/i\"; sid:1;)");
- FAIL_IF_NULL(s);
- s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
- "(msg:\"Test dns response pcre match\"; "
- "dns.response.rrname; content:\"google\"; nocase; "
- "pcre:\"/^\\.[a-z]{2,3}$/iR\"; sid:2;)");
- FAIL_IF_NULL(s);
-
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 2));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/**
- * \test ns2.google.com response matching 2nd additional section
- * with type: A records
- */
-static int DetectDnsResponseTest12(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x7a, 0x11, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* num queries */
- 0x00, 0x01, /* num answers */
- 0x00, 0x01, /* num authority */
- 0x00, 0x02, /* num additional */
- /* Query, name: google.com */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01, /* Type: A, Class: IN */
- /* Answer */
- 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04,
- 0x7f, 0x00, 0x00, 0x01,
- /* Authority */
- 0xc0, 0x0c, 0x00, 0x06, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x23,
- /* NS: ns1.google.com */
- 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x0c,
- 0x06, 0x61, 0x6e, 0x64, 0x72, 0x65,
- 0x69, 0xc0, 0x0c, 0x0b, 0xff, 0xb4,
- 0x5f, 0x00, 0x00, 0x0e, 0x10, 0x00,
- 0x00, 0x2a, 0x30, 0x00, 0x01, 0x51,
- 0x80, 0x00, 0x00, 0x0e, 0x10,
- /* Additional 1/2 */
- 0xc0, 0x38, /* name: ns1.google.com (pointer to authority) */
- 0x00, 0x01, /* Type: A */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x04, /* Data length: 4 */
- 0x7f, 0x00, 0x00, 0x01, /* 127.0.0.1 */
- /* Additional 2/2 */
- /* name: ns2.google.com (ns2 + pointer to query) */
- 0x03, 0x6e, 0x73, 0x32, 0xc0, 0x0c,
- 0x00, 0x01, /* Type: A */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x04, /* Data length: 4 */
- 0x7f, 0x00, 0x00, 0x01, /* 127.0.0.1 */
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response additional name match\"; "
- "dns.response.rrname; content:\"ns2.google.com\"; nocase; sid:1;)");
- FAIL_IF_NULL(s);
-
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-/**
- * \test Verify transform applies to dns.response.rrname sticky buffer.
- * Test using "to_uppercase". ns2.google.com response matching
- * 2nd additional section name field.
- */
-static int DetectDnsResponseTest13(void)
-{
- // clang-format off
- uint8_t buf[] = {
- 0x7a, 0x11, /* ID */
- 0x85, 0x80, /* Flags */
- 0x00, 0x01, /* num queries */
- 0x00, 0x01, /* num answers */
- 0x00, 0x01, /* num authority */
- 0x00, 0x02, /* num additional */
- /* Query, name: google.com */
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
- 0x00, 0x01, 0x00, 0x01, /* Type: A, Class: IN */
- /* Answer */
- 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04,
- 0x7f, 0x00, 0x00, 0x01,
- /* Authority */
- 0xc0, 0x0c, 0x00, 0x06, 0x00, 0x01,
- 0x00, 0x00, 0x01, 0x2c, 0x00, 0x23,
- /* NS: ns1.google.com */
- 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x0c,
- 0x06, 0x61, 0x6e, 0x64, 0x72, 0x65,
- 0x69, 0xc0, 0x0c, 0x0b, 0xff, 0xb4,
- 0x5f, 0x00, 0x00, 0x0e, 0x10, 0x00,
- 0x00, 0x2a, 0x30, 0x00, 0x01, 0x51,
- 0x80, 0x00, 0x00, 0x0e, 0x10,
- /* Additional 1/2 */
- 0xc0, 0x38, /* name: ns1.google.com (pointer to authority) */
- 0x00, 0x01, /* Type: A */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x04, /* Data length: 4 */
- 0x7f, 0x00, 0x00, 0x01, /* 127.0.0.1 */
- /* Additional 2/2 */
- /* name: ns2.google.com (ns2 + pointer to query) */
- 0x03, 0x6e, 0x73, 0x32, 0xc0, 0x0c,
- 0x00, 0x01, /* Type: A */
- 0x00, 0x01, /* Class: IN */
- 0x00, 0x00, 0x01, 0x2c, /* TTL: 300 */
- 0x00, 0x04, /* Data length: 4 */
- 0x7f, 0x00, 0x00, 0x01, /* 127.0.0.1 */
- };
- // clang-format on
-
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- ThreadVars tv;
- DetectEngineThreadCtx *det_ctx = NULL;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
-
- p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.1", "192.168.1.5", 53, 41424);
-
- FLOW_INITIALIZE(&f);
- f.flags |= FLOW_IPV4;
- f.proto = IPPROTO_UDP;
- f.protomap = FlowGetProtoMapping(f.proto);
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW;
- p->flowflags |= FLOW_PKT_TOCLIENT;
- f.alproto = ALPROTO_DNS;
-
- DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = mpm_default_matcher;
- de_ctx->flags |= DE_QUIET;
-
- /* content with upper case chars after "to_uppercase" transform should match */
- s = DetectEngineAppendSig(de_ctx,
- "alert dns any any -> any any "
- "(msg:\"Test dns response additional name match with transform\"; "
- "dns.response.rrname; to_uppercase; content:\"NS2.GOOGLE.COM\"; sid:1;)");
- FAIL_IF_NULL(s);
-
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf, sizeof(buf));
- FAIL_IF_NOT(r == 0);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- /* should match */
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- if (det_ctx != NULL) {
- StatsThreadCleanup(&tv);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- }
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
-
- PASS;
-}
-
-static void DetectDnsResponseRegisterTests(void)
-{
- UtRegisterTest("DetectDnsResponseTest01", DetectDnsResponseTest01);
- UtRegisterTest("DetectDnsResponseTest02", DetectDnsResponseTest02);
- UtRegisterTest("DetectDnsResponseTest03", DetectDnsResponseTest03);
- UtRegisterTest("DetectDnsResponseTest04", DetectDnsResponseTest04);
- UtRegisterTest("DetectDnsResponseTest05", DetectDnsResponseTest05);
- UtRegisterTest("DetectDnsResponseTest06", DetectDnsResponseTest06);
- UtRegisterTest("DetectDnsResponseTest07", DetectDnsResponseTest07);
- UtRegisterTest("DetectDnsResponseTest08", DetectDnsResponseTest08);
- UtRegisterTest("DetectDnsResponseTest09", DetectDnsResponseTest09);
- UtRegisterTest("DetectDnsResponseTest10", DetectDnsResponseTest10);
- UtRegisterTest("DetectDnsResponseTest11", DetectDnsResponseTest11);
- UtRegisterTest("DetectDnsResponseTest12", DetectDnsResponseTest12);
- UtRegisterTest("DetectDnsResponseTest13", DetectDnsResponseTest13);
-}
-
-#endif