]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
SMB: use kerberos-parser to extract Real and PrincipalName
authorPierre Chifflier <chifflier@wzdftpd.net>
Thu, 15 Mar 2018 07:24:10 +0000 (08:24 +0100)
committerVictor Julien <victor@inliniac.net>
Fri, 16 Mar 2018 11:25:36 +0000 (12:25 +0100)
rust/Cargo.toml.in
rust/src/smb/auth.rs
rust/src/smb/log.rs
rust/src/smb/mod.rs

index 9bc2198cfb73f9576f67bfb2b9b6de3ee44c4fb5..c56f8a0b5f883f67ba31d0013ed6f7a32c088cad 100644 (file)
@@ -18,6 +18,7 @@ debug = []
 nom = "~3.2.1"
 libc = "^0.2.36"
 crc = "~1.7.0"
-der-parser = "0.5.1"
+der-parser = "0.5.2"
+kerberos-parser = "0.1.0"
 
 ntp-parser = { version = "^0", optional = true }
index f34f25ae415d6db0beab927d7f54771af89a328d..8ec2b9bcab0c232dcaa0f9fea336889702e6ab05 100644 (file)
@@ -15,6 +15,9 @@
  * 02110-1301, USA.
  */
 
+use smb::kerberos_parser::krb5_parser;
+use smb::kerberos_parser::krb5::{ApReq,Realm,PrincipalName};
+
 use log::*;
 use smb::ntlmssp_records::*;
 use smb::smb::*;
