dcerpc: add probe function

(cherry picked from commit 3641f1b522)
pull/5934/head
Shivani Bhardwaj 5 years ago committed by Victor Julien
parent f8f0c2534e
commit d7a633a684

@ -16,7 +16,7 @@
*/
use std::mem::transmute;
use crate::applayer::{AppLayerResult, AppLayerTxData};
use crate::applayer::*;
use crate::core::{self, sc_detect_engine_state_free};
use crate::dcerpc::parser;
use nom::error::ErrorKind;
@ -1323,6 +1323,46 @@ pub unsafe extern "C" fn rs_dcerpc_get_stub_data(
*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) {
Ok((_, hdr)) => {
let is_request = hdr.hdrtype == 0x00;
let is_dcerpc = hdr.rpc_vers == 0x05 && hdr.rpc_vers_minor == 0x00;
return (is_dcerpc, is_request);
},
Err(_) => (false, false),
}
}
#[no_mangle]
pub extern "C" fn rs_dcerpc_probe_tcp(direction: u8, input: *const u8,
len: u32, rdir: *mut u8) -> i32
{
SCLogDebug!("Probing packet for DCERPC");
if len == 0 {
return core::ALPROTO_UNKNOWN;
}
let slice: &[u8] = unsafe {
std::slice::from_raw_parts(input as *mut u8, len as usize)
};
//is_incomplete is checked by caller
let (is_dcerpc, is_request, ) = probe(slice);
if is_dcerpc {
let dir = if is_request {
core::STREAM_TOSERVER
} else {
core::STREAM_TOCLIENT
};
if direction & (core::STREAM_TOSERVER|core::STREAM_TOCLIENT) != dir {
unsafe { *rdir = dir };
}
return 1;
}
return 0;
}
#[cfg(test)]
mod tests {
use crate::applayer::AppLayerResult;

@ -289,6 +289,47 @@ pub extern "C" fn rs_dcerpc_udp_get_tx_cnt(vtx: *mut std::os::raw::c_void) -> u6
dce_state.tx_id
}
/// Probe input to see if it looks like DCERPC.
fn probe(input: &[u8]) -> (bool, bool) {
match parser::parse_dcerpc_udp_header(input) {
Ok((_, hdr)) => {
let is_request = hdr.pkt_type == 0x00;
let is_dcerpc = hdr.rpc_vers == 0x04;
return (is_dcerpc, is_request);
},
Err(_) => (false, false),
}
}
#[no_mangle]
pub extern "C" fn rs_dcerpc_probe_udp(direction: u8, input: *const u8,
len: u32, rdir: *mut u8) -> i32
{
SCLogDebug!("Probing the packet for DCERPC/UDP");
if len == 0 {
return core::ALPROTO_UNKNOWN;
}
let slice: &[u8] = unsafe {
std::slice::from_raw_parts(input as *mut u8, len as usize)
};
//is_incomplete is checked by caller
let (is_dcerpc, is_request) = probe(slice);
if is_dcerpc {
let dir = if is_request {
core::STREAM_TOSERVER
} else {
core::STREAM_TOCLIENT
};
if direction & (core::STREAM_TOSERVER|core::STREAM_TOCLIENT) != dir {
unsafe { *rdir = dir };
}
return 1;
}
return 0;
}
#[cfg(test)]
mod tests {
use crate::applayer::AppLayerResult;

@ -102,11 +102,27 @@ static int RustDCERPCUDPGetAlstateProgress(void *tx, uint8_t direction)
return rs_dcerpc_get_alstate_progress(tx, direction);
}
static uint16_t DCERPCUDPProbe(
Flow *f, uint8_t direction, const uint8_t *input, uint32_t len, uint8_t *rdir)
{
SCLogDebug("DCERPCUDPProbe");
const int r = rs_dcerpc_probe_udp(direction, input, len, rdir);
switch (r) {
case 1:
return ALPROTO_DCERPC;
case 0:
return ALPROTO_UNKNOWN;
case -1:
default:
return ALPROTO_FAILED;
}
}
static int DCERPCUDPRegisterPatternsForProtocolDetection(void)
{
if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_DCERPC,
"|04 00|", 2, 0, STREAM_TOSERVER) < 0)
{
if (AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_UDP, ALPROTO_DCERPC, "|04 00|", 2, 0,
STREAM_TOSERVER, DCERPCUDPProbe, 0, 0) < 0) {
return -1;
}

@ -126,16 +126,31 @@ static int DCERPCGetAlstateProgress(void *tx, uint8_t direction)
return rs_dcerpc_get_alstate_progress(tx, direction);
}
static uint16_t DCERPCTCPProbe(
Flow *f, uint8_t direction, const uint8_t *input, uint32_t len, uint8_t *rdir)
{
SCLogDebug("DCERPCTCPProbe");
const int r = rs_dcerpc_probe_tcp(direction, input, len, rdir);
switch (r) {
case 1:
return ALPROTO_DCERPC;
case 0:
return ALPROTO_UNKNOWN;
case -1:
default:
return ALPROTO_FAILED;
}
}
static int DCERPCRegisterPatternsForProtocolDetection(void)
{
if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_DCERPC,
"|05 00|", 2, 0, STREAM_TOSERVER) < 0)
{
if (AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP, ALPROTO_DCERPC, "|05 00|", 2, 0,
STREAM_TOSERVER, DCERPCTCPProbe, 0, 0) < 0) {
return -1;
}
if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_DCERPC,
"|05 00|", 2, 0, STREAM_TOCLIENT) < 0)
{
if (AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP, ALPROTO_DCERPC, "|05 00|", 2, 0,
STREAM_TOCLIENT, DCERPCTCPProbe, 0, 0) < 0) {
return -1;
}

Loading…
Cancel
Save