mirror of https://github.com/OISF/suricata
pgsql: add query keyword
Add the `pgsql.query` rule keyword to match on PGSQL's query request message contents. This currently matches on the EVE field: pgsql.request.simple_query `pgsql.query` is a sticky buffer and can be used as a fast_pattern. Task #6259pull/13331/head
parent
5a5b48179a
commit
404bb53ce9
@ -0,0 +1,33 @@
|
|||||||
|
PGSQL Keywords
|
||||||
|
##############
|
||||||
|
|
||||||
|
.. role:: example-rule-emphasis
|
||||||
|
|
||||||
|
pgsql.query
|
||||||
|
***********
|
||||||
|
|
||||||
|
This keyword is a sticky buffer that allows matching on the contents of
|
||||||
|
PostgreSQL's `query` request messages parsed by the engine. Note that this
|
||||||
|
buffer inspects only the `string` portion of the PostgreSQL message, skipping
|
||||||
|
other fields such as identifier and length, and focusing on the query itself.
|
||||||
|
|
||||||
|
Currently, it exposes the contents of the ``pgsql.request.simple_query`` field
|
||||||
|
from EVE output.
|
||||||
|
|
||||||
|
``pgsql.query`` can be used as a ``fast_pattern``
|
||||||
|
(see :ref:`rules-keyword-fast_pattern`).
|
||||||
|
|
||||||
|
Use ``nocase`` with this keyword to avoid case sensitivity for the matches.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
========
|
||||||
|
|
||||||
|
.. container:: example-rule
|
||||||
|
|
||||||
|
alert pgsql any any -> any any (msg:"Simple SELECT rule";
|
||||||
|
:example-rule-emphasis:`pgsql.query; content:"SELECT \*";` sid:1;)
|
||||||
|
|
||||||
|
.. container:: example-rule
|
||||||
|
|
||||||
|
alert pgsql any any -> any any (msg:"Simple delete rule";
|
||||||
|
:example-rule-emphasis:`pgsql.query; content:"delete"; nocase` sid:2;)
|
@ -0,0 +1,76 @@
|
|||||||
|
/* Copyright (C) 2025 Open Information Security Foundation
|
||||||
|
*
|
||||||
|
* You can copy, redistribute or modify this Program under the terms of
|
||||||
|
* the GNU General Public License version 2 as published by the Free
|
||||||
|
* Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* version 2 along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// written by Juliana Fajardini <jufajardini@oisf.net>
|
||||||
|
|
||||||
|
use super::pgsql::{PgsqlTransaction, ALPROTO_PGSQL};
|
||||||
|
use crate::pgsql::parser::PgsqlFEMessage;
|
||||||
|
use crate::core::{STREAM_TOSERVER};
|
||||||
|
use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer};
|
||||||
|
use suricata_sys::sys::{
|
||||||
|
DetectEngineCtx, SCDetectBufferSetActiveList, SCDetectHelperBufferMpmRegister, SCDetectSignatureSetAppProto,
|
||||||
|
Signature,
|
||||||
|
};
|
||||||
|
use std::os::raw::{c_int, c_void};
|
||||||
|
|
||||||
|
static mut G_PGSQL_QUERY_BUFFER_ID: c_int = 0;
|
||||||
|
|
||||||
|
unsafe extern "C" fn pgsql_detect_query_setup(
|
||||||
|
de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,) -> c_int
|
||||||
|
{
|
||||||
|
if SCDetectSignatureSetAppProto(s, ALPROTO_PGSQL) != 0 {
|
||||||
|
return - 1;
|
||||||
|
}
|
||||||
|
if SCDetectBufferSetActiveList(de, s, G_PGSQL_QUERY_BUFFER_ID) < 0 {
|
||||||
|
return - 1;
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn pgsql_detect_query_get_data(
|
||||||
|
tx: *const c_void, _flags: u8, buffer: *mut *const u8, buffer_len: *mut u32,
|
||||||
|
) -> bool {
|
||||||
|
let tx = cast_pointer!(tx, PgsqlTransaction);
|
||||||
|
|
||||||
|
if let Some(PgsqlFEMessage::SimpleQuery(ref query)) = &tx.request {
|
||||||
|
*buffer = query.payload.as_ptr();
|
||||||
|
*buffer_len = query.payload.len() as u32;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer = std::ptr::null();
|
||||||
|
*buffer_len = 0;
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn SCDetectPgsqlRegister() {
|
||||||
|
let kw = SigTableElmtStickyBuffer {
|
||||||
|
name: String::from("pgsql.query"),
|
||||||
|
desc: String::from("match PGSQL query request content"),
|
||||||
|
url: String::from("/rules/pgsql-keywords.html#pgsql.query"),
|
||||||
|
setup: pgsql_detect_query_setup,
|
||||||
|
};
|
||||||
|
let _g_pgsql_query_kw_id = helper_keyword_register_sticky_buffer(&kw);
|
||||||
|
G_PGSQL_QUERY_BUFFER_ID = SCDetectHelperBufferMpmRegister(
|
||||||
|
b"pgsql.query\0".as_ptr() as *const libc::c_char,
|
||||||
|
b"pgsql query request content\0".as_ptr() as *const libc::c_char,
|
||||||
|
ALPROTO_PGSQL,
|
||||||
|
STREAM_TOSERVER,
|
||||||
|
Some(pgsql_detect_query_get_data),
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue