dcerpc: Replace C function calls with Rust

All the dead code in C after the Rust implementation is hereby removed.
Invalid/migrated tests have also been deleted.
All the function calls in C have been replaced with appropriate calls to
Rust functions. Same has been done for smb/detect.rs as a part of this
migration.
pull/4958/head
Shivani Bhardwaj 6 years ago committed by Victor Julien
parent 8036202c7b
commit 6457754fd6

@ -58,6 +58,7 @@ pub mod nfs;
pub mod ftp;
pub mod smb;
pub mod krb;
pub mod dcerpc;
pub mod ikev2;
pub mod snmp;

@ -15,11 +15,11 @@
* 02110-1301, USA.
*/
use std;
use std::ptr;
use crate::core::*;
use crate::log::*;
use crate::smb::smb::*;
use crate::dcerpc::detect::{DCEIfaceData, DCEOpnumData, DETECT_DCE_OPNUM_RANGE_UNINITIALIZED};
#[no_mangle]
pub extern "C" fn rs_smb_tx_get_share(tx: &mut SMBTransaction,
@ -111,17 +111,22 @@ pub extern "C" fn rs_smb_tx_get_stub_data(tx: &mut SMBTransaction,
}
#[no_mangle]
pub extern "C" fn rs_smb_tx_get_dce_opnum(tx: &mut SMBTransaction,
opnum: *mut u16)
pub extern "C" fn rs_smb_tx_match_dce_opnum(tx: &mut SMBTransaction,
dce_data: &mut DCEOpnumData)
-> u8
{
SCLogDebug!("rs_smb_tx_get_dce_opnum: start");
match tx.type_data {
Some(SMBTransactionTypeData::DCERPC(ref x)) => {
if x.req_cmd == 1 { // REQUEST
unsafe {
*opnum = x.opnum as u16;
return 1;
for range in dce_data.data.iter() {
if range.range2 == DETECT_DCE_OPNUM_RANGE_UNINITIALIZED {
if range.range1 == x.opnum as u32 {
return 1;
} else if range.range1 <= x.opnum as u32 && range.range2 >= x.opnum as u32 {
return 1;
}
}
}
}
}
@ -129,9 +134,6 @@ pub extern "C" fn rs_smb_tx_get_dce_opnum(tx: &mut SMBTransaction,
}
}
unsafe {
*opnum = 0;
}
return 0;
}
@ -176,12 +178,12 @@ fn match_version(op: u8, them: u16, us: u16) -> bool {
#[no_mangle]
pub extern "C" fn rs_smb_tx_get_dce_iface(state: &mut SMBState,
tx: &mut SMBTransaction,
uuid_ptr: *mut u8,
uuid_len: u16,
ver_op: u8,
ver_check: u16)
dce_data: &mut DCEIfaceData)
-> u8
{
let if_uuid = dce_data.if_uuid.as_slice();
let if_op = dce_data.op;
let if_version = dce_data.version;
let is_dcerpc_request = match tx.type_data {
Some(SMBTransactionTypeData::DCERPC(ref x)) => { x.req_cmd == 1 },
_ => { false },
@ -196,14 +198,13 @@ pub extern "C" fn rs_smb_tx_get_dce_iface(state: &mut SMBState,
},
};
let uuid = unsafe{std::slice::from_raw_parts(uuid_ptr, uuid_len as usize)};
SCLogDebug!("looking for UUID {:?}", uuid);
SCLogDebug!("looking for UUID {:?}", if_uuid);
for i in ifaces {
SCLogDebug!("stored UUID {:?} acked {} ack_result {}", i, i.acked, i.ack_result);
if i.acked && i.ack_result == 0 && i.uuid == uuid {
if match_version(ver_op as u8, ver_check as u16, i.ver) {
if i.acked && i.ack_result == 0 && i.uuid == if_uuid {
if match_version(if_op as u8, if_version as u16, i.ver) {
return 1;
}
}

@ -15,12 +15,6 @@
* 02110-1301, USA.
*/
/**
* \file
*
* \author Kirby Kuehl <kkuehl@gmail.com>
*/
#ifndef __APP_LAYER_DCERPC_COMMON_H__
#define __APP_LAYER_DCERPC_COMMON_H__
@ -34,210 +28,4 @@ void RegisterDCERPCParsers(void);
void DCERPCParserTests(void);
void DCERPCParserRegisterTests(void);
// http://www.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06
#define REQUEST 0
#define PING 1
#define RESPONSE 2
#define FAULT 3
#define WORKING 4
#define NOCALL 5
#define REJECT 6
#define ACK 7
#define CL_CANCEL 8
#define FACK 9
#define CANCEL_ACK 10
#define BIND 11
#define BIND_ACK 12
#define BIND_NAK 13
#define ALTER_CONTEXT 14
#define ALTER_CONTEXT_RESP 15
#define SHUTDOWN 17
#define CO_CANCEL 18
#define ORPHANED 19
#if 0
typedef struct {
uint8_t rpc_vers; /* 4 RPC protocol major version (4 LSB only)*/
uint8_t ptype; /* Packet type (5 LSB only) */
uint8_t flags1; /* Packet flags */
uint8_t flags2; /* Packet flags */
uint8_t drep[3]; /* Data representation format label */
uint8_t serial_hi; /* High byte of serial number */
uuid_t object; /* Object identifier */
uuid_t if_id; /* Interface identifier */
uuid_t act_id; /* Activity identifier */
unsigned long server_boot;/* Server boot time */
unsigned long if_vers; /* Interface version */
unsigned long seqnum; /* Sequence number */
unsigned short opnum; /* Operation number */
unsigned short ihint; /* Interface hint */
unsigned short ahint; /* Activity hint */
unsigned short len; /* Length of packet body */
unsigned short fragnum; /* Fragment number */
unsigned small auth_proto; /* Authentication protocol identifier*/
unsigned small serial_lo; /* Low byte of serial number */
} dc_rpc_cl_pkt_hdr_t;
#endif
#define RESERVED_01 0x01
#define LASTFRAG 0x02
#define FRAG 0x04
#define NOFACK 0x08
#define MAYBE 0x10
#define IDEMPOTENT 0x20
#define BROADCAST 0x40
#define RESERVED_80 0x80
#define CANCEL_PENDING 0x02
#define RESERVED_04 0x04
#define RESERVED_10 0x10
#define RESERVED_20 0x20
#define RESERVED_40 0x40
#define RESERVED_80 0x80
typedef struct DCERPCHdr_ {
uint8_t rpc_vers; /**< 00:01 RPC version should be 5 */
uint8_t rpc_vers_minor; /**< 01:01 minor version */
uint8_t type; /**< 02:01 packet type */
uint8_t pfc_flags; /**< 03:01 flags (see PFC_... ) */
uint8_t packed_drep[4]; /**< 04:04 NDR data representation format label */
uint16_t frag_length; /**< 08:02 total length of fragment */
uint16_t auth_length; /**< 10:02 length of auth_value */
uint32_t call_id; /**< 12:04 call identifier */
} DCERPCHdr;
#define DCERPC_HDR_LEN 16
typedef struct DCERPCHdrUdp_ {
uint8_t rpc_vers; /**< 4 RPC protocol major version (4 LSB only)*/
uint8_t type; /**< Packet type (5 LSB only) */
uint8_t flags1; /**< Packet flags */
uint8_t flags2; /**< Packet flags */
uint8_t drep[3]; /**< Data representation format label */
uint8_t serial_hi; /**< High byte of serial number */
uint8_t objectuuid[16];
uint8_t interfaceuuid[16];
uint8_t activityuuid[16];
uint32_t server_boot; /**< Server boot time */
uint32_t if_vers; /**< Interface version */
uint32_t seqnum; /**< Sequence number */
uint16_t opnum; /**< Operation number */
uint16_t ihint; /**< Interface hint */
uint16_t ahint; /**< Activity hint */
uint16_t fraglen; /**< Length of packet body */
uint16_t fragnum; /**< Fragment number */
uint8_t auth_proto; /**< Authentication protocol identifier*/
uint8_t serial_lo; /**< Low byte of serial number */
} DCERPCHdrUdp;
#define DCERPC_UDP_HDR_LEN 80
#define DCERPC_UUID_ENTRY_FLAG_FF 0x0001 /**< FIRST flag set on the packet
that contained this uuid entry */
typedef struct DCERPCUuidEntry_ {
uint16_t ctxid;
uint16_t internal_id;
uint16_t result;
uint8_t uuid[16];
uint16_t version;
uint16_t versionminor;
uint16_t flags; /**< DCERPC_UUID_ENTRY_FLAG_* flags */
TAILQ_ENTRY(DCERPCUuidEntry_) next;
} DCERPCUuidEntry;
typedef TAILQ_HEAD(DCERPCUuidEntryList_, DCERPCUuidEntry_) DCERPCUuidEntryList;
typedef struct DCERPCBindBindAck_ {
uint8_t numctxitems;
uint8_t numctxitemsleft;
uint8_t ctxbytesprocessed;
uint16_t ctxid;
uint8_t uuid[16];
uint16_t version;
uint16_t versionminor;
DCERPCUuidEntry *uuid_entry;
DCERPCUuidEntryList uuid_list;
/* the interface uuids that the server has accepted */
DCERPCUuidEntryList accepted_uuid_list;
uint16_t uuid_internal_id;
uint16_t secondaryaddrlen;
uint16_t secondaryaddrlenleft;
uint16_t result;
} DCERPCBindBindAck;
typedef struct DCERPCRequest_ {
uint16_t ctxid;
uint16_t opnum;
/* holds the stub data for the request */
uint8_t *stub_data_buffer;
/* length of the above buffer */
uint32_t stub_data_buffer_len;
uint8_t first_request_seen;
bool stub_data_buffer_reset;
} DCERPCRequest;
typedef struct DCERPCResponse_ {
/* holds the stub data for the response */
uint8_t *stub_data_buffer;
/* length of the above buffer */
uint32_t stub_data_buffer_len;
bool stub_data_buffer_reset;
} DCERPCResponse;
typedef struct DCERPC_ {
DCERPCHdr dcerpchdr;
DCERPCBindBindAck dcerpcbindbindack;
DCERPCRequest dcerpcrequest;
DCERPCResponse dcerpcresponse;
uint16_t bytesprocessed;
uint8_t pad;
uint16_t padleft;
uint16_t transaction_id;
} DCERPC;
typedef struct DCERPCUDP_ {
DCERPCHdrUdp dcerpchdrudp;
DCERPCBindBindAck dcerpcbindbindack;
DCERPCRequest dcerpcrequest;
DCERPCResponse dcerpcresponse;
uint16_t bytesprocessed;
uint16_t fraglenleft;
uint8_t *frag_data;
DCERPCUuidEntry *uuid_entry;
TAILQ_HEAD(, uuid_entry) uuid_list;
} DCERPCUDP;
/** First fragment */
#define PFC_FIRST_FRAG 0x01
/** Last fragment */
#define PFC_LAST_FRAG 0x02
/** Cancel was pending at sender */
#define PFC_PENDING_CANCEL 0x04
#define PFC_RESERVED_1 0x08
/** supports concurrent multiplexing of a single connection. */
#define PFC_CONC_MPX 0x10
/** only meaningful on `fault' packet; if true, guaranteed
* call did not execute. */
#define PFC_DID_NOT_EXECUTE 0x20
/** `maybe' call semantics requested */
#define PFC_MAYBE 0x40
/** if true, a non-nil object UUID was specified in the handle, and
* is present in the optional object field. If false, the object field
* is omitted. */
#define PFC_OBJECT_UUID 0x80
#define REASON_NOT_SPECIFIED 0
#define TEMPORARY_CONGESTION 1
#define LOCAL_LIMIT_EXCEEDED 2
#define CALLED_PADDR_UNKNOWN 3 /* not used */
#define PROTOCOL_VERSION_NOT_SUPPORTED 4
#define DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */
#define USER_DATA_NOT_READABLE 6 /* not used */
#define NO_PSAP_AVAILABLE 7 /* not used */
int32_t DCERPCParser(DCERPC *, const uint8_t *, uint32_t);
void hexdump(const void *buf, size_t len);
void printUUID(const char *type, DCERPCUuidEntry *uuid);
#endif /* __APP_LAYER_DCERPC_COMMON_H__ */

File diff suppressed because it is too large Load Diff

@ -1,31 +1,23 @@
/*
* Copyright (c) 2009,2010 Open Information Security Foundation
/* Copyright (C) 2017 Open Information Security Foundation
*
* \author Kirby Kuehl <kkuehl@gmail.com>
* 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 __APP_LAYER_DCERPC_UDP_H__
#define __APP_LAYER_DCERPC_UDP_H__
#include "app-layer-protos.h"
#include "app-layer-parser.h"
#include "app-layer-dcerpc-common.h"
#include "flow.h"
#include "queue.h"
#include "util-byte.h"
typedef struct DCERPCUDPState_ {
DCERPCUDP dcerpc;
uint16_t bytesprocessed;
uint16_t fraglenleft;
uint8_t *frag_data;
DCERPCUuidEntry *uuid_entry;
TAILQ_HEAD(, DCERPCUuidEntry_) uuid_list;
DetectEngineState *de_state;
} DCERPCUDPState;
#ifndef __APP_LAYER_DCERPC_UDP_RUST_H__
#define __APP_LAYER_DCERPC_UDP_RUST_H__
void RegisterDCERPCUDPParsers(void);
void DCERPCUDPParserTests(void);
void DCERPCUDPParserRegisterTests(void);
#endif /* __APP_LAYER_DCERPC_UDP_H__ */
#endif /* !__APP_LAYER_DCERPC_UDP_RUST_H__ */

File diff suppressed because it is too large Load Diff

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
/* Copyright (C) 2020 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
@ -15,35 +15,10 @@
* 02110-1301, USA.
*/
/**
* \file
*
* \author Kirby Kuehl <kkuehl@gmail.com>
*/
#ifndef __APP_LAYER_DCERPC_H__
#define __APP_LAYER_DCERPC_H__
#include "app-layer-protos.h"
#include "app-layer-parser.h"
#include "app-layer-dcerpc-common.h"
#include "flow.h"
#include "queue.h"
#include "util-byte.h"
typedef struct DCERPCState_ {
DCERPC dcerpc;
uint8_t data_needed_for_dir;
DetectEngineState *de_state;
uint64_t detect_flags_ts;
uint64_t detect_flags_tc;
} DCERPCState;
#ifndef __APP_LAYER_DCERPC_RUST_H__
#define __APP_LAYER_DCERPC_RUST_H__
void DCERPCInit(DCERPC *dcerpc);
void DCERPCCleanup(DCERPC *dcerpc);
void RegisterDCERPCParsers(void);
void DCERPCParserTests(void);
void DCERPCParserRegisterTests(void);
#endif /* __APP_LAYER_DCERPC_H__ */

File diff suppressed because it is too large Load Diff

@ -15,34 +15,11 @@
* 02110-1301, USA.
*/
/**
* \file
*
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
*/
#ifndef __DETECT_DCE_IFACE_H__
#define __DETECT_DCE_IFACE_H__
#include "app-layer-dcerpc.h"
typedef enum DetectDceIfaceOperators_ {
DETECT_DCE_IFACE_OP_NONE = 0,
DETECT_DCE_IFACE_OP_LT,
DETECT_DCE_IFACE_OP_GT,
DETECT_DCE_IFACE_OP_EQ,
DETECT_DCE_IFACE_OP_NE,
} DetectDceIfaceOperators;
typedef struct DetectDceIfaceData_ {
uint8_t uuid[16];
uint8_t op;
uint16_t version;
uint8_t any_frag;
} DetectDceIfaceData;
#include "app-layer-dcerpc-common.h"
void DetectDceIfaceRegister(void);
DCERPCState *DetectDceGetState(AppProto alproto, void *alstate);
#endif /* __DETECT_DCE_IFACE_H__ */

@ -79,151 +79,6 @@ void DetectDceOpnumRegister(void)
g_dce_generic_list_id = DetectBufferTypeRegister("dce_generic");
}
/**
* \internal
* \brief Creates and returns a new instance of DetectDceOpnumRange.
*
* \retval dor Pointer to the new instance DetectDceOpnumRange.
*/
static DetectDceOpnumRange *DetectDceOpnumAllocDetectDceOpnumRange(void)
{
DetectDceOpnumRange *dor = NULL;
if ( (dor = SCCalloc(1, sizeof(DetectDceOpnumRange))) == NULL)
return NULL;
dor->range1 = dor->range2 = DCE_OPNUM_RANGE_UNINITIALIZED;
return dor;
}
/**
* \internal
* \brief Parses the argument sent along with the "dce_opnum" keyword.
* \param de_ctx Pointer to the detection engine context
* \param arg Pointer to the string containing the argument to be parsed.
*
* \retval did Pointer to a DetectDceIfaceData instance that holds the data
* from the parsed arg.
*/
static DetectDceOpnumData *DetectDceOpnumArgParse(DetectEngineCtx *de_ctx, const char *arg)
{
DetectDceOpnumData *dod = NULL;
DetectDceOpnumRange *dor = NULL;
DetectDceOpnumRange *prev_dor = NULL;
int ret = 0, res = 0;
int ov[MAX_SUBSTRINGS];
const char *pcre_sub_str = NULL;
char *dup_str = NULL;
char *dup_str_temp = NULL;
char *dup_str_head = NULL;
char *comma_token = NULL;
char *hyphen_token = NULL;
if (arg == NULL) {
goto error;
}
ret = DetectParsePcreExec(&parse_regex, arg, 0, 0, ov, MAX_SUBSTRINGS);
if (ret < 2) {
SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, arg);
goto error;
}
res = pcre_get_substring(arg, ov, MAX_SUBSTRINGS, 0, &pcre_sub_str);
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
goto error;
}
if ( (dod = SCMalloc(sizeof(DetectDceOpnumData))) == NULL)
goto error;
memset(dod, 0, sizeof(DetectDceOpnumData));
if ( (dup_str = SCStrdup(pcre_sub_str)) == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
goto error;
}
/* free the substring */
pcre_free_substring(pcre_sub_str);
/* keep a copy of the strdup string in dup_str_head so that we can free it
* once we are done using it */
dup_str_head = dup_str;
dup_str_temp = dup_str;
while ( (comma_token = strchr(dup_str, ',')) != NULL) {
comma_token[0] = '\0';
dup_str = comma_token + 1;
dor = DetectDceOpnumAllocDetectDceOpnumRange();
if (dor == NULL)
goto error;
if (prev_dor == NULL) {
prev_dor = dor;
dod->range = dor;
} else {
prev_dor->next = dor;
prev_dor = dor;
}
if ((hyphen_token = strchr(dup_str_temp, '-')) != NULL) {
hyphen_token[0] = '\0';
hyphen_token++;
dor->range1 = atoi(dup_str_temp);
if (dor->range1 > DCE_OPNUM_RANGE_MAX)
goto error;
dor->range2 = atoi(hyphen_token);
if (dor->range2 > DCE_OPNUM_RANGE_MAX)
goto error;
if (dor->range1 > dor->range2)
goto error;
}
dor->range1 = atoi(dup_str_temp);
if (dor->range1 > DCE_OPNUM_RANGE_MAX)
goto error;
dup_str_temp = dup_str;
}
dor = DetectDceOpnumAllocDetectDceOpnumRange();
if (dor == NULL)
goto error;
if (prev_dor == NULL) {
dod->range = dor;
} else {
prev_dor->next = dor;
}
if ( (hyphen_token = strchr(dup_str, '-')) != NULL) {
hyphen_token[0] = '\0';
hyphen_token++;
dor->range1 = atoi(dup_str);
if (dor->range1 > DCE_OPNUM_RANGE_MAX)
goto error;
dor->range2 = atoi(hyphen_token);
if (dor->range2 > DCE_OPNUM_RANGE_MAX)
goto error;
if (dor->range1 > dor->range2)
goto error;
}
dor->range1 = atoi(dup_str);
if (dor->range1 > DCE_OPNUM_RANGE_MAX)
goto error;
if (dup_str_head != NULL)
SCFree(dup_str_head);
return dod;
error:
if (dup_str_head != NULL)
SCFree(dup_str_head);
DetectDceOpnumFree(de_ctx, dod);
return NULL;
}
/**
* \brief App layer match function for the "dce_opnum" keyword.
*
@ -238,38 +93,6 @@ static DetectDceOpnumData *DetectDceOpnumArgParse(DetectEngineCtx *de_ctx, const
* \retval 1 On Match.
* \retval 0 On no match.
*/
static int DetectDceOpnumMatch(DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, void *txv,
const Signature *s, const SigMatchCtx *m)
{
SCEnter();
DetectDceOpnumData *dce_data = (DetectDceOpnumData *)m;
DCERPCState *dcerpc_state = state;
if (dcerpc_state == NULL) {
SCLogDebug("No DCERPCState for the flow");
SCReturnInt(0);
}
uint16_t opnum = dcerpc_state->dcerpc.dcerpcrequest.opnum;
DetectDceOpnumRange *dor = dce_data->range;
for ( ; dor != NULL; dor = dor->next) {
if (dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED) {
if (dor->range1 == opnum) {
SCReturnInt(1);
}
} else {
if (dor->range1 <= opnum && dor->range2 >= opnum)
{
SCReturnInt(1);
}
}
}
SCReturnInt(0);
}
static int DetectDceOpnumMatchRust(DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, void *txv,
const Signature *s, const SigMatchCtx *m)
@ -277,36 +100,19 @@ static int DetectDceOpnumMatchRust(DetectEngineThreadCtx *det_ctx,
SCEnter();
if (f->alproto == ALPROTO_DCERPC) {
return DetectDceOpnumMatch(det_ctx, f, flags,
state, txv, s, m);
// TODO check for NULL state
return rs_dcerpc_opnum_match(state, (void *)m);
}
const DetectDceOpnumData *dce_data = (DetectDceOpnumData *)m;
const DetectDceOpnumRange *dor = dce_data->range;
uint16_t opnum;
if (rs_smb_tx_get_dce_opnum(txv, &opnum) != 1)
if (rs_smb_tx_match_dce_opnum(txv, (void *)m) != 1)
SCReturnInt(0);
SCLogDebug("(rust) opnum %u", opnum);
for ( ; dor != NULL; dor = dor->next) {
if (dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED) {
if (dor->range1 == opnum) {
SCReturnInt(1);
}
} else {
if (dor->range1 <= opnum && dor->range2 >= opnum) {
SCReturnInt(1);
}
}
}
SCReturnInt(0);
SCReturnInt(1);
}
/**
* \brief Creates a SigMatch for the "dce_opnum" keyword being sent as argument,
* and appends it to the Signature(s).
* and appends it to the rs_dcerpc_opnum_matchSignature(s).
*
* \param de_ctx Pointer to the detection engine context.
* \param s Pointer to signature for the current Signature being parsed
@ -324,7 +130,7 @@ static int DetectDceOpnumSetup(DetectEngineCtx *de_ctx, Signature *s, const char
return -1;
}
DetectDceOpnumData *dod = DetectDceOpnumArgParse(de_ctx, arg);
void *dod = rs_dcerpc_opnum_parse(arg);
if (dod == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Error parsing dce_opnum option in "
"signature");
@ -346,331 +152,21 @@ static int DetectDceOpnumSetup(DetectEngineCtx *de_ctx, Signature *s, const char
static void DetectDceOpnumFree(DetectEngineCtx *de_ctx, void *ptr)
{
DetectDceOpnumData *dod = ptr;
DetectDceOpnumRange *dor = NULL;
DetectDceOpnumRange *dor_temp = NULL;
if (dod != NULL) {
dor = dod->range;
while (dor != NULL) {
dor_temp = dor;
dor = dor->next;
SCFree(dor_temp);
}
SCFree(dod);
SCEnter();
if (ptr != NULL) {
rs_dcerpc_opnum_free(ptr);
}
return;
SCReturn;
}
/************************************Unittests*********************************/
#ifdef UNITTESTS
static int DetectDceOpnumTestParse01(void)
{
Signature *s = SigAlloc();
int result = 0;
result = (DetectDceOpnumSetup(NULL, s, "12") == 0);
result &= (DetectDceOpnumSetup(NULL, s, "12,24") == 0);
result &= (DetectDceOpnumSetup(NULL, s, "12,12-24") == 0);
result &= (DetectDceOpnumSetup(NULL, s, "12-14,12,121,62-78") == 0);
result &= (DetectDceOpnumSetup(NULL, s, "12,26,62,61,6513-6666") == 0);
result &= (DetectDceOpnumSetup(NULL, s, "12,26,62,61,6513--") == -1);
result &= (DetectDceOpnumSetup(NULL, s, "12-14,12,121,62-8") == -1);
if (s->sm_lists[g_dce_generic_list_id] != NULL) {
SigFree(NULL, s);
result &= 1;
}
return result;
}
static int DetectDceOpnumTestParse02(void)
{
Signature *s = SigAlloc();
int result = 0;
DetectDceOpnumData *dod = NULL;
DetectDceOpnumRange *dor = NULL;
SigMatch *temp = NULL;
result = (DetectDceOpnumSetup(NULL, s, "12") == 0);
if (s->sm_lists[g_dce_generic_list_id] != NULL) {
temp = s->sm_lists[g_dce_generic_list_id];
dod = (DetectDceOpnumData *)temp->ctx;
if (dod == NULL)
goto end;
dor = dod->range;
result &= (dor->range1 == 12 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next == NULL);
} else {
result = 0;
}
end:
SigFree(NULL, s);
return result;
}
static int DetectDceOpnumTestParse03(void)
{
Signature *s = SigAlloc();
int result = 0;
DetectDceOpnumData *dod = NULL;
DetectDceOpnumRange *dor = NULL;
SigMatch *temp = NULL;
result = (DetectDceOpnumSetup(NULL, s, "12-24") == 0);
if (s->sm_lists[g_dce_generic_list_id] != NULL) {
temp = s->sm_lists[g_dce_generic_list_id];
dod = (DetectDceOpnumData *)temp->ctx;
if (dod == NULL)
goto end;
dor = dod->range;
result &= (dor->range1 == 12 && dor->range2 == 24);
result &= (dor->next == NULL);
} else {
result = 0;
}
end:
SigFree(NULL, s);
return result;
}
static int DetectDceOpnumTestParse04(void)
{
Signature *s = SigAlloc();
int result = 0;
DetectDceOpnumData *dod = NULL;
DetectDceOpnumRange *dor = NULL;
SigMatch *temp = NULL;
result = (DetectDceOpnumSetup(NULL, s, "12-24,24,62-72,623-635,62,25,213-235") == 0);
if (s->sm_lists[g_dce_generic_list_id] != NULL) {
temp = s->sm_lists[g_dce_generic_list_id];
dod = (DetectDceOpnumData *)temp->ctx;
if (dod == NULL)
goto end;
dor = dod->range;
result &= (dor->range1 == 12 && dor->range2 == 24);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 24 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 62 && dor->range2 == 72);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 623 && dor->range2 == 635);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 62 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 25 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 213 && dor->range2 == 235);
if (result == 0)
goto end;
} else {
result = 0;
}
end:
SigFree(NULL, s);
return result;
}
static int DetectDceOpnumTestParse05(void)
{
Signature *s = SigAlloc();
int result = 0;
DetectDceOpnumData *dod = NULL;
DetectDceOpnumRange *dor = NULL;
SigMatch *temp = NULL;
result = (DetectDceOpnumSetup(NULL, s, "1,2,3,4,5,6,7") == 0);
if (s->sm_lists[g_dce_generic_list_id] != NULL) {
temp = s->sm_lists[g_dce_generic_list_id];
dod = (DetectDceOpnumData *)temp->ctx;
if (dod == NULL)
goto end;
dor = dod->range;
result &= (dor->range1 == 1 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 2 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 3 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 4 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 5 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 6 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 7 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
if (result == 0)
goto end;
} else {
result = 0;
}
end:
SigFree(NULL, s);
return result;
}
static int DetectDceOpnumTestParse06(void)
{
Signature *s = SigAlloc();
int result = 0;
DetectDceOpnumData *dod = NULL;
DetectDceOpnumRange *dor = NULL;
SigMatch *temp = NULL;
result = (DetectDceOpnumSetup(NULL, s, "1-2,3-4,5-6,7-8") == 0);
if (s->sm_lists[g_dce_generic_list_id] != NULL) {
temp = s->sm_lists[g_dce_generic_list_id];
dod = (DetectDceOpnumData *)temp->ctx;
if (dod == NULL)
goto end;
dor = dod->range;
result &= (dor->range1 == 1 && dor->range2 == 2);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 3 && dor->range2 == 4);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 5 && dor->range2 == 6);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 7 && dor->range2 == 8);
if (result == 0)
goto end;
} else {
result = 0;
}
end:
SigFree(NULL, s);
return result;
}
static int DetectDceOpnumTestParse07(void)
{
Signature *s = SigAlloc();
int result = 0;
DetectDceOpnumData *dod = NULL;
DetectDceOpnumRange *dor = NULL;
SigMatch *temp = NULL;
result = (DetectDceOpnumSetup(NULL, s, "1-2,3-4,5-6,7-8,9") == 0);
if (s->sm_lists[g_dce_generic_list_id] != NULL) {
temp = s->sm_lists[g_dce_generic_list_id];
dod = (DetectDceOpnumData *)temp->ctx;
if (dod == NULL)
goto end;
dor = dod->range;
result &= (dor->range1 == 1 && dor->range2 == 2);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 3 && dor->range2 == 4);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 5 && dor->range2 == 6);
result &= (dor->next != NULL);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 7 && dor->range2 == 8);
if (result == 0)
goto end;
dor = dor->next;
result &= (dor->range1 == 9 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED);
if (result == 0)
goto end;
} else {
result = 0;
}
end:
SigFree(NULL, s);
return result;
}
/**
* \test Test a valid dce_opnum entry with a bind, bind_ack and a request.
*/
static int DetectDceOpnumTestParse08(void)
static int DetectDceOpnumTestParse01(void)
{
int result = 0;
Signature *s = NULL;
@ -1238,7 +734,7 @@ static int DetectDceOpnumTestParse08(void)
/**
* \test Test a valid dce_opnum entry with only a request frag.
*/
static int DetectDceOpnumTestParse09(void)
static int DetectDceOpnumTestParse02(void)
{
int result = 0;
Signature *s = NULL;
@ -2914,13 +2410,6 @@ static void DetectDceOpnumRegisterTests(void)
#ifdef UNITTESTS
UtRegisterTest("DetectDceOpnumTestParse01", DetectDceOpnumTestParse01);
UtRegisterTest("DetectDceOpnumTestParse02", DetectDceOpnumTestParse02);
UtRegisterTest("DetectDceOpnumTestParse03", DetectDceOpnumTestParse03);
UtRegisterTest("DetectDceOpnumTestParse04", DetectDceOpnumTestParse04);
UtRegisterTest("DetectDceOpnumTestParse05", DetectDceOpnumTestParse05);
UtRegisterTest("DetectDceOpnumTestParse06", DetectDceOpnumTestParse06);
UtRegisterTest("DetectDceOpnumTestParse07", DetectDceOpnumTestParse07);
UtRegisterTest("DetectDceOpnumTestParse08", DetectDceOpnumTestParse08);
UtRegisterTest("DetectDceOpnumTestParse09", DetectDceOpnumTestParse09);
/* Disabled because of bug_753. Would be enabled, once we rewrite
* dce parser */
#if 0

@ -24,18 +24,7 @@
#ifndef __DETECT_DCE_OPNUM_H__
#define __DETECT_DCE_OPNUM_H__
#define DCE_OPNUM_RANGE_MAX 65535
#define DCE_OPNUM_RANGE_UNINITIALIZED 100000
typedef struct DetectDceOpnumRange_ {
uint32_t range1;
uint32_t range2;
struct DetectDceOpnumRange_ *next;
} DetectDceOpnumRange;
typedef struct DetectDceOpnumData_ {
DetectDceOpnumRange *range;
} DetectDceOpnumData;
#include "app-layer-dcerpc-common.h"
void DetectDceOpnumRegister(void);

@ -91,20 +91,14 @@ static InspectionBuffer *GetDCEData(DetectEngineThreadCtx *det_ctx,
InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
uint32_t data_len = 0;
uint8_t *data = NULL;
const uint8_t *data = NULL;
uint8_t endianness;
DCERPCState *dcerpc_state = txv;
if (dcerpc_state == NULL)
rs_dcerpc_get_stub_data(txv, &data, &data_len, &endianness, flow_flags);
if (data == NULL || data_len == 0)
return NULL;
if (flow_flags & STREAM_TOSERVER) {
data_len = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len;
data = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer;
} else if (flow_flags & STREAM_TOCLIENT) {
data_len = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer_len;
data = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer;
}
if (dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) {
if (endianness > 0) {
buffer->flags = DETECT_CI_FLAGS_DCE_LE;
} else {
buffer->flags |= DETECT_CI_FLAGS_DCE_BE;
@ -1550,7 +1544,6 @@ static int DetectDceStubDataTestParse04(void)
if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3))
goto end;
/* request3 */
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DCERPC,

@ -24,6 +24,8 @@
#ifndef __DETECT_DCE_STUB_DATA_H__
#define __DETECT_DCE_STUB_DATA_H__
#include "app-layer-dcerpc-common.h"
void DetectDceStubDataRegister(void);
#endif /* __DETECT_DCE_STUB_DATA_H__ */

@ -759,313 +759,6 @@ end:
return result;
}
/**
* \test Test the working of consecutive relative matches.
*/
static int DcePayloadTest21(void)
{
int result = 0;
uint8_t request1[] = {
0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00,
0x6e, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x69, 0x73, /* "now this" */
0x20, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x62, /* " is is b" */
0x69, 0x67, 0x20, 0x62, 0x69, 0x67, 0x20, 0x73, /* "ig big s" */
0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f, /* "tring no" */
0x77 }; /* "w" */
uint32_t request1_len = sizeof(request1);
TcpSession ssn;
Packet *p = NULL;
ThreadVars tv;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
Flow f;
int r;
const char *sig1 = "alert tcp any any -> any any "
"(msg:\"testing dce consecutive relative matches\"; dce_stub_data; "
"content:\"this\"; distance:0; content:\"is\"; within:6; content:\"big\"; within:8; "
"content:\"string\"; within:8; sid:1;)";
Signature *s;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
f.alproto = ALPROTO_DCERPC;
StreamTcpInitConfig(TRUE);
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, sig1);
s = de_ctx->sig_list;
if (s == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
/* request 1 */
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DCERPC,
STREAM_TOSERVER, request1, request1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* detection phase */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have for packet: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
UTHFreePackets(&p, 1);
return result;
}
/**
* \test Test the working of consecutive relative matches.
*/
static int DcePayloadTest22(void)
{
int result = 0;
uint8_t request1[] = {
0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00,
0x6e, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x69, 0x73, /* "now this" */
0x20, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x69, /* " is is i" */
0x73, 0x20, 0x62, 0x69, 0x67, 0x20, 0x62, 0x69, /* "s big bi" */
0x67, 0x20, 0x62, 0x69, 0x67, 0x20, 0x73, 0x74, /* "g big st" */
0x72, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f, 0x77 }; /* "ring now" */
uint32_t request1_len = sizeof(request1);
TcpSession ssn;
Packet *p = NULL;
ThreadVars tv;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
Flow f;
int r;
const char *sig1 = "alert tcp any any -> any any "
"(msg:\"testing dce consecutive relative matches\"; dce_stub_data; "
"content:\"this\"; distance:0; content:\"is\"; within:9; content:\"big\"; within:12; "
"content:\"string\"; within:8; sid:1;)";
Signature *s;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
f.alproto = ALPROTO_DCERPC;
StreamTcpInitConfig(TRUE);
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, sig1);
s = de_ctx->sig_list;
if (s == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
/* request 1 */
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DCERPC,
STREAM_TOSERVER, request1, request1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* detection phase */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have for packet: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
UTHFreePackets(&p, 1);
return result;
}
/**
* \test Test the working of consecutive relative matches.
*/
static int DcePayloadTest23(void)
{
int result = 0;
uint8_t request1[] = {
0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00,
0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x68, 0x69, /* "this thi" */
0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x69, 0x73, /* "s now is" */
0x20, 0x69, 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, /* " is " */
0x62, 0x69, 0x67, 0x20, 0x73, 0x74, 0x72, 0x69, /* "big stri" */
0x6e, 0x67, 0x20, 0x6e, 0x6f, 0x77 }; /* "ng now" */
uint32_t request1_len = sizeof(request1);
TcpSession ssn;
Packet *p = NULL;
ThreadVars tv;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
Flow f;
int r;
const char *sig1 = "alert tcp any any -> any any "
"(msg:\"testing dce consecutive relative matches\"; dce_stub_data; "
"content:\"now\"; distance:0; content:\"this\"; distance:-20; "
"content:\"is\"; within:12; content:\"big\"; within:8; "
"content:\"string\"; within:8; sid:1;)";
Signature *s;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
f.alproto = ALPROTO_DCERPC;
StreamTcpInitConfig(TRUE);
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, sig1);
s = de_ctx->sig_list;
if (s == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
/* request 1 */
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DCERPC,
STREAM_TOSERVER, request1, request1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* detection phase */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have for packet: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
UTHFreePackets(&p, 1);
return result;
}
/**
* \test Test content for dce sig.
*/
@ -3180,212 +2873,6 @@ static int DcePayloadParseTest41(void)
return result;
}
/**
* \test Test the working of consecutive relative matches with a negated content.
*/
static int DcePayloadTest42(void)
{
int result = 0;
uint8_t request1[] = {
0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00,
0x77, 0x65, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, /* "we need " */
0x74, 0x6f, 0x20, 0x66, 0x69, 0x78, 0x20, 0x74, /* "to fix t" */
0x68, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, /* "his and " */
0x79, 0x65, 0x73, 0x20, 0x66, 0x69, 0x78, 0x20, /* "yes fix " */
0x74, 0x68, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77 /* "this now" */
};
uint32_t request1_len = sizeof(request1);
TcpSession ssn;
Packet *p = NULL;
ThreadVars tv;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
Flow f;
int r;
const char *sig1 = "alert tcp any any -> any any "
"(msg:\"testing dce consecutive relative matches\"; dce_stub_data; "
"content:\"fix\"; distance:0; content:\"this\"; within:6; "
"content:!\"and\"; distance:0; sid:1;)";
Signature *s;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
f.alproto = ALPROTO_DCERPC;
StreamTcpInitConfig(TRUE);
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, sig1);
s = de_ctx->sig_list;
if (s == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
/* request 1 */
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DCERPC,
STREAM_TOSERVER, request1, request1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* detection phase */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 matched but shouldn't have for packet: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
UTHFreePackets(&p, 1);
return result;
}
/**
* \test Test the working of consecutive relative pcres.
*/
static int DcePayloadTest43(void)
{
int result = 0;
uint8_t request1[] = {
0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00,
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
0x61, 0x20, 0x73, 0x75, 0x70, 0x65, 0x72, 0x20,
0x64, 0x75, 0x70, 0x65, 0x72, 0x20, 0x6e, 0x6f,
0x76, 0x61, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x75,
0x70, 0x65, 0x72, 0x20, 0x6e, 0x6f, 0x76, 0x61,
0x20, 0x6e, 0x6f, 0x77
};
uint32_t request1_len = sizeof(request1);
TcpSession ssn;
Packet *p = NULL;
ThreadVars tv;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
Flow f;
int r;
const char *sig1 = "alert tcp any any -> any any "
"(msg:\"testing dce consecutive relative matches\"; dce_stub_data; "
"pcre:/super/R; content:\"nova\"; within:7; sid:1;)";
Signature *s;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
f.alproto = ALPROTO_DCERPC;
StreamTcpInitConfig(TRUE);
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, sig1);
s = de_ctx->sig_list;
if (s == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
/* request 1 */
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DCERPC,
STREAM_TOSERVER, request1, request1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* detection phase */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if ( !(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
UTHFreePackets(&p, 1);
return result;
}
/**
* \test Test content for dce sig.
*/
@ -3711,9 +3198,6 @@ void DcePayloadRegisterTests(void)
UtRegisterTest("DcePayloadTest18", DcePayloadTest18);
UtRegisterTest("DcePayloadTest19", DcePayloadTest19);
UtRegisterTest("DcePayloadTest20", DcePayloadTest20);
UtRegisterTest("DcePayloadTest21", DcePayloadTest21);
UtRegisterTest("DcePayloadTest22", DcePayloadTest22);
UtRegisterTest("DcePayloadTest23", DcePayloadTest23);
UtRegisterTest("DcePayloadParseTest25", DcePayloadParseTest25);
UtRegisterTest("DcePayloadParseTest26", DcePayloadParseTest26);
@ -3733,9 +3217,6 @@ void DcePayloadRegisterTests(void)
UtRegisterTest("DcePayloadParseTest40", DcePayloadParseTest40);
UtRegisterTest("DcePayloadParseTest41", DcePayloadParseTest41);
UtRegisterTest("DcePayloadTest42", DcePayloadTest42);
UtRegisterTest("DcePayloadTest43", DcePayloadTest43);
UtRegisterTest("DcePayloadParseTest44", DcePayloadParseTest44);
UtRegisterTest("DcePayloadParseTest45", DcePayloadParseTest45);
UtRegisterTest("DcePayloadParseTest46", DcePayloadParseTest46);

Loading…
Cancel
Save