diff --git a/rust/src/dcerpc/detect.rs b/rust/src/dcerpc/detect.rs index df3da3d56b..511161a8bb 100644 --- a/rust/src/dcerpc/detect.rs +++ b/rust/src/dcerpc/detect.rs @@ -21,7 +21,7 @@ use super::dcerpc::{ }; use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER}; use crate::detect::uint::{detect_match_uint, detect_parse_uint, DetectUintData}; -use crate::smb::detect::smb_tx_match_dce_opnum; +use crate::smb::detect::{smb_tx_match_dce_iface, smb_tx_match_dce_opnum}; use crate::smb::smb::ALPROTO_SMB; use std::ffi::CStr; use std::os::raw::{c_char, c_int, c_void}; @@ -76,7 +76,7 @@ pub(crate) enum DCEOpnumData { fn match_backuuid( tx: &DCERPCTransaction, state: &mut DCERPCState, if_data: &mut DCEIfaceData, -) -> u8 { +) -> c_int { let mut ret = 0; if !state.interface_uuids.is_empty() { for uuidentry in &state.interface_uuids { @@ -101,7 +101,7 @@ fn match_backuuid( } } let ctxid = tx.get_req_ctxid(); - ret &= (uuidentry.ctxid == ctxid) as u8; + ret &= (uuidentry.ctxid == ctxid) as c_int; if ret == 0 { SCLogDebug!("CTX IDs/UUIDs do not match"); continue; @@ -228,10 +228,13 @@ fn parse_opnum_data(arg: &str) -> Result { return Err(()); } -#[no_mangle] -pub extern "C" fn SCDcerpcIfaceMatch( - tx: &DCERPCTransaction, state: &mut DCERPCState, if_data: &mut DCEIfaceData, -) -> u8 { +unsafe fn dcerpc_tx_match_dce_iface( + tx: *mut c_void, state: *mut c_void, if_data: *const SigMatchCtx, +) -> c_int { + let tx = cast_pointer!(tx, DCERPCTransaction); + let state = cast_pointer!(state, DCERPCState); + let if_data = cast_pointer!(if_data, DCEIfaceData); + let first_req_seen = tx.get_first_req_seen(); if first_req_seen == 0 { return 0; @@ -244,11 +247,21 @@ pub extern "C" fn SCDcerpcIfaceMatch( return match_backuuid(tx, state, if_data); } -#[no_mangle] -pub unsafe extern "C" fn SCDcerpcIfaceParse(carg: *const c_char) -> *mut c_void { - if carg.is_null() { - return std::ptr::null_mut(); +unsafe extern "C" fn dcerpc_iface_match( + _de: *mut DetectEngineThreadCtx, f: *mut crate::flow::Flow, _flags: u8, state: *mut c_void, + tx: *mut c_void, _sig: *const Signature, ctx: *const SigMatchCtx, +) -> c_int { + if SCFlowGetAppProtocol(f) == ALPROTO_DCERPC { + return dcerpc_tx_match_dce_iface(tx, state, ctx); + } + if smb_tx_match_dce_iface(state, tx, ctx) != 1 { + return 0; } + + return 1; +} + +unsafe fn dcerpc_iface_parse(carg: *const c_char) -> *mut c_void { let arg = match CStr::from_ptr(carg).to_str() { Ok(arg) => arg, _ => { @@ -262,8 +275,32 @@ pub unsafe extern "C" fn SCDcerpcIfaceParse(carg: *const c_char) -> *mut c_void } } -#[no_mangle] -pub unsafe extern "C" fn SCDcerpcIfaceFree(ptr: *mut c_void) { +unsafe extern "C" fn dcerpc_iface_setup( + de: *mut DetectEngineCtx, s: *mut Signature, raw: *const libc::c_char, +) -> c_int { + if SCDetectSignatureSetAppProto(s, ALPROTO_DCERPC) != 0 { + return -1; + } + let ctx = dcerpc_iface_parse(raw); + if ctx.is_null() { + return -1; + } + if SCSigMatchAppendSMToList( + de, + s, + G_DCERPC_IFACE_KW_ID, + ctx as *mut SigMatchCtx, + G_DCERPC_GENERIC_BUFFER_ID, + ) + .is_null() + { + dcerpc_iface_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; +} + +unsafe extern "C" fn dcerpc_iface_free(_de: *mut DetectEngineCtx, ptr: *mut c_void) { if !ptr.is_null() { std::mem::drop(Box::from_raw(ptr as *mut DCEIfaceData)); } @@ -325,7 +362,7 @@ unsafe extern "C" fn dcerpc_opnum_setup( s, G_DCERPC_OPNUM_KW_ID, ctx as *mut SigMatchCtx, - G_DCERPC_OPNUM_BUFFER_ID, + G_DCERPC_GENERIC_BUFFER_ID, ) .is_null() { @@ -356,7 +393,8 @@ unsafe extern "C" fn dcerpc_opnum_free(_de: *mut DetectEngineCtx, ptr: *mut c_vo } static mut G_DCERPC_OPNUM_KW_ID: u16 = 0; -static mut G_DCERPC_OPNUM_BUFFER_ID: c_int = 0; +static mut G_DCERPC_GENERIC_BUFFER_ID: c_int = 0; +static mut G_DCERPC_IFACE_KW_ID: u16 = 0; #[no_mangle] pub unsafe extern "C" fn SCDetectDcerpcRegister() { @@ -371,14 +409,14 @@ pub unsafe extern "C" fn SCDetectDcerpcRegister() { flags: 0, }; G_DCERPC_OPNUM_KW_ID = SCDetectHelperKeywordRegister(&kw); - G_DCERPC_OPNUM_BUFFER_ID = SCDetectHelperBufferProgressRegister( - b"dcerpc_opnum\0".as_ptr() as *const libc::c_char, + G_DCERPC_GENERIC_BUFFER_ID = SCDetectHelperBufferProgressRegister( + b"dce_generic\0".as_ptr() as *const libc::c_char, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_TOCLIENT, 0, ); _ = SCDetectHelperBufferProgressRegister( - b"dcerpc_opnum\0".as_ptr() as *const libc::c_char, + b"dce_generic\0".as_ptr() as *const libc::c_char, ALPROTO_SMB, STREAM_TOSERVER | STREAM_TOCLIENT, 0, @@ -387,6 +425,22 @@ pub unsafe extern "C" fn SCDetectDcerpcRegister() { G_DCERPC_OPNUM_KW_ID, b"dce_opnum\0".as_ptr() as *const libc::c_char, ); + + let kw = SCSigTableAppLiteElmt { + name: b"dcerpc.iface\0".as_ptr() as *const libc::c_char, + desc: b"match on the value of the interface UUID in a DCERPC header\0".as_ptr() + as *const libc::c_char, + url: b"/rules/dcerpc-keywords.html#dcerpc-iface\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(dcerpc_iface_match), + Setup: Some(dcerpc_iface_setup), + Free: Some(dcerpc_iface_free), + flags: 0, + }; + G_DCERPC_IFACE_KW_ID = SCDetectHelperKeywordRegister(&kw); + SCDetectHelperKeywordAliasRegister( + G_DCERPC_IFACE_KW_ID, + b"dce_iface\0".as_ptr() as *const libc::c_char, + ); } #[cfg(test)] diff --git a/rust/src/smb/detect.rs b/rust/src/smb/detect.rs index 113a078e7a..1c9d0c0a3c 100644 --- a/rust/src/smb/detect.rs +++ b/rust/src/smb/detect.rs @@ -129,10 +129,13 @@ pub(crate) unsafe extern "C" fn smb_tx_match_dce_opnum( * - match on REQUEST (so not on BIND/BINDACK (probably for mixing with * dce_opnum and dce_stub_data) * - only match on approved ifaces (so ack_result == 0) */ -#[no_mangle] -pub extern "C" fn SCSmbTxGetDceIface( - state: &mut SMBState, tx: &SMBTransaction, dce_data: &mut DCEIfaceData, -) -> u8 { +pub(crate) unsafe fn smb_tx_match_dce_iface( + state: *mut c_void, tx: *mut c_void, dce_data: *const SigMatchCtx, +) -> c_int { + let tx = cast_pointer!(tx, SMBTransaction); + let state = cast_pointer!(state, SMBState); + let dce_data = cast_pointer!(dce_data, DCEIfaceData); + let if_uuid = dce_data.if_uuid.as_slice(); let is_dcerpc_request = match tx.type_data { Some(SMBTransactionTypeData::DCERPC(ref x)) => x.req_cmd == DCERPC_TYPE_REQUEST, diff --git a/src/Makefile.am b/src/Makefile.am index dc90c103c6..187fefc070 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -117,7 +117,6 @@ noinst_HEADERS = \ detect-csum.h \ detect-datarep.h \ detect-dataset.h \ - detect-dce-iface.h \ detect-dce-stub-data.h \ detect-depth.h \ detect-detection-filter.h \ @@ -697,7 +696,6 @@ libsuricata_c_a_SOURCES = \ detect-csum.c \ detect-datarep.c \ detect-dataset.c \ - detect-dce-iface.c \ detect-dce-stub-data.c \ detect-depth.c \ detect-detection-filter.c \ diff --git a/src/detect-dce-iface.c b/src/detect-dce-iface.c deleted file mode 100644 index eff6e56fcc..0000000000 --- a/src/detect-dce-iface.c +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright (C) 2007-2022 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. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements dce_iface keyword. - */ - -#include "suricata-common.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-engine-build.h" -#include "detect-dce-iface.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "app-layer.h" -#include "queue.h" -#include "stream-tcp-reassemble.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "stream-tcp.h" - -#include "rust.h" - -#define PARSE_REGEX "^\\s*([0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12})(?:\\s*,\\s*(<|>|=|!)([0-9]{1,5}))?(?:\\s*,\\s*(any_frag))?\\s*$" - -static DetectParseRegex parse_regex; - -static int DetectDceIfaceMatchRust(DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, void *txv, - const Signature *s, const SigMatchCtx *m); -static int DetectDceIfaceSetup(DetectEngineCtx *, Signature *, const char *); -static void DetectDceIfaceFree(DetectEngineCtx *, void *); -static int g_dce_generic_list_id = 0; - -/** - * \brief Registers the keyword handlers for the "dce_iface" keyword. - */ -void DetectDceIfaceRegister(void) -{ - sigmatch_table[DETECT_DCE_IFACE].name = "dcerpc.iface"; - sigmatch_table[DETECT_DCE_IFACE].alias = "dce_iface"; - sigmatch_table[DETECT_DCE_IFACE].AppLayerTxMatch = DetectDceIfaceMatchRust; - sigmatch_table[DETECT_DCE_IFACE].Setup = DetectDceIfaceSetup; - sigmatch_table[DETECT_DCE_IFACE].Free = DetectDceIfaceFree; - sigmatch_table[DETECT_DCE_IFACE].desc = - "match on the value of the interface UUID in a DCERPC header"; - sigmatch_table[DETECT_DCE_IFACE].url = "/rules/dcerpc-keywords.html#dcerpc-iface"; - DetectSetupParseRegexes(PARSE_REGEX, &parse_regex); - - g_dce_generic_list_id = DetectBufferTypeRegister("dce_generic"); - - DetectAppLayerInspectEngineRegister("dce_generic", ALPROTO_DCERPC, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectGenericList, NULL); - DetectAppLayerInspectEngineRegister( - "dce_generic", ALPROTO_SMB, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister("dce_generic", ALPROTO_DCERPC, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectGenericList, NULL); - DetectAppLayerInspectEngineRegister( - "dce_generic", ALPROTO_SMB, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL); -} - -/** - * \brief App layer match function for the "dce_iface" keyword. - * - * \param t Pointer to the ThreadVars instance. - * \param det_ctx Pointer to the DetectEngineThreadCtx. - * \param f Pointer to the flow. - * \param flags Pointer to the flags indicating the flow direction. - * \param state Pointer to the app layer state data. - * \param s Pointer to the Signature instance. - * \param m Pointer to the SigMatch. - * - * \retval 1 On Match. - * \retval 0 On no match. - */ -static int DetectDceIfaceMatchRust(DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, void *txv, - const Signature *s, const SigMatchCtx *m) -{ - SCEnter(); - - if (f->alproto == ALPROTO_DCERPC) { - // TODO check if state is NULL - return SCDcerpcIfaceMatch(txv, state, (void *)m); - } - - int ret = 0; - - if (SCSmbTxGetDceIface(f->alstate, txv, (void *)m) != 1) { - SCLogDebug("SCSmbTxGetDceIface: didn't match"); - } else { - SCLogDebug("SCSmbTxGetDceIface: matched!"); - ret = 1; - // TODO validate frag - } - SCReturnInt(ret); -} - -/** - * \brief Creates a SigMatch for the "dce_iface" keyword being sent as argument, - * and appends it to the Signature(s). - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to signature for the current Signature being parsed - * from the rules. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 on success, -1 on failure. - */ - -static int DetectDceIfaceSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) -{ - SCEnter(); - - if (SCDetectSignatureSetAppProto(s, ALPROTO_DCERPC) < 0) - return -1; - - void *did = SCDcerpcIfaceParse(arg); - if (did == NULL) { - SCLogError("Error parsing dce_iface option in " - "signature"); - return -1; - } - - if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_DCE_IFACE, did, g_dce_generic_list_id) == NULL) { - DetectDceIfaceFree(de_ctx, did); - return -1; - } - return 0; -} - -static void DetectDceIfaceFree(DetectEngineCtx *de_ctx, void *ptr) -{ - SCEnter(); - if (ptr != NULL) { - SCDcerpcIfaceFree(ptr); - } - SCReturn; -} diff --git a/src/detect-dce-iface.h b/src/detect-dce-iface.h deleted file mode 100644 index 161988f929..0000000000 --- a/src/detect-dce-iface.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2007-2010 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. - */ - -#ifndef SURICATA_DETECT_DCE_IFACE_H -#define SURICATA_DETECT_DCE_IFACE_H - -void DetectDceIfaceRegister(void); - -#endif /* SURICATA_DETECT_DCE_IFACE_H */ diff --git a/src/detect-dce-stub-data.c b/src/detect-dce-stub-data.c index b2f97076f8..977e78fd67 100644 --- a/src/detect-dce-stub-data.c +++ b/src/detect-dce-stub-data.c @@ -47,7 +47,6 @@ #include "stream-tcp-reassemble.h" #include "detect-dce-stub-data.h" -#include "detect-dce-iface.h" #include "util-debug.h" diff --git a/src/detect-engine-dcepayload.c b/src/detect-engine-dcepayload.c index b334175539..2ee20416e9 100644 --- a/src/detect-engine-dcepayload.c +++ b/src/detect-engine-dcepayload.c @@ -49,8 +49,6 @@ #include "util-unittest.h" #include "util-unittest-helper.h" -#include "detect-dce-iface.h" - static int g_dce_stub_data_buffer_id = 0; diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index c18aab43f3..7da7075086 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -156,7 +156,6 @@ #include "detect-icmpv4hdr.h" #include "detect-igmphdr.h" #include "detect-igmp-type.h" -#include "detect-dce-iface.h" #include "detect-dce-stub-data.h" #include "detect-urilen.h" #include "detect-bsize.h" @@ -667,7 +666,6 @@ void SigTableSetup(void) DetectIcmpv4HdrRegister(); DetectIGMPHdrRegister(); DetectIGMPTypeRegister(); - DetectDceIfaceRegister(); DetectDceStubDataRegister(); DetectTlsRegister(); DetectTlsValidityRegister(); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index 8c16ad2c9f..040335fc79 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -209,7 +209,6 @@ enum DetectKeywordId { DETECT_HTTP_REQUEST_HEADER, DETECT_HTTP_RESPONSE_HEADER, - DETECT_DCE_IFACE, DETECT_DCE_STUB_DATA, DETECT_ENGINE_EVENT,