@@ -25,113 +28,8 @@ use der_parser;
 
 #[derive(Debug,PartialEq)]
 pub struct Kerberos5Ticket {
-    pub realm: Vec<u8>,
-    pub snames: Vec<Vec<u8>>,
-}
-
-/// ticket starts with custom header [APPLICATION 1]
-fn parse_kerberos5_request_ticket(blob: &[u8]) -> IResult<&[u8], Kerberos5Ticket>
-{
-    let (rem, ticket_hdr) = match der_parser::der_read_element_header(blob) {
-        IResult::Done(rem, o) => (rem, o),
-        IResult::Incomplete(needed) => {  return IResult::Incomplete(needed); },
-        IResult::Error(err) => { return IResult::Error(err); },
-    };
-    SCLogDebug!("parse_kerberos5_request_ticket: ticket {:?}, remaining data {}", ticket_hdr, rem.len());
-
-    if !(ticket_hdr.class == 1 && ticket_hdr.structured == 1 && ticket_hdr.tag == 1 && ticket_hdr.len == rem.len() as u64) {
-        SCLogDebug!("parse_kerberos5_request_ticket: bad data");
-        return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-    }
-    let (_, ticket_seq) = match der_parser::parse_der_sequence(rem) {
-        IResult::Done(rem, o) => (rem, o),
-        IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
-        IResult::Error(err) => { return IResult::Error(err); },
-    };
-    SCLogDebug!("parse_kerberos5_request_ticket: ticket {:?}", ticket_seq);
-
-    let ticket_vec = ticket_seq.as_sequence().unwrap(); // parse_der_sequence is checked
-    SCLogDebug!("parse_kerberos5_request_ticket: ticket_vec {:?}", ticket_vec);
-    if ticket_vec.len() != 4 {
-        SCLogDebug!("parse_kerberos5_request_ticket: unexpected format");
-        return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-    }
-
-    SCLogDebug!("parse_kerberos5_request_ticket: tkt-vno {:?}", ticket_vec[0]);
-    SCLogDebug!("parse_kerberos5_request_ticket: realm {:?}", ticket_vec[1]);
-    SCLogDebug!("parse_kerberos5_request_ticket: sname {:?}", ticket_vec[2]);
-    SCLogDebug!("parse_kerberos5_request_ticket: enc-part {:?}", ticket_vec[3]);
-
-    let gs = match ticket_vec[1].content.as_slice() {
-        Ok(s) => s,
-        Err(_) => {
-            return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-        },
-    };
-    let realm = match der_parser::parse_der_generalstring(gs) {
-        IResult::Done(_, o) => o,
-        IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
-        IResult::Error(err) => { return IResult::Error(err); },
-    };
-    SCLogDebug!("parse_kerberos5_request_ticket: realm {:?}", realm);
-
-    if !(realm.class == 0 && realm.structured == 0 && realm.tag == 27) {
-        SCLogDebug!("bad realm data");
-        return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-    }
-    let realm_v = realm.content.as_slice().unwrap().to_vec();
-    SCLogDebug!("parse_kerberos5_request_ticket: realm_v {:?}", realm_v);
-
-    let sname = match der_parser::parse_der_sequence(ticket_vec[2].content.as_slice().unwrap()) {
-        IResult::Done(_, o) => o,
-        IResult::Incomplete(needed) => {
-            SCLogDebug!("parse_kerberos5_request_ticket: needed {:?}", needed);
-            return IResult::Incomplete(needed);
-        },
-        IResult::Error(err) => {
-            SCLogDebug!("parse_kerberos5_request_ticket: err {:?}", err);
-            return IResult::Error(err);
-        },
-    };
-    SCLogDebug!("parse_kerberos5_request_ticket: sname {:?}", sname);
-
-    let sname_vec = sname.as_sequence().unwrap(); // parse_der_sequence is checked
-    SCLogDebug!("parse_kerberos5_request_ticket: sname_vec {:?}", sname_vec);
-
-    if sname_vec.len() != 2 {
-        SCLogDebug!("parse_kerberos5_request_ticket: unexpected format");
-        return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-    }
-    let sname_seq = match der_parser::parse_der_sequence(sname_vec[1].content.as_slice().unwrap()) {
-        IResult::Done(_, o) => o,
-        IResult::Incomplete(needed) => {
-            SCLogDebug!("parse_kerberos5_request_ticket: needed {:?}", needed);
-            return IResult::Incomplete(needed);
-        },
-        IResult::Error(err) => {
-            SCLogDebug!("parse_kerberos5_request_ticket: err {:?}", err);
-            return IResult::Error(err);
-        },
-    };
-    SCLogDebug!("parse_kerberos5_request_ticket: sname_seq {:?}", sname_seq);
-    let snamestr_vec = sname_seq.as_sequence().unwrap(); // parse_der_sequence is checked
-
-    let mut snames : Vec<Vec<u8>> = Vec::new();
-    for o in snamestr_vec {
-        SCLogDebug!("parse_kerberos5_request_ticket: sname o {:?}", o);
-        if o.tag == 27 {
-            let v = o.content.as_slice().unwrap().to_vec();
-            SCLogDebug!("sname {:?}", v);
-            snames.push(v);
-        }
-    }
-
-    let t = Kerberos5Ticket {
-        realm: realm_v,
-        snames: snames,
-    };
-    SCLogDebug!("ticket {:?}", t);
-    IResult::Done(&[],t)
+    pub realm: Realm,
+    pub sname: PrincipalName,
 }
 
 // get SPNEGO
@@ -140,7 +38,7 @@ fn parse_kerberos5_request_ticket(blob: &[u8]) -> IResult<&[u8], Kerberos5Ticket
 // else if OID has NTLMSSP get NTLMSSP
 // else bruteforce NTLMSSP
 
