detect/dcerpc: move stub_data keyword to rust

Ticket: 8391
pull/15278/head
Philippe Antoine 5 months ago committed by Victor Julien
parent 3d56472d16
commit b0e63a2c95

@ -241,10 +241,6 @@ impl DCERPCTransaction {
pub fn get_req_opnum(&self) -> u16 {
self.opnum
}
pub fn get_endianness(&self) -> u8 {
self.endianness
}
}
#[derive(Debug)]
@ -1147,25 +1143,6 @@ unsafe extern "C" fn get_tx_data(
return &mut tx.tx_data.0;
}
#[no_mangle]
pub unsafe extern "C" fn SCDcerpcGetStubData(
tx: &mut DCERPCTransaction, buf: *mut *const u8, len: *mut u32, endianness: *mut u8, dir: u8,
) {
match dir.into() {
Direction::ToServer => {
*len = tx.stub_data_buffer_ts.len() as u32;
*buf = tx.stub_data_buffer_ts.as_ptr();
SCLogDebug!("DCERPC Request stub buffer: Setting buffer to: {:?}", *buf);
}
Direction::ToClient => {
*len = tx.stub_data_buffer_tc.len() as u32;
*buf = tx.stub_data_buffer_tc.as_ptr();
SCLogDebug!("DCERPC Response stub buffer: Setting buffer to: {:?}", *buf);
}
}
*endianness = tx.get_endianness();
}
/// Probe input to see if it looks like DCERPC.
fn probe(input: &[u8]) -> (bool, bool) {
match parser::parse_dcerpc_header(input) {

@ -21,15 +21,18 @@ 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_iface, smb_tx_match_dce_opnum};
use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer};
use crate::smb::detect::{smb_tx_get_stub_data, 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};
use suricata_sys::sys::{
DetectEngineCtx, DetectEngineThreadCtx, SCDetectHelperBufferProgressRegister,
SCDetectHelperKeywordAliasRegister, SCDetectHelperKeywordRegister,
SCDetectSignatureSetAppProto, SCFlowGetAppProtocol, SCSigMatchAppendSMToList,
SCSigTableAppLiteElmt, SigMatchCtx, Signature,
DetectEngineCtx, DetectEngineThreadCtx, DetectEngineTransforms, Flow, InspectionBuffer,
SCDetectBufferSetActiveList, SCDetectHelperBufferMpmRegister,
SCDetectHelperBufferProgressRegister, SCDetectHelperKeywordAliasRegister,
SCDetectHelperKeywordRegister, SCDetectRegisterMpmGeneric, SCDetectSignatureSetAppProto,
SCFlowGetAppProtocol, SCInspectionBufferGet, SCInspectionBufferSetupAndApplyTransforms,
SCSigMatchAppendSMToList, SCSigTableAppLiteElmt, SigMatchCtx, Signature,
};
use uuid::Uuid;
@ -392,9 +395,57 @@ unsafe extern "C" fn dcerpc_opnum_free(_de: *mut DetectEngineCtx, ptr: *mut c_vo
}
}
unsafe extern "C" fn dcerpc_stub_data_setup(
de_ctx: *mut DetectEngineCtx, s: *mut Signature, _str: *const c_char,
) -> c_int {
if SCDetectSignatureSetAppProto(s, ALPROTO_DCERPC) < 0 {
return -1;
}
if SCDetectBufferSetActiveList(de_ctx, s, G_DCERPC_STUB_BUFFER_ID) < 0 {
return -1;
}
return 0;
}
pub const DETECT_CI_FLAGS_DCE_LE: u8 = 1 << 2;
pub const DETECT_CI_FLAGS_DCE_BE: u8 = 1 << 3;
unsafe extern "C" fn dcerpc_tx_get_stub_data(
det_ctx: *mut DetectEngineThreadCtx, transforms: *const DetectEngineTransforms,
_flow: *mut Flow, dir: u8, tx: *mut c_void, list_id: c_int,
) -> *mut InspectionBuffer {
let tx = cast_pointer!(tx, DCERPCTransaction);
let buffer = SCInspectionBufferGet(det_ctx, list_id);
if !(*buffer).initialized {
let (data, data_len) = if (dir & STREAM_TOSERVER) != 0 {
(
tx.stub_data_buffer_ts.as_ptr(),
tx.stub_data_buffer_ts.len() as u32,
)
} else {
(
tx.stub_data_buffer_tc.as_ptr(),
tx.stub_data_buffer_tc.len() as u32,
)
};
if tx.endianness > 0 {
(*buffer).flags |= DETECT_CI_FLAGS_DCE_LE;
} else {
(*buffer).flags |= DETECT_CI_FLAGS_DCE_BE;
}
SCInspectionBufferSetupAndApplyTransforms(
det_ctx, list_id, buffer, data, data_len, transforms,
);
}
return buffer;
}
static mut G_DCERPC_OPNUM_KW_ID: u16 = 0;
static mut G_DCERPC_GENERIC_BUFFER_ID: c_int = 0;
static mut G_DCERPC_IFACE_KW_ID: u16 = 0;
static mut G_DCERPC_STUB_BUFFER_ID: c_int = 0;
#[no_mangle]
pub unsafe extern "C" fn SCDetectDcerpcRegister() {
@ -441,6 +492,33 @@ pub unsafe extern "C" fn SCDetectDcerpcRegister() {
G_DCERPC_IFACE_KW_ID,
b"dce_iface\0".as_ptr() as *const libc::c_char,
);
let kw_stub = SigTableElmtStickyBuffer {
name: String::from("dcerpc.stub_data"),
desc: String::from("match on the stub data in a DCERPC packet"),
url: String::from("/rules/dcerpc-keywords.html#dcerpc-stub-data"),
setup: dcerpc_stub_data_setup,
};
let stub_kw_id = helper_keyword_register_sticky_buffer(&kw_stub);
G_DCERPC_STUB_BUFFER_ID = SCDetectRegisterMpmGeneric(
b"dce_stub_data\0".as_ptr() as *const libc::c_char,
b"dcerpc stub data\0".as_ptr() as *const libc::c_char,
ALPROTO_DCERPC,
STREAM_TOSERVER | STREAM_TOCLIENT,
Some(dcerpc_tx_get_stub_data),
);
G_DCERPC_STUB_BUFFER_ID = SCDetectHelperBufferMpmRegister(
b"dce_stub_data\0".as_ptr() as *const libc::c_char,
b"dcerpc stub data\0".as_ptr() as *const libc::c_char,
ALPROTO_SMB,
STREAM_TOSERVER | STREAM_TOCLIENT,
Some(smb_tx_get_stub_data),
);
SCDetectHelperKeywordAliasRegister(
stub_kw_id,
b"dce_stub_data\0".as_ptr() as *const libc::c_char,
);
}
#[cfg(test)]

