diff --git a/pcaps/NTP_sync.pcap b/pcaps/NTP_sync.pcap new file mode 100644 index 0000000..997d9fb Binary files /dev/null and b/pcaps/NTP_sync.pcap differ diff --git a/pcaps/SSHv2.cap b/pcaps/SSHv2.cap new file mode 100644 index 0000000..b682bb8 Binary files /dev/null and b/pcaps/SSHv2.cap differ diff --git a/pcaps/http.cap b/pcaps/http.cap new file mode 100644 index 0000000..54f6f29 Binary files /dev/null and b/pcaps/http.cap differ diff --git a/pcaps/http_image.cap b/pcaps/http_image.cap new file mode 100644 index 0000000..0908f59 Binary files /dev/null and b/pcaps/http_image.cap differ diff --git a/pcaps/http_redirects.pcapng b/pcaps/http_redirects.pcapng new file mode 100644 index 0000000..cd8958d Binary files /dev/null and b/pcaps/http_redirects.pcapng differ diff --git a/pcaps/telnet-cooked.pcap b/pcaps/telnet-cooked.pcap new file mode 100644 index 0000000..34515d4 Binary files /dev/null and b/pcaps/telnet-cooked.pcap differ diff --git a/src/main.rs b/src/main.rs index a6835e0..59be6ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,8 +31,8 @@ fn main() { Some(pf) => Capture::from_file(pf).expect("Invalid pcap file provided"), None => { warn!("Using example.pcap as no pcap was provided"); - Capture::from_file(PathBuf::from("./pcaps/ssh_test.pcap")) - .expect("./pcaps/ssh_test.pcap does not exist") + Capture::from_file(PathBuf::from("./pcaps/dns.cap")) + .expect("./pcaps/dns.cap does not exist") } }; info!("Pcap loaded"); @@ -57,6 +57,9 @@ fn main() { stats.known_packets += 1; trace!("Known packet type found: {:?}", x); let extracted = extract_info(x, sliced.payload.to_vec()); + if extracted.is_some() { + stats.analyzed += 1; + } if opt.print_analysis { info!("{:?}", extracted); } diff --git a/src/protocols/dns.rs b/src/protocols/dns.rs index ad8a45e..8ed11a2 100644 --- a/src/protocols/dns.rs +++ b/src/protocols/dns.rs @@ -1,4 +1,4 @@ -use crate::util::*; +use crate::{util::*, ExtractedInfo, KnownProtocol, ProtocolType}; use nom::{ bytes::complete::{tag, take}, combinator::map, @@ -15,6 +15,22 @@ pub enum DNSType { Response, } +impl KnownProtocol for DNSType { + fn extract_info(&self, payload: Vec) -> ExtractedInfo { + ExtractedInfo::DNSQuery(analyse_dns_query(payload)) + } + + fn classify_proto(payload: Vec) -> Result { + if is_dns_query(&payload) { + return Ok(ProtocolType::DNS(DNSType::Query)); + } + if is_dns_response(&payload) { + return Ok(ProtocolType::DNS(DNSType::Response)); + } + Err(()) + } +} + #[derive(Debug, PartialEq, Eq)] pub struct DNSValue { pub txid: u16, diff --git a/src/protocols/mod.rs b/src/protocols/mod.rs index fd85658..f44671e 100644 --- a/src/protocols/mod.rs +++ b/src/protocols/mod.rs @@ -1,6 +1,12 @@ use dns::{DNSType, DNSValue}; mod dns; +mod ssh; + +pub trait KnownProtocol { + fn classify_proto(payload: Vec) -> Result; + fn extract_info(&self, payload: Vec) -> ExtractedInfo; +} #[derive(Debug)] pub enum ProtocolType { @@ -24,9 +30,8 @@ pub fn extract_info(ptype: ProtocolType, payload: Vec) -> Option) -> Result { - match dns::is_dns(payload) { - Ok(x) => return Ok(ProtocolType::DNS(x)), - Err(_) => {} + if let Ok(x) = dns::is_dns(payload) { + return Ok(ProtocolType::DNS(x)); }; - return Err(()); + Err(()) } diff --git a/src/protocols/ssh.rs b/src/protocols/ssh.rs index 8b13789..7599008 100644 --- a/src/protocols/ssh.rs +++ b/src/protocols/ssh.rs @@ -1 +1,4 @@ - +pub fn is_ssh(payload: Vec) -> bool { + // Check for ASCII "SSH" + payload[0] == 0x53 && payload[1] == 0x53 && payload[2] == 0x48 +} diff --git a/src/util.rs b/src/util.rs index 3e87538..cbcf991 100644 --- a/src/util.rs +++ b/src/util.rs @@ -11,6 +11,7 @@ pub struct Stats { pub unknown_packets: usize, pub errored_packets: usize, pub empty_payload: usize, + pub analyzed: usize, } impl Stats { @@ -21,6 +22,7 @@ impl Stats { unknown_packets: 0, errored_packets: 0, empty_payload: 0, + analyzed: 0, } } @@ -37,9 +39,10 @@ impl Display for Stats { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "Total: {}\nKnown: {}\nUnknown: {}\nErrored: {}\nEmpty: {}", + "Total: {}\nKnown/Analyzed: {}({})\nUnknown: {}\nErrored: {}\nEmpty: {}", self.total_packets, self.known_packets, + self.analyzed, self.unknown_packets, self.errored_packets, self.empty_payload