diff --git a/tests/detect-bidir-flowbits/README.md b/tests/detect-bidir-flowbits/README.md new file mode 100644 index 000000000..f8188b9e2 --- /dev/null +++ b/tests/detect-bidir-flowbits/README.md @@ -0,0 +1,11 @@ +# Description + +Test bidirection matching with a real life example +https://redmine.openinfosecfoundation.org/issues/5665 + +# PCAP + +Crafted from the rules +Client is +`curl -d '"goog:chromeOptions";"binary";"args":["' -X POST 127.0.0.1:8080/wd/hub/session` +Server is server.go diff --git a/tests/detect-bidir-flowbits/input.pcap b/tests/detect-bidir-flowbits/input.pcap new file mode 100644 index 000000000..9888603e7 Binary files /dev/null and b/tests/detect-bidir-flowbits/input.pcap differ diff --git a/tests/detect-bidir-flowbits/server.go b/tests/detect-bidir-flowbits/server.go new file mode 100644 index 000000000..9f2429752 --- /dev/null +++ b/tests/detect-bidir-flowbits/server.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + "net/http" +) + +func main() { + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Server", "Jetty") + w.WriteHeader(http.StatusInternalServerError) + content := "org.openqa.selenium.WebDriverException: unknown error: Chrome failed to start: exited normally." + content = content + `unknown error: DevToolsActivePort file doesn't exist)\n (The process started from chrome location` + n, err := w.Write([]byte(content)) + fmt.Printf("lola %v %v\n", n, err) + }) + + server := &http.Server{ + Addr: "0.0.0.0:8080", + Handler: handler, + } + + fmt.Printf("Listening [0.0.0.0:8080]...\n") + err := server.ListenAndServe() + fmt.Printf("lol %s", err) +} diff --git a/tests/detect-bidir-flowbits/test.rules b/tests/detect-bidir-flowbits/test.rules new file mode 100644 index 000000000..f38707d1f --- /dev/null +++ b/tests/detect-bidir-flowbits/test.rules @@ -0,0 +1,6 @@ +#flowbits version +alert http any any -> any any (msg:"ET EXPLOIT Selenium Server Chrome 3.141.59 Remote Code Execution"; flow:established,to_server; flowbits:set,ET.Selenium314159.RCE; urilen:15; http.method; content:"POST"; http.uri; content:"/wd/hub/session"; fast_pattern; http.request_body; content:"|22|goog|3a|chromeOptions|22|"; content:"|22|binary|22|"; content:"|22|args|22|"; content:"|5b 22|"; within:5; reference:url,github.com/BoredHackerBlog/selenium_code_exec_notes; classtype:attempted-admin; sid:2052319; rev:2; metadata:attack_target Web_Server, tls_state TLSDecrypt, created_at 2024_05_01, deployment Perimeter, deployment Internal, deployment SSLDecrypt, former_category EXPLOIT, performance_impact Low, confidence High, signature_severity Major, updated_at 2024_05_02; target:dest_ip;) +alert http any any -> any any (msg:"ET EXPLOIT Selenium Server Grid Chrome 3.141.59 Remote Code Execution - Successful"; flow:established,to_client; flowbits:isset,ET.Selenium314159.RCE; http.stat_code; content:"500"; http.server; content:"Jetty"; startswith; file.data; content:"org|2e|openqa|2e|selenium|2e|WebDriverException|3a 20|unknown|20|error|3a 20|Chrome|20|failed|20|to|20|start|3a 20|exited|20|normally|2e|"; content:"unknown|20|error|3a 20|DevToolsActivePort|20|file|20|doesn|27|t|20|exist|29 5c|n|20 20 28|The|20|process|20|started|20|from|20|chrome|20|location"; fast_pattern; reference:url,github.com/BoredHackerBlog/selenium_code_exec_notes; classtype:successful-admin; sid:2052359; rev:1; metadata:attack_target Web_Server, tls_state TLSDecrypt, created_at 2024_05_02, deployment Perimeter, deployment Internal, former_category EXPLOIT, confidence High, signature_severity Critical, updated_at 2024_05_02; target:src_ip;) + +# and now the bidir version +alert http any any => any any (msg:"ET EXPLOIT Selenium Server Chrome 3.141.59 Remote Code Execution"; urilen:15; http.method; content:"POST"; http.uri; content:"/wd/hub/session"; fast_pattern; http.request_body; content:"|22|goog|3a|chromeOptions|22|"; content:"|22|binary|22|"; content:"|22|args|22|"; content:"|5b 22|"; within:5; http.stat_code; content:"500"; http.server; content:"Jetty"; startswith; bidir.toclient; file.data; content:"org|2e|openqa|2e|selenium|2e|WebDriverException|3a 20|unknown|20|error|3a 20|Chrome|20|failed|20|to|20|start|3a 20|exited|20|normally|2e|"; content:"unknown|20|error|3a 20|DevToolsActivePort|20|file|20|doesn|27|t|20|exist|29 5c|n|20 20 28|The|20|process|20|started|20|from|20|chrome|20|location"; reference:url,github.com/BoredHackerBlog/selenium_code_exec_notes; classtype:attempted-admin; sid:1; metadata:attack_target Web_Server, tls_state TLSDecrypt, created_at 2024_05_01, deployment Perimeter, deployment Internal, deployment SSLDecrypt, former_category EXPLOIT, performance_impact Low, confidence High, signature_severity Major, updated_at 2024_05_02; target:dest_ip;) diff --git a/tests/detect-bidir-flowbits/test.yaml b/tests/detect-bidir-flowbits/test.yaml new file mode 100644 index 000000000..cf960eb7f --- /dev/null +++ b/tests/detect-bidir-flowbits/test.yaml @@ -0,0 +1,17 @@ +requires: + min-version: 8 + +args: + - -k none + +checks: + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 1 + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 2052359 diff --git a/tests/detect-bidir-impossible/README.md b/tests/detect-bidir-impossible/README.md new file mode 100644 index 000000000..aeec7416a --- /dev/null +++ b/tests/detect-bidir-impossible/README.md @@ -0,0 +1,8 @@ +# Description + +Test invalid rules for bidirection matching +https://redmine.openinfosecfoundation.org/issues/5665 + +# PCAP + +Reusing a pcap, but does not matter diff --git a/tests/detect-bidir-impossible/test.rules b/tests/detect-bidir-impossible/test.rules new file mode 100644 index 000000000..0dd4c7696 --- /dev/null +++ b/tests/detect-bidir-impossible/test.rules @@ -0,0 +1,7 @@ +alert http any any => any any (msg:"matching both uri and status"; sid: 11; http.uri; content: "/download"; http.stat_code; content: "200"; flow: to_server;) +alert http any any => any any (msg:"matching only uri"; sid: 2; http.uri; content: "/download"; ) +alert http any any => any any (msg:"matching only status"; sid: 3; http.stat_code; content: "200";) +alert http any any => any any (msg:"matching connection, but from ambiguous direction"; sid: 4; http.uri; content: "/download"; http.stat_code; content: "200"; http.connection; content: "eep";) +alert http any any => any any (msg:"stream rule"; sid: 5; content: "/download"; content: "200";) +alert http any any => any any (msg:"stream rule"; sid: 6; bidir.toserver; content: "/download"; bidir.toclient; content: "200";) +alert enip any any => any any (msg:"frame rule"; sid: 7; bidir.toserver; frame: enip.pdu; content: "/download"; bidir.toclient; frame: enip.pdu; content: "200";) diff --git a/tests/detect-bidir-impossible/test.yaml b/tests/detect-bidir-impossible/test.yaml new file mode 100644 index 000000000..6f8e6c877 --- /dev/null +++ b/tests/detect-bidir-impossible/test.yaml @@ -0,0 +1,35 @@ +requires: + min-version: 8 + +pcap: ../http-all-headers/input.pcap + +args: + - --set app-layer.protocols.enip.enabled=yes + +exit-code: 1 + +checks: + - shell: + args: grep -c 'error parsing signature' suricata.log + expect: 7 + - shell: + args: grep -c 'rule 2 should use both directions, but does not' suricata.log + expect: 1 + - shell: + args: grep -c 'rule 3 should use both directions, but does not' suricata.log + expect: 1 + - shell: + args: grep -c 'rule 4 means to use both directions, cannot have keywords ambiguous about directions' suricata.log + expect: 1 + - shell: + args: grep -c 'rule 5 should use both directions, but does not' suricata.log + expect: 1 + - shell: + args: grep -c 'rule 6 should use both directions, but does not' suricata.log + expect: 1 + - shell: + args: grep -c 'rule 7 should use both directions, but does not' suricata.log + expect: 1 + - shell: + args: grep -c 'rule 11 means to use both directions, cannot specify a flow direction' suricata.log + expect: 1 diff --git a/tests/detect-bidir-ja3/README.md b/tests/detect-bidir-ja3/README.md new file mode 100644 index 000000000..3cdcc9e1f --- /dev/null +++ b/tests/detect-bidir-ja3/README.md @@ -0,0 +1,8 @@ +# Description + +Test bidirection matching with TLS ja3 +https://redmine.openinfosecfoundation.org/issues/5665 + +# PCAP + +reused diff --git a/tests/detect-bidir-ja3/test.rules b/tests/detect-bidir-ja3/test.rules new file mode 100644 index 000000000..3165d8e21 --- /dev/null +++ b/tests/detect-bidir-ja3/test.rules @@ -0,0 +1,4 @@ +alert tls any any => any any (msg:"bidir ja3"; ja3s.hash; content:"5d79edf64e03689ff559a54e9d9487bc"; ja3.string; content:"771,49196-49200"; sid:1;) +# should not match +alert tls any any => any any (msg:"bidir ja3"; ja3s.hash; content:"6d79edf64e03689ff559a54e9d9487bc"; ja3.string; content:"771,49196-49200"; sid:2;) +alert tls any any => any any (msg:"bidir ja3"; ja3s.hash; content:"5d79edf64e03689ff559a54e9d9487bc"; ja3.string; content:"9999999999"; sid:3;) diff --git a/tests/detect-bidir-ja3/test.yaml b/tests/detect-bidir-ja3/test.yaml new file mode 100644 index 000000000..751428fb0 --- /dev/null +++ b/tests/detect-bidir-ja3/test.yaml @@ -0,0 +1,18 @@ +requires: + min-version: 8 + +pcap: ../tls/tls-certs-alert/input.pcap + +args: + - -k none + +checks: + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 1 + - filter: + count: 1 + match: + event_type: alert diff --git a/tests/detect-bidir/README.md b/tests/detect-bidir/README.md new file mode 100644 index 000000000..35b0d6504 --- /dev/null +++ b/tests/detect-bidir/README.md @@ -0,0 +1,8 @@ +# Description + +Test bidirection matching +https://redmine.openinfosecfoundation.org/issues/5665 + +# PCAP + +Reusing pcap from http-all-headers diff --git a/tests/detect-bidir/test.rules b/tests/detect-bidir/test.rules new file mode 100644 index 000000000..70054d2d7 --- /dev/null +++ b/tests/detect-bidir/test.rules @@ -0,0 +1,10 @@ +alert http any any => any any (msg:"matching both uri and status"; sid: 1; http.uri; content: "/download"; http.stat_code; content: "200";) +alert http any any => any any (msg:"not matching both uri and status"; sid: 2; http.uri; content: "/download"; http.stat_code; content: "404";) +alert http any any => any any (msg:"not matching both uri and status"; sid: 3; http.uri; content: "/upload"; http.stat_code; content: "200";) +alert http any any => any any (msg:"fast_pattern on to_client side"; sid: 7; http.uri; content: "down"; http.server; content: "Apache"; fast_pattern;) +alert http any any => any any (msg:"fast_pattern on to_client side but not matching"; sid: 8; http.uri; content: "upload"; http.server; content: "Apache"; fast_pattern;) +alert http any any => any any (msg:"disambiguated toclient"; sid: 11; http.uri; content: "/download"; http.stat_code; content: "200"; bidir.toclient; http.connection; content: "eep";) +alert http any any => any any (msg:"disambiguated toserver"; sid: 12; http.uri; content: "/download"; bidir.toserver; http.connection; content: "eep"; bidir.toclient; http.stat_code; content: "200";) +alert http any any => any any (msg:"disambiguated toclient, without other toclient"; sid: 13; http.uri; content: "/download"; bidir.toclient; http.connection; content: "eep";) +alert http any any => any any (msg:"disambiguated both sides"; sid: 14; bidir.toclient; http.connection; content: "eep"; bidir.toserver; http.connection; content: "eep";) +alert http any any => any any (msg:"toclient, followed by http.uri implicitly toserver"; sid: 15; bidir.toclient; http.connection; content: "eep"; http.uri; content: "/download"; ) diff --git a/tests/detect-bidir/test.yaml b/tests/detect-bidir/test.yaml new file mode 100644 index 000000000..5a56f45ec --- /dev/null +++ b/tests/detect-bidir/test.yaml @@ -0,0 +1,56 @@ +requires: + min-version: 8 + +pcap: ../http-all-headers/input.pcap + +checks: + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 1 + - filter: + count: 0 + match: + event_type: alert + alert.signature_id: 2 + - filter: + count: 0 + match: + event_type: alert + alert.signature_id: 3 + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 7 + - filter: + count: 0 + match: + event_type: alert + alert.signature_id: 8 + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 11 + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 12 + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 13 + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 14 + - filter: + count: 1 + match: + event_type: alert + alert.signature_id: 15 diff --git a/tests/rules/detect-bidir-http-rule/README.md b/tests/rules/detect-bidir-http-rule/README.md new file mode 100644 index 000000000..eaa073ab2 --- /dev/null +++ b/tests/rules/detect-bidir-http-rule/README.md @@ -0,0 +1,7 @@ +# Description + +Test bidirection rule with HTTP analysis + +# Ticket + +https://redmine.openinfosecfoundation.org/issues/5665 diff --git a/tests/rules/detect-bidir-http-rule/test.rules b/tests/rules/detect-bidir-http-rule/test.rules new file mode 100644 index 000000000..a3fe12307 --- /dev/null +++ b/tests/rules/detect-bidir-http-rule/test.rules @@ -0,0 +1 @@ +alert http1 any any => any any (msg:"matching both uri and status"; sid: 1; http.uri; content: "/download"; http.stat_code; content: "200";) \ No newline at end of file diff --git a/tests/rules/detect-bidir-http-rule/test.yaml b/tests/rules/detect-bidir-http-rule/test.yaml new file mode 100644 index 000000000..4eaae0e28 --- /dev/null +++ b/tests/rules/detect-bidir-http-rule/test.yaml @@ -0,0 +1,20 @@ +requires: + min-version: 8 + pcap: false + +args: + - --engine-analysis + +checks: +- filter: + filename: rules.json + count: 1 + match: + id: 1 + engines[0].name: "http_uri" + engines[0].direction: "toserver" + engines[0].app_proto: "http" + engines[1].name: "http_stat_code" + engines[1].direction: "toclient" + engines[1].app_proto: "http" + mpm.buffer: "http_uri" diff --git a/tests/rules/detect-bidir-ja3-rule/README.md b/tests/rules/detect-bidir-ja3-rule/README.md new file mode 100644 index 000000000..323964024 --- /dev/null +++ b/tests/rules/detect-bidir-ja3-rule/README.md @@ -0,0 +1,7 @@ +# Description + +Test bidirection rule with TLS ja3 analysis + +# Ticket + +https://redmine.openinfosecfoundation.org/issues/5665 diff --git a/tests/rules/detect-bidir-ja3-rule/test.rules b/tests/rules/detect-bidir-ja3-rule/test.rules new file mode 100644 index 000000000..7488fecb3 --- /dev/null +++ b/tests/rules/detect-bidir-ja3-rule/test.rules @@ -0,0 +1 @@ +alert tls any any => any any (msg:"bidir ja3"; ja3s.hash; content:"5d79edf64e03689ff559a54e9d9487bc"; ja3.string; content:"771,49196-49200"; sid:1;) diff --git a/tests/rules/detect-bidir-ja3-rule/test.yaml b/tests/rules/detect-bidir-ja3-rule/test.yaml new file mode 100644 index 000000000..681919061 --- /dev/null +++ b/tests/rules/detect-bidir-ja3-rule/test.yaml @@ -0,0 +1,20 @@ +requires: + min-version: 8 + pcap: false + +args: + - --engine-analysis + +checks: +- filter: + filename: rules.json + count: 1 + match: + id: 1 + engines[0].name: "ja3.string" + engines[0].direction: "toserver" + engines[0].app_proto: "tls" + engines[1].name: "ja3s.hash" + engines[1].direction: "toclient" + engines[1].app_proto: "tls" + mpm.buffer: "ja3.string"