Skip to content

Commit

Permalink
Working TCP tagger #1052
Browse files Browse the repository at this point in the history
  • Loading branch information
lennartkoopmann committed May 30, 2024
1 parent 0f1cd35 commit 4d2a36d
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 25 deletions.
25 changes: 7 additions & 18 deletions tap/src/ethernet/detection/taggers/socks_tagger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use byteorder::{BigEndian, ByteOrder};
use chrono::{DateTime, Utc};
use log::{debug};
use crate::data::tcp_table::{TcpSession, TcpSessionState};
use crate::ethernet::packets::{SocksAuthenticationMethod, SocksAuthenticationResult, SocksConnectionHandshakeStatus, SocksConnectionStatus, SocksTunnel, SocksType};
use crate::ethernet::packets::{GenericConnectionStatus, SocksAuthenticationMethod, SocksAuthenticationResult, SocksConnectionHandshakeStatus, SocksTunnel, SocksType};
use crate::ethernet::packets::SocksType::{Socks4, Socks4A};
use crate::ethernet::tcp_tools::determine_tcp_session_state;
use crate::helpers::network::{string_up_to_null_byte, to_ipv4_address, to_ipv6_address};
use crate::tracemark;

Expand Down Expand Up @@ -44,6 +45,10 @@ pub fn tag(cts: &[u8], stc: &[u8], session: &TcpSession) -> Option<SocksTunnel>
None => 1
};

if cursor > cts.len() {
return None;
}

let tunneled_destination_host = if tunneled_destination_address.is_none() {
string_up_to_null_byte(&cts[cursor..])
} else {
Expand Down Expand Up @@ -384,22 +389,6 @@ fn process_socks5_username_password_auth(cts: &[u8], stc: &[u8])
Ok((auth_result, Some(username), cts_cursor, stc_cursor))
}

fn determine_tcp_session_state(session: &TcpSession)
-> (SocksConnectionStatus, Option<DateTime<Utc>>) {
match session.state {
TcpSessionState::SynSent
| TcpSessionState::SynReceived
| TcpSessionState::Established
| TcpSessionState::FinWait1
| TcpSessionState::FinWait2 => (SocksConnectionStatus::Active, None),
TcpSessionState::ClosedFin
| TcpSessionState::ClosedRst
| TcpSessionState::Refused => (SocksConnectionStatus::Inactive, session.end_time),
TcpSessionState::ClosedTimeout =>
(SocksConnectionStatus::InactiveTimeout, session.end_time)
}
}

fn is_socks_4a_address(address: &[u8]) -> bool {
address.len() == 4
&& address[0] == 0x00
Expand All @@ -417,7 +406,7 @@ fn build_auth_failed_result(session: &TcpSession,
socks_type: SocksType::Socks5,
authentication_status: auth_result,
handshake_status: SocksConnectionHandshakeStatus::NotReached,
connection_status: SocksConnectionStatus::Inactive,
connection_status: GenericConnectionStatus::Inactive,
username,
tunneled_bytes: 0,
tunneled_destination_address: None,
Expand Down
22 changes: 18 additions & 4 deletions tap/src/ethernet/detection/taggers/ssh_tagger.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use anyhow::{bail, Error};
use byteorder::{BigEndian, ByteOrder};
use log::{info, trace};
use log::{trace};
use crate::data::tcp_table::TcpSession;
use crate::ethernet::packets::{SocksTunnel, SshSession, SshVersion};
use crate::ethernet::tcp_tools::determine_tcp_session_state;
use crate::tracemark;

const SSH_GREETING: &[u8] = b"SSH-2.0-";
Expand Down Expand Up @@ -61,9 +62,12 @@ pub fn tag(cts: &[u8], stc: &[u8], session: &TcpSession) -> Option<SshSession> {
return None;
}

let (connection_status, terminated_at) = determine_tcp_session_state(session);

return Some(SshSession {
client_version,
server_version,
connection_status,
tunneled_bytes: session.bytes_count,
source_mac: session.source_mac.clone(),
destination_mac: session.destination_mac.clone(),
Expand All @@ -72,7 +76,7 @@ pub fn tag(cts: &[u8], stc: &[u8], session: &TcpSession) -> Option<SshSession> {
source_port: session.source_port,
destination_port: session.destination_port,
established_at: session.start_time,
terminated_at: session.end_time,
terminated_at,
most_recent_segment_time: session.most_recent_segment_time
});
}
Expand Down Expand Up @@ -147,6 +151,7 @@ fn parse_version_string(data: &[u8]) -> Result<(usize, SshVersion), Error> {
}))
}

