diff --git a/Cargo.lock b/Cargo.lock index d3b621a..d00e863 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1717,7 +1717,6 @@ dependencies = [ "include_dir", "log", "mime_guess", - "nix", "rayhunter", "serde", "serde_json", diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 8145144..71d15d5 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -32,5 +32,4 @@ clap = { version = "4.5.2", features = ["derive"] } serde_json = "1.0.114" image = "0.25.1" tempfile = "3.10.1" -simple_logger = "5.0.0" -nix = { version = "0.29.0", features = ["feature"] } \ No newline at end of file +simple_logger = "5.0.0" \ No newline at end of file diff --git a/bin/src/qmdl_store.rs b/bin/src/qmdl_store.rs index e8c48ca..f7681bb 100644 --- a/bin/src/qmdl_store.rs +++ b/bin/src/qmdl_store.rs @@ -1,7 +1,6 @@ +use rayhunter::util::RayhunterMetadata; use chrono::{DateTime, Local}; -use nix::sys::utsname::uname; use serde::{Deserialize, Serialize}; -use std::env::consts::OS; use std::path::{Path, PathBuf}; use thiserror::Error; use tokio::{ @@ -52,22 +51,15 @@ pub struct ManifestEntry { impl ManifestEntry { fn new() -> Self { let now = Local::now(); - let operating_system = match uname() { - Ok(utsname) => format!( - "{} {}", - utsname.sysname().to_string_lossy(), - utsname.release().to_string_lossy() - ), - Err(_) => OS.to_owned(), - }; + let metadata = RayhunterMetadata::new(); ManifestEntry { name: format!("{}", now.timestamp()), start_time: now, last_message_time: None, qmdl_size_bytes: 0, analysis_size_bytes: 0, - rayhunter_version: Some(env!("CARGO_PKG_VERSION").to_owned()), - rayhunter_os: Some(operating_system), + rayhunter_version: Some(metadata.version), + rayhunter_os: Some(metadata.os), } } diff --git a/lib/src/analysis/analyzer.rs b/lib/src/analysis/analyzer.rs index c1f8da6..4db9623 100644 --- a/lib/src/analysis/analyzer.rs +++ b/lib/src/analysis/analyzer.rs @@ -70,9 +70,18 @@ pub struct AnalyzerMetadata { pub description: String, } +#[derive(Serialize, Debug)] +pub struct RayhunterMetadata { + pub version: String, + pub os: String, + pub arch: String, + pub hardware: String, +} + #[derive(Serialize, Debug)] pub struct ReportMetadata { pub analyzers: Vec, + pub rayhunter: RayhunterMetadata, } #[derive(Serialize, Debug, Clone)] @@ -205,8 +214,18 @@ impl Harness { }); } + let metadata = crate::util::RayhunterMetadata::new(); + + let rayhunter = RayhunterMetadata { + version: metadata.version, + os: metadata.os, + arch: metadata.arch, + hardware: metadata.hardware, + }; + ReportMetadata { analyzers, + rayhunter, } } } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index d6b459b..08508de 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -7,6 +7,7 @@ pub mod gsmtap; pub mod gsmtap_parser; pub mod pcap; pub mod analysis; +pub mod util; // re-export telcom_parser, since we use its types in our API pub use telcom_parser; diff --git a/lib/src/pcap.rs b/lib/src/pcap.rs index 0fd9782..56fed98 100644 --- a/lib/src/pcap.rs +++ b/lib/src/pcap.rs @@ -7,13 +7,11 @@ use tokio::io::AsyncWrite; use std::borrow::Cow; use chrono::prelude::*; use deku::prelude::*; -use nix::sys::utsname::uname; use pcap_file_tokio::pcapng::blocks::enhanced_packet::EnhancedPacketBlock; use pcap_file_tokio::pcapng::blocks::interface_description::InterfaceDescriptionBlock; use pcap_file_tokio::pcapng::blocks::section_header::{SectionHeaderBlock, SectionHeaderOption}; use pcap_file_tokio::pcapng::PcapNgWriter; use pcap_file_tokio::{Endianness, PcapError}; -use std::env::consts::OS; use thiserror::Error; #[derive(Error, Debug)] @@ -63,23 +61,18 @@ struct UdpHeader { impl GsmtapPcapWriter where T: AsyncWrite + Unpin + Send { pub async fn new(writer: T) -> Result { - let package = format!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")); - let application = SectionHeaderOption::UserApplication(Cow::from(package)); - let operating_system = match uname() { - Ok(utsname) => format!( - "{} {}", - utsname.sysname().to_string_lossy(), - utsname.release().to_string_lossy() - ), - Err(_) => OS.to_owned(), - }; - let os = SectionHeaderOption::OS(Cow::from(operating_system)); + let metadata = crate::util::RayhunterMetadata::new(); + let package = format!("{} {}", metadata.name, metadata.version); let section = SectionHeaderBlock { endianness: Endianness::Big, major_version: 1, minor_version: 0, section_length: -1, - options: vec![os, application], + options: vec![ + SectionHeaderOption::Hardware(Cow::from(metadata.arch)), + SectionHeaderOption::OS(Cow::from(metadata.os)), + SectionHeaderOption::UserApplication(Cow::from(package)), + ], }; let writer = PcapNgWriter::with_section_header(writer, section).await?; Ok(GsmtapPcapWriter { writer, ip_id: 0 }) diff --git a/lib/src/util.rs b/lib/src/util.rs new file mode 100644 index 0000000..3701f97 --- /dev/null +++ b/lib/src/util.rs @@ -0,0 +1,35 @@ +use nix::sys::utsname::uname; + +/// Expose binary and system information. +pub struct RayhunterMetadata { + pub name: String, + pub version: String, + pub os: String, + pub arch: String, + pub hardware: String, +} + +impl RayhunterMetadata { + pub fn new() -> Self { + match uname() { + Ok(utsname) => RayhunterMetadata { + name: env!("CARGO_PKG_NAME").to_owned(), + version: env!("CARGO_PKG_VERSION").to_owned(), + arch: format!("{}", utsname.machine().to_string_lossy()), + os: format!( + "{} {}", + utsname.sysname().to_string_lossy(), + utsname.release().to_string_lossy(), + ), + hardware: String::from("unknown"), + }, + Err(_) => RayhunterMetadata { + name: env!("CARGO_PKG_NAME").to_owned(), + version: env!("CARGO_PKG_VERSION").to_owned(), + arch: std::env::consts::ARCH.to_string(), + os: std::env::consts::OS.to_string(), + hardware: String::from("unknown"), + }, + } + } +}