mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2181 lines
113 KiB
Rust
2181 lines
113 KiB
Rust
/* Copyright (C) 2020-2024 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.
|
|
*/
|
|
|
|
use crate::applayer::{self, *};
|
|
use crate::core::{self, *};
|
|
use crate::dcerpc::parser;
|
|
use crate::direction::{Direction, DIR_BOTH};
|
|
use crate::flow::Flow;
|
|
use crate::frames::*;
|
|
use nom7::error::{Error, ErrorKind};
|
|
use nom7::number::Endianness;
|
|
use nom7::{Err, IResult, Needed};
|
|
use suricata_sys::sys::{
|
|
AppLayerParserState, AppProto, SCAppLayerParserConfParserEnabled,
|
|
SCAppLayerProtoDetectConfProtoDetectionEnabled, SCAppLayerProtoDetectPMRegisterPatternCSwPP,
|
|
};
|
|
use std;
|
|
use std::cmp;
|
|
use std::ffi::CString;
|
|
use std::collections::VecDeque;
|
|
use crate::conf::conf_get;
|
|
|
|
// Constant DCERPC UDP Header length
|
|
pub const DCERPC_HDR_LEN: u16 = 16;
|
|
// FIRST flag set on the packet
|
|
pub const DCERPC_UUID_ENTRY_FLAG_FF: u16 = 0x0001;
|
|
|
|
// Flag bits in connection-oriented PDU header
|
|
|
|
// Value to indicate first fragment
|
|
pub const PFC_FIRST_FRAG: u8 = 0x01;
|
|
// Value to indicate last fragment
|
|
pub const PFC_LAST_FRAG: u8 = 0x02;
|
|
// Cancel was pending at sender
|
|
pub const PFC_PENDING_CANCEL: u8 = 0x04;
|
|
pub const PFC_RESERVED_1: u8 = 0x08;
|
|
// supports concurrent multiplexing of a single connection.
|
|
pub const PFC_CONC_MPX: u8 = 0x10;
|
|
// only meaningful on `fault' packet; if true, guaranteed
|
|
// call did not execute.
|
|
pub const PFC_DID_NOT_EXECUTE: u8 = 0x20;
|
|
// `maybe' call semantics requested
|
|
pub const PFC_MAYBE: u8 = 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.
|
|
pub const PFC_OBJECT_UUID: u8 = 0x80;
|
|
|
|
// Flag bits in first flag field in connectionless PDU header.
|
|
pub const PFCL1_RESERVED_01: u8 = 0x01; // Reserved for use by implementations
|
|
pub const PFCL1_LASTFRAG: u8 = 0x02; // If set, the PDU is the last fragment
|
|
// of a multi-PDU transmission
|
|
pub const PFCL1_FRAG: u8 = 0x04; // If set, the PDU is a fragment
|
|
// of a multi-PDU transmission
|
|
pub const PFCL1_NOFACK: u8 = 0x08; // If set, the receiver is not requested
|
|
// to send a `fack' PDU for the fragment
|
|
pub const PFCL1_MAYBE: u8 = 0x10; // If set, the PDU is for a `maybe' request
|
|
pub const PFCL1_IDEMPOTENT: u8 = 0x20; // If set, the PDU is for
|
|
// an idempotent request
|
|
pub const PFCL1_BROADCAST: u8 = 0x40; // If set, the PDU is for
|
|
// a broadcast request
|
|
pub const PFCL1_RESERVED_80: u8 = 0x80; // Reserved for use by implementations
|
|
|
|
// Flag bits in second flag field in connectionless PDU header.
|
|
pub const PFCL2_RESERVED_01: u8 = 0x01; // Reserved for use by implementations
|
|
pub const PFCL2_CANCEL_PENDING: u8 = 0x02; // Cancel pending at the call end
|
|
pub const PFCL2_RESERVED_04: u8 = 0x04; // Reserved for future use
|
|
pub const PFCL2_RESERVED_08: u8 = 0x08; // Reserved for future use
|
|
pub const PFCL2_RESERVED_10: u8 = 0x10; // Reserved for future use
|
|
pub const PFCL2_RESERVED_20: u8 = 0x20; // Reserved for future use
|
|
pub const PFCL2_RESERVED_40: u8 = 0x40; // Reserved for future use
|
|
pub const PFCL2_RESERVED_80: u8 = 0x80; // Reserved for future use
|
|
|
|
pub const REASON_NOT_SPECIFIED: u8 = 0;
|
|
pub const TEMPORARY_CONGESTION: u8 = 1;
|
|
pub const LOCAL_LIMIT_EXCEEDED: u8 = 2;
|
|
pub const CALLED_PADDR_UNKNOWN: u8 = 3; /* not used */
|
|
pub const PROTOCOL_VERSION_NOT_SUPPORTED: u8 = 4;
|
|
pub const DEFAULT_CONTEXT_NOT_SUPPORTED: u8 = 5; /* not used */
|
|
pub const USER_DATA_NOT_READABLE: u8 = 6; /* not used */
|
|
pub const NO_PSAP_AVAILABLE: u8 = 7; /* not used */
|
|
|
|
// DCERPC Header packet types
|
|
pub const DCERPC_TYPE_REQUEST: u8 = 0;
|
|
pub const DCERPC_TYPE_PING: u8 = 1;
|
|
pub const DCERPC_TYPE_RESPONSE: u8 = 2;
|
|
pub const DCERPC_TYPE_FAULT: u8 = 3;
|
|
pub const DCERPC_TYPE_WORKING: u8 = 4;
|
|
pub const DCERPC_TYPE_NOCALL: u8 = 5;
|
|
pub const DCERPC_TYPE_REJECT: u8 = 6;
|
|
pub const DCERPC_TYPE_ACK: u8 = 7;
|
|
pub const DCERPC_TYPE_CL_CANCEL: u8 = 8;
|
|
pub const DCERPC_TYPE_FACK: u8 = 9;
|
|
pub const DCERPC_TYPE_CANCEL_ACK: u8 = 10;
|
|
pub const DCERPC_TYPE_BIND: u8 = 11;
|
|
pub const DCERPC_TYPE_BINDACK: u8 = 12;
|
|
pub const DCERPC_TYPE_BINDNAK: u8 = 13;
|
|
pub const DCERPC_TYPE_ALTER_CONTEXT: u8 = 14;
|
|
pub const DCERPC_TYPE_ALTER_CONTEXT_RESP: u8 = 15;
|
|
pub const DCERPC_TYPE_AUTH3: u8 = 16;
|
|
pub const DCERPC_TYPE_SHUTDOWN: u8 = 17;
|
|
pub const DCERPC_TYPE_CO_CANCEL: u8 = 18;
|
|
pub const DCERPC_TYPE_ORPHANED: u8 = 19;
|
|
pub const DCERPC_TYPE_RTS: u8 = 20;
|
|
pub const DCERPC_TYPE_UNKNOWN: u8 = 99;
|
|
|
|
pub(super) static mut DCERPC_MAX_TX: usize = 1024;
|
|
|
|
pub static mut ALPROTO_DCERPC: AppProto = ALPROTO_UNKNOWN;
|
|
|
|
#[derive(AppLayerFrameType)]
|
|
pub enum DCERPCFrameType {
|
|
Pdu,
|
|
Hdr,
|
|
Data,
|
|
}
|
|
|
|
pub fn dcerpc_type_string(t: u8) -> String {
|
|
match t {
|
|
DCERPC_TYPE_REQUEST => "REQUEST",
|
|
DCERPC_TYPE_PING => "PING",
|
|
DCERPC_TYPE_RESPONSE => "RESPONSE",
|
|
DCERPC_TYPE_FAULT => "FAULT",
|
|
DCERPC_TYPE_WORKING => "WORKING",
|
|
DCERPC_TYPE_NOCALL => "NOCALL",
|
|
DCERPC_TYPE_REJECT => "REJECT",
|
|
DCERPC_TYPE_ACK => "ACK",
|
|
DCERPC_TYPE_CL_CANCEL => "CL_CANCEL",
|
|
DCERPC_TYPE_FACK => "FACK",
|
|
DCERPC_TYPE_CANCEL_ACK => "CANCEL_ACK",
|
|
DCERPC_TYPE_BIND => "BIND",
|
|
DCERPC_TYPE_BINDACK => "BINDACK",
|
|
DCERPC_TYPE_BINDNAK => "BINDNAK",
|
|
DCERPC_TYPE_ALTER_CONTEXT => "ALTER_CONTEXT",
|
|
DCERPC_TYPE_ALTER_CONTEXT_RESP => "ALTER_CONTEXT_RESP",
|
|
DCERPC_TYPE_AUTH3 => "AUTH3",
|
|
DCERPC_TYPE_SHUTDOWN => "SHUTDOWN",
|
|
DCERPC_TYPE_CO_CANCEL => "CO_CANCEL",
|
|
DCERPC_TYPE_ORPHANED => "ORPHANED",
|
|
DCERPC_TYPE_RTS => "RTS",
|
|
DCERPC_TYPE_UNKNOWN => "UNKNOWN",
|
|
_ => {
|
|
return (t).to_string();
|
|
}
|
|
}
|
|
.to_string()
|
|
}
|
|
|
|
pub fn get_resp_type_for_req(t: u8) -> u8 {
|
|
match t {
|
|
DCERPC_TYPE_REQUEST => DCERPC_TYPE_RESPONSE,
|
|
DCERPC_TYPE_BIND => DCERPC_TYPE_BINDACK,
|
|
DCERPC_TYPE_ALTER_CONTEXT => DCERPC_TYPE_ALTER_CONTEXT_RESP,
|
|
_ => DCERPC_TYPE_UNKNOWN,
|
|
}
|
|
}
|
|
|
|
pub fn get_req_type_for_resp(t: u8) -> u8 {
|
|
match t {
|
|
DCERPC_TYPE_RESPONSE => DCERPC_TYPE_REQUEST,
|
|
DCERPC_TYPE_BINDACK => DCERPC_TYPE_BIND,
|
|
DCERPC_TYPE_ALTER_CONTEXT_RESP => DCERPC_TYPE_ALTER_CONTEXT,
|
|
_ => DCERPC_TYPE_UNKNOWN,
|
|
}
|
|
}
|
|
|
|
#[derive(Default, Debug)]
|
|
pub struct DCERPCTransaction {
|
|
pub id: u64, // internal transaction ID
|
|
pub ctxid: u16,
|
|
pub opnum: u16,
|
|
pub first_request_seen: u8,
|
|
pub min_version: u8,
|
|
pub call_id: u32, // ID to match any request-response pair
|
|
pub frag_cnt_ts: u16,
|
|
pub frag_cnt_tc: u16,
|
|
pub endianness: u8,
|
|
pub stub_data_buffer_ts: Vec<u8>,
|
|
pub stub_data_buffer_tc: Vec<u8>,
|
|
pub stub_data_buffer_reset_ts: bool,
|
|
pub stub_data_buffer_reset_tc: bool,
|
|
pub req_done: bool,
|
|
pub resp_done: bool,
|
|
pub req_lost: bool,
|
|
pub resp_lost: bool,
|
|
pub req_cmd: u8,
|
|
pub resp_cmd: u8,
|
|
pub activityuuid: Vec<u8>,
|
|
pub seqnum: u32,
|
|
pub tx_data: AppLayerTxData,
|
|
}
|
|
|
|
impl Transaction for DCERPCTransaction {
|
|
fn id(&self) -> u64 {
|
|
// need +1 to match state.tx_id
|
|
self.id + 1
|
|
}
|
|
}
|
|
|
|
impl DCERPCTransaction {
|
|
pub fn new() -> Self {
|
|
return Self {
|
|
stub_data_buffer_ts: Vec::new(),
|
|
stub_data_buffer_tc: Vec::new(),
|
|
req_cmd: DCERPC_TYPE_REQUEST,
|
|
resp_cmd: DCERPC_TYPE_RESPONSE,
|
|
activityuuid: Vec::new(),
|
|
tx_data: AppLayerTxData::new(),
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
pub fn get_req_ctxid(&self) -> u16 {
|
|
self.ctxid
|
|
}
|
|
|
|
pub fn get_first_req_seen(&self) -> u8 {
|
|
self.first_request_seen
|
|
}
|
|
|
|
pub fn get_req_opnum(&self) -> u16 {
|
|
self.opnum
|
|
}
|
|
|
|
pub fn get_endianness(&self) -> u8 {
|
|
self.endianness
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct DCERPCRequest {
|
|
pub ctxid: u16,
|
|
pub opnum: u16,
|
|
pub first_request_seen: u8,
|
|
}
|
|
|
|
#[derive(Default, Debug, Clone)]
|
|
pub struct DCERPCUuidEntry {
|
|
pub ctxid: u16,
|
|
pub internal_id: u16,
|
|
pub result: u16,
|
|
pub uuid: Vec<u8>,
|
|
pub version: u16,
|
|
pub versionminor: u16,
|
|
pub flags: u16,
|
|
}
|
|
|
|
impl DCERPCUuidEntry {
|
|
pub fn new() -> Self {
|
|
Default::default()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
pub struct Uuid {
|
|
pub time_low: Vec<u8>,
|
|
pub time_mid: Vec<u8>,
|
|
pub time_hi_and_version: Vec<u8>,
|
|
pub clock_seq_hi_and_reserved: u8,
|
|
pub clock_seq_low: u8,
|
|
pub node: Vec<u8>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct DCERPCHdr {
|
|
pub rpc_vers: u8,
|
|
pub rpc_vers_minor: u8,
|
|
pub hdrtype: u8,
|
|
pub pfc_flags: u8,
|
|
pub packed_drep: Vec<u8>,
|
|
pub frag_length: u16,
|
|
pub auth_length: u16,
|
|
pub call_id: u32,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct DCERPCBind {
|
|
pub numctxitems: u8,
|
|
pub uuid_list: Vec<DCERPCUuidEntry>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct BindCtxItem {
|
|
pub ctxid: u16,
|
|
pub uuid: Vec<u8>,
|
|
pub version: u16,
|
|
pub versionminor: u16,
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
pub struct DCERPCBindAckResult {
|
|
pub ack_result: u16,
|
|
pub ack_reason: u16,
|
|
pub transfer_syntax: Vec<u8>,
|
|
pub syntax_version: u32,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct DCERPCBindAck {
|
|
pub accepted_uuid_list: Vec<DCERPCUuidEntry>,
|
|
pub sec_addr_len: u16,
|
|
pub numctxitems: u8,
|
|
pub ctxitems: Vec<DCERPCBindAckResult>,
|
|
}
|
|
|
|
#[derive(Default, Debug)]
|
|
pub struct DCERPCState {
|
|
pub header: Option<DCERPCHdr>,
|
|
pub bind: Option<DCERPCBind>,
|
|
pub bindack: Option<DCERPCBindAck>,
|
|
pub transactions: VecDeque<DCERPCTransaction>,
|
|
tx_index_completed: usize,
|
|
pub pad: u8,
|
|
pub padleft: u16,
|
|
pub tx_id: u64,
|
|
ts_gap: bool,
|
|
tc_gap: bool,
|
|
ts_ssn_gap: bool,
|
|
tc_ssn_gap: bool,
|
|
pub flow: Option<*mut Flow>,
|
|
state_data: AppLayerStateData,
|
|
}
|
|
|
|
impl State<DCERPCTransaction> for DCERPCState {
|
|
fn get_transaction_count(&self) -> usize {
|
|
self.transactions.len()
|
|
}
|
|
|
|
fn get_transaction_by_index(&self, index: usize) -> Option<&DCERPCTransaction> {
|
|
self.transactions.get(index)
|
|
}
|
|
}
|
|
|
|
impl DCERPCState {
|
|
pub fn new() -> Self {
|
|
return Self {
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
fn create_tx(&mut self, call_id: u32) -> DCERPCTransaction {
|
|
let mut tx = DCERPCTransaction::new();
|
|
let endianness = self.get_hdr_drep_0() & 0x10;
|
|
tx.id = self.tx_id;
|
|
tx.call_id = call_id;
|
|
tx.endianness = endianness;
|
|
self.tx_id += 1;
|
|
if self.transactions.len() > unsafe { DCERPC_MAX_TX } {
|
|
let mut index = self.tx_index_completed;
|
|
for tx_old in &mut self.transactions.range_mut(self.tx_index_completed..) {
|
|
index += 1;
|
|
if !tx_old.req_done || !tx_old.resp_done {
|
|
tx_old.tx_data.updated_tc = true;
|
|
tx_old.tx_data.updated_ts = true;
|
|
tx_old.req_done = true;
|
|
tx_old.resp_done = true;
|
|
break;
|
|
}
|
|
}
|
|
self.tx_index_completed = index;
|
|
}
|
|
if let Some(hdr) = &self.header {
|
|
tx.min_version = hdr.rpc_vers_minor;
|
|
}
|
|
tx
|
|
}
|
|
|
|
pub fn free_tx(&mut self, tx_id: u64) {
|
|
SCLogDebug!("Freeing TX with ID {} TX.ID {}", tx_id, tx_id+1);
|
|
let len = self.transactions.len();
|
|
let mut found = false;
|
|
let mut index = 0;
|
|
for i in 0..len {
|
|
let tx = &self.transactions[i];
|
|
if tx.id == tx_id { //+ 1 {
|
|
found = true;
|
|
index = i;
|
|
SCLogDebug!("tx {} progress {}/{}", tx.id, tx.req_done, tx.resp_done);
|
|
break;
|
|
}
|
|
}
|
|
if found {
|
|
SCLogDebug!("freeing TX with ID {} TX.ID {} at index {} left: {} max id: {}",
|
|
tx_id, tx_id+1, index, self.transactions.len(), self.tx_id);
|
|
self.tx_index_completed = 0;
|
|
self.transactions.remove(index);
|
|
}
|
|
}
|
|
|
|
fn get_hdr_drep_0(&self) -> u8 {
|
|
if let Some(ref hdr) = &self.header {
|
|
return hdr.packed_drep[0];
|
|
}
|
|
0
|
|
}
|
|
|
|
fn get_endianness(&self) -> Endianness {
|
|
let drep_0 = self.get_hdr_drep_0();
|
|
if drep_0 & 0x10 == 0 {
|
|
return Endianness::Big;
|
|
}
|
|
Endianness::Little
|
|
}
|
|
|
|
fn get_hdr_fraglen(&self) -> Option<u16> {
|
|
debug_validate_bug_on!(self.header.is_none());
|
|
if let Some(ref hdr) = self.header {
|
|
return Some(hdr.frag_length);
|
|
}
|
|
// Shouldn't happen
|
|
None
|
|
}
|
|
|
|
fn get_hdr_pfcflags(&self) -> Option<u8> {
|
|
debug_validate_bug_on!(self.header.is_none());
|
|
if let Some(ref hdr) = self.header {
|
|
return Some(hdr.pfc_flags);
|
|
}
|
|
// Shouldn't happen
|
|
None
|
|
}
|
|
|
|
pub fn get_hdr_type(&self) -> Option<u8> {
|
|
debug_validate_bug_on!(self.header.is_none());
|
|
if let Some(ref hdr) = self.header {
|
|
return Some(hdr.hdrtype);
|
|
}
|
|
// Shouldn't happen
|
|
None
|
|
}
|
|
|
|
pub fn get_hdr_call_id(&self) -> Option<u32> {
|
|
debug_validate_bug_on!(self.header.is_none());
|
|
if let Some(ref hdr) = self.header {
|
|
return Some(hdr.call_id);
|
|
}
|
|
// Shouldn't happen
|
|
None
|
|
}
|
|
|
|
/// Get transaction as per the given transaction ID. Transaction ID with
|
|
/// which the lookup is supposed to be done as per the calls from AppLayer
|
|
/// parser in C. This requires an internal transaction ID to be maintained.
|
|
///
|
|
/// Arguments:
|
|
/// * `tx_id`: internal transaction ID to track transactions
|
|
///
|
|
/// Return value:
|
|
/// Option mutable reference to DCERPCTransaction
|
|
pub fn get_tx(&mut self, tx_id: u64) -> Option<&mut DCERPCTransaction> {
|
|
for tx in &mut self.transactions {
|
|
let found = tx.id == tx_id;
|
|
if found {
|
|
return Some(tx);
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
/// Find the transaction as per call ID defined in header. If the tx is not
|
|
/// found, create one.
|
|
///
|
|
/// Arguments:
|
|
/// * `call_id`: call_id param derived from TCP Header
|
|
/// * `dir`: direction of the flow
|
|
///
|
|
/// Return value:
|
|
/// Option mutable reference to DCERPCTransaction
|
|
pub fn get_tx_by_call_id(&mut self, call_id: u32, dir: Direction) -> Option<&mut DCERPCTransaction> {
|
|
let cmd = self.get_hdr_type().unwrap_or(0);
|
|
for tx in &mut self.transactions {
|
|
let found = tx.call_id == call_id;
|
|
if found {
|
|
match dir {
|
|
Direction::ToServer => {
|
|
if tx.req_done || tx.req_lost {
|
|
continue;
|
|
}
|
|
let resp_cmd = get_resp_type_for_req(cmd);
|
|
if resp_cmd != tx.resp_cmd {
|
|
continue;
|
|
}
|
|
}
|
|
Direction::ToClient => {
|
|
if tx.resp_done || tx.resp_lost {
|
|
continue;
|
|
}
|
|
let req_cmd = get_req_type_for_resp(cmd);
|
|
if req_cmd != tx.req_cmd {
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
tx.tx_data.updated_tc = true;
|
|
tx.tx_data.updated_ts = true;
|
|
return Some(tx);
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
fn post_gap_housekeeping(&mut self, dir: Direction) {
|
|
SCLogDebug!("ts ssn gap: {:?}, tc ssn gap: {:?}, dir: {:?}", self.ts_ssn_gap, self.tc_ssn_gap, dir);
|
|
if self.ts_ssn_gap && dir == Direction::ToServer {
|
|
for tx in &mut self.transactions {
|
|
if tx.id >= self.tx_id {
|
|
SCLogDebug!("post_gap_housekeeping: done");
|
|
break;
|
|
}
|
|
if !tx.req_done {
|
|
tx.req_lost = true;
|
|
}
|
|
tx.req_done = true;
|
|
if let Some(flow) = self.flow {
|
|
sc_app_layer_parser_trigger_raw_stream_inspection(flow, dir as i32);
|
|
}
|
|
}
|
|
} else if self.tc_ssn_gap && dir == Direction::ToClient {
|
|
for tx in &mut self.transactions {
|
|
if tx.id >= self.tx_id {
|
|
SCLogDebug!("post_gap_housekeeping: done");
|
|
break;
|
|
}
|
|
if !tx.req_done {
|
|
tx.req_lost = true;
|
|
}
|
|
if !tx.resp_done {
|
|
tx.resp_lost = true;
|
|
}
|
|
tx.req_done = true;
|
|
tx.resp_done = true;
|
|
if let Some(flow) = self.flow {
|
|
sc_app_layer_parser_trigger_raw_stream_inspection(flow, dir as i32);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn search_dcerpc_record<'a>(&mut self, i: &'a[u8]) -> IResult<&'a[u8], &'a[u8]> {
|
|
let mut d = i;
|
|
while d.len() >= 2 {
|
|
if d[0] == 0x05 && d[1] == 0x00 {
|
|
return Ok((&d[2..], d));
|
|
}
|
|
d = &d[1..];
|
|
}
|
|
Err(Err::Incomplete(Needed::new(2_usize - d.len())))
|
|
}
|
|
|
|
/// Makes a call to the nom parser for parsing DCERPC Header.
|
|
///
|
|
/// Arguments:
|
|
/// * `input`: bytes from the beginning of the buffer.
|
|
///
|
|
/// Return value:
|
|
/// * Success: Number of bytes successfully parsed.
|
|
/// * Failure:
|
|
// -1 in case of Incomplete data or Eof.
|
|
/// -2 in case of Error while parsing.
|
|
/// -3 in case of invalid DCERPC header.
|
|
pub fn process_header(&mut self, input: &[u8]) -> i32 {
|
|
match parser::parse_dcerpc_header(input) {
|
|
Ok((leftover_bytes, header)) => {
|
|
if header.rpc_vers != 5
|
|
|| (header.rpc_vers_minor != 0 && header.rpc_vers_minor != 1)
|
|
{
|
|
SCLogDebug!(
|
|
"DCERPC Header did not validate. Major version: {:?} Minor version: {:?}",
|
|
header.rpc_vers,
|
|
header.rpc_vers_minor
|
|
);
|
|
return -3;
|
|
}
|
|
self.header = Some(header);
|
|
(input.len() - leftover_bytes.len()) as i32
|
|
}
|
|
Err(Err::Incomplete(_)) => {
|
|
// Insufficient data.
|
|
SCLogDebug!("Insufficient data while parsing DCERPC header");
|
|
-1
|
|
}
|
|
Err(Err::Error(Error{code:ErrorKind::Eof, ..})) => {
|
|
SCLogDebug!("EoF reached while parsing DCERPC header");
|
|
-1
|
|
}
|
|
Err(_) => {
|
|
// Error, probably malformed data.
|
|
SCLogDebug!("An error occurred while parsing DCERPC header");
|
|
-2
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn handle_bindctxitem(&mut self, input: &[u8], uuid_internal_id: u16) -> i32 {
|
|
let endianness = self.get_endianness();
|
|
match parser::parse_bindctx_item(input, endianness) {
|
|
Ok((leftover_bytes, ctxitem)) => {
|
|
let mut uuidentry = DCERPCUuidEntry::new();
|
|
uuidentry.uuid = ctxitem.uuid;
|
|
uuidentry.internal_id = uuid_internal_id;
|
|
uuidentry.ctxid = ctxitem.ctxid;
|
|
uuidentry.version = ctxitem.version;
|
|
uuidentry.versionminor = ctxitem.versionminor;
|
|
let pfcflags = self.get_hdr_pfcflags().unwrap_or(0);
|
|
// Store the first frag flag in the uuid as pfc_flags will
|
|
// be overwritten by new packets
|
|
if pfcflags & PFC_FIRST_FRAG > 0 {
|
|
uuidentry.flags |= DCERPC_UUID_ENTRY_FLAG_FF;
|
|
}
|
|
if let Some(ref mut bind) = self.bind {
|
|
SCLogDebug!("DCERPC BIND CtxItem: Pushing uuid: {:?}", uuidentry);
|
|
bind.uuid_list.push(uuidentry);
|
|
}
|
|
(input.len() - leftover_bytes.len()) as i32
|
|
}
|
|
Err(Err::Incomplete(_)) => {
|
|
// Insufficient data.
|
|
SCLogDebug!("Insufficient data while parsing DCERPC BIND CTXItem");
|
|
-1
|
|
}
|
|
Err(_) => {
|
|
// Error, probably malformed data.
|
|
SCLogDebug!("An error occurred while parsing DCERPC BIND CTXItem");
|
|
-1
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn process_bind_pdu(&mut self, input: &[u8]) -> i32 {
|
|
let mut retval = 0;
|
|
let mut idx = 12; // Bytes consumed if parser returns OK would be 12
|
|
match parser::parse_dcerpc_bind(input) {
|
|
Ok((leftover_bytes, header)) => {
|
|
let numctxitems = header.numctxitems;
|
|
self.bind = Some(header);
|
|
for i in 0..numctxitems {
|
|
retval = self.handle_bindctxitem(&input[idx as usize..], i as u16);
|
|
if retval == -1 {
|
|
return -1;
|
|
}
|
|
idx += retval;
|
|
}
|
|
let call_id = self.get_hdr_call_id().unwrap_or(0);
|
|
let mut tx = self.create_tx(call_id);
|
|
tx.req_cmd = self.get_hdr_type().unwrap_or(0);
|
|
tx.req_done = true;
|
|
if let Some(flow) = self.flow {
|
|
sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToServer as i32);
|
|
}
|
|
tx.frag_cnt_ts = 1;
|
|
self.transactions.push_back(tx);
|
|
// Bytes parsed with `parse_dcerpc_bind` + (bytes parsed per bindctxitem [44] * number
|
|
// of bindctxitems)
|
|
(input.len() - leftover_bytes.len()) as i32 + retval * numctxitems as i32
|
|
}
|
|
Err(Err::Incomplete(_)) => {
|
|
// Insufficient data.
|
|
SCLogDebug!("Insufficient data while parsing DCERPC BIND header");
|
|
-1
|
|
}
|
|
Err(_) => {
|
|
// Error, probably malformed data.
|
|
SCLogDebug!("An error occurred while parsing DCERPC BIND header");
|
|
-1
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn process_bindack_pdu(&mut self, input: &[u8]) -> i32 {
|
|
match parser::parse_dcerpc_bindack(input) {
|
|
Ok((leftover_bytes, mut back)) => {
|
|
if let Some(ref mut bind) = self.bind {
|
|
for (uuid_internal_id, r) in back.ctxitems.iter().enumerate() {
|
|
for uuid in bind.uuid_list.iter_mut() {
|
|
if uuid.internal_id == uuid_internal_id as u16 {
|
|
uuid.result = r.ack_result;
|
|
if uuid.result != 0 {
|
|
break;
|
|
}
|
|
back.accepted_uuid_list.push(uuid.clone());
|
|
SCLogDebug!("DCERPC BINDACK accepted UUID: {:?}", uuid);
|
|
}
|
|
}
|
|
}
|
|
self.bindack = Some(back);
|
|
}
|
|
(input.len() - leftover_bytes.len()) as i32
|
|
}
|
|
Err(Err::Incomplete(_)) => {
|
|
// Insufficient data.
|
|
SCLogDebug!("Insufficient data while parsing DCERPC BINDACK");
|
|
-1
|
|
}
|
|
Err(_) => {
|
|
// Error, probably malformed data.
|
|
SCLogDebug!("An error occurred while parsing DCERPC BINDACK");
|
|
-1
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn handle_stub_data(&mut self, input: &[u8], input_len: usize, dir: Direction) -> u16 {
|
|
let retval;
|
|
let hdrpfcflags = self.get_hdr_pfcflags().unwrap_or(0);
|
|
let padleft = self.padleft;
|
|
let call_id = self.get_hdr_call_id().unwrap_or(0);
|
|
let hdrtype = self.get_hdr_type();
|
|
let tx;
|
|
if let Some(transaction) = self.get_tx_by_call_id(call_id, dir) {
|
|
tx = transaction;
|
|
} else {
|
|
SCLogDebug!("No transaction found matching the call ID: {:?}", call_id);
|
|
return 0;
|
|
}
|
|
|
|
// Update the stub params based on the packet type
|
|
match hdrtype {
|
|
Some(x) => match x {
|
|
DCERPC_TYPE_REQUEST => {
|
|
retval = evaluate_stub_params(
|
|
input,
|
|
input_len,
|
|
hdrpfcflags,
|
|
padleft,
|
|
&mut tx.stub_data_buffer_ts,
|
|
&mut tx.stub_data_buffer_reset_ts,
|
|
);
|
|
tx.req_done = true;
|
|
tx.frag_cnt_ts = 1;
|
|
if let Some(flow) = self.flow {
|
|
sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToServer as i32);
|
|
}
|
|
}
|
|
DCERPC_TYPE_RESPONSE => {
|
|
retval = evaluate_stub_params(
|
|
input,
|
|
input_len,
|
|
hdrpfcflags,
|
|
padleft,
|
|
&mut tx.stub_data_buffer_tc,
|
|
&mut tx.stub_data_buffer_reset_tc,
|
|
);
|
|
tx.resp_done = true;
|
|
tx.frag_cnt_tc = 1;
|
|
if let Some(flow) = self.flow {
|
|
sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToClient as i32);
|
|
}
|
|
}
|
|
_ => {
|
|
SCLogDebug!("Unrecognized packet type");
|
|
return 0;
|
|
}
|
|
},
|
|
None => {
|
|
return 0;
|
|
}
|
|
}
|
|
// Update the remaining fragment length
|
|
self.padleft -= retval;
|
|
|
|
retval
|
|
}
|
|
|
|
/// Handles stub data for both request and response.
|
|
///
|
|
/// Arguments:
|
|
/// * `input`: bytes left *after* parsing header.
|
|
/// * `bytes_consumed`: bytes consumed *after* parsing header.
|
|
/// * `dir`: direction whose stub is supposed to be handled.
|
|
///
|
|
/// Return value:
|
|
/// * Success: Number of bytes successfully parsed.
|
|
/// * Failure: -1 in case fragment length defined by header mismatches the data.
|
|
pub fn handle_common_stub(&mut self, input: &[u8], bytes_consumed: usize, dir: Direction) -> i32 {
|
|
let fraglen = self.get_hdr_fraglen().unwrap_or(0);
|
|
if (fraglen as usize) < bytes_consumed + (DCERPC_HDR_LEN as usize) {
|
|
return -1;
|
|
}
|
|
// Above check makes sure padleft stays in u16 limits
|
|
self.padleft = fraglen - DCERPC_HDR_LEN - bytes_consumed as u16;
|
|
let mut input_left = input.len() - bytes_consumed;
|
|
let mut parsed = bytes_consumed as i32;
|
|
while input_left > 0 && parsed < fraglen as i32 {
|
|
let retval = self.handle_stub_data(&input[parsed as usize..], input_left, dir);
|
|
if retval > 0 && retval as usize <= input_left {
|
|
parsed += retval as i32;
|
|
input_left -= <u16 as std::convert::Into<usize>>::into(retval);
|
|
} else if input_left > 0 {
|
|
SCLogDebug!(
|
|
"Error parsing DCERPC {} stub data",
|
|
if dir == Direction::ToServer {
|
|
"request"
|
|
} else {
|
|
"response"
|
|
}
|
|
);
|
|
parsed -= input_left as i32;
|
|
input_left = 0;
|
|
}
|
|
}
|
|
parsed
|
|
}
|
|
|
|
pub fn process_request_pdu(&mut self, input: &[u8]) -> i32 {
|
|
let endianness = self.get_endianness();
|
|
match parser::parse_dcerpc_request(input, endianness) {
|
|
Ok((leftover_input, request)) => {
|
|
let call_id = self.get_hdr_call_id().unwrap_or(0);
|
|
let hdr_type = self.get_hdr_type().unwrap_or(0);
|
|
let mut transaction = self.get_tx_by_call_id(call_id, Direction::ToServer);
|
|
match transaction {
|
|
Some(ref mut tx) => {
|
|
tx.req_cmd = hdr_type;
|
|
tx.ctxid = request.ctxid;
|
|
tx.opnum = request.opnum;
|
|
tx.first_request_seen = request.first_request_seen;
|
|
}
|
|
None => {
|
|
let mut tx = self.create_tx(call_id);
|
|
tx.req_cmd = hdr_type;
|
|
tx.ctxid = request.ctxid;
|
|
tx.opnum = request.opnum;
|
|
tx.first_request_seen = request.first_request_seen;
|
|
self.transactions.push_back(tx);
|
|
}
|
|
}
|
|
let parsed = self.handle_common_stub(
|
|
input,
|
|
input.len() - leftover_input.len(),
|
|
Direction::ToServer,
|
|
);
|
|
parsed
|
|
}
|
|
Err(Err::Incomplete(_)) => {
|
|
// Insufficient data.
|
|
SCLogDebug!("Insufficient data while parsing DCERPC REQUEST");
|
|
-1
|
|
}
|
|
Err(_) => {
|
|
// Error, probably malformed data.
|
|
SCLogDebug!("An error occurred while parsing DCERPC REQUEST");
|
|
-1
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn handle_input_data(&mut self, stream_slice: StreamSlice, direction: Direction) -> AppLayerResult {
|
|
let mut parsed = 0;
|
|
let retval;
|
|
let mut cur_i = stream_slice.as_slice();
|
|
let mut consumed = 0u32;
|
|
|
|
// Skip the record since this means that its in the middle of a known length record
|
|
if (self.ts_gap && direction == Direction::ToServer) || (self.tc_gap && direction == Direction::ToClient) {
|
|
SCLogDebug!("Trying to catch up after GAP (input {})", cur_i.len());
|
|
match self.search_dcerpc_record(cur_i) {
|
|
Ok((_, pg)) => {
|
|
SCLogDebug!("DCERPC record found");
|
|
let offset = cur_i.len() - pg.len();
|
|
cur_i = &cur_i[offset..];
|
|
consumed = offset as u32;
|
|
match direction {
|
|
Direction::ToServer => {
|
|
self.ts_gap = false;
|
|
},
|
|
Direction::ToClient => {
|
|
self.tc_gap = false;
|
|
}
|
|
}
|
|
},
|
|
_ => {
|
|
consumed = cur_i.len() as u32;
|
|
// At least 2 bytes are required to know if a new record is beginning
|
|
if consumed < 2 {
|
|
consumed = 0;
|
|
} else {
|
|
consumed -= 1;
|
|
}
|
|
SCLogDebug!("DCERPC record NOT found");
|
|
return AppLayerResult::incomplete(consumed, 2);
|
|
},
|
|
}
|
|
}
|
|
|
|
let mut frag_bytes_consumed: u16 = 0;
|
|
let mut flow = std::ptr::null();
|
|
if let Some(f) = self.flow {
|
|
flow = f;
|
|
}
|
|
// Check if header data was complete. In case of EoF or incomplete data, wait for more
|
|
// data else return error
|
|
if self.header.is_none() && !cur_i.is_empty() {
|
|
parsed = self.process_header(cur_i);
|
|
if parsed == -1 {
|
|
return AppLayerResult::incomplete(consumed, DCERPC_HDR_LEN as u32);
|
|
}
|
|
if parsed < 0 {
|
|
return AppLayerResult::err();
|
|
}
|
|
} else {
|
|
frag_bytes_consumed = DCERPC_HDR_LEN;
|
|
}
|
|
|
|
let fraglen = self.get_hdr_fraglen().unwrap_or(0);
|
|
|
|
if (cur_i.len() + frag_bytes_consumed as usize) < fraglen as usize {
|
|
SCLogDebug!("Possibly fragmented data, waiting for more..");
|
|
return AppLayerResult::incomplete(consumed + parsed as u32, fraglen as u32 - parsed as u32);
|
|
}
|
|
|
|
let _hdr = Frame::new(flow, &stream_slice, cur_i, parsed as i64, DCERPCFrameType::Hdr as u8, None);
|
|
let _pdu = Frame::new(flow, &stream_slice, cur_i, fraglen as i64, DCERPCFrameType::Pdu as u8, None);
|
|
if fraglen >= DCERPC_HDR_LEN && cur_i.len() > DCERPC_HDR_LEN as usize {
|
|
let _data = Frame::new(flow, &stream_slice, &cur_i[DCERPC_HDR_LEN as usize..], (fraglen - DCERPC_HDR_LEN) as i64, DCERPCFrameType::Data as u8, None);
|
|
}
|
|
let current_call_id = self.get_hdr_call_id().unwrap_or(0);
|
|
|
|
match self.get_hdr_type() {
|
|
Some(x) => match x {
|
|
DCERPC_TYPE_BIND | DCERPC_TYPE_ALTER_CONTEXT => {
|
|
retval = self.process_bind_pdu(&cur_i[parsed as usize..]);
|
|
if retval == -1 {
|
|
return AppLayerResult::err();
|
|
}
|
|
}
|
|
DCERPC_TYPE_BINDACK | DCERPC_TYPE_ALTER_CONTEXT_RESP => {
|
|
retval = self.process_bindack_pdu(&cur_i[parsed as usize..]);
|
|
if retval == -1 {
|
|
return AppLayerResult::err();
|
|
}
|
|
let tx = if let Some(tx) = self.get_tx_by_call_id(current_call_id, Direction::ToClient) {
|
|
tx.resp_cmd = x;
|
|
tx
|
|
} else {
|
|
let mut tx = self.create_tx(current_call_id);
|
|
tx.resp_cmd = x;
|
|
self.transactions.push_back(tx);
|
|
self.transactions.back_mut().unwrap()
|
|
};
|
|
tx.resp_done = true;
|
|
tx.frag_cnt_tc = 1;
|
|
if let Some(flow) = self.flow {
|
|
sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToClient as i32);
|
|
}
|
|
}
|
|
DCERPC_TYPE_REQUEST => {
|
|
retval = self.process_request_pdu(&cur_i[parsed as usize..]);
|
|
if retval < 0 {
|
|
return AppLayerResult::err();
|
|
}
|
|
// In case the response came first, the transaction would complete later when
|
|
// the corresponding request also comes through
|
|
}
|
|
DCERPC_TYPE_RESPONSE => {
|
|
let transaction = self.get_tx_by_call_id(current_call_id, Direction::ToClient);
|
|
match transaction {
|
|
Some(tx) => {
|
|
tx.resp_cmd = x;
|
|
}
|
|
None => {
|
|
let mut tx = self.create_tx(current_call_id);
|
|
tx.resp_cmd = x;
|
|
self.transactions.push_back(tx);
|
|
}
|
|
};
|
|
retval = self.handle_common_stub(
|
|
&cur_i[parsed as usize..],
|
|
0,
|
|
Direction::ToClient,
|
|
);
|
|
if retval < 0 {
|
|
return AppLayerResult::err();
|
|
}
|
|
}
|
|
_ => {
|
|
SCLogDebug!("Unrecognized packet type: {:?}", x);
|
|
return AppLayerResult::err();
|
|
}
|
|
},
|
|
None => {
|
|
return AppLayerResult::err();
|
|
}
|
|
}
|
|
|
|
self.post_gap_housekeeping(direction);
|
|
self.header = None;
|
|
return AppLayerResult::ok();
|
|
}
|
|
}
|
|
|
|
fn evaluate_stub_params(
|
|
input: &[u8], input_len: usize, hdrflags: u8, lenleft: u16,
|
|
stub_data_buffer: &mut Vec<u8>,stub_data_buffer_reset: &mut bool,
|
|
) -> u16 {
|
|
|
|
let fragtype = hdrflags & (PFC_FIRST_FRAG | PFC_LAST_FRAG);
|
|
// min of usize and u16 is a valid u16
|
|
let stub_len: u16 = cmp::min(lenleft as usize, input_len) as u16;
|
|
if stub_len == 0 {
|
|
return 0;
|
|
}
|
|
if stub_len == lenleft && (fragtype == 0 || (fragtype & PFC_LAST_FRAG > 0)) {
|
|
*stub_data_buffer_reset = true;
|
|
}
|
|
|
|
let input_slice = &input[..stub_len as usize];
|
|
stub_data_buffer.extend_from_slice(input_slice);
|
|
|
|
stub_len
|
|
}
|
|
|
|
unsafe extern "C" fn parse_request(
|
|
flow: *mut Flow, state: *mut std::os::raw::c_void, _pstate: *mut AppLayerParserState,
|
|
stream_slice: StreamSlice,
|
|
_data: *const std::os::raw::c_void,
|
|
) -> AppLayerResult {
|
|
let state = cast_pointer!(state, DCERPCState);
|
|
let flags = stream_slice.flags();
|
|
|
|
SCLogDebug!("Handling request: input_len {} flags {:x} EOF {}",
|
|
stream_slice.len(), flags, flags & core::STREAM_EOF != 0);
|
|
if flags & core::STREAM_EOF != 0 && stream_slice.is_empty() {
|
|
return AppLayerResult::ok();
|
|
}
|
|
/* START with MIDSTREAM set: record might be starting the middle. */
|
|
if flags & (core::STREAM_START|core::STREAM_MIDSTREAM) == (core::STREAM_START|core::STREAM_MIDSTREAM) {
|
|
state.ts_gap = true;
|
|
}
|
|
if !stream_slice.is_gap() {
|
|
state.flow = Some(flow);
|
|
return state.handle_input_data(stream_slice, Direction::ToServer);
|
|
}
|
|
AppLayerResult::err()
|
|
}
|
|
|
|
unsafe extern "C" fn parse_response(
|
|
flow: *mut Flow, state: *mut std::os::raw::c_void, _pstate: *mut AppLayerParserState,
|
|
stream_slice: StreamSlice,
|
|
_data: *const std::os::raw::c_void,
|
|
) -> AppLayerResult {
|
|
let state = cast_pointer!(state, DCERPCState);
|
|
let flags = stream_slice.flags();
|
|
|
|
if flags & core::STREAM_EOF != 0 && stream_slice.is_empty() {
|
|
return AppLayerResult::ok();
|
|
}
|
|
/* START with MIDSTREAM set: record might be starting the middle. */
|
|
if flags & (core::STREAM_START|core::STREAM_MIDSTREAM) == (core::STREAM_START|core::STREAM_MIDSTREAM) {
|
|
state.tc_gap = true;
|
|
}
|
|
if !stream_slice.is_gap() {
|
|
state.flow = Some(flow);
|
|
return state.handle_input_data(stream_slice, Direction::ToClient);
|
|
}
|
|
AppLayerResult::err()
|
|
}
|
|
|
|
extern "C" fn state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
|
|
let state = DCERPCState::new();
|
|
let boxed = Box::new(state);
|
|
return Box::into_raw(boxed) as *mut _;
|
|
}
|
|
|
|
extern "C" fn state_free(state: *mut std::os::raw::c_void) {
|
|
std::mem::drop(unsafe { Box::from_raw(state as *mut DCERPCState)} );
|
|
}
|
|
|
|
unsafe extern "C" fn state_transaction_free(state: *mut std::os::raw::c_void, tx_id: u64) {
|
|
let dce_state = cast_pointer!(state, DCERPCState);
|
|
SCLogDebug!("freeing tx {}", tx_id);
|
|
dce_state.free_tx(tx_id);
|
|
}
|
|
|
|
unsafe extern "C" fn get_tx(
|
|
vtx: *mut std::os::raw::c_void, tx_id: u64,
|
|
) -> *mut std::os::raw::c_void {
|
|
let dce_state = cast_pointer!(vtx, DCERPCState);
|
|
match dce_state.get_tx(tx_id) {
|
|
Some(tx) => tx as *const _ as *mut _,
|
|
None => std::ptr::null_mut(),
|
|
}
|
|
}
|
|
|
|
unsafe extern "C" fn get_tx_cnt(vtx: *mut std::os::raw::c_void) -> u64 {
|
|
let dce_state = cast_pointer!(vtx, DCERPCState);
|
|
dce_state.tx_id
|
|
}
|
|
|
|
pub(super) unsafe extern "C" fn get_alstate_progress(tx: *mut std::os::raw::c_void, direction: u8
|
|
)-> std::os::raw::c_int {
|
|
let tx = cast_pointer!(tx, DCERPCTransaction);
|
|
if direction == u8::from(Direction::ToServer) && tx.req_done {
|
|
SCLogDebug!("tx {} TOSERVER progress 1 => {:?}", tx.call_id, tx);
|
|
return 1;
|
|
} else if direction == u8::from(Direction::ToClient) && tx.resp_done {
|
|
SCLogDebug!("tx {} TOCLIENT progress 1 => {:?}", tx.call_id, tx);
|
|
return 1;
|
|
}
|
|
SCLogDebug!("tx {} direction {} progress 0", tx.call_id, direction);
|
|
return 0;
|
|
}
|
|
|
|
unsafe extern "C" fn get_tx_data(
|
|
tx: *mut std::os::raw::c_void)
|
|
-> *mut AppLayerTxData
|
|
{
|
|
let tx = cast_pointer!(tx, DCERPCTransaction);
|
|
return &mut tx.tx_data;
|
|
}
|
|
|
|
#[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) {
|
|
Ok((_, hdr)) => {
|
|
let is_request = hdr.hdrtype == 0x00 || hdr.hdrtype == 0x0e;
|
|
let is_dcerpc = hdr.rpc_vers == 0x05 &&
|
|
hdr.rpc_vers_minor == 0x00 &&
|
|
hdr.packed_drep[0] & 0xee == 0 &&
|
|
hdr.packed_drep[1] <= 3;
|
|
return (is_dcerpc, is_request);
|
|
},
|
|
Err(_) => (false, false),
|
|
}
|
|
}
|
|
|
|
unsafe extern "C" fn probe_tcp(_f: *const Flow, direction: u8, input: *const u8,
|
|
len: u32, rdir: *mut u8) -> AppProto
|
|
{
|
|
SCLogDebug!("Probing packet for DCERPC");
|
|
if len == 0 || input.is_null() {
|
|
return core::ALPROTO_UNKNOWN;
|
|
}
|
|
let slice: &[u8] = 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 {
|
|
Direction::ToServer
|
|
} else {
|
|
Direction::ToClient
|
|
};
|
|
if (direction & DIR_BOTH) != dir as u8 {
|
|
*rdir = dir as u8;
|
|
}
|
|
return ALPROTO_DCERPC;
|
|
}
|
|
return core::ALPROTO_FAILED;
|
|
}
|
|
|
|
fn register_pattern_probe() -> i8 {
|
|
unsafe {
|
|
if SCAppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP, ALPROTO_DCERPC,
|
|
b"|05 00|\0".as_ptr() as *const std::os::raw::c_char, 2, 0,
|
|
Direction::ToServer.into(), Some(probe_tcp), 0, 0) < 0 {
|
|
SCLogDebug!("TOSERVER => SCAppLayerProtoDetectPMRegisterPatternCSwPP FAILED");
|
|
return -1;
|
|
}
|
|
if SCAppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP, ALPROTO_DCERPC,
|
|
b"|05 00|\0".as_ptr() as *const std::os::raw::c_char, 2, 0,
|
|
Direction::ToClient.into(), Some(probe_tcp), 0, 0) < 0 {
|
|
SCLogDebug!("TOCLIENT => SCAppLayerProtoDetectPMRegisterPatternCSwPP FAILED");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
0
|
|
}
|
|
|
|
export_state_data_get!(get_state_data, DCERPCState);
|
|
|
|
// Parser name as a C style string.
|
|
pub const PARSER_NAME: &[u8] = b"dcerpc\0";
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn SCRegisterDcerpcParser() {
|
|
let parser = RustParser {
|
|
name: PARSER_NAME.as_ptr() as *const std::os::raw::c_char,
|
|
default_port: std::ptr::null(),
|
|
ipproto: IPPROTO_TCP,
|
|
probe_ts: None,
|
|
probe_tc: None,
|
|
min_depth: 0,
|
|
max_depth: 16,
|
|
state_new,
|
|
state_free,
|
|
tx_free: state_transaction_free,
|
|
parse_ts: parse_request,
|
|
parse_tc: parse_response,
|
|
get_tx_count: get_tx_cnt,
|
|
get_tx,
|
|
tx_comp_st_ts: 1,
|
|
tx_comp_st_tc: 1,
|
|
tx_get_progress: get_alstate_progress,
|
|
get_eventinfo: None,
|
|
get_eventinfo_byid : None,
|
|
localstorage_new: None,
|
|
localstorage_free: None,
|
|
get_tx_files: None,
|
|
get_tx_iterator: Some(applayer::state_get_tx_iterator::<DCERPCState, DCERPCTransaction>),
|
|
get_tx_data,
|
|
get_state_data,
|
|
apply_tx_config: None,
|
|
flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS,
|
|
get_frame_id_by_name: Some(DCERPCFrameType::ffi_id_from_name),
|
|
get_frame_name_by_id: Some(DCERPCFrameType::ffi_name_from_id),
|
|
get_state_id_by_name: None,
|
|
get_state_name_by_id: None,
|
|
};
|
|
|
|
let ip_proto_str = CString::new("tcp").unwrap();
|
|
|
|
if SCAppLayerProtoDetectConfProtoDetectionEnabled(
|
|
ip_proto_str.as_ptr(),
|
|
parser.name,
|
|
) != 0
|
|
{
|
|
let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
|
|
ALPROTO_DCERPC = alproto;
|
|
if register_pattern_probe() < 0 {
|
|
return;
|
|
}
|
|
if SCAppLayerParserConfParserEnabled(
|
|
ip_proto_str.as_ptr(),
|
|
parser.name,
|
|
) != 0
|
|
{
|
|
let _ = AppLayerRegisterParser(&parser, alproto);
|
|
}
|
|
if let Some(val) = conf_get("app-layer.protocols.dcerpc.max-tx") {
|
|
if let Ok(v) = val.parse::<usize>() {
|
|
DCERPC_MAX_TX = v;
|
|
} else {
|
|
SCLogError!("Invalid value for smb.max-tx");
|
|
}
|
|
}
|
|
SCLogDebug!("Rust DCERPC parser registered.");
|
|
} else {
|
|
SCLogDebug!("Protocol detector and parser disabled for DCERPC.");
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::applayer::{AppLayerResult, StreamSlice};
|
|
use crate::core::*;
|
|
use crate::dcerpc::dcerpc::DCERPCState;
|
|
use crate::direction::Direction;
|
|
use std::cmp;
|
|
|
|
#[test]
|
|
fn test_process_header() {
|
|
let request: &[u8] = &[
|
|
0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
assert_eq!(16, dcerpc_state.process_header(request));
|
|
}
|
|
|
|
#[test]
|
|
fn test_process_bind_pdu() {
|
|
let header: &[u8] = &[
|
|
0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let bind: &[u8] = &[
|
|
0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x2c, 0xd0, 0x28, 0xda, 0x76, 0x91, 0xf6, 0x6e, 0xcb, 0x0f, 0xbf, 0x85,
|
|
0xcd, 0x9b, 0xf6, 0x39, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x01, 0x00, 0x2c, 0x75, 0xce, 0x7e, 0x82, 0x3b, 0x06, 0xac, 0x1b, 0xf0,
|
|
0xf5, 0xb7, 0xa7, 0xf7, 0x28, 0xaf, 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0xe3, 0xb2, 0x10, 0xd1, 0xd0, 0x0c, 0xcc, 0x3d,
|
|
0x2f, 0x80, 0x20, 0x7c, 0xef, 0xe7, 0x09, 0xe0, 0x04, 0x00, 0x00, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0xde, 0x85, 0x70, 0xc4, 0x02, 0x7c,
|
|
0x60, 0x23, 0x67, 0x0c, 0x22, 0xbf, 0x18, 0x36, 0x79, 0x17, 0x01, 0x00, 0x02, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x41, 0x65, 0x29, 0x51,
|
|
0xaa, 0xe7, 0x7b, 0xa8, 0xf2, 0x37, 0x0b, 0xd0, 0x3f, 0xb3, 0x36, 0xed, 0x05, 0x00,
|
|
0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x14, 0x96,
|
|
0x80, 0x01, 0x2e, 0x78, 0xfb, 0x5d, 0xb4, 0x3c, 0x14, 0xb3, 0x3d, 0xaa, 0x02, 0xfb,
|
|
0x06, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00,
|
|
0x3b, 0x04, 0x68, 0x3e, 0x63, 0xfe, 0x9f, 0xd8, 0x64, 0x55, 0xcd, 0xe7, 0x39, 0xaf,
|
|
0x98, 0x9f, 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00,
|
|
0x01, 0x00, 0x16, 0x7a, 0x4f, 0x1b, 0xdb, 0x25, 0x92, 0x55, 0xdd, 0xae, 0x9e, 0x5b,
|
|
0x3e, 0x93, 0x66, 0x93, 0x04, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x08, 0x00, 0x01, 0x00, 0xe8, 0xa4, 0x8a, 0xcf, 0x95, 0x6c, 0xc7, 0x8f, 0x14, 0xcc,
|
|
0x56, 0xfc, 0x7b, 0x5f, 0x4f, 0xe8, 0x04, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0xd8, 0xda, 0xfb, 0xbc, 0xa2, 0x55, 0x6f, 0x5d,
|
|
0xc0, 0x2d, 0x88, 0x6f, 0x00, 0x17, 0x52, 0x8d, 0x06, 0x00, 0x03, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x3f, 0x17, 0x55, 0x0c, 0xf4, 0x23,
|
|
0x3c, 0xca, 0xe6, 0xa0, 0xaa, 0xcc, 0xb5, 0xe3, 0xf9, 0xce, 0x04, 0x00, 0x00, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x6a, 0x28, 0x19, 0x39,
|
|
0x0c, 0xb1, 0xd0, 0x11, 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, 0x00, 0x00,
|
|
0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0xc9, 0x9f,
|
|
0x3e, 0x6e, 0x82, 0x0a, 0x2b, 0x28, 0x37, 0x78, 0xe1, 0x13, 0x70, 0x05, 0x38, 0x4d,
|
|
0x01, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x01, 0x00,
|
|
0x11, 0xaa, 0x4b, 0x15, 0xdf, 0xa6, 0x86, 0x3f, 0xfb, 0xe0, 0x09, 0xb7, 0xf8, 0x56,
|
|
0xd2, 0x3f, 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00,
|
|
0x01, 0x00, 0xee, 0x99, 0xc4, 0x25, 0x11, 0xe4, 0x95, 0x62, 0x29, 0xfa, 0xfd, 0x26,
|
|
0x57, 0x02, 0xf1, 0xce, 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x0f, 0x00, 0x01, 0x00, 0xba, 0x81, 0x9e, 0x1a, 0xdf, 0x2b, 0xba, 0xe4, 0xd3, 0x17,
|
|
0x41, 0x60, 0x6d, 0x2d, 0x9e, 0x28, 0x03, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0xa0, 0x24, 0x03, 0x9a, 0xa9, 0x99, 0xfb, 0xbe,
|
|
0x49, 0x11, 0xad, 0x77, 0x30, 0xaa, 0xbc, 0xb6, 0x02, 0x00, 0x03, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x32, 0x04, 0x7e, 0xae, 0xec, 0x28,
|
|
0xd1, 0x55, 0x83, 0x4e, 0xc3, 0x47, 0x5d, 0x1d, 0xc6, 0x65, 0x02, 0x00, 0x03, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x01, 0x00, 0xc6, 0xa4, 0x81, 0x48,
|
|
0x66, 0x2a, 0x74, 0x7d, 0x56, 0x6e, 0xc5, 0x1d, 0x19, 0xf2, 0xb5, 0xb6, 0x03, 0x00,
|
|
0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x01, 0x00, 0xcb, 0xae,
|
|
0xb3, 0xc0, 0x0c, 0xf4, 0xa4, 0x5e, 0x91, 0x72, 0xdd, 0x53, 0x24, 0x70, 0x89, 0x02,
|
|
0x05, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01, 0x00,
|
|
0xb8, 0xd0, 0xa0, 0x1a, 0x5e, 0x7a, 0x2d, 0xfe, 0x35, 0xc6, 0x7d, 0x08, 0x0d, 0x33,
|
|
0x73, 0x18, 0x02, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00,
|
|
0x01, 0x00, 0x21, 0xd3, 0xaa, 0x09, 0x03, 0xa7, 0x0b, 0xc2, 0x06, 0x45, 0xd9, 0x6c,
|
|
0x75, 0xc2, 0x15, 0xa8, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x16, 0x00, 0x01, 0x00, 0xe1, 0xbd, 0x59, 0xfc, 0xbc, 0xa9, 0x95, 0xc2, 0x68, 0x79,
|
|
0xf3, 0x75, 0xe0, 0xae, 0x6c, 0xe5, 0x04, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x17, 0x00, 0x01, 0x00, 0x06, 0x52, 0xb4, 0x71, 0x70, 0x15, 0x4e, 0xf5,
|
|
0x7f, 0x08, 0x86, 0x14, 0xe6, 0x17, 0xd5, 0x97, 0x04, 0x00, 0x00, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
assert_eq!(16, dcerpc_state.process_header(header));
|
|
assert_eq!(1068, dcerpc_state.process_bind_pdu(bind));
|
|
}
|
|
|
|
#[test]
|
|
fn test_handle_bindctxitem() {
|
|
let header: &[u8] = &[
|
|
0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let bind: &[u8] = &[
|
|
0x00, 0x00, 0x01, 0x00, 0x2c, 0xd0, 0x28, 0xda, 0x76, 0x91, 0xf6, 0x6e, 0xcb, 0x0f,
|
|
0xbf, 0x85, 0xcd, 0x9b, 0xf6, 0x39, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
assert_eq!(16, dcerpc_state.process_header(header));
|
|
assert_eq!(44, dcerpc_state.handle_bindctxitem(bind, 0));
|
|
}
|
|
|
|
#[test]
|
|
fn test_process_bindack_pdu() {
|
|
let bind: &[u8] = &[
|
|
0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x2c, 0xd0, 0x28, 0xda, 0x76, 0x91, 0xf6, 0x6e, 0xcb, 0x0f,
|
|
0xbf, 0x85, 0xcd, 0x9b, 0xf6, 0x39, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x2c, 0x75, 0xce, 0x7e, 0x82, 0x3b, 0x06, 0xac,
|
|
0x1b, 0xf0, 0xf5, 0xb7, 0xa7, 0xf7, 0x28, 0xaf, 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0xe3, 0xb2, 0x10, 0xd1, 0xd0, 0x0c,
|
|
0xcc, 0x3d, 0x2f, 0x80, 0x20, 0x7c, 0xef, 0xe7, 0x09, 0xe0, 0x04, 0x00, 0x00, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0xde, 0x85, 0x70, 0xc4,
|
|
0x02, 0x7c, 0x60, 0x23, 0x67, 0x0c, 0x22, 0xbf, 0x18, 0x36, 0x79, 0x17, 0x01, 0x00,
|
|
0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x41, 0x65,
|
|
0x29, 0x51, 0xaa, 0xe7, 0x7b, 0xa8, 0xf2, 0x37, 0x0b, 0xd0, 0x3f, 0xb3, 0x36, 0xed,
|
|
0x05, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00,
|
|
0x14, 0x96, 0x80, 0x01, 0x2e, 0x78, 0xfb, 0x5d, 0xb4, 0x3c, 0x14, 0xb3, 0x3d, 0xaa,
|
|
0x02, 0xfb, 0x06, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00,
|
|
0x01, 0x00, 0x3b, 0x04, 0x68, 0x3e, 0x63, 0xfe, 0x9f, 0xd8, 0x64, 0x55, 0xcd, 0xe7,
|
|
0x39, 0xaf, 0x98, 0x9f, 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x07, 0x00, 0x01, 0x00, 0x16, 0x7a, 0x4f, 0x1b, 0xdb, 0x25, 0x92, 0x55, 0xdd, 0xae,
|
|
0x9e, 0x5b, 0x3e, 0x93, 0x66, 0x93, 0x04, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0xe8, 0xa4, 0x8a, 0xcf, 0x95, 0x6c, 0xc7, 0x8f,
|
|
0x14, 0xcc, 0x56, 0xfc, 0x7b, 0x5f, 0x4f, 0xe8, 0x04, 0x00, 0x00, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0xd8, 0xda, 0xfb, 0xbc, 0xa2, 0x55,
|
|
0x6f, 0x5d, 0xc0, 0x2d, 0x88, 0x6f, 0x00, 0x17, 0x52, 0x8d, 0x06, 0x00, 0x03, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x3f, 0x17, 0x55, 0x0c,
|
|
0xf4, 0x23, 0x3c, 0xca, 0xe6, 0xa0, 0xaa, 0xcc, 0xb5, 0xe3, 0xf9, 0xce, 0x04, 0x00,
|
|
0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x6a, 0x28,
|
|
0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5,
|
|
0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00,
|
|
0xc9, 0x9f, 0x3e, 0x6e, 0x82, 0x0a, 0x2b, 0x28, 0x37, 0x78, 0xe1, 0x13, 0x70, 0x05,
|
|
0x38, 0x4d, 0x01, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x00,
|
|
0x01, 0x00, 0x11, 0xaa, 0x4b, 0x15, 0xdf, 0xa6, 0x86, 0x3f, 0xfb, 0xe0, 0x09, 0xb7,
|
|
0xf8, 0x56, 0xd2, 0x3f, 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x0e, 0x00, 0x01, 0x00, 0xee, 0x99, 0xc4, 0x25, 0x11, 0xe4, 0x95, 0x62, 0x29, 0xfa,
|
|
0xfd, 0x26, 0x57, 0x02, 0xf1, 0xce, 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0xba, 0x81, 0x9e, 0x1a, 0xdf, 0x2b, 0xba, 0xe4,
|
|
0xd3, 0x17, 0x41, 0x60, 0x6d, 0x2d, 0x9e, 0x28, 0x03, 0x00, 0x03, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0xa0, 0x24, 0x03, 0x9a, 0xa9, 0x99,
|
|
0xfb, 0xbe, 0x49, 0x11, 0xad, 0x77, 0x30, 0xaa, 0xbc, 0xb6, 0x02, 0x00, 0x03, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x32, 0x04, 0x7e, 0xae,
|
|
0xec, 0x28, 0xd1, 0x55, 0x83, 0x4e, 0xc3, 0x47, 0x5d, 0x1d, 0xc6, 0x65, 0x02, 0x00,
|
|
0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x01, 0x00, 0xc6, 0xa4,
|
|
0x81, 0x48, 0x66, 0x2a, 0x74, 0x7d, 0x56, 0x6e, 0xc5, 0x1d, 0x19, 0xf2, 0xb5, 0xb6,
|
|
0x03, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x01, 0x00,
|
|
0xcb, 0xae, 0xb3, 0xc0, 0x0c, 0xf4, 0xa4, 0x5e, 0x91, 0x72, 0xdd, 0x53, 0x24, 0x70,
|
|
0x89, 0x02, 0x05, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00,
|
|
0x01, 0x00, 0xb8, 0xd0, 0xa0, 0x1a, 0x5e, 0x7a, 0x2d, 0xfe, 0x35, 0xc6, 0x7d, 0x08,
|
|
0x0d, 0x33, 0x73, 0x18, 0x02, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x15, 0x00, 0x01, 0x00, 0x21, 0xd3, 0xaa, 0x09, 0x03, 0xa7, 0x0b, 0xc2, 0x06, 0x45,
|
|
0xd9, 0x6c, 0x75, 0xc2, 0x15, 0xa8, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x16, 0x00, 0x01, 0x00, 0xe1, 0xbd, 0x59, 0xfc, 0xbc, 0xa9, 0x95, 0xc2,
|
|
0x68, 0x79, 0xf3, 0x75, 0xe0, 0xae, 0x6c, 0xe5, 0x04, 0x00, 0x02, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00, 0x06, 0x52, 0xb4, 0x71, 0x70, 0x15,
|
|
0x4e, 0xf5, 0x7f, 0x08, 0x86, 0x14, 0xe6, 0x17, 0xd5, 0x97, 0x04, 0x00, 0x00, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
let bindack: &[u8] = &[
|
|
0xb8, 0x10, 0xb8, 0x10, 0xce, 0x47, 0x00, 0x00, 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50,
|
|
0x45, 0x5c, 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0xf6, 0x6e, 0x18, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
assert_eq!(16, dcerpc_state.process_header(bind));
|
|
assert_eq!(1068, dcerpc_state.process_bind_pdu(&bind[16..]));
|
|
assert_eq!(604, dcerpc_state.process_bindack_pdu(bindack));
|
|
if let Some(back) = dcerpc_state.bindack {
|
|
assert_eq!(1, back.accepted_uuid_list.len());
|
|
assert_eq!(
|
|
vec!(57, 25, 40, 106, 177, 12, 17, 208, 155, 168, 0, 192, 79, 217, 46, 245),
|
|
back.accepted_uuid_list[0].uuid
|
|
);
|
|
assert_eq!(11, back.accepted_uuid_list[0].internal_id);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
pub fn test_process_request_pdu() {
|
|
let request: &[u8] = &[
|
|
0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x45, 0x00, 0x2c, 0x00,
|
|
0x4d, 0x00, 0x73, 0x00, 0x53, 0x00, 0x59, 0x00, 0x2a, 0x00, 0x4a, 0x00, 0x7a, 0x00,
|
|
0x3e, 0x00, 0x58, 0x00, 0x21, 0x00, 0x4a, 0x00, 0x30, 0x00, 0x41, 0x00, 0x4b, 0x00,
|
|
0x4b, 0x00, 0x3c, 0x00, 0x48, 0x00, 0x24, 0x00, 0x38, 0x00, 0x54, 0x00, 0x60, 0x00,
|
|
0x2d, 0x00, 0x29, 0x00, 0x64, 0x00, 0x5b, 0x00, 0x77, 0x00, 0x3a, 0x00, 0x4c, 0x00,
|
|
0x24, 0x00, 0x23, 0x00, 0x66, 0x00, 0x43, 0x00, 0x68, 0x00, 0x22, 0x00, 0x55, 0x00,
|
|
0x29, 0x00, 0x2c, 0x00, 0x4f, 0x00, 0x5a, 0x00, 0x50, 0x00, 0x61, 0x00, 0x2a, 0x00,
|
|
0x6f, 0x00, 0x2f, 0x00, 0x4d, 0x00, 0x68, 0x00, 0x3a, 0x00, 0x5c, 0x00, 0x67, 0x00,
|
|
0x68, 0x00, 0x68, 0x00, 0x49, 0x00, 0x45, 0x00, 0x4c, 0x00, 0x72, 0x00, 0x53, 0x00,
|
|
0x4c, 0x00, 0x25, 0x00, 0x4d, 0x00, 0x67, 0x00, 0x2e, 0x00, 0x4f, 0x00, 0x64, 0x00,
|
|
0x61, 0x00, 0x73, 0x00, 0x24, 0x00, 0x46, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x45, 0x00,
|
|
0x6f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x33, 0x00, 0x38, 0x00, 0x47, 0x00, 0x71, 0x00,
|
|
0x5a, 0x00, 0x37, 0x00, 0x7a, 0x00, 0x35, 0x00, 0x6b, 0x00, 0x3c, 0x00, 0x26, 0x00,
|
|
0x37, 0x00, 0x69, 0x00, 0x75, 0x00, 0x36, 0x00, 0x37, 0x00, 0x47, 0x00, 0x21, 0x00,
|
|
0x2d, 0x00, 0x69, 0x00, 0x37, 0x00, 0x78, 0x00, 0x5f, 0x00, 0x72, 0x00, 0x4b, 0x00,
|
|
0x5c, 0x00, 0x74, 0x00, 0x3e, 0x00, 0x52, 0x00, 0x7a, 0x00, 0x49, 0x00, 0x31, 0x00,
|
|
0x5a, 0x00, 0x7b, 0x00, 0x29, 0x00, 0x3b, 0x00, 0x78, 0x00, 0x3b, 0x00, 0x55, 0x00,
|
|
0x3e, 0x00, 0x35, 0x00, 0x2b, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x59, 0x00, 0x38, 0x00,
|
|
0x2a, 0x00, 0x59, 0x00, 0x6b, 0x00, 0x42, 0x00, 0x4c, 0x00, 0x3e, 0x00, 0x6a, 0x00,
|
|
0x49, 0x00, 0x2c, 0x00, 0x79, 0x00, 0x6e, 0x00, 0x35, 0x00, 0x4f, 0x00, 0x49, 0x00,
|
|
0x55, 0x00, 0x35, 0x00, 0x61, 0x00, 0x72, 0x00, 0x77, 0x00, 0x38, 0x00, 0x32, 0x00,
|
|
0x24, 0x00, 0x46, 0x00, 0x32, 0x00, 0x32, 0x00, 0x27, 0x00, 0x64, 0x00, 0x5a, 0x00,
|
|
0x77, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x77, 0x00, 0x2e, 0x00, 0x28, 0x00, 0x63, 0x00,
|
|
0x4f, 0x00, 0x67, 0x00, 0x64, 0x00, 0x39, 0x00, 0x37, 0x00, 0x31, 0x00, 0x30, 0x00,
|
|
0x28, 0x00, 0x2e, 0x00, 0x6f, 0x00, 0x3e, 0x00, 0x59, 0x00, 0x28, 0x00, 0x67, 0x00,
|
|
0x52, 0x00, 0x35, 0x00, 0x5a, 0x00, 0x7c, 0x00, 0x56, 0x00, 0x6a, 0x00, 0x5c, 0x00,
|
|
0x3c, 0x00, 0x30, 0x00, 0x59, 0x00, 0x5c, 0x00, 0x5e, 0x00, 0x38, 0x00, 0x54, 0x00,
|
|
0x5c, 0x00, 0x5b, 0x00, 0x42, 0x00, 0x62, 0x00, 0x70, 0x00, 0x34, 0x00, 0x5c, 0x00,
|
|
0x57, 0x00, 0x7a, 0x00, 0x4b, 0x00, 0x2f, 0x00, 0x6b, 0x00, 0x6a, 0x00, 0x4f, 0x00,
|
|
0x41, 0x00, 0x33, 0x00, 0x52, 0x00, 0x36, 0x00, 0x27, 0x00, 0x30, 0x00, 0x6d, 0x00,
|
|
0x4a, 0x00, 0x30, 0x00, 0x78, 0x00, 0x46, 0x00, 0x65, 0x00, 0x4e, 0x00, 0x29, 0x00,
|
|
0x66, 0x00, 0x3f, 0x00, 0x72, 0x00, 0x71, 0x00, 0x75, 0x00, 0x4c, 0x00, 0x2b, 0x00,
|
|
0x5c, 0x00, 0x46, 0x00, 0x52, 0x00, 0x7b, 0x00, 0x5c, 0x00, 0x69, 0x00, 0x66, 0x00,
|
|
0x56, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x72, 0x00, 0x61, 0x00, 0x68, 0x00, 0x28, 0x00,
|
|
0x7d, 0x00, 0x58, 0x00, 0x2a, 0x00, 0x7b, 0x00, 0x28, 0x00, 0x5b, 0x00, 0x54, 0x00,
|
|
0x3a, 0x00, 0x26, 0x00, 0x52, 0x00, 0x44, 0x00, 0x60, 0x00, 0x50, 0x00, 0x65, 0x00,
|
|
0x48, 0x00, 0x7d, 0x00, 0x2a, 0x00, 0x74, 0x00, 0x49, 0x00, 0x7b, 0x00, 0x21, 0x00,
|
|
0x61, 0x00, 0x52, 0x00, 0x43, 0x00, 0x5f, 0x00, 0x5a, 0x00, 0x74, 0x00, 0x5c, 0x00,
|
|
0x62, 0x00, 0x68, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x2b, 0x00, 0x6f, 0x00, 0x7c, 0x00,
|
|
0x42, 0x00, 0x67, 0x00, 0x32, 0x00, 0x58, 0x00, 0x35, 0x00, 0x30, 0x00, 0x2f, 0x00,
|
|
0x2d, 0x00, 0x60, 0x00, 0x62, 0x00, 0x51, 0x00, 0x2a, 0x00, 0x30, 0x00, 0x31, 0x00,
|
|
0x48, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x5d, 0x00, 0x25, 0x00, 0x58, 0x00, 0x4a, 0x00,
|
|
0x76, 0x00, 0x32, 0x00, 0x62, 0x00, 0x27, 0x00, 0x42, 0x00, 0x40, 0x00, 0x53, 0x00,
|
|
0x7c, 0x00, 0x7d, 0x00, 0x50, 0x00, 0x3d, 0x00, 0x40, 0x00, 0x76, 0x00, 0x38, 0x00,
|
|
0x58, 0x00, 0x39, 0x00, 0x63, 0x00, 0x3c, 0x00, 0x5b, 0x00, 0x23, 0x00, 0x53, 0x00,
|
|
0x7a, 0x00, 0x54, 0x00, 0x74, 0x00, 0x61, 0x00, 0x76, 0x00, 0x4a, 0x00, 0x3e, 0x00,
|
|
0x33, 0x00, 0x75, 0x00, 0x66, 0x00, 0x2d, 0x00, 0x48, 0x00, 0x33, 0x00, 0x71, 0x00,
|
|
0x76, 0x00, 0x48, 0x00, 0x71, 0x00, 0x41, 0x00, 0x6f, 0x00, 0x2a, 0x00, 0x67, 0x00,
|
|
0x70, 0x00, 0x21, 0x00, 0x70, 0x00, 0x4b, 0x00, 0x52, 0x00, 0x58, 0x00, 0x68, 0x00,
|
|
0x23, 0x00, 0x39, 0x00, 0x46, 0x00, 0x4d, 0x00, 0x51, 0x00, 0x57, 0x00, 0x3a, 0x00,
|
|
0x79, 0x00, 0x7b, 0x00, 0x6c, 0x00, 0x55, 0x00, 0x33, 0x00, 0x65, 0x00, 0x49, 0x00,
|
|
0x72, 0x00, 0x30, 0x00, 0x4f, 0x00, 0x41, 0x00, 0x6e, 0x00, 0x31, 0x00, 0x4a, 0x00,
|
|
0x60, 0x00, 0x79, 0x00, 0x70, 0x00, 0x4f, 0x00, 0x58, 0x00, 0x75, 0x00, 0x44, 0x00,
|
|
0x59, 0x00, 0x58, 0x00, 0x46, 0x00, 0x3d, 0x00, 0x46, 0x00, 0x74, 0x00, 0x51, 0x00,
|
|
0x57, 0x00, 0x6e, 0x00, 0x2d, 0x00, 0x47, 0x00, 0x23, 0x00, 0x45, 0x00, 0x60, 0x00,
|
|
0x4c, 0x00, 0x72, 0x00, 0x4e, 0x00, 0x74, 0x00, 0x40, 0x00, 0x76, 0x00, 0x75, 0x00,
|
|
0x74, 0x00, 0x56, 0x00, 0x44, 0x00, 0x29, 0x00, 0x62, 0x00, 0x58, 0x00, 0x31, 0x00,
|
|
0x78, 0x00, 0x32, 0x00, 0x52, 0x00, 0x4a, 0x00, 0x6b, 0x00, 0x55, 0x00, 0x72, 0x00,
|
|
0x6f, 0x00, 0x6f, 0x00, 0x4a, 0x00, 0x54, 0x00, 0x7d, 0x00, 0x68, 0x00, 0x3f, 0x00,
|
|
0x28, 0x00, 0x21, 0x00, 0x53, 0x00, 0x48, 0x00, 0x5a, 0x00, 0x34, 0x00, 0x36, 0x00,
|
|
0x35, 0x00, 0x64, 0x00, 0x4e, 0x00, 0x75, 0x00, 0x69, 0x00, 0x23, 0x00, 0x75, 0x00,
|
|
0x55, 0x00, 0x43, 0x00, 0x75, 0x00, 0x2f, 0x00, 0x73, 0x00, 0x62, 0x00, 0x6f, 0x00,
|
|
0x37, 0x00, 0x4e, 0x00, 0x25, 0x00, 0x25, 0x00, 0x21, 0x00, 0x3d, 0x00, 0x3c, 0x00,
|
|
0x71, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x30, 0x00, 0x36, 0x00, 0x62, 0x00, 0x63, 0x00,
|
|
0x53, 0x00, 0x54, 0x00, 0x5d, 0x00, 0x61, 0x00, 0x4c, 0x00, 0x28, 0x00, 0x2b, 0x00,
|
|
0x4c, 0x00, 0x4e, 0x00, 0x66, 0x00, 0x5f, 0x00, 0x4b, 0x00, 0x43, 0x00, 0x75, 0x00,
|
|
0x45, 0x00, 0x37, 0x00, 0x28, 0x00, 0x56, 0x00, 0x36, 0x00, 0x6a, 0x00, 0x3e, 0x00,
|
|
0x64, 0x00, 0x34, 0x00, 0x6a, 0x00, 0x7d, 0x00, 0x4a, 0x00, 0x66, 0x00, 0x7a, 0x00,
|
|
0x3e, 0x00, 0x75, 0x00, 0x38, 0x00, 0x7b, 0x00, 0x42, 0x00, 0x76, 0x00, 0x29, 0x00,
|
|
0x4c, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x2b, 0x00, 0x51, 0x00,
|
|
0x47, 0x00, 0x22, 0x00, 0x48, 0x00, 0x3d, 0x00, 0x49, 0x00, 0x44, 0x00, 0x5d, 0x00,
|
|
0x59, 0x00, 0x63, 0x00, 0x5c, 0x00, 0x24, 0x00, 0x35, 0x00, 0x34, 0x00, 0x70, 0x00,
|
|
0x69, 0x00,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
assert_eq!(16, dcerpc_state.process_header(request));
|
|
assert_eq!(1008, dcerpc_state.process_request_pdu(&request[16..]));
|
|
}
|
|
|
|
#[test]
|
|
pub fn test_parse_dcerpc() {
|
|
let request: &[u8] = &[
|
|
0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x45, 0x00, 0x2c, 0x00,
|
|
0x4d, 0x00, 0x73, 0x00, 0x53, 0x00, 0x59, 0x00, 0x2a, 0x00, 0x4a, 0x00, 0x7a, 0x00,
|
|
0x3e, 0x00, 0x58, 0x00, 0x21, 0x00, 0x4a, 0x00, 0x30, 0x00, 0x41, 0x00, 0x4b, 0x00,
|
|
0x4b, 0x00, 0x3c, 0x00, 0x48, 0x00, 0x24, 0x00, 0x38, 0x00, 0x54, 0x00, 0x60, 0x00,
|
|
0x2d, 0x00, 0x29, 0x00, 0x64, 0x00, 0x5b, 0x00, 0x77, 0x00, 0x3a, 0x00, 0x4c, 0x00,
|
|
0x24, 0x00, 0x23, 0x00, 0x66, 0x00, 0x43, 0x00, 0x68, 0x00, 0x22, 0x00, 0x55, 0x00,
|
|
0x29, 0x00, 0x2c, 0x00, 0x4f, 0x00, 0x5a, 0x00, 0x50, 0x00, 0x61, 0x00, 0x2a, 0x00,
|
|
0x6f, 0x00, 0x2f, 0x00, 0x4d, 0x00, 0x68, 0x00, 0x3a, 0x00, 0x5c, 0x00, 0x67, 0x00,
|
|
0x68, 0x00, 0x68, 0x00, 0x49, 0x00, 0x45, 0x00, 0x4c, 0x00, 0x72, 0x00, 0x53, 0x00,
|
|
0x4c, 0x00, 0x25, 0x00, 0x4d, 0x00, 0x67, 0x00, 0x2e, 0x00, 0x4f, 0x00, 0x64, 0x00,
|
|
0x61, 0x00, 0x73, 0x00, 0x24, 0x00, 0x46, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x45, 0x00,
|
|
0x6f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x33, 0x00, 0x38, 0x00, 0x47, 0x00, 0x71, 0x00,
|
|
0x5a, 0x00, 0x37, 0x00, 0x7a, 0x00, 0x35, 0x00, 0x6b, 0x00, 0x3c, 0x00, 0x26, 0x00,
|
|
0x37, 0x00, 0x69, 0x00, 0x75, 0x00, 0x36, 0x00, 0x37, 0x00, 0x47, 0x00, 0x21, 0x00,
|
|
0x2d, 0x00, 0x69, 0x00, 0x37, 0x00, 0x78, 0x00, 0x5f, 0x00, 0x72, 0x00, 0x4b, 0x00,
|
|
0x5c, 0x00, 0x74, 0x00, 0x3e, 0x00, 0x52, 0x00, 0x7a, 0x00, 0x49, 0x00, 0x31, 0x00,
|
|
0x5a, 0x00, 0x7b, 0x00, 0x29, 0x00, 0x3b, 0x00, 0x78, 0x00, 0x3b, 0x00, 0x55, 0x00,
|
|
0x3e, 0x00, 0x35, 0x00, 0x2b, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x59, 0x00, 0x38, 0x00,
|
|
0x2a, 0x00, 0x59, 0x00, 0x6b, 0x00, 0x42, 0x00, 0x4c, 0x00, 0x3e, 0x00, 0x6a, 0x00,
|
|
0x49, 0x00, 0x2c, 0x00, 0x79, 0x00, 0x6e, 0x00, 0x35, 0x00, 0x4f, 0x00, 0x49, 0x00,
|
|
0x55, 0x00, 0x35, 0x00, 0x61, 0x00, 0x72, 0x00, 0x77, 0x00, 0x38, 0x00, 0x32, 0x00,
|
|
0x24, 0x00, 0x46, 0x00, 0x32, 0x00, 0x32, 0x00, 0x27, 0x00, 0x64, 0x00, 0x5a, 0x00,
|
|
0x77, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x77, 0x00, 0x2e, 0x00, 0x28, 0x00, 0x63, 0x00,
|
|
0x4f, 0x00, 0x67, 0x00, 0x64, 0x00, 0x39, 0x00, 0x37, 0x00, 0x31, 0x00, 0x30, 0x00,
|
|
0x28, 0x00, 0x2e, 0x00, 0x6f, 0x00, 0x3e, 0x00, 0x59, 0x00, 0x28, 0x00, 0x67, 0x00,
|
|
0x52, 0x00, 0x35, 0x00, 0x5a, 0x00, 0x7c, 0x00, 0x56, 0x00, 0x6a, 0x00, 0x5c, 0x00,
|
|
0x3c, 0x00, 0x30, 0x00, 0x59, 0x00, 0x5c, 0x00, 0x5e, 0x00, 0x38, 0x00, 0x54, 0x00,
|
|
0x5c, 0x00, 0x5b, 0x00, 0x42, 0x00, 0x62, 0x00, 0x70, 0x00, 0x34, 0x00, 0x5c, 0x00,
|
|
0x57, 0x00, 0x7a, 0x00, 0x4b, 0x00, 0x2f, 0x00, 0x6b, 0x00, 0x6a, 0x00, 0x4f, 0x00,
|
|
0x41, 0x00, 0x33, 0x00, 0x52, 0x00, 0x36, 0x00, 0x27, 0x00, 0x30, 0x00, 0x6d, 0x00,
|
|
0x4a, 0x00, 0x30, 0x00, 0x78, 0x00, 0x46, 0x00, 0x65, 0x00, 0x4e, 0x00, 0x29, 0x00,
|
|
0x66, 0x00, 0x3f, 0x00, 0x72, 0x00, 0x71, 0x00, 0x75, 0x00, 0x4c, 0x00, 0x2b, 0x00,
|
|
0x5c, 0x00, 0x46, 0x00, 0x52, 0x00, 0x7b, 0x00, 0x5c, 0x00, 0x69, 0x00, 0x66, 0x00,
|
|
0x56, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x72, 0x00, 0x61, 0x00, 0x68, 0x00, 0x28, 0x00,
|
|
0x7d, 0x00, 0x58, 0x00, 0x2a, 0x00, 0x7b, 0x00, 0x28, 0x00, 0x5b, 0x00, 0x54, 0x00,
|
|
0x3a, 0x00, 0x26, 0x00, 0x52, 0x00, 0x44, 0x00, 0x60, 0x00, 0x50, 0x00, 0x65, 0x00,
|
|
0x48, 0x00, 0x7d, 0x00, 0x2a, 0x00, 0x74, 0x00, 0x49, 0x00, 0x7b, 0x00, 0x21, 0x00,
|
|
0x61, 0x00, 0x52, 0x00, 0x43, 0x00, 0x5f, 0x00, 0x5a, 0x00, 0x74, 0x00, 0x5c, 0x00,
|
|
0x62, 0x00, 0x68, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x2b, 0x00, 0x6f, 0x00, 0x7c, 0x00,
|
|
0x42, 0x00, 0x67, 0x00, 0x32, 0x00, 0x58, 0x00, 0x35, 0x00, 0x30, 0x00, 0x2f, 0x00,
|
|
0x2d, 0x00, 0x60, 0x00, 0x62, 0x00, 0x51, 0x00, 0x2a, 0x00, 0x30, 0x00, 0x31, 0x00,
|
|
0x48, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x5d, 0x00, 0x25, 0x00, 0x58, 0x00, 0x4a, 0x00,
|
|
0x76, 0x00, 0x32, 0x00, 0x62, 0x00, 0x27, 0x00, 0x42, 0x00, 0x40, 0x00, 0x53, 0x00,
|
|
0x7c, 0x00, 0x7d, 0x00, 0x50, 0x00, 0x3d, 0x00, 0x40, 0x00, 0x76, 0x00, 0x38, 0x00,
|
|
0x58, 0x00, 0x39, 0x00, 0x63, 0x00, 0x3c, 0x00, 0x5b, 0x00, 0x23, 0x00, 0x53, 0x00,
|
|
0x7a, 0x00, 0x54, 0x00, 0x74, 0x00, 0x61, 0x00, 0x76, 0x00, 0x4a, 0x00, 0x3e, 0x00,
|
|
0x33, 0x00, 0x75, 0x00, 0x66, 0x00, 0x2d, 0x00, 0x48, 0x00, 0x33, 0x00, 0x71, 0x00,
|
|
0x76, 0x00, 0x48, 0x00, 0x71, 0x00, 0x41, 0x00, 0x6f, 0x00, 0x2a, 0x00, 0x67, 0x00,
|
|
0x70, 0x00, 0x21, 0x00, 0x70, 0x00, 0x4b, 0x00, 0x52, 0x00, 0x58, 0x00, 0x68, 0x00,
|
|
0x23, 0x00, 0x39, 0x00, 0x46, 0x00, 0x4d, 0x00, 0x51, 0x00, 0x57, 0x00, 0x3a, 0x00,
|
|
0x79, 0x00, 0x7b, 0x00, 0x6c, 0x00, 0x55, 0x00, 0x33, 0x00, 0x65, 0x00, 0x49, 0x00,
|
|
0x72, 0x00, 0x30, 0x00, 0x4f, 0x00, 0x41, 0x00, 0x6e, 0x00, 0x31, 0x00, 0x4a, 0x00,
|
|
0x60, 0x00, 0x79, 0x00, 0x70, 0x00, 0x4f, 0x00, 0x58, 0x00, 0x75, 0x00, 0x44, 0x00,
|
|
0x59, 0x00, 0x58, 0x00, 0x46, 0x00, 0x3d, 0x00, 0x46, 0x00, 0x74, 0x00, 0x51, 0x00,
|
|
0x57, 0x00, 0x6e, 0x00, 0x2d, 0x00, 0x47, 0x00, 0x23, 0x00, 0x45, 0x00, 0x60, 0x00,
|
|
0x4c, 0x00, 0x72, 0x00, 0x4e, 0x00, 0x74, 0x00, 0x40, 0x00, 0x76, 0x00, 0x75, 0x00,
|
|
0x74, 0x00, 0x56, 0x00, 0x44, 0x00, 0x29, 0x00, 0x62, 0x00, 0x58, 0x00, 0x31, 0x00,
|
|
0x78, 0x00, 0x32, 0x00, 0x52, 0x00, 0x4a, 0x00, 0x6b, 0x00, 0x55, 0x00, 0x72, 0x00,
|
|
0x6f, 0x00, 0x6f, 0x00, 0x4a, 0x00, 0x54, 0x00, 0x7d, 0x00, 0x68, 0x00, 0x3f, 0x00,
|
|
0x28, 0x00, 0x21, 0x00, 0x53, 0x00, 0x48, 0x00, 0x5a, 0x00, 0x34, 0x00, 0x36, 0x00,
|
|
0x35, 0x00, 0x64, 0x00, 0x4e, 0x00, 0x75, 0x00, 0x69, 0x00, 0x23, 0x00, 0x75, 0x00,
|
|
0x55, 0x00, 0x43, 0x00, 0x75, 0x00, 0x2f, 0x00, 0x73, 0x00, 0x62, 0x00, 0x6f, 0x00,
|
|
0x37, 0x00, 0x4e, 0x00, 0x25, 0x00, 0x25, 0x00, 0x21, 0x00, 0x3d, 0x00, 0x3c, 0x00,
|
|
0x71, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x30, 0x00, 0x36, 0x00, 0x62, 0x00, 0x63, 0x00,
|
|
0x53, 0x00, 0x54, 0x00, 0x5d, 0x00, 0x61, 0x00, 0x4c, 0x00, 0x28, 0x00, 0x2b, 0x00,
|
|
0x4c, 0x00, 0x4e, 0x00, 0x66, 0x00, 0x5f, 0x00, 0x4b, 0x00, 0x43, 0x00, 0x75, 0x00,
|
|
0x45, 0x00, 0x37, 0x00, 0x28, 0x00, 0x56, 0x00, 0x36, 0x00, 0x6a, 0x00, 0x3e, 0x00,
|
|
0x64, 0x00, 0x34, 0x00, 0x6a, 0x00, 0x7d, 0x00, 0x4a, 0x00, 0x66, 0x00, 0x7a, 0x00,
|
|
0x3e, 0x00, 0x75, 0x00, 0x38, 0x00, 0x7b, 0x00, 0x42, 0x00, 0x76, 0x00, 0x29, 0x00,
|
|
0x4c, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x2b, 0x00, 0x51, 0x00,
|
|
0x47, 0x00, 0x22, 0x00, 0x48, 0x00, 0x3d, 0x00, 0x49, 0x00, 0x44, 0x00, 0x5d, 0x00,
|
|
0x59, 0x00, 0x63, 0x00, 0x5c, 0x00, 0x24, 0x00, 0x35, 0x00, 0x34, 0x00, 0x70, 0x00,
|
|
0x69, 0x00,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(request, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
if let Some(hdr) = dcerpc_state.header {
|
|
assert_eq!(0, hdr.hdrtype);
|
|
assert_eq!(5, hdr.rpc_vers);
|
|
assert_eq!(1024, hdr.frag_length);
|
|
}
|
|
let tx = &dcerpc_state.transactions[0];
|
|
assert_eq!(11, tx.ctxid);
|
|
assert_eq!(9, tx.opnum);
|
|
assert_eq!(1, tx.first_request_seen);
|
|
assert_eq!(1000, tx.stub_data_buffer_ts.len());
|
|
assert!(tx.stub_data_buffer_reset_ts);
|
|
}
|
|
|
|
#[test]
|
|
pub fn test_parse_bind_pdu() {
|
|
let bind1: &[u8] = &[
|
|
0x05, 0x00, 0x0b, 0x01, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11, 0x86, 0x1e,
|
|
0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x57, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let bind2: &[u8] = &[
|
|
0x05, 0x00, 0x0b, 0x02, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x01, 0x00, 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11, 0x86, 0x1e,
|
|
0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x67, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind1, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
assert_eq!(
|
|
AppLayerResult::ok(), // TODO ASK if this is correct?
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind2, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
// Check if the parser accepts bind pdus that have context ids starting
|
|
// from a non-zero value.
|
|
pub fn test_parse_bind_pdu_ctx_id_non_zero() {
|
|
let bindbuf: &[u8] = &[
|
|
0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x7f, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
let expected_uuid: &[u8] = &[
|
|
0x00, 0x00, 0x01, 0xa0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x46,
|
|
];
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bindbuf, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
if let Some(ref bind) = dcerpc_state.bind {
|
|
let bind_uuid = &bind.uuid_list[0].uuid;
|
|
assert_eq!(1, bind.uuid_list.len());
|
|
assert_eq!(
|
|
cmp::Ordering::Equal,
|
|
bind_uuid
|
|
.iter()
|
|
.zip(expected_uuid)
|
|
.map(|(x, y)| x.cmp(y))
|
|
.find(|&ord| ord != cmp::Ordering::Equal)
|
|
.unwrap_or_else(|| bind_uuid.len().cmp(&expected_uuid.len()))
|
|
);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
// Check for endless loop with bind PDUs (Imported from C code)
|
|
pub fn test_parse_bind_pdu_infinite_loop() {
|
|
let bindbuf: &[u8] = &[
|
|
0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x7f, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
|
|
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02,
|
|
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
|
0x01, 0x02, 0x03, 0x04, 0xFF, /* ka boom - endless loop */
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bindbuf, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
// Check for endless loop with bind_ack PDUs (Imported from C code)
|
|
pub fn test_parse_bindack_pdu_infinite_loop() {
|
|
let bind_ack: &[u8] = &[
|
|
0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7f, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0xfd, 0x04, 0x01, 0x00, 0x04, 0x00, 0x31, 0x33,
|
|
0x35, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x01, 0x02, 0x03, 0x04,
|
|
0xFF,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind_ack, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
// Check for correct internal ids for bind_acks
|
|
pub fn test_parse_bindack_internal_ids() {
|
|
let bind1: &[u8] = &[
|
|
0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x50, 0x08, 0x43, 0x95, 0x43, 0x5a, 0x8b, 0xb2, 0xf4, 0xc5,
|
|
0xb9, 0xee, 0x67, 0x55, 0x7c, 0x19, 0x00, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0xda, 0xc2, 0xbc, 0x9b, 0x35, 0x2e, 0xd4, 0xc9,
|
|
0x1f, 0x85, 0x01, 0xe6, 0x4e, 0x5a, 0x5e, 0xd4, 0x04, 0x00, 0x03, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0xb2, 0x97, 0xcc, 0x14, 0x6f, 0x70,
|
|
0x0d, 0xa5, 0x33, 0xd7, 0xf4, 0xe3, 0x8e, 0xb2, 0x2a, 0x1e, 0x05, 0x00, 0x02, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x96, 0x4e, 0xa6, 0xf6,
|
|
0xb2, 0x4b, 0xae, 0xb3, 0x21, 0xf4, 0x97, 0x7c, 0xcd, 0xa7, 0x08, 0xb0, 0x00, 0x00,
|
|
0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0xbc, 0xc0,
|
|
0xf7, 0x71, 0x3f, 0x71, 0x54, 0x44, 0x22, 0xa8, 0x55, 0x0f, 0x98, 0x83, 0x1f, 0xfe,
|
|
0x04, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00,
|
|
0xbe, 0x52, 0xf2, 0x58, 0x4a, 0xc3, 0xb5, 0xd0, 0xba, 0xac, 0xda, 0xf0, 0x12, 0x99,
|
|
0x38, 0x6e, 0x04, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00,
|
|
0x01, 0x00, 0xdb, 0xfa, 0x73, 0x01, 0xb3, 0x81, 0x01, 0xd4, 0x7f, 0xa0, 0x36, 0xb1,
|
|
0x97, 0xae, 0x29, 0x7f, 0x01, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x07, 0x00, 0x01, 0x00, 0x89, 0xbe, 0x41, 0x1d, 0x38, 0x75, 0xf5, 0xb5, 0xad, 0x27,
|
|
0x73, 0xf1, 0xb0, 0x7a, 0x28, 0x82, 0x05, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0xf6, 0x87, 0x09, 0x93, 0xb8, 0xa8, 0x20, 0xc4,
|
|
0xb8, 0x63, 0xe6, 0x95, 0xed, 0x59, 0xee, 0x3f, 0x05, 0x00, 0x03, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x92, 0x77, 0x92, 0x68, 0x3e, 0xa4,
|
|
0xbc, 0x3f, 0x44, 0x33, 0x0e, 0xb8, 0x33, 0x0a, 0x2f, 0xdf, 0x01, 0x00, 0x02, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0xa1, 0x03, 0xd2, 0xa9,
|
|
0xd2, 0x16, 0xc9, 0x89, 0x67, 0x18, 0x3e, 0xb1, 0xee, 0x6b, 0xf9, 0x18, 0x02, 0x00,
|
|
0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x2f, 0x09,
|
|
0x5e, 0x74, 0xec, 0xa0, 0xbb, 0xc1, 0x60, 0x18, 0xf1, 0x93, 0x04, 0x17, 0x11, 0xf9,
|
|
0x01, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00,
|
|
0xc8, 0x4f, 0x32, 0x4b, 0x70, 0x16, 0xd3, 0x01, 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e,
|
|
0xe1, 0x88, 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
let bind_ack1: &[u8] = &[
|
|
0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xb8, 0x10, 0xb8, 0x10, 0xc1, 0x2b, 0x00, 0x00, 0x0e, 0x00, 0x5c, 0x50,
|
|
0x49, 0x50, 0x45, 0x5c, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x00, 0x0d, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
let bind2: &[u8] = &[
|
|
0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0xdc, 0x02, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0xc7, 0x70, 0x0d, 0x3e, 0x71, 0x37, 0x39, 0x0d, 0x3a, 0x4f,
|
|
0xd3, 0xdc, 0xca, 0x49, 0xe8, 0xa3, 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x84, 0xb6, 0x55, 0x75, 0xdb, 0x9e, 0xba, 0x54,
|
|
0x56, 0xd3, 0x45, 0x10, 0xb7, 0x7a, 0x2a, 0xe2, 0x04, 0x00, 0x01, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x6e, 0x39, 0x21, 0x24, 0x70, 0x6f,
|
|
0x41, 0x57, 0x54, 0x70, 0xb8, 0xc3, 0x5e, 0x89, 0x3b, 0x43, 0x03, 0x00, 0x00, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x39, 0x6a, 0x86, 0x5d,
|
|
0x24, 0x0f, 0xd2, 0xf7, 0xb6, 0xce, 0x95, 0x9c, 0x54, 0x1d, 0x3a, 0xdb, 0x02, 0x00,
|
|
0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x12, 0xa5,
|
|
0xdd, 0xc5, 0x55, 0xce, 0xc3, 0x46, 0xbd, 0xa0, 0x94, 0x39, 0x3c, 0x0d, 0x9b, 0x5b,
|
|
0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00,
|
|
0x87, 0x1c, 0x8b, 0x6e, 0x11, 0xa8, 0x67, 0x98, 0xd4, 0x5d, 0xf6, 0x8a, 0x2f, 0x33,
|
|
0x24, 0x7b, 0x05, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00,
|
|
0x01, 0x00, 0x9b, 0x82, 0x13, 0xd1, 0x28, 0xe0, 0x63, 0xf3, 0x62, 0xee, 0x76, 0x73,
|
|
0xf9, 0xac, 0x3d, 0x2e, 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x07, 0x00, 0x01, 0x00, 0xa9, 0xd4, 0x73, 0xf2, 0xed, 0xad, 0xe8, 0x82, 0xf8, 0xcf,
|
|
0x9d, 0x9f, 0x66, 0xe6, 0x43, 0x37, 0x02, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x06, 0x2b, 0x85, 0x38, 0x4f, 0x73, 0x96, 0xb1,
|
|
0x73, 0xe1, 0x59, 0xbe, 0x9d, 0xe2, 0x6c, 0x07, 0x05, 0x00, 0x01, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0xbf, 0xfa, 0xbb, 0xa4, 0x9e, 0x5c,
|
|
0x80, 0x61, 0xb5, 0x8b, 0x79, 0x69, 0xa6, 0x32, 0x88, 0x77, 0x01, 0x00, 0x01, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x39, 0xa8, 0x2c, 0x39,
|
|
0x73, 0x50, 0x06, 0x8d, 0xf2, 0x37, 0x1e, 0x1e, 0xa8, 0x8f, 0x46, 0x98, 0x02, 0x00,
|
|
0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x91, 0x13,
|
|
0xd0, 0xa7, 0xef, 0xc4, 0xa7, 0x96, 0x0c, 0x4a, 0x0d, 0x29, 0x80, 0xd3, 0xfe, 0xbf,
|
|
0x00, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00,
|
|
0xcc, 0x2b, 0x55, 0x1d, 0xd4, 0xa4, 0x0d, 0xfb, 0xcb, 0x6f, 0x86, 0x36, 0xa6, 0x57,
|
|
0xc3, 0x21, 0x02, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x00,
|
|
0x01, 0x00, 0x43, 0x7b, 0x07, 0xee, 0x85, 0xa8, 0xb9, 0x3a, 0x0f, 0xf9, 0x83, 0x70,
|
|
0xe6, 0x0b, 0x4f, 0x33, 0x02, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x0e, 0x00, 0x01, 0x00, 0x9c, 0x6a, 0x15, 0x8c, 0xd6, 0x9c, 0xa6, 0xc3, 0xb2, 0x9e,
|
|
0x62, 0x9f, 0x3d, 0x8e, 0x47, 0x73, 0x02, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0xc8, 0x4f, 0x32, 0x4b, 0x70, 0x16, 0xd3, 0x01,
|
|
0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88, 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
let bind_ack2: &[u8] = &[
|
|
0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, 0xac, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xb8, 0x10, 0xb8, 0x10, 0xc2, 0x2b, 0x00, 0x00, 0x0e, 0x00, 0x5c, 0x50,
|
|
0x49, 0x50, 0x45, 0x5c, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x00, 0x10, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
let bind3: &[u8] = &[
|
|
0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0xa4, 0x7f, 0x8e, 0xc6, 0xef, 0x56, 0x9b, 0x63, 0x92, 0xfa,
|
|
0x08, 0xb3, 0x35, 0xe2, 0xa5, 0x81, 0x00, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x9f, 0xfc, 0x78, 0xd2, 0x5f, 0x16, 0x0b, 0xbc,
|
|
0xc6, 0xdb, 0x5d, 0xef, 0xde, 0x54, 0xa2, 0x6f, 0x04, 0x00, 0x01, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x78, 0xb8, 0x96, 0xc7, 0x2f, 0xda,
|
|
0x11, 0x6b, 0xd1, 0x28, 0x68, 0xe1, 0xd6, 0x71, 0xac, 0x9d, 0x03, 0x00, 0x00, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0xcf, 0xf4, 0xd7, 0x37,
|
|
0x03, 0xda, 0xcc, 0xe3, 0x3e, 0x34, 0x7f, 0x67, 0x99, 0x91, 0x41, 0x3d, 0x01, 0x00,
|
|
0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x48, 0xeb,
|
|
0x32, 0xf0, 0x27, 0xd5, 0x9d, 0xd0, 0x1e, 0xc6, 0x48, 0x46, 0x97, 0xe9, 0xdb, 0x09,
|
|
0x05, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00,
|
|
0x82, 0xec, 0x0d, 0x08, 0xf2, 0x8f, 0x22, 0x57, 0x42, 0x9b, 0xce, 0xa8, 0x74, 0x16,
|
|
0xc6, 0xec, 0x00, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00,
|
|
0x01, 0x00, 0x2e, 0x00, 0x70, 0x44, 0xee, 0xc9, 0x30, 0x6b, 0xf4, 0x34, 0x1e, 0x3d,
|
|
0x35, 0x0f, 0xf7, 0xf7, 0x00, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
0x07, 0x00, 0x01, 0x00, 0x59, 0x04, 0x39, 0x3f, 0x59, 0x87, 0x14, 0x0e, 0x76, 0x8d,
|
|
0x17, 0xc2, 0x47, 0xfa, 0x67, 0x7f, 0x04, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x30, 0xd6, 0xed, 0x2e, 0x57, 0xfa, 0xf4, 0x72,
|
|
0x6c, 0x10, 0x0d, 0xe5, 0x51, 0x7f, 0xd0, 0x39, 0x02, 0x00, 0x01, 0x00, 0x04, 0x5d,
|
|
0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
|
|
0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0xea, 0x8b, 0x84, 0x4d, 0x44, 0x43,
|
|
0xc1, 0x94, 0x75, 0xe2, 0x81, 0x48, 0xd8, 0x77, 0xd9, 0xce, 0x05, 0x00, 0x00, 0x00,
|
|
0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10,
|
|
0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x89, 0x4f, 0xe7, 0x95,
|
|
0xa3, 0xc1, 0x62, 0x36, 0x26, 0x9e, 0x67, 0xdb, 0x2c, 0x52, 0x89, 0xd3, 0x01, 0x00,
|
|
0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
|
|
0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x78, 0x56,
|
|
0x34, 0x12, 0x34, 0x12, 0xcd, 0xab, 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
|
|
0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
let bind_ack3: &[u8] = &[
|
|
0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xb8, 0x10, 0xb8, 0x10, 0x1a, 0x33, 0x00, 0x00, 0x0e, 0x00, 0x5c, 0x70,
|
|
0x69, 0x70, 0x65, 0x5c, 0x73, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x73, 0x00, 0x0c, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8,
|
|
0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
let expected_uuid1 = vec![
|
|
0x4b, 0x32, 0x4f, 0xc8, 0x16, 0x70, 0x01, 0xd3, 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e,
|
|
0xe1, 0x88,
|
|
];
|
|
let expected_uuid2 = vec![
|
|
0x4b, 0x32, 0x4f, 0xc8, 0x16, 0x70, 0x01, 0xd3, 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e,
|
|
0xe1, 0x88,
|
|
];
|
|
let expected_uuid3 = vec![
|
|
0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0xab, 0xcd, 0xef, 0x00, 0x01, 0x23, 0x45, 0x67,
|
|
0x89, 0xab,
|
|
];
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind1, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind_ack1, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
if let Some(ref back) = dcerpc_state.bindack {
|
|
assert_eq!(1, back.accepted_uuid_list.len());
|
|
assert_eq!(12, back.accepted_uuid_list[0].ctxid);
|
|
assert_eq!(expected_uuid1, back.accepted_uuid_list[0].uuid);
|
|
}
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind2, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind_ack2, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
if let Some(ref back) = dcerpc_state.bindack {
|
|
assert_eq!(1, back.accepted_uuid_list.len());
|
|
assert_eq!(15, back.accepted_uuid_list[0].ctxid);
|
|
assert_eq!(expected_uuid2, back.accepted_uuid_list[0].uuid);
|
|
}
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind3, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind_ack3, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
if let Some(ref back) = dcerpc_state.bindack {
|
|
assert_eq!(1, back.accepted_uuid_list.len());
|
|
assert_eq!(11, back.accepted_uuid_list[0].ctxid);
|
|
assert_eq!(expected_uuid3, back.accepted_uuid_list[0].uuid);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
pub fn test_bind_acks_alter_contexts_internal_ids() {
|
|
let bind: &[u8] = &[
|
|
0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x40, 0xfd, 0x2c, 0x34, 0x6c, 0x3c, 0xce, 0x11, 0xa8, 0x93,
|
|
0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let bindack: &[u8] = &[
|
|
0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, 0x0d, 0x00, 0x5c, 0x70,
|
|
0x69, 0x70, 0x65, 0x5c, 0x6c, 0x6c, 0x73, 0x72, 0x70, 0x63, 0x00, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
|
|
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
let alter_context: &[u8] = &[
|
|
0x05, 0x00, 0x0e, 0x03, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x01, 0x00, 0xd0, 0x4c, 0x67, 0x57, 0x00, 0x52, 0xce, 0x11, 0xa8, 0x97,
|
|
0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
|
|
0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
|
|
0x00, 0x00,
|
|
];
|
|
let alter_context_resp: &[u8] = &[
|
|
0x05, 0x00, 0x0f, 0x03, 0x10, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c,
|
|
0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
|
|
];
|
|
|
|
let mut dcerpc_state = DCERPCState::new();
|
|
let expected_uuid1 = vec![
|
|
0x34, 0x2c, 0xfd, 0x40, 0x3c, 0x6c, 0x11, 0xce, 0xa8, 0x93, 0x08, 0x00, 0x2b, 0x2e,
|
|
0x9c, 0x6d,
|
|
];
|
|
let expected_uuid2 = vec![
|
|
0x57, 0x67, 0x4c, 0xd0, 0x52, 0x00, 0x11, 0xce, 0xa8, 0x97, 0x08, 0x00, 0x2b, 0x2e,
|
|
0x9c, 0x6d,
|
|
];
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bind, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(bindack, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
if let Some(ref back) = dcerpc_state.bindack {
|
|
assert_eq!(1, back.accepted_uuid_list.len());
|
|
assert_eq!(0, back.accepted_uuid_list[0].ctxid);
|
|
assert_eq!(expected_uuid1, back.accepted_uuid_list[0].uuid);
|
|
}
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(alter_context, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
assert_eq!(
|
|
AppLayerResult::ok(),
|
|
dcerpc_state.handle_input_data(StreamSlice::from_slice(alter_context_resp, STREAM_TOSERVER, 0), Direction::ToServer)
|
|
);
|
|
if let Some(ref back) = dcerpc_state.bindack {
|
|
assert_eq!(1, back.accepted_uuid_list.len());
|
|
assert_eq!(1, back.accepted_uuid_list[0].ctxid);
|
|
assert_eq!(expected_uuid2, back.accepted_uuid_list[0].uuid);
|
|
}
|
|
}
|
|
}
|