// Only identifies if the slice contains a KEXI and does not attempt to parse it.
fn identify_kex_init(data: &[u8], kexi_len: usize) -> Result<(), Error> {
if data.len() < kexi_len || data.len() < 2{
bail!("Payload too short.");
Expand All @@ -159,7 +164,16 @@ fn identify_kex_init(data: &[u8], kexi_len: usize) -> Result<(), Error> {
bail!("Invalid key exchange init message code. Expected <20>, got <{}>.", message_code);
}

// skip over entire data (as kexi_len) and confirm padding == padding and seq == 0
let trailing_count: usize = (padding as usize)+1;

if data.len() < trailing_count {
bail!("Payload too short for padding and sequence number.");
}

// Skip over entire KEXI length and confirm trailing bytes are padding + sequence number 0.
if !data[data.len() - trailing_count..].iter().all(|&x| x == 0x00) {
bail!("Invalid trailing bytes.")
}

bail!("Not implemented.")
Ok(())
}
3 changes: 2 additions & 1 deletion tap/src/ethernet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ pub mod packets;
pub mod types;
pub mod tcp_session_key;
pub mod detection;
pub mod traffic_direction;
pub mod traffic_direction;
pub mod tcp_tools;
5 changes: 3 additions & 2 deletions tap/src/ethernet/packets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ pub enum SocksConnectionHandshakeStatus {
}

#[derive(Debug, Display, Clone)]
pub enum SocksConnectionStatus {
pub enum GenericConnectionStatus {
Active, Inactive, InactiveTimeout
}

Expand All @@ -192,7 +192,7 @@ pub struct SocksTunnel {
pub socks_type: SocksType,
pub authentication_status: SocksAuthenticationResult,
pub handshake_status: SocksConnectionHandshakeStatus,
pub connection_status: SocksConnectionStatus,
pub connection_status: GenericConnectionStatus,
pub username: Option<String>,
pub tunneled_bytes: u64,
pub tunneled_destination_address: Option<IpAddr>,
Expand Down Expand Up @@ -221,6 +221,7 @@ pub struct SshVersion {
pub struct SshSession {
pub client_version: SshVersion,
pub server_version: SshVersion,
pub connection_status: GenericConnectionStatus,
pub tunneled_bytes: u64,
pub source_mac: String,
pub destination_mac: String,
Expand Down
20 changes: 20 additions & 0 deletions tap/src/ethernet/tcp_tools.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use chrono::{DateTime, Utc};
use crate::data::tcp_table::{TcpSession, TcpSessionState};
use crate::ethernet::packets::GenericConnectionStatus;

pub fn determine_tcp_session_state(session: &TcpSession)
-> (GenericConnectionStatus, Option<DateTime<Utc>>) {

match session.state {
TcpSessionState::SynSent
| TcpSessionState::SynReceived
| TcpSessionState::Established
| TcpSessionState::FinWait1
| TcpSessionState::FinWait2 => (GenericConnectionStatus::Active, None),
TcpSessionState::ClosedFin
| TcpSessionState::ClosedRst
| TcpSessionState::Refused => (GenericConnectionStatus::Inactive, session.end_time),
TcpSessionState::ClosedTimeout =>
(GenericConnectionStatus::InactiveTimeout, session.end_time)
}
}

0 comments on commit 4d2a36d

Please sign in to comment.