diff --git a/rust/src/krb/detect.rs b/rust/src/krb/detect.rs index 40eddc56c5..e5dd64f4e0 100644 --- a/rust/src/krb/detect.rs +++ b/rust/src/krb/detect.rs @@ -83,7 +83,7 @@ unsafe extern "C" fn krb5_sname_get_data( const KRB_TICKET_FASTARRAY_SIZE: usize = 256; #[derive(Debug)] -pub struct DetectKrb5TicketEncryptionList { +struct DetectKrb5TicketEncryptionList { positive: [bool; KRB_TICKET_FASTARRAY_SIZE], negative: [bool; KRB_TICKET_FASTARRAY_SIZE], other: Vec, @@ -96,7 +96,7 @@ impl Default for DetectKrb5TicketEncryptionList { } impl DetectKrb5TicketEncryptionList { - pub fn new() -> Self { + fn new() -> Self { Self { positive: [false; KRB_TICKET_FASTARRAY_SIZE], negative: [false; KRB_TICKET_FASTARRAY_SIZE], @@ -105,20 +105,20 @@ impl DetectKrb5TicketEncryptionList { } } -// Suppress large enum variant lint as the LIST is very large compared +// Suppress large enum variant lint as the List is very large compared // to the boolean variant. #[derive(Debug)] #[allow(clippy::large_enum_variant)] -pub enum DetectKrb5TicketEncryptionData { - WEAK(bool), - LIST(DetectKrb5TicketEncryptionList), +enum DetectKrb5TicketEncryptionData { + Weak(bool), + List(DetectKrb5TicketEncryptionList), } -pub fn detect_parse_encryption_weak(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> { +fn detect_parse_encryption_weak(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> { let (i, neg) = opt(char('!')).parse(i)?; let (i, _) = tag("weak").parse(i)?; let value = neg.is_none(); - return Ok((i, DetectKrb5TicketEncryptionData::WEAK(value))); + return Ok((i, DetectKrb5TicketEncryptionData::Weak(value))); } trait MyFromStr { @@ -175,11 +175,11 @@ impl MyFromStr for EncryptionType { } } -pub fn is_alphanumeric_or_dash(chr: char) -> bool { +fn is_alphanumeric_or_dash(chr: char) -> bool { return chr.is_alphanumeric() || chr == '-'; } -pub fn detect_parse_encryption_item(i: &str) -> IResult<&str, EncryptionType> { +fn detect_parse_encryption_item(i: &str) -> IResult<&str, EncryptionType> { let (i, _) = opt(is_a(" ")).parse(i)?; let (i, e) = map_res(take_while1(is_alphanumeric_or_dash), |s: &str| { EncryptionType::from_str(s) @@ -190,7 +190,7 @@ pub fn detect_parse_encryption_item(i: &str) -> IResult<&str, EncryptionType> { return Ok((i, e)); } -pub fn detect_parse_encryption_list(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> { +fn detect_parse_encryption_list(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> { let mut l = DetectKrb5TicketEncryptionList::new(); let (i, v) = many1(detect_parse_encryption_item).parse(i)?; for &val in v.iter() { @@ -204,18 +204,17 @@ pub fn detect_parse_encryption_list(i: &str) -> IResult<&str, DetectKrb5TicketEn l.other.push(val); } } - return Ok((i, DetectKrb5TicketEncryptionData::LIST(l))); + return Ok((i, DetectKrb5TicketEncryptionData::List(l))); } -pub fn detect_parse_encryption(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> { +fn detect_parse_encryption(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> { let (i, _) = opt(is_a(" ")).parse(i)?; let (i, parsed) = alt((detect_parse_encryption_weak, detect_parse_encryption_list)).parse(i)?; let (i, _) = all_consuming(take_while(|c| c == ' ')).parse(i)?; return Ok((i, parsed)); } -#[no_mangle] -pub unsafe extern "C" fn SCKrb5DetectEncryptionParse( +unsafe extern "C" fn krb5_detect_encryption_parse( ustr: *const std::os::raw::c_char, ) -> *mut DetectKrb5TicketEncryptionData { let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe @@ -228,18 +227,20 @@ pub unsafe extern "C" fn SCKrb5DetectEncryptionParse( return std::ptr::null_mut(); } -#[no_mangle] -pub unsafe extern "C" fn SCKrb5DetectEncryptionMatch( - tx: &KRB5Transaction, ctx: &DetectKrb5TicketEncryptionData, -) -> std::os::raw::c_int { +unsafe extern "C" fn krb5_ticket_encryption_match( + _de: *mut DetectEngineThreadCtx, _f: *mut Flow, _flags: u8, _state: *mut c_void, + tx: *mut c_void, _sig: *const Signature, ctx: *const SigMatchCtx, +) -> c_int { + let tx = cast_pointer!(tx, KRB5Transaction); + let ctx = cast_pointer!(ctx, DetectKrb5TicketEncryptionData); if let Some(x) = tx.ticket_etype { match ctx { - DetectKrb5TicketEncryptionData::WEAK(w) => { + DetectKrb5TicketEncryptionData::Weak(w) => { if (test_weak_encryption(x) && *w) || (!test_weak_encryption(x) && !*w) { return 1; } } - DetectKrb5TicketEncryptionData::LIST(l) => { + DetectKrb5TicketEncryptionData::List(l) => { let vali = x.0; if vali < 0 && ((-vali) as usize) < KRB_TICKET_FASTARRAY_SIZE { if l.negative[(-vali) as usize] { @@ -262,12 +263,6 @@ pub unsafe extern "C" fn SCKrb5DetectEncryptionMatch( return 0; } -#[no_mangle] -pub unsafe extern "C" fn SCKrb5DetectEncryptionFree(ctx: &mut DetectKrb5TicketEncryptionData) { - // Just unbox... - std::mem::drop(Box::from_raw(ctx)); -} - #[cfg(test)] mod tests { @@ -278,7 +273,7 @@ mod tests { match detect_parse_encryption(" weak ") { Ok((rem, ctx)) => { match ctx { - DetectKrb5TicketEncryptionData::WEAK(w) => { + DetectKrb5TicketEncryptionData::Weak(w) => { assert!(w); } _ => { @@ -295,7 +290,7 @@ mod tests { match detect_parse_encryption("!weak") { Ok((rem, ctx)) => { match ctx { - DetectKrb5TicketEncryptionData::WEAK(w) => { + DetectKrb5TicketEncryptionData::Weak(w) => { assert!(!w); } _ => { @@ -312,7 +307,7 @@ mod tests { match detect_parse_encryption(" des-cbc-crc , -128,2 257") { Ok((rem, ctx)) => { match ctx { - DetectKrb5TicketEncryptionData::LIST(l) => { + DetectKrb5TicketEncryptionData::List(l) => { assert!(l.positive[EncryptionType::DES_CBC_CRC.0 as usize]); assert!(l.negative[128]); assert!(l.positive[2]); @@ -332,7 +327,7 @@ mod tests { } let ctx = detect_parse_encryption("-2147483648").unwrap().1; match ctx { - DetectKrb5TicketEncryptionData::LIST(l) => { + DetectKrb5TicketEncryptionData::List(l) => { assert_eq!(l.other.len(), 1); assert_eq!(l.other[0], EncryptionType(i32::MIN)); } @@ -348,6 +343,8 @@ static mut G_KRB5_GENERIC_BUFFER_ID: c_int = 0; static mut G_KRB5_ERR_CODE_KW_ID: u16 = 0; static mut G_KRB5_CNAME_BUFFER_ID: c_int = 0; static mut G_KRB5_SNAME_BUFFER_ID: c_int = 0; +static mut G_KRB5_TICKET_ENCRYPTION_KW_ID: u16 = 0; +static mut G_KRB5_TICKET_ENCRYPTION_BUFFER_ID: c_int = 0; // We should apply the derive on the kerberos_parser MessageType #[repr(u32)] @@ -501,6 +498,36 @@ unsafe extern "C" fn krb5_cname_setup( return 0; } +unsafe extern "C" fn krb5_ticket_encryption_setup( + de: *mut DetectEngineCtx, s: *mut Signature, raw: *const libc::c_char, +) -> c_int { + if SCDetectSignatureSetAppProto(s, ALPROTO_KRB5 as AppProto) != 0 { + return -1; + } + let ctx = krb5_detect_encryption_parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SCSigMatchAppendSMToList( + de, + s, + G_KRB5_TICKET_ENCRYPTION_KW_ID, + ctx as *mut SigMatchCtx, + G_KRB5_TICKET_ENCRYPTION_BUFFER_ID, + ) + .is_null() + { + krb5_ticket_encryption_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; +} + +unsafe extern "C" fn krb5_ticket_encryption_free(_de: *mut DetectEngineCtx, ctx: *mut c_void) { + let ctx = cast_pointer!(ctx, DetectKrb5TicketEncryptionData); + std::mem::drop(Box::from_raw(ctx)); +} + #[no_mangle] pub unsafe extern "C" fn SCDetectKrb5Register() { let kw = SCSigTableAppLiteElmt { @@ -570,4 +597,22 @@ pub unsafe extern "C" fn SCDetectKrb5Register() { krb5_cname_hdr_kw_id, b"krb5_cname\0".as_ptr() as *const libc::c_char, ); + + let kw = SCSigTableAppLiteElmt { + name: b"krb5.ticket_encryption\0".as_ptr() as *const libc::c_char, + desc: b"match Kerberos 5 ticket encryption\0".as_ptr() as *const libc::c_char, + url: b"/rules/kerberos-keywords.html#krb5-ticket-encryption\0".as_ptr() + as *const libc::c_char, + AppLayerTxMatch: Some(krb5_ticket_encryption_match), + Setup: Some(krb5_ticket_encryption_setup), + Free: Some(krb5_ticket_encryption_free), + flags: 0, + }; + G_KRB5_TICKET_ENCRYPTION_KW_ID = SCDetectHelperKeywordRegister(&kw); + G_KRB5_TICKET_ENCRYPTION_BUFFER_ID = SCDetectHelperBufferProgressRegister( + b"krb5_ticket_encryption\0".as_ptr() as *const libc::c_char, + ALPROTO_KRB5 as AppProto, + STREAM_TOCLIENT, + 1, + ); } diff --git a/src/Makefile.am b/src/Makefile.am index 3caa30e8e5..aa49ffe661 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -242,7 +242,6 @@ noinst_HEADERS = \ detect-isdataat.h \ detect-itype.h \ detect-ja4-hash.h \ - detect-krb5-ticket-encryption.h \ detect-l3proto.h \ detect-lua-extensions.h \ detect-lua.h \ @@ -820,7 +819,6 @@ libsuricata_c_a_SOURCES = \ detect-isdataat.c \ detect-itype.c \ detect-ja4-hash.c \ - detect-krb5-ticket-encryption.c \ detect-l3proto.c \ detect-lua-extensions.c \ detect-lua.c \ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 06cbebc271..e98e9d1ac5 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -196,7 +196,6 @@ #include "detect-icmpv6-mtu.h" #include "detect-ipv4hdr.h" #include "detect-ipv6hdr.h" -#include "detect-krb5-ticket-encryption.h" #include "detect-sip-method.h" #include "detect-sip-uri.h" #include "detect-target.h" @@ -713,7 +712,6 @@ void SigTableSetup(void) DetectEtherhdrRegister(); DetectIpv4hdrRegister(); DetectIpv6hdrRegister(); - DetectKrb5TicketEncryptionRegister(); DetectSipMethodRegister(); DetectSipUriRegister(); DetectTargetRegister(); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index aac719689b..c1efe6ddde 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -258,8 +258,6 @@ enum DetectKeywordId { DETECT_DNP3IND, DETECT_DNP3OBJ, - DETECT_KRB5_TICKET_ENCRYPTION, - DETECT_SIP_METHOD, DETECT_SIP_URI, DETECT_TEMPLATE, diff --git a/src/detect-krb5-ticket-encryption.c b/src/detect-krb5-ticket-encryption.c deleted file mode 100644 index b4514a0483..0000000000 --- a/src/detect-krb5-ticket-encryption.c +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (C) 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 - * 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. - */ - -#include "suricata-common.h" -#include "rust.h" - -#include "detect-krb5-ticket-encryption.h" - -#include "detect-engine.h" -#include "detect-parse.h" - -static int g_krb5_ticket_encryption_list_id = 0; - -static void DetectKrb5TicketEncryptionFree(DetectEngineCtx *de_ctx, void *ptr) -{ - SCKrb5DetectEncryptionFree(ptr); -} - -static int DetectKrb5TicketEncryptionMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, - void *state, void *txv, const Signature *s, const SigMatchCtx *ctx) -{ - const DetectKrb5TicketEncryptionData *dd = (const DetectKrb5TicketEncryptionData *)ctx; - - SCEnter(); - - SCReturnInt(SCKrb5DetectEncryptionMatch(txv, dd)); -} - -static int DetectKrb5TicketEncryptionSetup( - DetectEngineCtx *de_ctx, Signature *s, const char *krb5str) -{ - DetectKrb5TicketEncryptionData *krb5d = NULL; - - if (SCDetectSignatureSetAppProto(s, ALPROTO_KRB5) != 0) - return -1; - - krb5d = SCKrb5DetectEncryptionParse(krb5str); - if (krb5d == NULL) - goto error; - - if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_KRB5_TICKET_ENCRYPTION, (SigMatchCtx *)krb5d, - g_krb5_ticket_encryption_list_id) == NULL) { - goto error; - } - - return 0; - -error: - if (krb5d != NULL) - DetectKrb5TicketEncryptionFree(de_ctx, krb5d); - return -1; -} - -void DetectKrb5TicketEncryptionRegister(void) -{ - sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].name = "krb5.ticket_encryption"; - sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].desc = "match Kerberos 5 ticket encryption"; - sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].url = - "/rules/kerberos-keywords.html#krb5-ticket-encryption"; - sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].Match = NULL; - sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].AppLayerTxMatch = DetectKrb5TicketEncryptionMatch; - sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].Setup = DetectKrb5TicketEncryptionSetup; - sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].Free = DetectKrb5TicketEncryptionFree; - - // Tickets are only from server to client - DetectAppLayerInspectEngineRegister("krb5_ticket_encryption", ALPROTO_KRB5, SIG_FLAG_TOCLIENT, - 0, DetectEngineInspectGenericList, NULL); - - g_krb5_ticket_encryption_list_id = DetectBufferTypeRegister("krb5_ticket_encryption"); - SCLogDebug("g_krb5_ticket_encryption_list_id %d", g_krb5_ticket_encryption_list_id); -} diff --git a/src/detect-krb5-ticket-encryption.h b/src/detect-krb5-ticket-encryption.h deleted file mode 100644 index 57dabd5e57..0000000000 --- a/src/detect-krb5-ticket-encryption.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 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 - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef SURICATA_DETECT_KRB5_TICKET_ENCRYPTION_H -#define SURICATA_DETECT_KRB5_TICKET_ENCRYPTION_H - -void DetectKrb5TicketEncryptionRegister(void); - -#endif /* SURICATA_DETECT_KRB5_TICKET_ENCRYPTION_H */