forked from OISF/suricata
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ldap.request.operation matches on Lightweight Directory Access Protocol request operations It is an unsigned 8-bit integer Doesn't support prefiltering Ticket: OISF#7453
- Loading branch information
1 parent
8f6795d
commit 261b4f4
Showing
7 changed files
with
253 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,3 +50,4 @@ Suricata Rules | |
multi-buffer-matching | ||
tag | ||
vlan-keywords | ||
ldap-keywords |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
LDAP Keywords | ||
============= | ||
|
||
.. role:: example-rule-action | ||
.. role:: example-rule-header | ||
.. role:: example-rule-options | ||
.. role:: example-rule-emphasis | ||
|
||
LDAP Request and Response operations | ||
------------------------------------ | ||
|
||
.. table:: **Operation values for ldap.request.operation and ldap.responses.operation keywords** | ||
|
||
==== ================================================ | ||
Code Operation | ||
==== ================================================ | ||
0 bind_request | ||
1 bind_response | ||
2 unbind_request | ||
3 search_request | ||
4 search_result_entry | ||
5 search_result_done | ||
6 modify_request | ||
7 modify_response | ||
8 add_request | ||
9 add_response | ||
10 del_request | ||
11 del_response | ||
12 mod_dn_request | ||
13 mod_dn_response | ||
14 compare_request | ||
15 compare_response | ||
16 abandon_request | ||
19 search_result_reference | ||
23 extended_request | ||
24 extended_response | ||
25 intermediate_response | ||
==== ================================================ | ||
|
||
The keywords ldap.request.operation and ldap.responses.operation | ||
accept both the operation code and the operation name as arguments. | ||
|
||
ldap.request.operation | ||
---------------------- | ||
|
||
Suricata has a ``ldap.request.operation`` keyword that can be used in signatures to identify | ||
and filter network packets based on Lightweight Directory Access Protocol request operations. | ||
|
||
Syntax:: | ||
|
||
ldap.request.operation: operation; | ||
|
||
ldap.request.operation uses :ref:`unsigned 8-bit integer <rules-integer-keywords>`. | ||
|
||
Examples | ||
^^^^^^^^ | ||
|
||
Example of a signatures that would alert if the packet has an LDAP bind request operation: | ||
|
||
.. container:: example-rule | ||
|
||
alert tcp any any -> any any (msg:"Test LDAP bind request"; :example-rule-emphasis:`ldap.request.operation:0;` sid:1;) | ||
|
||
.. container:: example-rule | ||
|
||
alert tcp any any -> any any (msg:"Test LDAP bind request"; :example-rule-emphasis:`ldap.request.operation:bind_request;` sid:1;) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* 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. | ||
*/ | ||
|
||
use super::ldap::{LdapTransaction, ALPROTO_LDAP}; | ||
use crate::detect::uint::{ | ||
detect_parse_uint_enum, rs_detect_u32_free, rs_detect_u32_match, rs_detect_u32_parse, | ||
rs_detect_u8_free, rs_detect_u8_match, DetectUintData, | ||
}; | ||
use crate::detect::{ | ||
DetectHelperBufferRegister, DetectHelperKeywordRegister, DetectSignatureSetAppProto, | ||
SCSigTableElmt, SigMatchAppendSMToList, | ||
}; | ||
use crate::ldap::types::{LdapMessage, ProtocolOpCode}; | ||
|
||
use std::ffi::CStr; | ||
use std::os::raw::{c_int, c_void}; | ||
use std::str::FromStr; | ||
|
||
#[derive(Debug, PartialEq)] | ||
enum LdapIndex { | ||
Any, | ||
All, | ||
Index(i32), | ||
} | ||
|
||
#[derive(Debug, PartialEq)] | ||
struct DetectLdapRespData { | ||
/// Ldap response code | ||
pub response: DetectUintData<u8>, | ||
/// Index can be Any to match with any responses index, | ||
/// All to match if all indices, or an i32 integer | ||
/// Negative values represent back to front indexing. | ||
pub index: LdapIndex, | ||
} | ||
|
||
static mut G_LDAP_REQUEST_OPERATION_KW_ID: c_int = 0; | ||
static mut G_LDAP_REQUEST_OPERATION_BUFFER_ID: c_int = 0; | ||
|
||
unsafe extern "C" fn ldap_parse_protocol_req_op( | ||
ustr: *const std::os::raw::c_char, | ||
) -> *mut DetectUintData<u8> { | ||
let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe | ||
if let Ok(s) = ft_name.to_str() { | ||
if let Some(ctx) = detect_parse_uint_enum::<u8, ProtocolOpCode>(s) { | ||
let boxed = Box::new(ctx); | ||
return Box::into_raw(boxed) as *mut _; | ||
} | ||
} | ||
return std::ptr::null_mut(); | ||
} | ||
|
||
unsafe extern "C" fn ldap_detect_request_operation_setup( | ||
de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, | ||
) -> c_int { | ||
if DetectSignatureSetAppProto(s, ALPROTO_LDAP) != 0 { | ||
return -1; | ||
} | ||
let ctx = ldap_parse_protocol_req_op(raw) as *mut c_void; | ||
if ctx.is_null() { | ||
return -1; | ||
} | ||
if SigMatchAppendSMToList( | ||
de, | ||
s, | ||
G_LDAP_REQUEST_OPERATION_KW_ID, | ||
ctx, | ||
G_LDAP_REQUEST_OPERATION_BUFFER_ID, | ||
) | ||
.is_null() | ||
{ | ||
ldap_detect_request_free(std::ptr::null_mut(), ctx); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
unsafe extern "C" fn ldap_detect_request_operation_match( | ||
_de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, | ||
_sig: *const c_void, ctx: *const c_void, | ||
) -> c_int { | ||
let tx = cast_pointer!(tx, LdapTransaction); | ||
let ctx = cast_pointer!(ctx, DetectUintData<u8>); | ||
if let Some(request) = &tx.request { | ||
let option = request.protocol_op.to_u8(); | ||
return rs_detect_u8_match(option, ctx); | ||
} | ||
return 0; | ||
} | ||
|
||
unsafe extern "C" fn ldap_detect_request_free(_de: *mut c_void, ctx: *mut c_void) { | ||
// Just unbox... | ||
let ctx = cast_pointer!(ctx, DetectUintData<u8>); | ||
rs_detect_u8_free(ctx); | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn ScDetectLdapRegister() { | ||
let kw = SCSigTableElmt { | ||
name: b"ldap.request.operation\0".as_ptr() as *const libc::c_char, | ||
desc: b"match LDAP request operation\0".as_ptr() as *const libc::c_char, | ||
url: b"/rules/ldap-keywords.html#ldap.request.operation\0".as_ptr() as *const libc::c_char, | ||
AppLayerTxMatch: Some(ldap_detect_request_operation_match), | ||
Setup: ldap_detect_request_operation_setup, | ||
Free: Some(ldap_detect_request_free), | ||
flags: 0, | ||
}; | ||
G_LDAP_REQUEST_OPERATION_KW_ID = DetectHelperKeywordRegister(&kw); | ||
G_LDAP_REQUEST_OPERATION_BUFFER_ID = DetectHelperBufferRegister( | ||
b"ldap.request.operation\0".as_ptr() as *const libc::c_char, | ||
ALPROTO_LDAP, | ||
false, //to client | ||
true, //to server | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
|
||
// written by Giuseppe Longo <[email protected]> | ||
|
||
pub mod detect; | ||
pub mod filters; | ||
pub mod ldap; | ||
pub mod logger; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters