Skip to content

Commit

Permalink
pgsql: add tests with alert metadata
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jufajardini committed Aug 30, 2024
1 parent 0a3ea82 commit 2029d02
Show file tree
Hide file tree
Showing 7 changed files with 337 additions and 0 deletions.
18 changes: 18 additions & 0 deletions tests/pgsql/pgsql-7000-ids/README.md
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions tests/pgsql/pgsql-7000-ids/suricata.yaml
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions tests/pgsql/pgsql-7000-ids/test.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Rules are similar but would match on different postgresql transactions
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;)
183 changes: 183 additions & 0 deletions tests/pgsql/pgsql-7000-ids/test.yaml
Original file line number Diff line number Diff line change
@@ -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\
[email protected].....\n[email protected]...'[email protected]...)[email protected]...,[email protected]...'[email protected]...)[email protected][email protected]...\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
22 changes: 22 additions & 0 deletions tests/rules/pgsql-7000/suricata.yaml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions tests/rules/pgsql-7000/test.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
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;)
92 changes: 92 additions & 0 deletions tests/rules/pgsql-7000/test.yaml
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 2029d02

Please sign in to comment.