From 8a7f5b3d46a85d5f014d5b9aa49247eb7e76e75f Mon Sep 17 00:00:00 2001 From: Cole Dishington Date: Tue, 8 Aug 2023 14:50:59 +1200 Subject: [PATCH] flow: Add test for excluding pkt recursion from flow Add tests for verifying matching packet flows when including and excluding pkt recursion from flow matching. Bug: #6260 --- tests/flow-pkt-recursion/README.md | 25 +++++++++++++ .../test.yaml | 16 ++++++++ .../test.pcap | Bin 0 -> 320 bytes .../test.yaml | 11 ++++++ .../test.yaml | 17 +++++++++ .../test.pcap | Bin 0 -> 536 bytes .../test.yaml | 12 ++++++ tests/flow-pkt-recursion/test.py | 35 ++++++++++++++++++ 8 files changed, 116 insertions(+) create mode 100644 tests/flow-pkt-recursion/README.md create mode 100644 tests/flow-pkt-recursion/flow-pkt-recursion-middleware-excluded/test.yaml create mode 100644 tests/flow-pkt-recursion/flow-pkt-recursion-middleware-included/test.pcap create mode 100644 tests/flow-pkt-recursion/flow-pkt-recursion-middleware-included/test.yaml create mode 100644 tests/flow-pkt-recursion/flow-pkt-recursion-terminated-excluded/test.yaml create mode 100644 tests/flow-pkt-recursion/flow-pkt-recursion-terminated-included/test.pcap create mode 100644 tests/flow-pkt-recursion/flow-pkt-recursion-terminated-included/test.yaml create mode 100644 tests/flow-pkt-recursion/test.py diff --git a/tests/flow-pkt-recursion/README.md b/tests/flow-pkt-recursion/README.md new file mode 100644 index 000000000..6ad98acdb --- /dev/null +++ b/tests/flow-pkt-recursion/README.md @@ -0,0 +1,25 @@ +# Test Purpose + +Tests comparing flows with and without recursion level set. Ignoring +recursion level in flows is useful for devices that run inline IPS and +terminate an unencrypted tunnel, like an IPv6 tunnel. Terminating the +tunnel causes ingress request and reply traffic to have different +headers. e.g. + +request: IPv4]ICMP] -> |IPS| -> IPv6]IPv4]ICMP] +reply: <- |IPS| <- IPv6]IPv4]ICMP] + +The terminated tests are checking when the suricata is an inline IPS +device that is terminating a tunnel. Both flow directions are tested, +first packet ingress on non-tunneled interface and first packet ingress +on tunneled interface. +This is the case where recursion level can affect the flows when IPS is +running inline IPS and terminating a tunnel. + +Middleware tests check when the suricata device is analysing tunneled +packets and is not a tunnel terminator. +This case should not be affected by recursion level in flows. + +## PCAP + +This PCAP was generated with scapy. \ No newline at end of file diff --git a/tests/flow-pkt-recursion/flow-pkt-recursion-middleware-excluded/test.yaml b/tests/flow-pkt-recursion/flow-pkt-recursion-middleware-excluded/test.yaml new file mode 100644 index 000000000..88ce347e7 --- /dev/null +++ b/tests/flow-pkt-recursion/flow-pkt-recursion-middleware-excluded/test.yaml @@ -0,0 +1,16 @@ +requires: + min-version: 8 + +pcap: ../flow-pkt-recursion-middleware-included/test.pcap + +args: +- --set decoder.recursion-level.use-for-tracking=false + +checks: + - filter: + count: 1 + match: + event_type: flow + proto: ICMP + flow.pkts_toserver: 1 + flow.pkts_toclient: 1 diff --git a/tests/flow-pkt-recursion/flow-pkt-recursion-middleware-included/test.pcap b/tests/flow-pkt-recursion/flow-pkt-recursion-middleware-included/test.pcap new file mode 100644 index 0000000000000000000000000000000000000000..5efa32306a17f9a0ca3864162aaca5a6eb0ed7a1 GIT binary patch literal 320 zcmca|c+)~A1{MYw`2U}Qff2|tT5~CdD~_F^1;_?r&qb|UqOYX>Y(Y`dEP6k+gV zarg^T3I&Wn@Rte3V_;wc0#~3akZ}%-B`ZPlATbUGE^DAFMrE(yr0B$?pg42O#4wF) z7e_xG4QH+xN9_WIFl}EqbKVroC^a=p7h^*`>kw6*5>?tJN*Cv literal 0 HcmV?d00001 diff --git a/tests/flow-pkt-recursion/flow-pkt-recursion-middleware-included/test.yaml b/tests/flow-pkt-recursion/flow-pkt-recursion-middleware-included/test.yaml new file mode 100644 index 000000000..420916c37 --- /dev/null +++ b/tests/flow-pkt-recursion/flow-pkt-recursion-middleware-included/test.yaml @@ -0,0 +1,11 @@ +requires: + min-version: 8 + +checks: + - filter: + count: 1 + match: + event_type: flow + proto: ICMP + flow.pkts_toserver: 1 + flow.pkts_toclient: 1 diff --git a/tests/flow-pkt-recursion/flow-pkt-recursion-terminated-excluded/test.yaml b/tests/flow-pkt-recursion/flow-pkt-recursion-terminated-excluded/test.yaml new file mode 100644 index 000000000..cf9cce035 --- /dev/null +++ b/tests/flow-pkt-recursion/flow-pkt-recursion-terminated-excluded/test.yaml @@ -0,0 +1,17 @@ +requires: + min-version: 8 + +pcap: ../flow-pkt-recursion-terminated-included/test.pcap + +args: +- --set decoder.recursion-level.use-for-tracking=false + +checks: + # All packets should be caught as being in one flow + - filter: + count: 2 + match: + event_type: flow + proto: ICMP + flow.pkts_toserver: 1 + flow.pkts_toclient: 1 \ No newline at end of file diff --git a/tests/flow-pkt-recursion/flow-pkt-recursion-terminated-included/test.pcap b/tests/flow-pkt-recursion/flow-pkt-recursion-terminated-included/test.pcap new file mode 100644 index 0000000000000000000000000000000000000000..d3efbd01057b52c79dffaf45e136aed729e8bce1 GIT binary patch literal 536 zcmca|c+)~A1{MYw`2U}Qff2|tT5~CdD~_EZ2FM0s&qb|UqOYX>Y(WT2LO%eX}$me literal 0 HcmV?d00001 diff --git a/tests/flow-pkt-recursion/flow-pkt-recursion-terminated-included/test.yaml b/tests/flow-pkt-recursion/flow-pkt-recursion-terminated-included/test.yaml new file mode 100644 index 000000000..d96a6f8de --- /dev/null +++ b/tests/flow-pkt-recursion/flow-pkt-recursion-terminated-included/test.yaml @@ -0,0 +1,12 @@ +requires: + min-version: 8 + +checks: + # None of the flows are joined due to different recursion levels + - filter: + count: 4 + match: + event_type: flow + proto: ICMP + flow.pkts_toserver: 1 + flow.pkts_toclient: 0 diff --git a/tests/flow-pkt-recursion/test.py b/tests/flow-pkt-recursion/test.py new file mode 100644 index 000000000..cc1410145 --- /dev/null +++ b/tests/flow-pkt-recursion/test.py @@ -0,0 +1,35 @@ +from pathlib import Path + +from scapy.all import ICMP, IP, Ether, IPv6, PcapWriter, Raw + +mac_1, mac_2 = 'cb:cf:2b:50:a7:61', '49:a2:25:1a:07:4a' + +request = Ether(src=mac_1, dst=mac_2) +reply = Ether(src=mac_2, dst=mac_1) + +ip_1, ip_2 = '1.1.1.1', '2.2.2.2' +ipv6_1, ipv6_2 = 'fd01::1.1.1.1', 'fd02::2.2.2.2' + +payload = Raw(b'#JSb[abR^79aV(kDAN,(C\n\\A+p V+MF7\rd9Z&&9D31.;T%\x0ct.#') +icmp_echo = ICMP(type=8, seq=1) / payload +icmp_reply = ICMP(type=0, seq=1) / payload + +test = 'flow-pkt-recursion' + +middleware_pcap = Path.cwd() / f'{test}-middleware-included' / 'test.pcap' +with PcapWriter(str(middleware_pcap)) as pcap: + # Flow of IPv6 tunneled packets in both directions + pcap.write(request / IPv6(src=ipv6_1, dst=ipv6_2) / IP(src=ip_1, dst=ip_2) / icmp_echo) + pcap.write(reply / IPv6(src=ipv6_2, dst=ipv6_1) / IP(src=ip_2, dst=ip_1) / icmp_reply) + +terminated_pcap = Path.cwd() / f'{test}-terminated-included' / 'test.pcap' +with PcapWriter(str(terminated_pcap)) as pcap: + # Flow of tunnel terminated on Suricata device, echo originates + # from Suricata device + pcap.write(request / IP(src=ip_1, dst=ip_2) / icmp_echo) + pcap.write(reply / IPv6(src=ipv6_2, dst=ipv6_1) / IP(src=ip_2, dst=ip_1) / icmp_reply) + + # Flow of tunnel terminated on Suricata device, reply originates + # from Suricata device + pcap.write(reply / IPv6(src=ipv6_2, dst=ipv6_1) / IP(src=ip_2, dst=ip_1) / icmp_echo) + pcap.write(request / IP(src=ip_1, dst=ip_2) / icmp_reply)