-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MySQL: parser v2 #12541
base: master
Are you sure you want to change the base?
MySQL: parser v2 #12541
Changes from all commits
f6fcdca
5714416
5c7b64b
bfc207a
4dc6b73
3eb00cf
1b16bcd
e6ebdea
67eb48e
25b613b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
MySQL Keywords | ||
============ | ||
|
||
The MySQL keywords are implemented and can be used to match on fields in MySQL messages. | ||
|
||
============================== ================== | ||
Keyword Direction | ||
============================== ================== | ||
mysql.command Request | ||
mysql.rows Response | ||
============================== ================== | ||
|
||
mysql.command | ||
---------- | ||
|
||
This keyword matches on the query statement like `select * from xxx where yyy = zzz` found in a MySQL request. | ||
|
||
Syntax | ||
~~~~~~ | ||
|
||
:: | ||
|
||
mysql.command; content:<command>; | ||
|
||
Examples | ||
~~~~~~~~ | ||
|
||
:: | ||
|
||
mysql.commands; content:"select"; | ||
|
||
mysql.rows | ||
------- | ||
|
||
This keyword matches on the rows which come from query statement result found in a Mysql response. | ||
row format: 1,foo,bar | ||
|
||
Syntax | ||
~~~~~~ | ||
|
||
:: | ||
|
||
mysql.rows; content:<rows>; | ||
|
||
Examples | ||
~~~~~~~~ | ||
|
||
:: | ||
|
||
mysql.rows; content:"foo,bar"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2409,6 +2409,35 @@ | |
}, | ||
"additionalProperties": false | ||
}, | ||
"mysql": { | ||
"type": "object", | ||
"optional": true, | ||
"properties": { | ||
"version": { | ||
"type": "string", | ||
"description": "Mysql server version" | ||
}, | ||
"tls": { | ||
"type": "boolean" | ||
}, | ||
"command": { | ||
"type": "string", | ||
"description": "sql query statement or some utility commands like ping." | ||
}, | ||
"affected_rows": { | ||
"type": "integer" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Description please. |
||
}, | ||
"rows": { | ||
"type": "array", | ||
"optional": true, | ||
"minItems": 1, | ||
"items": { | ||
"type": "string" | ||
}, | ||
"description": "Comma separated result from sql statement" | ||
} | ||
} | ||
}, | ||
"ldap": { | ||
"type": "object", | ||
"optional": true, | ||
|
@@ -4689,6 +4718,10 @@ | |
"description": "Errors encountered parsing MQTT protocol", | ||
"$ref": "#/$defs/stats_applayer_error" | ||
}, | ||
"mysql": { | ||
"description": "Errors encountered parsing MySQL protocol", | ||
"$ref": "#/$defs/stats_applayer_error" | ||
}, | ||
"nfs_tcp": { | ||
"description": "Errors encountered parsing NFS/TCP protocol", | ||
"$ref": "#/$defs/stats_applayer_error" | ||
|
@@ -4864,6 +4897,10 @@ | |
"description": "Number of flows for MQTT protocol", | ||
"type": "integer" | ||
}, | ||
"mysql": { | ||
"description": "Number of flows for MySQL protocol", | ||
"type": "integer" | ||
}, | ||
"nfs_tcp": { | ||
"description": "Number of flows for NFS/TCP protocol", | ||
"type": "integer" | ||
|
@@ -5034,6 +5071,10 @@ | |
"description": "Number of transactions for MQTT protocol", | ||
"type": "integer" | ||
}, | ||
"mysql": { | ||
"description": "Number of flows for MySQL protocol", | ||
"type": "integer" | ||
}, | ||
"nfs_tcp": { | ||
"description": "Number of transactions for NFS/TCP protocol", | ||
"type": "integer" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
/* Copyright (C) 2024 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. | ||
*/ | ||
|
||
// Author: QianKaiLin <[email protected]> | ||
|
||
/// Detect | ||
/// Get the mysql query | ||
use super::mysql::{MysqlTransaction, ALPROTO_MYSQL}; | ||
use crate::detect::{ | ||
DetectBufferSetActiveList, DetectHelperBufferMpmRegister, DetectHelperGetData, | ||
DetectHelperGetMultiData, DetectHelperKeywordRegister, DetectHelperMultiBufferMpmRegister, | ||
DetectSignatureSetAppProto, SCSigTableElmt, SIGMATCH_NOOPT, | ||
}; | ||
use std::os::raw::{c_int, c_void}; | ||
|
||
static mut G_MYSQL_COMMAND_BUFFER_ID: c_int = 0; | ||
static mut G_MYSQL_ROWS_BUFFER_ID: c_int = 0; | ||
|
||
#[no_mangle] | ||
unsafe extern "C" fn SCMysqlCommandSetup( | ||
Comment on lines
+33
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No pub, and only used by function pointer, this doesn't have to be |
||
de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, | ||
) -> c_int { | ||
if DetectSignatureSetAppProto(s, ALPROTO_MYSQL) != 0 { | ||
return -1; | ||
} | ||
if DetectBufferSetActiveList(de, s, G_MYSQL_COMMAND_BUFFER_ID) < 0 { | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
#[no_mangle] | ||
unsafe extern "C" fn SCMysqlGetCommand( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, no pub, probably doesn't need no_mangle. |
||
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, | ||
tx: *const c_void, list_id: c_int, | ||
) -> *mut c_void { | ||
return DetectHelperGetData( | ||
de, | ||
transforms, | ||
flow, | ||
flow_flags, | ||
tx, | ||
list_id, | ||
SCMysqlGetCommandData, | ||
); | ||
} | ||
|
||
#[no_mangle] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, no_mangle not needed. |
||
unsafe extern "C" fn SCMysqlGetCommandData( | ||
tx: *const c_void, _flags: u8, buf: *mut *const u8, len: *mut u32, | ||
) -> bool { | ||
let tx = cast_pointer!(tx, MysqlTransaction); | ||
if let Some(command) = &tx.command { | ||
if !command.is_empty() { | ||
*buf = command.as_ptr(); | ||
*len = command.len() as u32; | ||
return true; | ||
} | ||
} | ||
|
||
false | ||
} | ||
|
||
#[no_mangle] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unneeded |
||
unsafe extern "C" fn SCMysqlRowsSetup( | ||
de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, | ||
) -> c_int { | ||
if DetectSignatureSetAppProto(s, ALPROTO_MYSQL) != 0 { | ||
return -1; | ||
} | ||
if DetectBufferSetActiveList(de, s, G_MYSQL_ROWS_BUFFER_ID) < 0 { | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
#[no_mangle] | ||
unsafe extern "C" fn SCMysqlGetRows( | ||
Comment on lines
+91
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unneeded no_mangle. |
||
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, | ||
tx: *const c_void, list_id: c_int, local_id: u32, | ||
) -> *mut c_void { | ||
return DetectHelperGetMultiData( | ||
de, | ||
transforms, | ||
flow, | ||
flow_flags, | ||
tx, | ||
list_id, | ||
local_id, | ||
SCMysqlGetRowsData, | ||
); | ||
} | ||
|
||
/// Get the mysql rows at index i | ||
#[no_mangle] | ||
pub unsafe extern "C" fn SCMysqlGetRowsData( | ||
Comment on lines
+109
to
+110
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
tx: *const c_void, _flow_flags: u8, local_id: u32, buf: *mut *const u8, len: *mut u32, | ||
) -> bool { | ||
let tx = cast_pointer!(tx, MysqlTransaction); | ||
if let Some(rows) = &tx.rows { | ||
if !rows.is_empty() { | ||
let index = local_id as usize; | ||
if let Some(row) = rows.get(index) { | ||
*buf = row.as_ptr(); | ||
*len = row.len() as u32; | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
false | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn ScDetectMysqlRegister() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefix should be |
||
let kw = SCSigTableElmt { | ||
name: b"mysql.command\0".as_ptr() as *const libc::c_char, | ||
desc: b"sticky buffer to match on the MySQL command\0".as_ptr() as *const libc::c_char, | ||
url: b"/rules/mysql-keywords.html#mysql-command\0".as_ptr() as *const libc::c_char, | ||
Setup: SCMysqlCommandSetup, | ||
flags: SIGMATCH_NOOPT, | ||
AppLayerTxMatch: None, | ||
Free: None, | ||
}; | ||
let _g_mysql_command_kw_id = DetectHelperKeywordRegister(&kw); | ||
G_MYSQL_COMMAND_BUFFER_ID = DetectHelperBufferMpmRegister( | ||
b"mysql.command\0".as_ptr() as *const libc::c_char, | ||
b"mysql.command\0".as_ptr() as *const libc::c_char, | ||
ALPROTO_MYSQL, | ||
false, | ||
true, | ||
SCMysqlGetCommand, | ||
); | ||
let kw = SCSigTableElmt { | ||
name: b"mysql.rows\0".as_ptr() as *const libc::c_char, | ||
desc: b"sticky buffer to match on the MySQL Rows\0".as_ptr() as *const libc::c_char, | ||
url: b"/rules/mysql-keywords.html#mysql-rows\0".as_ptr() as *const libc::c_char, | ||
Setup: SCMysqlRowsSetup, | ||
flags: SIGMATCH_NOOPT, | ||
AppLayerTxMatch: None, | ||
Free: None, | ||
}; | ||
let _g_mysql_rows_kw_id = DetectHelperKeywordRegister(&kw); | ||
G_MYSQL_ROWS_BUFFER_ID = DetectHelperMultiBufferMpmRegister( | ||
b"mysql.rows\0".as_ptr() as *const libc::c_char, | ||
b"mysql select statement resultset\0".as_ptr() as *const libc::c_char, | ||
ALPROTO_MYSQL, | ||
true, | ||
false, | ||
SCMysqlGetRows, | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description please.