-fn parse_kerberos5_request(blob: &[u8]) -> IResult<&[u8], Kerberos5Ticket>
+fn parse_kerberos5_request(blob: &[u8]) -> IResult<&[u8], ApReq>
 {
     let blob = match der_parser::parse_der(blob) {
         IResult::Done(_, b) => {
@@ -167,75 +65,7 @@ fn parse_kerberos5_request(blob: &[u8]) -> IResult<&[u8], Kerberos5Ticket>
     };
     SCLogDebug!("parse_kerberos5_request: tok_id {}", tok_id);
 
-    // APPLICATION 14
-    let (rem, base_o) = match der_parser::der_read_element_header(rem) {
-        IResult::Done(rem, o) => (rem, o),
-        IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
-        IResult::Error(err) => { return IResult::Error(err); },
-    };
-    if !(base_o.class == 1 && base_o.structured == 1 && base_o.tag == 14 && base_o.len == rem.len() as u64) {
-        SCLogDebug!("parse_kerberos5_request_ticket: bad data");
-        return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-    }
-
-    let base_seq = match der_parser::parse_der_sequence(rem) {
-        IResult::Done(_, o) => o,
-        IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
-        IResult::Error(err) => { return IResult::Error(err); },
-    };
-    SCLogDebug!("parse_kerberos5_request: base_seq {:?}", base_seq);
-
-    if base_seq.as_sequence().unwrap().len() < 4 {
-        SCLogDebug!("parse_kerberos5_request_ticket: bad data");
-        return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-    }
-
-    let pvno_s = match base_seq[0].content.as_slice() {
-        Ok(s) => s,
-        Err(_) => {
-            return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-        },
-    };
-    let pvno = match der_parser::parse_der_integer(pvno_s) {
-        IResult::Done(_, o) => o,
-        IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
-        IResult::Error(err) => { return IResult::Error(err); },
-    };
-    SCLogDebug!("pvno {:?}", pvno);
-
-    let msg_type_s = match base_seq[1].content.as_slice() {
-        Ok(s) => s,
-        Err(_) => {
-            return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-        },
-    };
-    let msg_type = match der_parser::parse_der_integer(msg_type_s) {
-        IResult::Done(_, o) => o,
-        IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
-        IResult::Error(err) => { return IResult::Error(err); },
-    };
-    SCLogDebug!("msg_type {:?}", msg_type);
-
-    let padding_s = match base_seq[2].content.as_slice() {
-        Ok(s) => s,
-        Err(_) => {
-            return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-        },
-    };
-    let padding = match der_parser::parse_der_bitstring(padding_s) {
-        IResult::Done(_, o) => o,
-        IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
-        IResult::Error(err) => { return IResult::Error(err); },
-    };
-    SCLogDebug!("padding {:?}", padding);
-
-    let ticket_s = match base_seq[3].content.as_slice() {
-        Ok(s) => s,
-        Err(_) => {
-            return IResult::Error(error_code!(ErrorKind::Custom(SECBLOB_KRB_FMT_ERR)));
-        },
-    };
-    parse_kerberos5_request_ticket(ticket_s)
+    krb5_parser::parse_ap_req(rem)
 }
 
 
@@ -358,7 +188,11 @@ fn parse_secblob_spnego(blob: &[u8]) -> Option<SpnegoRequest>
             der_parser::DerObjectContent::OctetString(ref os) => {
                 if have_kerberos {
                     match parse_kerberos5_request(os) {
-                        IResult::Done(_, t) => {
+                        IResult::Done(_, req) => {
+                            let t = Kerberos5Ticket {
+                                realm: req.ticket.realm,
+                                sname: req.ticket.sname,
+                            };
                             kticket = Some(t)
                         },
                         _ => { },
index fe3f901826465082b3bdf4194267d25e86c33efe..ded03ef4529903331203e9ba0b1a69283e4cbd52 100644 (file)
@@ -173,18 +173,10 @@ fn smb_common_header(state: &SMBState, tx: &SMBTransaction) -> Json
 
             if let Some(ref ticket) = x.krb_ticket {
                 let jsd = Json::object();
-                let realm = match str::from_utf8(&ticket.realm) {
-                    Ok(v) => v,
-                    Err(_) => "UTF8_ERROR",
-                };
-                jsd.set_string("realm", &realm);
+                jsd.set_string("realm", &ticket.realm.0);
                 let jsa = Json::array();
-                for sname in &ticket.snames {
-                    let name = match str::from_utf8(&sname) {
-                        Ok(v) => v,
-                        Err(_) => "UTF8_ERROR",
-                    };
-                    jsa.array_append_string(&name);
+                for sname in ticket.sname.name_string.iter() {
+                    jsa.array_append_string(&sname);
                 }
                 jsd.set("snames", jsa);
                 js.set("kerberos", jsd);
index 65e1577ffc2ff375a424cb2a185c1aa6312eca66..618a59c3c03c6505c76e9ca2d52e21463e310204 100644 (file)
@@ -15,6 +15,8 @@
  * 02110-1301, USA.
  */
 
+extern crate kerberos_parser;
+
 pub mod smb_records;
 pub mod smb1_records;
 pub mod smb2_records;