@ -70,10 +70,10 @@ unsafe extern "C" fn smb_tx_get_named_pipe(
return false;
}
#[no_mangle]
pub unsafe extern "C" fn SCSmbTxGetStubData(
tx: &SMBTransaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
pub(crate) unsafe extern "C" fn smb_tx_get_stub_data(
tx: *const c_void, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32,
) -> bool {
let tx = cast_pointer!(tx, SMBTransaction);
if let Some(SMBTransactionTypeData::DCERPC(ref x)) = tx.type_data {
let vref = if direction == Direction::ToServer as u8 {
&x.stub_data_ts
@ -83,13 +83,13 @@ pub unsafe extern "C" fn SCSmbTxGetStubData(
if !vref.is_empty() {
*buffer = vref.as_ptr();
*buffer_len = vref.len() as u32;
return 1;
return true;
}
}
*buffer = ptr::null();
*buffer_len = 0;
return 0;
return false;
}
pub(crate) unsafe extern "C" fn smb_tx_match_dce_opnum(

@ -117,7 +117,6 @@ noinst_HEADERS = \
detect-csum.h \
detect-datarep.h \
detect-dataset.h \
detect-dce-stub-data.h \
detect-depth.h \
detect-detection-filter.h \
detect-distance.h \
@ -695,7 +694,6 @@ libsuricata_c_a_SOURCES = \
detect-csum.c \
detect-datarep.c \
detect-dataset.c \
detect-dce-stub-data.c \
detect-depth.c \
detect-detection-filter.c \
detect-distance.c \

@ -1,159 +0,0 @@
/* Copyright (C) 2007-2018 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>
* \author Victor Julien <victor@inliniac.net>
*
* Implements dce_stub_data keyword
*/
#include "suricata-common.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-buffer.h"
#include "detect-engine-build.h"
#include "detect-engine-mpm.h"
#include "detect-engine-state.h"
#include "detect-engine-prefilter.h"
#include "detect-engine-content-inspection.h"
#include "flow.h"
#include "flow-var.h"
#include "flow-util.h"
#include "app-layer.h"
#include "app-layer-parser.h"
#include "queue.h"
#include "stream-tcp-reassemble.h"
#include "detect-dce-stub-data.h"
#include "util-debug.h"
#include "stream-tcp.h"
#include "rust.h"
#define BUFFER_NAME "dce_stub_data"
static int DetectDceStubDataSetup(DetectEngineCtx *, Signature *, const char *);
static int g_dce_stub_data_buffer_id = 0;
static InspectionBuffer *GetSMBData(DetectEngineThreadCtx *det_ctx,
const DetectEngineTransforms *transforms,
Flow *_f, const uint8_t flow_flags,
void *txv, const int list_id)
{
InspectionBuffer *buffer = SCInspectionBufferGet(det_ctx, list_id);
if (!buffer->initialized) {
uint32_t data_len = 0;
const uint8_t *data = NULL;
uint8_t dir = flow_flags & (STREAM_TOSERVER|STREAM_TOCLIENT);
if (SCSmbTxGetStubData(txv, dir, &data, &data_len) != 1)
return NULL;
SCLogDebug("have data!");
SCInspectionBufferSetupAndApplyTransforms(
det_ctx, list_id, buffer, data, data_len, transforms);
}
return buffer;
}
static InspectionBuffer *GetDCEData(DetectEngineThreadCtx *det_ctx,
const DetectEngineTransforms *transforms,
Flow *_f, const uint8_t flow_flags,
void *txv, const int list_id)
{
InspectionBuffer *buffer = SCInspectionBufferGet(det_ctx, list_id);
if (!buffer->initialized) {
uint32_t data_len = 0;
const uint8_t *data = NULL;
uint8_t endianness;
SCDcerpcGetStubData(txv, &data, &data_len, &endianness, flow_flags);
if (data == NULL || data_len == 0)
return NULL;
if (endianness > 0) {
buffer->flags = DETECT_CI_FLAGS_DCE_LE;
} else {
buffer->flags |= DETECT_CI_FLAGS_DCE_BE;
}
SCInspectionBufferSetupAndApplyTransforms(
det_ctx, list_id, buffer, data, data_len, transforms);
}
return buffer;
}
/**
* \brief Registers the keyword handlers for the "dce_stub_data" keyword.
*/
void DetectDceStubDataRegister(void)
{
sigmatch_table[DETECT_DCE_STUB_DATA].name = "dcerpc.stub_data";
sigmatch_table[DETECT_DCE_STUB_DATA].alias = "dce_stub_data";
sigmatch_table[DETECT_DCE_STUB_DATA].Setup = DetectDceStubDataSetup;
sigmatch_table[DETECT_DCE_STUB_DATA].desc = "match on the stub data in a DCERPC packet";
sigmatch_table[DETECT_DCE_STUB_DATA].url = "/rules/dcerpc-keywords.html#dcerpc-stub-data";
sigmatch_table[DETECT_DCE_STUB_DATA].flags |= SIGMATCH_NOOPT|SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerInspectEngineRegister(BUFFER_NAME, ALPROTO_SMB, SIG_FLAG_TOSERVER, 0,
DetectEngineInspectBufferGeneric, GetSMBData);
DetectAppLayerMpmRegister(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister,
GetSMBData, ALPROTO_SMB, 0);
DetectAppLayerInspectEngineRegister(BUFFER_NAME, ALPROTO_SMB, SIG_FLAG_TOCLIENT, 0,
DetectEngineInspectBufferGeneric, GetSMBData);
DetectAppLayerMpmRegister(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister,
GetSMBData, ALPROTO_SMB, 0);
DetectAppLayerInspectEngineRegister(BUFFER_NAME, ALPROTO_DCERPC, SIG_FLAG_TOSERVER, 0,
DetectEngineInspectBufferGeneric, GetDCEData);
DetectAppLayerMpmRegister(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister,
GetDCEData, ALPROTO_DCERPC, 0);
DetectAppLayerInspectEngineRegister(BUFFER_NAME, ALPROTO_DCERPC, SIG_FLAG_TOCLIENT, 0,
DetectEngineInspectBufferGeneric, GetDCEData);
DetectAppLayerMpmRegister(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister,
GetDCEData, ALPROTO_DCERPC, 0);
g_dce_stub_data_buffer_id = DetectBufferTypeGetByName(BUFFER_NAME);
}
/**
* \brief setups the dce_stub_data list
*
* \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 DetectDceStubDataSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
if (SCDetectSignatureSetAppProto(s, ALPROTO_DCERPC) < 0)
return -1;
if (SCDetectBufferSetActiveList(de_ctx, s, g_dce_stub_data_buffer_id) < 0)
return -1;
return 0;
}

@ -1,29 +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.
*/
/**
* \file
*
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
*/
#ifndef SURICATA_DETECT_DCE_STUB_DATA_H
#define SURICATA_DETECT_DCE_STUB_DATA_H
void DetectDceStubDataRegister(void);
#endif /* SURICATA_DETECT_DCE_STUB_DATA_H */

@ -41,8 +41,9 @@ enum DetectContentInspectionType {
BIT_U8(0) /**< indication that current buffer is the start of the data */
#define DETECT_CI_FLAGS_END BIT_U8(1) /**< indication that current buffer
* is the end of the data */
#define DETECT_CI_FLAGS_DCE_LE BIT_U8(2) /**< DCERPC record in little endian */
#define DETECT_CI_FLAGS_DCE_BE BIT_U8(3) /**< DCERPC record in big endian */
// next ones come from rust dcerpc
// #define DETECT_CI_FLAGS_DCE_LE BIT_U8(2) /**< DCERPC record in little endian */
// #define DETECT_CI_FLAGS_DCE_BE BIT_U8(3) /**< DCERPC record in big endian */
/** buffer is a single, non-streaming, buffer. Data sent to the content
* inspection function contains both start and end of the data. */

@ -155,7 +155,6 @@
#include "detect-icmpv4hdr.h"
#include "detect-igmphdr.h"
#include "detect-igmp-type.h"
#include "detect-dce-stub-data.h"
#include "detect-urilen.h"
#include "detect-bsize.h"
#include "detect-detection-filter.h"
@ -665,7 +664,6 @@ void SigTableSetup(void)
DetectIcmpv4HdrRegister();
DetectIGMPHdrRegister();
DetectIGMPTypeRegister();
DetectDceStubDataRegister();
DetectTlsRegister();
DetectTlsValidityRegister();
DetectTlsVersionRegister();

@ -209,8 +209,6 @@ enum DetectKeywordId {
DETECT_HTTP_REQUEST_HEADER,
DETECT_HTTP_RESPONSE_HEADER,
DETECT_DCE_STUB_DATA,
DETECT_ENGINE_EVENT,
DETECT_STREAM_EVENT,

Loading…
Cancel
Save