]> git.ipfire.org Git - thirdparty/suricata-verify.git/commitdiff
tests/dns: add tests for task 7018 1976/head
authorJuliana Fajardini <jufajardini@oisf.net>
Thu, 23 May 2024 16:47:15 +0000 (13:47 -0300)
committerVictor Julien <victor@inliniac.net>
Thu, 11 Jul 2024 16:12:39 +0000 (18:12 +0200)
Also related to
Bug #7004

13 files changed:
tests/dns/task-7018-dns-ips-stream-rule/README.md [new file with mode: 0644]
tests/dns/task-7018-dns-ips-stream-rule/test.rules [new file with mode: 0644]
tests/dns/task-7018-dns-ips-stream-rule/test.yaml [new file with mode: 0644]
tests/dns/task-7018-ids-dns-keywords/README.md [new file with mode: 0644]
tests/dns/task-7018-ids-dns-keywords/input.pcap [new file with mode: 0644]
tests/dns/task-7018-ids-dns-keywords/test.rules [new file with mode: 0644]
tests/dns/task-7018-ids-dns-keywords/test.yaml [new file with mode: 0644]
tests/dns/task-7018-ids-dns-stream-rule/README.md [new file with mode: 0644]
tests/dns/task-7018-ids-dns-stream-rule/test.rules [new file with mode: 0644]
tests/dns/task-7018-ids-dns-stream-rule/test.yaml [new file with mode: 0644]
tests/dns/task-7018-ips-dns-keywords/README.md [new file with mode: 0644]
tests/dns/task-7018-ips-dns-keywords/test.rules [new file with mode: 0644]
tests/dns/task-7018-ips-dns-keywords/test.yaml [new file with mode: 0644]

