Skip to content

Commit

Permalink
Merge pull request #3 from biandratti/feature/packages
Browse files Browse the repository at this point in the history
move packages
  • Loading branch information
biandratti authored Sep 15, 2024
2 parents 527c42f + 18c4ee9 commit 42320d6
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 57 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ edition = "2021"
[dependencies]
clap = { version = "4.5.17", features = ["derive"] }
pnet = "0.35.0"
regex = "1.10.6"
87 changes: 87 additions & 0 deletions src/fingerprint_http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use pnet::packet::{ipv6::Ipv6Packet, tcp::TcpPacket, Packet};
use regex::Regex;
use std::net::Ipv6Addr;

pub fn process_packet(packet: &[u8]) {
if let Some(ipv6_packet) = Ipv6Packet::new(packet) {
let client_ip = ipv6_packet.get_source();
let server_ip = ipv6_packet.get_destination();

if let Some(tcp_packet) = TcpPacket::new(ipv6_packet.payload()) {
let client_port = tcp_packet.get_source();
let server_port = tcp_packet.get_destination();
let payload = tcp_packet.payload();

process_http_payload(payload, client_ip, client_port, server_ip, server_port);
}
}
}

fn process_http_payload(
payload: &[u8],
client_ip: Ipv6Addr,
client_port: u16,
server_ip: Ipv6Addr,
server_port: u16,
) {
let payload_str = match std::str::from_utf8(payload) {
Ok(v) => v,
Err(_) => return, // Not valid UTF-8, skip processing
};
log_http_signature(client_ip, client_port, server_ip, server_port, payload_str);
}

fn log_http_signature(
client_ip: Ipv6Addr,
client_port: u16,
server_ip: Ipv6Addr,
server_port: u16,
headers: &str,
) {
let user_agent = extract_user_agent(headers).unwrap_or("Unknown".to_string());
let os = detect_os_from_user_agent(&user_agent);
println!(
".-[ {}/{} -> {}/{} ]-",
client_ip, client_port, server_ip, server_port
);
println!("|");
println!("| client = {}/{}", client_ip, client_port);
println!("| headers = {}", headers);
println!("| raw_sig = {}", extract_raw_signature(headers));
println!("| os = {}", os);
println!("|");
println!("`----");
}

fn extract_raw_signature(headers: &str) -> String {
headers.to_string()
}

fn extract_user_agent(payload: &str) -> Option<String> {
// Basic regex to find User-Agent
let re = Regex::new(r"(?i)User-Agent: (.+)").unwrap();
re.captures(payload).map(|caps| {
caps.get(1)
.map_or("Unknown".to_string(), |m| m.as_str().to_string())
})
}

fn detect_os_from_user_agent(user_agent: &str) -> String {
// Define patterns and corresponding OS names
let os_patterns = vec![
(r"Windows NT 10\.0", "Windows 10"),
(r"Windows NT 6\.3", "Windows 8.1"),
(r"Macintosh; Intel Mac OS X", "Mac OS X"),
(r"Android", "Android"),
(r"Linux", "Linux"),
// Add more patterns as needed
];

for (pattern, os_name) in os_patterns {
if user_agent.contains(pattern) {
return os_name.to_string();
}
}

"Unknown".to_string()
}
59 changes: 2 additions & 57 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod fingerprint_http;
use clap::Parser;
use fingerprint_http::process_packet;
use pnet::datalink::{self, Channel::Ethernet, Config, NetworkInterface};
use pnet::packet::{ipv6::Ipv6Packet, tcp::TcpPacket, Packet};
use std::net::Ipv6Addr;

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
Expand All @@ -25,7 +25,6 @@ fn main() {
..Config::default()
};

// Open the channel
let (mut _tx, mut rx) = match datalink::channel(&interface, config) {
Ok(Ethernet(tx, rx)) => (tx, rx),
Ok(_) => panic!("Unhandled channel type"),
Expand All @@ -43,57 +42,3 @@ fn main() {
}
}
}

fn process_packet(packet: &[u8]) {
if let Some(ipv6_packet) = Ipv6Packet::new(packet) {
let client_ip = ipv6_packet.get_source();
let server_ip = ipv6_packet.get_destination();

// Extract TCP segment
if let Some(tcp_packet) = TcpPacket::new(ipv6_packet.payload()) {
let client_port = tcp_packet.get_source();
let server_port = tcp_packet.get_destination();
let payload = tcp_packet.payload();

process_http_payload(payload, client_ip, client_port, server_ip, server_port);
}
}
}

// Function to process the HTTP payload and log relevant details
fn process_http_payload(
payload: &[u8],
client_ip: Ipv6Addr,
client_port: u16,
server_ip: Ipv6Addr,
server_port: u16,
) {
let payload_str = match std::str::from_utf8(payload) {
Ok(v) => v,
Err(_) => return, // Not valid UTF-8, skip processing
};
log_http_signature(client_ip, client_port, server_ip, server_port, payload_str);
}

fn log_http_signature(
client_ip: Ipv6Addr,
client_port: u16,
server_ip: Ipv6Addr,
server_port: u16,
headers: &str,
) {
println!(
".-[ {}/{} -> {}/{} ]-",
client_ip, client_port, server_ip, server_port
);
println!("|");
println!("| client = {}/{}", client_ip, client_port);
println!("| headers = {}", headers);
println!("| raw_sig = {}", extract_raw_signature(headers));
println!("|");
println!("`----");
}

fn extract_raw_signature(headers: &str) -> String {
headers.to_string()
}

0 comments on commit 42320d6

Please sign in to comment.