From: Juliana Fajardini Date: Mon, 10 Jun 2024 23:38:46 +0000 (-0300) Subject: pgsql: add tests with alert metadata X-Git-Tag: suricata-7.0.7~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6eab6f9b387ac1bf57bf6d5019a36d5c12e5090f;p=thirdparty%2Fsuricata-verify.git pgsql: add tests with alert metadata Check for transaction metadata in PGSQL alerts. Add `engine-analysis` tests for the used rules, as well, to better describe them and compare with expected behavior. Related to Task #7000 --- diff --git a/tests/pgsql/pgsql-7000-ids/README.md b/tests/pgsql/pgsql-7000-ids/README.md new file mode 100644 index 000000000..bd3dffc6f --- /dev/null +++ b/tests/pgsql/pgsql-7000-ids/README.md @@ -0,0 +1,18 @@ +# Description + +Showcase engine behavior with simple pgsql stream rules and alert metadata. + +## Behavior + +The 2 rules will match on the PGSQL queries for `SELECT` (sid 1) and `DELETE FROM`, +(sid 2) with one extra alert for sid 1 due to the portion of the stream +containing the last seen SELECT after the real message was seen. + +## Pcap + +This test uses the pcap from PGSQL test `pgsql-simple-query-rollback` + +## Redmine ticket + +Partly related to: +https://redmine.openinfosecfoundation.org/issues/7000 diff --git a/tests/pgsql/pgsql-7000-ids/suricata.yaml b/tests/pgsql/pgsql-7000-ids/suricata.yaml new file mode 100644 index 000000000..aac151f99 --- /dev/null +++ b/tests/pgsql/pgsql-7000-ids/suricata.yaml @@ -0,0 +1,17 @@ +%YAML 1.1 +--- + +outputs: + - eve-log: + enabled: yes + filetype: regular + filename: eve.json + types: + - pgsql + - alert: + payload-printable: yes + +app-layer: + protocols: + pgsql: + enabled: yes diff --git a/tests/pgsql/pgsql-7000-ids/test.rules b/tests/pgsql/pgsql-7000-ids/test.rules new file mode 100644 index 000000000..9bb144115 --- /dev/null +++ b/tests/pgsql/pgsql-7000-ids/test.rules @@ -0,0 +1,5 @@ +# Rules are similar but would match on different postgresql transactions +# disclaimer: these rules are not a good example of pgsql rules for a real-life scenario, +# as there are no pgsql keywords used +alert pgsql any any -> any any (msg:"Pgsql table select"; content:"select"; nocase; sid:1;) +alert pgsql any any -> any any (msg:"Pgsql table delete"; content:"delete from"; nocase; sid:2;) diff --git a/tests/pgsql/pgsql-7000-ids/test.yaml b/tests/pgsql/pgsql-7000-ids/test.yaml new file mode 100644 index 000000000..fb7906c19 --- /dev/null +++ b/tests/pgsql/pgsql-7000-ids/test.yaml @@ -0,0 +1,183 @@ +requires: + min-version: 8 +args: +- -k none + +pcap: ../pgsql-simple-query-rollback/input.pcap + +checks: +- filter: + count: 9 + match: + event_type: alert +# check 2 +- filter: + count: 1 + match: + alert.signature: Pgsql table delete + alert.signature_id: 2 + app_proto: pgsql + direction: to_server + event_type: alert + payload_printable: Q....DELETE FROM new_table WHERE NAME='Remus';. + pcap_cnt: 21 + pgsql.request.simple_query: DELETE FROM new_table WHERE NAME='Remus'; + pgsql.response.command_completed: DELETE 1 + pgsql.tx_id: 6 + stream: 1 + tx_id: 5 +# check 3 +- filter: + count: 1 + match: + alert.signature: Pgsql table delete + alert.signature_id: 2 + app_proto: pgsql + direction: to_server + event_type: alert + payload_printable: Q...1DELETE FROM new_table WHERE NAME='Londubat';. + pcap_cnt: 24 + pgsql.request.simple_query: DELETE FROM new_table WHERE NAME='Londubat'; + pgsql.response.command_completed: DELETE 1 + pgsql.tx_id: 7 + stream: 1 + tx_id: 6 +# check 4 +- filter: + count: 1 + match: + alert.signature: Pgsql table delete + alert.signature_id: 2 + app_proto: pgsql + direction: to_server + event_type: alert + payload_printable: Q...1DELETE FROM new_table WHERE NAME='Hermione';. + pcap_cnt: 26 + pgsql.request.simple_query: DELETE FROM new_table WHERE NAME='Hermione'; + pgsql.response.command_completed: DELETE 1 + pgsql.tx_id: 8 + stream: 1 + tx_id: 7 +# check 5 +- filter: + count: 1 + match: + alert.signature: Pgsql table delete + alert.signature_id: 2 + app_proto: pgsql + direction: to_server + event_type: alert + payload_printable: Q.../DELETE FROM new_table WHERE NAME='Maugre';. + pcap_cnt: 28 + pgsql.request.simple_query: DELETE FROM new_table WHERE NAME='Maugre'; + pgsql.response.command_completed: DELETE 1 + pgsql.tx_id: 9 + stream: 1 + tx_id: 8 +# check 6 +- filter: + count: 1 + match: + alert.signature: Pgsql table select + alert.signature_id: 1 + app_proto: pgsql + direction: to_server + event_type: alert + payload_printable: Q....SELECT 1/0;. + pcap_cnt: 43 + pgsql.request.simple_query: SELECT 1/0; + pgsql.response.code: '22012' + pgsql.response.file: d:\pginstaller_13.auto\postgres.windows-x64\src\backend\utils\adt\int.c + pgsql.response.line: '824' + pgsql.response.message: division by zero + pgsql.response.routine: int4div + pgsql.response.severity_localizable: ERROR + pgsql.response.severity_non_localizable: ERROR + pgsql.tx_id: 14 + stream: 1 + tx_id: 13 +# check 7 +- filter: + count: 1 + match: + alert.signature: Pgsql table select + alert.signature_id: 1 + app_proto: pgsql + direction: to_server + event_type: alert + payload_printable: Q....SELECT * FROM new_table;. + pcap_cnt: 57 + pgsql.request.simple_query: SELECT * FROM new_table; + pgsql.response.code: 25P02 + pgsql.response.file: d:\pginstaller_13.auto\postgres.windows-x64\src\backend\tcop\postgres.c + pgsql.response.line: '1105' + pgsql.response.message: current transaction is aborted, commands ignored until + end of transaction block + pgsql.response.routine: exec_simple_query + pgsql.response.severity_localizable: ERROR + pgsql.response.severity_non_localizable: ERROR + pgsql.tx_id: 17 + stream: 1 + tx_id: 16 +# check 8 +- filter: + count: 1 + match: + alert.signature: Pgsql table select + alert.signature_id: 1 + app_proto: pgsql + direction: to_server + event_type: alert + payload_printable: Q....SELECT 1/0;. + pcap_cnt: 76 + pgsql.request.simple_query: SELECT 1/0; + pgsql.response.code: '22012' + pgsql.response.file: d:\pginstaller_13.auto\postgres.windows-x64\src\backend\utils\adt\int.c + pgsql.response.line: '824' + pgsql.response.message: division by zero + pgsql.response.routine: int4div + pgsql.response.severity_localizable: ERROR + pgsql.response.severity_non_localizable: ERROR + pgsql.tx_id: 23 + stream: 1 + tx_id: 22 +# check 9 +- filter: + count: 1 + match: + alert.signature: Pgsql table select + alert.signature_id: 1 + app_proto: pgsql + direction: to_server + event_type: alert + payload_printable: Q....SELECT * FROM new_table;. + pcap_cnt: 84 + pgsql.request.simple_query: SELECT * FROM new_table; + pgsql.response.command_completed: SELECT 8 + pgsql.response.data_rows: 8 + pgsql.response.data_size: 236 + pgsql.response.field_count: 2 + pgsql.tx_id: 26 + stream: 1 + tx_id: 25 +# check 10 +- filter: + count: 1 + match: + alert.signature: Pgsql table select + alert.signature_id: 1 + app_proto: pgsql + direction: to_client + event_type: alert + payload_printable: "T...5..name...@*..............email...@*...........\"..D...1.....\n\ + Dumbledore....prof_dumbledore@gmail.comD...2.....\nMcGonagall....prof_mc.gonagall@gmail.comD...'......Rogue....prof_rogue@yahoo.comD...)......Hagrid....prof_hagrid@gmail.comD...,......Hermione....prof_gramger@gmail.comD...'......Remus....prof_lupin@gmail.comD...)......Maugre....prof_folloy@gmail.comD...-......Londubat....prof_londubat@gmail.comC...\r\ + SELECT 8.Z....I" + pcap_cnt: 87 + pgsql.request.simple_query: SELECT * FROM new_table; + pgsql.response.command_completed: SELECT 8 + pgsql.response.data_rows: 8 + pgsql.response.data_size: 236 + pgsql.response.field_count: 2 + pgsql.tx_id: 26 + stream: 1 + tx_id: 25 diff --git a/tests/rules/pgsql-7000/suricata.yaml b/tests/rules/pgsql-7000/suricata.yaml new file mode 100644 index 000000000..d6dd6a58c --- /dev/null +++ b/tests/rules/pgsql-7000/suricata.yaml @@ -0,0 +1,22 @@ +%YAML 1.1 +--- + +outputs: + - eve-log: + enabled: yes + filetype: regular + filename: eve.json + types: + - pgsql + - alert: + payload: yes + payload-printable: yes + packet: yes + +engine-analysis: + rules: yes + +app-layer: + protocols: + pgsql: + enabled: yes diff --git a/tests/rules/pgsql-7000/test.rules b/tests/rules/pgsql-7000/test.rules new file mode 100644 index 000000000..c2a60ed6f --- /dev/null +++ b/tests/rules/pgsql-7000/test.rules @@ -0,0 +1,4 @@ +# disclaimer: these rules are not a good example of pgsql rules for a real-life scenario, +# as there are no pgsql keywords used +alert pgsql any any -> any any (msg:"Pgsql table select"; content:"select"; nocase; sid:1;) +alert pgsql any any -> any any (msg:"Pgsql table delete"; content:"delete from"; nocase; sid:2;) diff --git a/tests/rules/pgsql-7000/test.yaml b/tests/rules/pgsql-7000/test.yaml new file mode 100644 index 000000000..ef41a0e4b --- /dev/null +++ b/tests/rules/pgsql-7000/test.yaml @@ -0,0 +1,92 @@ +requires: + pcap: false + min-version: 7 + +args: +- --engine-analysis + +checks: +- filter: + filename: rules.json + count: 1 + match: + id: 1 + raw: "alert pgsql any any -> any any (msg:\"Pgsql table select\"; content:\"select\"; nocase; sid:1;)" + app_proto: "pgsql" + requirements[0]: "payload" + requirements[1]: "flow" + type: "stream" + flags[0]: "src_any" + flags[1]: "dst_any" + flags[2]: "sp_any" + flags[3]: "dp_any" + flags[4]: "applayer" + flags[5]: "need_stream" + flags[6]: "toserver" + flags[7]: "toclient" + flags[8]: "prefilter" + pkt_engines[0].name: "payload" + pkt_engines[0].is_mpm: true + lists.payload.matches[0].name: content + lists.payload.matches[0].content.pattern: "select" + lists.payload.matches[0].content.length: 6 + lists.payload.matches[0].content.nocase: true + lists.payload.matches[0].content.negated: false + lists.payload.matches[0].content.starts_with: false + lists.payload.matches[0].content.ends_with: false + lists.payload.matches[0].content.is_mpm: true + lists.payload.matches[0].content.no_double_inspect: true + lists.payload.matches[0].content.fast_pattern: false + lists.payload.matches[0].content.relative_next: false + mpm.buffer: "payload" + mpm.pattern: "select" + mpm.length: 6 + mpm.nocase: true + mpm.starts_with: false + mpm.ends_with: false + mpm.is_mpm: true + mpm.no_double_inspect: true + mpm.fast_pattern: false + mpm.relative_next: false +- filter: + filename: rules.json + count: 1 + match: + id: 2 + raw: "alert pgsql any any -> any any (msg:\"Pgsql table delete\"; content:\"delete from\"; nocase; sid:2;)" + app_proto: "pgsql" + requirements[0]: "payload" + requirements[1]: "flow" + type: "stream" + flags[0]: "src_any" + flags[1]: "dst_any" + flags[2]: "sp_any" + flags[3]: "dp_any" + flags[4]: "applayer" + flags[5]: "need_stream" + flags[6]: "toserver" + flags[7]: "toclient" + flags[8]: "prefilter" + pkt_engines[0].name: "payload" + pkt_engines[0].is_mpm: true + lists.payload.matches[0].name: content + lists.payload.matches[0].content.pattern: "delete|20|from" + lists.payload.matches[0].content.length: 11 + lists.payload.matches[0].content.nocase: true + lists.payload.matches[0].content.negated: false + lists.payload.matches[0].content.starts_with: false + lists.payload.matches[0].content.ends_with: false + lists.payload.matches[0].content.is_mpm: true + lists.payload.matches[0].content.no_double_inspect: true + lists.payload.matches[0].content.fast_pattern: false + lists.payload.matches[0].content.relative_next: false + mpm.buffer: "payload" + mpm.pattern: "delete|20|from" + mpm.length: 11 + mpm.nocase: true + mpm.starts_with: false + mpm.ends_with: false + mpm.is_mpm: true + mpm.no_double_inspect: true + mpm.fast_pattern: false + mpm.relative_next: false