diff --git a/tests/dns/task-7018-dns-ips-stream-rule/README.md b/tests/dns/task-7018-dns-ips-stream-rule/README.md
new file mode 100644 (file)
index 0000000..3f47a96
--- /dev/null
@@ -0,0 +1,32 @@
+# Test Description
+
+Test for alert matches after triggering raw stream reassembly when there's a
+completed DNS TCP transaction.
+
+## PCAP
+
+dns-tcp-multi.pcap, crafted for this test, shared in the Redmine ticket (#7004).
+
+The capture shows three request-response DNS transactions:
+Query 1: suricata.io
+Query 2: oisf.net
+Query 3: suricata.org
+
+## Behavior
+
+We match those against a single payload rule without any DNS keywords,
+and inspecting for content `suricata|02|`. The expectation is to have 2 alerts
+for the portion of the stream associated with Query 1 - that's because on the
+wire we observe that for Query 3 the content is `suricata|03|`.
+
+### Observed [undesired] behavior
+
+While Suricata is matching on the correct traffic, for IPS mode, as a larger
+portion of the stream buffer is kept available, and as it still contains the
+matching bytes, more alerts are triggered, and will actually log the transaction
+for Query 3 (`oisf.net`).
+
+## Related issues
+
+https://redmine.openinfosecfoundation.org/issues/7018
+https://redmine.openinfosecfoundation.org/issues/7004
diff --git a/tests/dns/task-7018-dns-ips-stream-rule/test.rules b/tests/dns/task-7018-dns-ips-stream-rule/test.rules
new file mode 100644 (file)
index 0000000..b4631df
--- /dev/null
@@ -0,0 +1,3 @@
+# This rule will only match on the first DNS transaction that contains
+# `suricata`, as the second is followed by |03|
+alert dns any any -> any any (msg:"DNS suricata query - payload rule"; content:"suricata|02|"; sid:1; rev:1;)
diff --git a/tests/dns/task-7018-dns-ips-stream-rule/test.yaml b/tests/dns/task-7018-dns-ips-stream-rule/test.yaml
new file mode 100644 (file)
index 0000000..85a249e
--- /dev/null
@@ -0,0 +1,288 @@
+requires:
+   min-version: 7
+args:
+- -k none
+pcap: ../task-7018-ids-dns-keywords/input.pcap
+
+checks:
+- filter:
+    count: 6
+    match:
+      event_type: alert
+- filter:
+    count: 1
+    match:
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: suricata.io
+      dns.rrtype: A
+      dns.tx_id: 0
+      dns.type: query
+      event_type: dns
+      pcap_cnt: 4
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 4
+      proto: TCP
+      app_proto: dns
+      src_ip: 10.16.1.11
+      src_port: 36926
+      alert.signature: DNS suricata query - payload rule
+      alert.signature_id: 1
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      direction: to_server
+      tx_id: 0
+      dns.query[0].id: 0
+      dns.query[0].opcode: 0
+      dns.query[0].rrname: suricata.io
+      dns.query[0].rrtype: A
+      dns.query[0].tx_id: 0
+      dns.query[0].type: query
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 6
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 35.212.0.44
+      dns.answers[0].rrname: suricata.io
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 490
+      dns.flags: '8180'
+      dns.grouped.A[0]: 35.212.0.44
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: suricata.io
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 6
+      proto: TCP
+      src_ip: 9.9.9.9
+      src_port: 53
+      alert.signature: DNS suricata query - payload rule
+      alert.signature_id: 1
+      app_proto: dns
+      dest_ip: 10.16.1.11
+      dest_port: 36926
+      direction: to_client
+      tx_id: 1
+      dns.answer.flags: '8180'
+      dns.answer.id: 0
+      dns.answer.opcode: 0
+      dns.answer.qr: true
+      dns.answer.ra: true
+      dns.answer.rcode: NOERROR
+      dns.answer.rd: true
+      dns.answer.rrname: suricata.io
+      dns.answer.rrtype: A
+      dns.answer.type: answer
+      dns.answer.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: oisf.net
+      dns.rrtype: A
+      dns.tx_id: 2
+      dns.type: query
+      pcap_cnt: 8
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 8
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      alert.signature: DNS suricata query - payload rule
+      alert.signature_id: 1
+      app_proto: dns
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      direction: to_server
+      tx_id: 2
+      dns.query[0].type: query
+      dns.query[0].id: 0
+      dns.query[0].rrname: oisf.net
+      dns.query[0].opcode: 0
+      dns.query[0].rrtype: A
+      dns.query[0].tx_id: 2
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 9
+      alert.signature: DNS suricata query - payload rule
+      alert.signature_id: 1
+      proto: TCP
+      src_ip: 9.9.9.9
+      src_port: 53
+      dest_ip: 10.16.1.11
+      dest_port: 36926
+      app_proto: dns
+      direction: to_client
+      dns.answer.rrname: oisf.net
+      dns.answer.rrtype: A
+      dns.answer.flags: '8180'
+      dns.answer.id: 0
+      dns.answer.opcode: 0
+      dns.answer.qr: true
+      dns.answer.rd: true
+      dns.answer.ra: true
+      dns.answer.rcode: NOERROR
+      dns.answer.type: answer
+      dns.answer.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 9
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 192.0.78.190
+      dns.answers[0].rrname: oisf.net
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 207
+      dns.answers[1].rdata: 192.0.78.209
+      dns.answers[1].rrname: oisf.net
+      dns.answers[1].rrtype: A
+      dns.answers[1].ttl: 207
+      dns.flags: '8180'
+      dns.grouped.A[0]: 192.0.78.190
+      dns.grouped.A[1]: 192.0.78.209
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: oisf.net
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      alert.signature: DNS suricata query - payload rule
+      alert.signature_id: 1
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      direction: to_server
+      pcap_cnt: 10
+      tx_id: 4
+      dns.query[0].id: 0
+      dns.query[0].opcode: 0
+      dns.query[0].rrname: suricata.org
+      dns.query[0].rrtype: A
+      dns.query[0].tx_id: 4
+      dns.query[0].type: query
+- filter:
+    count: 1
+    match:
+      pcap_cnt: 10
+      event_type: dns
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: suricata.org
+      dns.rrtype: A
+      dns.tx_id: 4
+      dns.type: query
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 11
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 15.197.148.33
+      dns.answers[0].rrname: suricata.org
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 600
+      dns.answers[1].rdata: 3.33.130.190
+      dns.answers[1].rrname: suricata.org
+      dns.answers[1].rrtype: A
+      dns.answers[1].ttl: 600
+      dns.flags: '8180'
+      dns.grouped.A[0]: 15.197.148.33
+      dns.grouped.A[1]: 3.33.130.190
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: suricata.org
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      app_proto: dns
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      event_type: flow
+      flow.age: 0
+      flow.alerted: true
+      flow.bytes_toclient: 575
+      flow.bytes_toserver: 627
+      flow.pkts_toclient: 6
+      flow.pkts_toserver: 8
+      flow.reason: shutdown
+      flow.state: closed
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      tcp.ack: true
+      tcp.fin: true
+      tcp.psh: true
+      tcp.state: closed
+      tcp.syn: true
+      tcp.tc_max_regions: 1
+      tcp.tcp_flags: 1b
+      tcp.tcp_flags_tc: 1b
+      tcp.tcp_flags_ts: 1b
+      tcp.ts_max_regions: 1
diff --git a/tests/dns/task-7018-ids-dns-keywords/README.md b/tests/dns/task-7018-ids-dns-keywords/README.md
new file mode 100644 (file)
index 0000000..73b7cf4
--- /dev/null
@@ -0,0 +1,21 @@
+# Test Description
+
+Test to investigate that Suricata is properly inspecting and alerting on DNS
+transactions, without missing any, in IDS mode.
+
+## PCAP
+
+dns-tcp-multi.pcap, crafted for this test, shared in the Redmine ticket.
+
+The capture shows three request-response DNS transactions:
+Query 1: suricata.io
+Query 2: oisf.net
+Query 3: suricata.org
+
+We match those against a single rule with `dns.query.name` and inspecting
+content `suricata`, so the expectation is to have 4 alerts.
+
+## Related issues
+
+https://redmine.openinfosecfoundation.org/issues/7018
+https://redmine.openinfosecfoundation.org/issues/7004
diff --git a/tests/dns/task-7018-ids-dns-keywords/input.pcap b/tests/dns/task-7018-ids-dns-keywords/input.pcap
new file mode 100644 (file)
index 0000000..4c52123
Binary files /dev/null and b/tests/dns/task-7018-ids-dns-keywords/input.pcap differ
diff --git a/tests/dns/task-7018-ids-dns-keywords/test.rules b/tests/dns/task-7018-ids-dns-keywords/test.rules
new file mode 100644 (file)
index 0000000..4ba624a
--- /dev/null
@@ -0,0 +1 @@
+alert dns any any -> any any (msg:"DNS suricata query.name"; dns.query.name; content:"suricata"; sid:1; rev:1;)
diff --git a/tests/dns/task-7018-ids-dns-keywords/test.yaml b/tests/dns/task-7018-ids-dns-keywords/test.yaml
new file mode 100644 (file)
index 0000000..cf7756b
--- /dev/null
@@ -0,0 +1,269 @@
+args:
+- -k none
+
+requires:
+  min-version: 8
+
+checks:
+- filter:
+    count: 4
+    match:
+      event_type: alert
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 7
+      tx_id: 0
+      alert.signature: DNS suricata query.name
+      alert.signature_id: 1
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      app_proto: dns
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      direction: to_server
+      dns.query[0].id: 0
+      dns.query[0].opcode: 0
+      dns.query[0].rrname: suricata.io
+      dns.query[0].rrtype: A
+      dns.query[0].tx_id: 0
+      dns.query[0].type: query
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 9
+      tx_id: 1
+      alert.signature: DNS suricata query.name
+      alert.signature_id: 1
+      app_proto: dns
+      proto: TCP
+      src_ip: 9.9.9.9
+      src_port: 53
+      dest_ip: 10.16.1.11
+      dest_port: 36926
+      direction: to_client
+      dns.answer.flags: '8180'
+      dns.answer.id: 0
+      dns.answer.opcode: 0
+      dns.answer.qr: true
+      dns.answer.ra: true
+      dns.answer.rcode: NOERROR
+      dns.answer.rd: true
+      dns.answer.rrname: suricata.io
+      dns.answer.rrtype: A
+      dns.answer.type: answer
+      dns.answer.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 12
+      tx_id: 4
+      alert.signature: DNS suricata query.name
+      alert.signature_id: 1
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      app_proto: dns
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      direction: to_server
+      dns.query[0].id: 0
+      dns.query[0].opcode: 0
+      dns.query[0].rrname: suricata.org
+      dns.query[0].rrtype: A
+      dns.query[0].tx_id: 4
+      dns.query[0].type: query
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 13
+      tx_id: 5
+      alert.signature: DNS suricata query.name
+      alert.signature_id: 1
+      proto: TCP
+      src_ip: 9.9.9.9
+      src_port: 53
+      app_proto: dns
+      dest_ip: 10.16.1.11
+      dest_port: 36926
+      direction: to_client
+      dns.answer.flags: '8180'
+      dns.answer.id: 0
+      dns.answer.opcode: 0
+      dns.answer.qr: true
+      dns.answer.ra: true
+      dns.answer.rcode: NOERROR
+      dns.answer.rd: true
+      dns.answer.rrname: suricata.org
+      dns.answer.rrtype: A
+      dns.answer.type: answer
+      dns.answer.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 5
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: suricata.io
+      dns.rrtype: A
+      dns.tx_id: 0
+      dns.type: query
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 7
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 35.212.0.44
+      dns.answers[0].rrname: suricata.io
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 490
+      dns.flags: '8180'
+      dns.grouped.A[0]: 35.212.0.44
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: suricata.io
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 9
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: oisf.net
+      dns.rrtype: A
+      dns.tx_id: 2
+      dns.type: query
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 10
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 192.0.78.190
+      dns.answers[0].rrname: oisf.net
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 207
+      dns.answers[1].rdata: 192.0.78.209
+      dns.answers[1].rrname: oisf.net
+      dns.answers[1].rrtype: A
+      dns.answers[1].ttl: 207
+      dns.flags: '8180'
+      dns.grouped.A[0]: 192.0.78.190
+      dns.grouped.A[1]: 192.0.78.209
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: oisf.net
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 11
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: suricata.org
+      dns.rrtype: A
+      dns.tx_id: 4
+      dns.type: query
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 12
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 15.197.148.33
+      dns.answers[0].rrname: suricata.org
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 600
+      dns.answers[1].rdata: 3.33.130.190
+      dns.answers[1].rrname: suricata.org
+      dns.answers[1].rrtype: A
+      dns.answers[1].ttl: 600
+      dns.flags: '8180'
+      dns.grouped.A[0]: 15.197.148.33
+      dns.grouped.A[1]: 3.33.130.190
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: suricata.org
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: flow
+      app_proto: dns
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      flow.age: 0
+      flow.alerted: true
+      flow.bytes_toclient: 575
+      flow.bytes_toserver: 627
+      flow.pkts_toclient: 6
+      flow.pkts_toserver: 8
+      flow.reason: shutdown
+      flow.state: closed
+      tcp.ack: true
+      tcp.fin: true
+      tcp.psh: true
+      tcp.state: closed
+      tcp.syn: true
+      tcp.tc_max_regions: 1
+      tcp.tcp_flags: 1b
+      tcp.tcp_flags_tc: 1b
+      tcp.tcp_flags_ts: 1b
+      tcp.ts_max_regions: 1
diff --git a/tests/dns/task-7018-ids-dns-stream-rule/README.md b/tests/dns/task-7018-ids-dns-stream-rule/README.md
new file mode 100644 (file)
index 0000000..840cda6
--- /dev/null
@@ -0,0 +1,26 @@
+# Test Description
+
+Test that alert matches will happen earlier, after triggering raw stream
+reassembly when there's a completed DNS TCP transaction will show up earlier
+in the logs.
+
+## PCAP
+
+dns-tcp-multi.pcap, crafted for this test, shared in the Redmine ticket.
+
+## Behavior
+
+The capture shows three request-response DNS transactions:
+Query 1: suricata.io
+Query 2: oisf.net
+Query 3: suricata.org
+
+We match those against a single payload rule without any DNS keywords,
+and inspecting content `suricata|02|`. The expectation is to have 2 alerts,
+for the portion of the stream associated with Query 1 - that's because on the
+wire we observe that for Query three the content is `suricata|03|`.
+
+## Related issues
+
+https://redmine.openinfosecfoundation.org/issues/7018
+https://redmine.openinfosecfoundation.org/issues/7004
diff --git a/tests/dns/task-7018-ids-dns-stream-rule/test.rules b/tests/dns/task-7018-ids-dns-stream-rule/test.rules
new file mode 100644 (file)
index 0000000..b4631df
--- /dev/null
@@ -0,0 +1,3 @@
+# This rule will only match on the first DNS transaction that contains
+# `suricata`, as the second is followed by |03|
+alert dns any any -> any any (msg:"DNS suricata query - payload rule"; content:"suricata|02|"; sid:1; rev:1;)
diff --git a/tests/dns/task-7018-ids-dns-stream-rule/test.yaml b/tests/dns/task-7018-ids-dns-stream-rule/test.yaml
new file mode 100644 (file)
index 0000000..ad733e9
--- /dev/null
@@ -0,0 +1,219 @@
+requires:
+   min-version: 7
+args:
+- -k none
+
+pcap: ../task-7018-ids-dns-keywords/input.pcap
+
+checks:
+- filter:
+    count: 1
+    match:
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: suricata.io
+      dns.rrtype: A
+      dns.tx_id: 0
+      dns.type: query
+      event_type: dns
+      pcap_cnt: 5
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 7
+      proto: TCP
+      app_proto: dns
+      src_ip: 10.16.1.11
+      src_port: 36926
+      alert.signature: DNS suricata query - payload rule
+      alert.signature_id: 1
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      direction: to_server
+      tx_id: 0
+      dns.query[0].id: 0
+      dns.query[0].opcode: 0
+      dns.query[0].rrname: suricata.io
+      dns.query[0].rrtype: A
+      dns.query[0].tx_id: 0
+      dns.query[0].type: query
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 7
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 35.212.0.44
+      dns.answers[0].rrname: suricata.io
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 490
+      dns.flags: '8180'
+      dns.grouped.A[0]: 35.212.0.44
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: suricata.io
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 9
+      proto: TCP
+      app_proto: dns
+      src_ip: 9.9.9.9
+      src_port: 53
+      alert.signature: DNS suricata query - payload rule
+      alert.signature_id: 1
+      dest_ip: 10.16.1.11
+      dest_port: 36926
+      direction: to_client
+      tx_id: 1
+      dns.answer.flags: '8180'
+      dns.answer.id: 0
+      dns.answer.opcode: 0
+      dns.answer.qr: true
+      dns.answer.ra: true
+      dns.answer.rcode: NOERROR
+      dns.answer.rd: true
+      dns.answer.rrname: suricata.io
+      dns.answer.rrtype: A
+      dns.answer.type: answer
+      dns.answer.version: 2
+- filter:
+    count: 1
+    match:
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: oisf.net
+      dns.rrtype: A
+      dns.tx_id: 2
+      dns.type: query
+      event_type: dns
+      pcap_cnt: 9
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 10
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 192.0.78.190
+      dns.answers[0].rrname: oisf.net
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 207
+      dns.answers[1].rdata: 192.0.78.209
+      dns.answers[1].rrname: oisf.net
+      dns.answers[1].rrtype: A
+      dns.answers[1].ttl: 207
+      dns.flags: '8180'
+      dns.grouped.A[0]: 192.0.78.190
+      dns.grouped.A[1]: 192.0.78.209
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: oisf.net
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: suricata.org
+      dns.rrtype: A
+      dns.tx_id: 4
+      dns.type: query
+      event_type: dns
+      pcap_cnt: 11
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 12
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 15.197.148.33
+      dns.answers[0].rrname: suricata.org
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 600
+      dns.answers[1].rdata: 3.33.130.190
+      dns.answers[1].rrname: suricata.org
+      dns.answers[1].rrtype: A
+      dns.answers[1].ttl: 600
+      dns.flags: '8180'
+      dns.grouped.A[0]: 15.197.148.33
+      dns.grouped.A[1]: 3.33.130.190
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: suricata.org
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      app_proto: dns
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      event_type: flow
+      flow.age: 0
+      flow.alerted: true
+      flow.bytes_toclient: 575
+      flow.bytes_toserver: 627
+      flow.pkts_toclient: 6
+      flow.pkts_toserver: 8
+      flow.reason: shutdown
+      flow.state: closed
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      tcp.ack: true
+      tcp.fin: true
+      tcp.psh: true
+      tcp.state: closed
+      tcp.syn: true
+      tcp.tc_max_regions: 1
+      tcp.tcp_flags: 1b
+      tcp.tcp_flags_tc: 1b
+      tcp.tcp_flags_ts: 1b
+      tcp.ts_max_regions: 1
diff --git a/tests/dns/task-7018-ips-dns-keywords/README.md b/tests/dns/task-7018-ips-dns-keywords/README.md
new file mode 100644 (file)
index 0000000..0178fda
--- /dev/null
@@ -0,0 +1,23 @@
+# Test Description
+
+Test to investigate that Suricata is properly inspecting and alerting on DNS
+transactions, without missing any, in IPS mode.
+
+The difference in this case should only be the pcap_cnt for the events.
+
+## PCAP
+
+dns-tcp-multi.pcap, crafted for this test, shared in the Redmine ticket.
+
+The capture shows three request-response DNS transactions:
+Query 1: suricata.io
+Query 2: oisf.net
+Query 3: suricata.org
+
+We match those against a single rule with `dns.query.name` and inspecting
+content `suricata`, so the expectation is to have 4 alerts.
+
+## Related issues
+
+https://redmine.openinfosecfoundation.org/issues/7018
+https://redmine.openinfosecfoundation.org/issues/7004
diff --git a/tests/dns/task-7018-ips-dns-keywords/test.rules b/tests/dns/task-7018-ips-dns-keywords/test.rules
new file mode 100644 (file)
index 0000000..4ba624a
--- /dev/null
@@ -0,0 +1 @@
+alert dns any any -> any any (msg:"DNS suricata query.name"; dns.query.name; content:"suricata"; sid:1; rev:1;)
diff --git a/tests/dns/task-7018-ips-dns-keywords/test.yaml b/tests/dns/task-7018-ips-dns-keywords/test.yaml
new file mode 100644 (file)
index 0000000..6b6445b
--- /dev/null
@@ -0,0 +1,272 @@
+args:
+- -k none
+- --simulate-ips
+
+requires:
+  min-version: 8
+
+pcap: ../task-7018-ids-dns-keywords/input.pcap
+
+checks:
+- filter:
+    count: 4
+    match:
+      event_type: alert
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 4
+      tx_id: 0
+      alert.signature: DNS suricata query.name
+      alert.signature_id: 1
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      app_proto: dns
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      direction: to_server
+      dns.query[0].id: 0
+      dns.query[0].opcode: 0
+      dns.query[0].rrname: suricata.io
+      dns.query[0].rrtype: A
+      dns.query[0].tx_id: 0
+      dns.query[0].type: query
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 6
+      tx_id: 1
+      alert.signature: DNS suricata query.name
+      alert.signature_id: 1
+      app_proto: dns
+      proto: TCP
+      src_ip: 9.9.9.9
+      src_port: 53
+      dest_ip: 10.16.1.11
+      dest_port: 36926
+      direction: to_client
+      dns.answer.flags: '8180'
+      dns.answer.id: 0
+      dns.answer.opcode: 0
+      dns.answer.qr: true
+      dns.answer.ra: true
+      dns.answer.rcode: NOERROR
+      dns.answer.rd: true
+      dns.answer.rrname: suricata.io
+      dns.answer.rrtype: A
+      dns.answer.type: answer
+      dns.answer.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 10
+      tx_id: 4
+      alert.signature: DNS suricata query.name
+      alert.signature_id: 1
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      app_proto: dns
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      direction: to_server
+      dns.query[0].id: 0
+      dns.query[0].opcode: 0
+      dns.query[0].rrname: suricata.org
+      dns.query[0].rrtype: A
+      dns.query[0].tx_id: 4
+      dns.query[0].type: query
+- filter:
+    count: 1
+    match:
+      event_type: alert
+      pcap_cnt: 11
+      tx_id: 5
+      alert.signature: DNS suricata query.name
+      alert.signature_id: 1
+      proto: TCP
+      src_ip: 9.9.9.9
+      src_port: 53
+      app_proto: dns
+      dest_ip: 10.16.1.11
+      dest_port: 36926
+      direction: to_client
+      dns.answer.flags: '8180'
+      dns.answer.id: 0
+      dns.answer.opcode: 0
+      dns.answer.qr: true
+      dns.answer.ra: true
+      dns.answer.rcode: NOERROR
+      dns.answer.rd: true
+      dns.answer.rrname: suricata.org
+      dns.answer.rrtype: A
+      dns.answer.type: answer
+      dns.answer.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 4
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: suricata.io
+      dns.rrtype: A
+      dns.tx_id: 0
+      dns.type: query
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 6
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 35.212.0.44
+      dns.answers[0].rrname: suricata.io
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 490
+      dns.flags: '8180'
+      dns.grouped.A[0]: 35.212.0.44
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: suricata.io
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 8
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: oisf.net
+      dns.rrtype: A
+      dns.tx_id: 2
+      dns.type: query
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 9
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 192.0.78.190
+      dns.answers[0].rrname: oisf.net
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 207
+      dns.answers[1].rdata: 192.0.78.209
+      dns.answers[1].rrname: oisf.net
+      dns.answers[1].rrtype: A
+      dns.answers[1].ttl: 207
+      dns.flags: '8180'
+      dns.grouped.A[0]: 192.0.78.190
+      dns.grouped.A[1]: 192.0.78.209
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: oisf.net
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 10
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.id: 0
+      dns.opcode: 0
+      dns.rrname: suricata.org
+      dns.rrtype: A
+      dns.tx_id: 4
+      dns.type: query
+- filter:
+    count: 1
+    match:
+      event_type: dns
+      pcap_cnt: 11
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      dns.answers[0].rdata: 15.197.148.33
+      dns.answers[0].rrname: suricata.org
+      dns.answers[0].rrtype: A
+      dns.answers[0].ttl: 600
+      dns.answers[1].rdata: 3.33.130.190
+      dns.answers[1].rrname: suricata.org
+      dns.answers[1].rrtype: A
+      dns.answers[1].ttl: 600
+      dns.flags: '8180'
+      dns.grouped.A[0]: 15.197.148.33
+      dns.grouped.A[1]: 3.33.130.190
+      dns.id: 0
+      dns.opcode: 0
+      dns.qr: true
+      dns.ra: true
+      dns.rcode: NOERROR
+      dns.rd: true
+      dns.rrname: suricata.org
+      dns.rrtype: A
+      dns.type: answer
+      dns.version: 2
+- filter:
+    count: 1
+    match:
+      event_type: flow
+      app_proto: dns
+      proto: TCP
+      src_ip: 10.16.1.11
+      src_port: 36926
+      dest_ip: 9.9.9.9
+      dest_port: 53
+      flow.age: 0
+      flow.alerted: true
+      flow.bytes_toclient: 575
+      flow.bytes_toserver: 627
+      flow.pkts_toclient: 6
+      flow.pkts_toserver: 8
+      flow.reason: shutdown
+      flow.state: closed
+      tcp.ack: true
+      tcp.fin: true
+      tcp.psh: true
+      tcp.state: closed
+      tcp.syn: true
+      tcp.tc_max_regions: 1
+      tcp.tcp_flags: 1b
+      tcp.tcp_flags_tc: 1b
+      tcp.tcp_flags_ts: 1b
+      tcp.ts_max_regions: 1