You need to enable JavaScript to run this app. 如何将Rust编写的TCP反向Shell监听器改为类似Netcat的UDP实现
优惠活动
大模型
产品
解决方案
定价
更多

如何将Rust编写的TCP反向Shell监听器改为类似Netcat的UDP实现

UDP是无连接协议,和TCP面向流的逻辑差异很大,netcat -ul 55100的默认行为是:绑定指定UDP端口后,将收到的任意UDP数据输出到标准输出,同时将标准输入的内容发送给最近一次向本地端口发送数据的对端地址。修改后的完整实现代码如下:
use std::net::{UdpSocket, SocketAddr};
use std::sync::{Arc, Mutex};

fn stdin_to_udp(socket: UdpSocket, peer_addr: Arc<Mutex<Option<SocketAddr>>>) -> std::thread::JoinHandle<()> {
    std::thread::spawn(move || {
        let mut buffer = [0; 1024];
        loop {
            let len = std::io::stdin().read(&mut buffer).unwrap();
            if len == 0 {
                std::process::exit(0x0100);
            }
            // 仅当已经收到过对端的包才发送
            if let Some(addr) = *peer_addr.lock().unwrap() {
                socket.send_to(&buffer[..len], addr).unwrap();
            }
        }
    })
}

fn udp_to_stdout(socket: UdpSocket, peer_addr: Arc<Mutex<Option<SocketAddr>>>) -> std::thread::JoinHandle<()> {
    std::thread::spawn(move || {
        let mut buffer = [0; 1024];
        loop {
            let (len, addr) = socket.recv_from(&mut buffer).unwrap();
            if len == 0 {
                println!("Connection lost");
                std::process::exit(0x0100);
            }
            // 更新最近一次通信的对端地址
            *peer_addr.lock().unwrap() = Some(addr);
            std::io::stdout().write_all(&buffer[..len]).unwrap();
            std::io::stdout().flush().unwrap();
        }
    })
}

fn listen() -> std::io::Result<()> {
    let socket = UdpSocket::bind("0.0.0.0:55100")?;
    println!("Started UDP listener on 0.0.0.0:55100");

    // 用Arc<Mutex>共享对端地址,两个线程都可以读写
    let peer_addr = Arc::new(Mutex::new(None));

    let t1 = stdin_to_udp(socket.try_clone()?, peer_addr.clone());
    let t2 = udp_to_stdout(socket, peer_addr);

    t1.join().unwrap();
    t2.join().unwrap();

    Ok(())
}

核心改动点

  • 把原来的TcpListener替换为UdpSocket,UDP没有监听-accept的连接建立步骤,直接绑定端口即可使用
  • 移除了原来通用的pipe_thread,拆分出两个单独的线程函数:一个负责把标准输入的数据发送到UDP对端,另一个负责把UDP收到的数据输出到标准输出
  • 增加Arc<Mutex<Option<SocketAddr>>>结构共享最近一次通信的对端地址,对齐netcat的行为:在收到第一个对端包之前,不会发送标准输入的内容
  • 替换了原来的流读写read/write,换成UDP数据报专用的recv_from/send_to方法适配无连接的读写逻辑

内容的提问来源于stack exchange,提问作者user16139080

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 01:45:04