detect/dcerpc: move iface keyword to rust

Ticket: 8391

Use same buffer dce_generic as for dcerpc.opnum
(name dce_generic is enforced by a SV test currently)
pull/15268/head
Philippe Antoine 3 months ago committed by Victor Julien
parent d1481af94e
commit 4fc6ca5d6c

@ -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<DCEOpnumData, ()> {
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)]

@ -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,

@ -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 \

@ -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 <anoopsaldanha@gmail.com>
*
* 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;
}

@ -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 */

@ -47,7 +47,6 @@
#include "stream-tcp-reassemble.h"
#include "detect-dce-stub-data.h"
#include "detect-dce-iface.h"
#include "util-debug.h"

@ -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;

@ -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();

@ -209,7 +209,6 @@ enum DetectKeywordId {
DETECT_HTTP_REQUEST_HEADER,
DETECT_HTTP_RESPONSE_HEADER,
DETECT_DCE_IFACE,
DETECT_DCE_STUB_DATA,
DETECT_ENGINE_EVENT,

Loading…
Cancel
Save