From 78ba17caa80ef3267b1dfb1d4b8381639fc429e8 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Wed, 10 Aug 2022 17:06:51 -0600 Subject: [PATCH] bittorrent-dht: register a pattern for protocol detection Removes the port based probing which takes a long time to register for ports 1024-65535 and instead use pattern based protocol detection. --- rust/src/applayer.rs | 3 ++ rust/src/bittorrent_dht/bittorrent_dht.rs | 62 +++++++++++------------ 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index a9b2135bb4..dbebdb5387 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -431,6 +431,9 @@ extern { alproto_name: *const c_char, alproto: AppProto, min_depth: u16, max_depth: u16, pparser_ts: ProbeFn, pparser_tc: ProbeFn) -> i32; + pub fn AppLayerProtoDetectPMRegisterPatternCS(ipproto: u8, alproto: AppProto, + pattern: *const c_char, depth: u16, + offset: u16, direction: u8) -> c_int; pub fn AppLayerProtoDetectPMRegisterPatternCSwPP(ipproto: u8, alproto: AppProto, pattern: *const c_char, depth: u16, offset: u16, direction: u8, ppfn: ProbeFn, diff --git a/rust/src/bittorrent_dht/bittorrent_dht.rs b/rust/src/bittorrent_dht/bittorrent_dht.rs index 9b7dc0d8f7..d90e9e0bf5 100644 --- a/rust/src/bittorrent_dht/bittorrent_dht.rs +++ b/rust/src/bittorrent_dht/bittorrent_dht.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Open Information Security Foundation +/* Copyright (C) 2021-2022 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -21,9 +21,9 @@ use crate::bittorrent_dht::parser::{ }; use crate::core::{AppProto, Flow, ALPROTO_UNKNOWN, IPPROTO_UDP}; use std::ffi::CString; +use std::os::raw::c_char; -const BITTORRENT_DHT_PAYLOAD_PREFIX: &[u8] = b"d1:ad2:id20:"; -const BITTORRENT_DHT_PAYLOAD_PREFIX_LEN: u32 = 12; +const BITTORRENT_DHT_PAYLOAD_PREFIX: &[u8] = b"d1:ad2:id20:\0"; static mut ALPROTO_BITTORRENT_DHT: AppProto = ALPROTO_UNKNOWN; @@ -127,36 +127,11 @@ impl BitTorrentDHTState { } } -/// Probe to see if this flow looks like BitTorrent DHT -fn probe(input: &[u8]) -> bool { - // Ensure the flow started with a request from the client which - // contained the BitTorrent DHT request payload prefix bytes - if input.starts_with(BITTORRENT_DHT_PAYLOAD_PREFIX) { - return true; - } - return false; -} - // C exports. export_tx_data_get!(rs_bittorrent_dht_get_tx_data, BitTorrentDHTTransaction); export_state_data_get!(rs_bittorrent_dht_get_state_data, BitTorrentDHTState); -/// C entry point for BitTorrent DHT probing parser. -#[no_mangle] -pub unsafe extern "C" fn rs_bittorrent_dht_probing_parser( - _flow: *const Flow, _direction: u8, input: *const u8, input_len: u32, _rdir: *mut u8, -) -> AppProto { - // Need more than BITTORRENT_DHT_PAYLOAD_PREFIX_LEN bytes. - if input_len > BITTORRENT_DHT_PAYLOAD_PREFIX_LEN && input != std::ptr::null_mut() { - let slice = build_slice!(input, input_len as usize); - if probe(slice) { - return ALPROTO_BITTORRENT_DHT; - } - } - return ALPROTO_UNKNOWN; -} - #[no_mangle] pub extern "C" fn rs_bittorrent_dht_state_new( _orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto, @@ -249,13 +224,12 @@ const PARSER_NAME: &[u8] = b"bittorrent-dht\0"; #[no_mangle] pub unsafe extern "C" fn rs_bittorrent_dht_udp_register_parser() { - let default_port = CString::new("[1024:65535]").unwrap(); let parser = RustParser { name: PARSER_NAME.as_ptr() as *const std::os::raw::c_char, - default_port: default_port.as_ptr(), + default_port: std::ptr::null(), ipproto: IPPROTO_UDP, - probe_ts: Some(rs_bittorrent_dht_probing_parser), - probe_tc: Some(rs_bittorrent_dht_probing_parser), + probe_ts: None, + probe_tc: None, min_depth: 0, max_depth: 16, state_new: rs_bittorrent_dht_state_new, @@ -291,6 +265,30 @@ pub unsafe extern "C" fn rs_bittorrent_dht_udp_register_parser() { if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { let _ = AppLayerRegisterParser(&parser, alproto); } + + if AppLayerProtoDetectPMRegisterPatternCS( + IPPROTO_UDP as u8, + ALPROTO_BITTORRENT_DHT, + BITTORRENT_DHT_PAYLOAD_PREFIX.as_ptr() as *const c_char, + BITTORRENT_DHT_PAYLOAD_PREFIX.len() as u16 - 1, + 0, + crate::core::Direction::ToServer.into(), + ) < 0 + { + SCLogDebug!("Failed to register protocol detection pattern for direction TOSERVER"); + }; + if AppLayerProtoDetectPMRegisterPatternCS( + IPPROTO_UDP as u8, + ALPROTO_BITTORRENT_DHT, + BITTORRENT_DHT_PAYLOAD_PREFIX.as_ptr() as *const c_char, + BITTORRENT_DHT_PAYLOAD_PREFIX.len() as u16 - 1, + 0, + crate::core::Direction::ToClient.into(), + ) < 0 + { + SCLogDebug!("Failed to register protocol detection pattern for direction TOCLIENT"); + } + SCLogDebug!("Parser registered for bittorrent-dht."); } else { SCLogDebug!("Protocol detector and parser disabled for bittorrent-dht.");