Assignment 2 – TCP Reverse Shell
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
Student ID: SLAE-1112
This is the second from seven assignments in order to complete the SLAE (32bit) certification.
The objective of this assignment is to create a TCP Reverse Shell shellcode with the following requirements:
- Reverse connects to a configured IP and Port
- Execs a shell on successful connection
- The IP Address and Port number should be easily configurable (via wrapper)
In order to create the Reverse Shell shellcode can divided in four parts:
- Creat the Socket
- Connect to the remote host
- Redirect stdin, stdout and stderr to the Socket via dup2
- Call Execve to run /bin/sh
This post will be shorter than the last one since most of the code was reused from Assignment 1.
Create the Socket
Just like last Assignment, let’s start by creating a socket using sys_socketcall:
Connect to the remote host
This is the only different part from Assignment 1. This time we need the connect() function call in order to connect to the remote host.
Just like in the previous sys_socketcall we set al to 0x66. Then we take advantage of the fact that ebx is 0x1 and increment it to use it as AF_INET (2).
The connect() function call requires 3 arguments, a socket file descriptor, a structure called sockaddr and an address length.
The Sockaddr structure is composed by sin_family (Address family), sin_port (Port number) and a structure called sin_addr (Address).
In order to create the Sockaddr structure we need to push into the stack the remote IP Address, the Port Number and the Adress family (ebx = AF_INET).
Then we save this structure to ecx and push into the stack the Connect() arguments.
Finally we increment ebx again, making its value 3 (SYS_CONNECT). At this point we have everything ready to perform the syscall:
Redirect stdin, stdout and stderr to the Socket via dup2
Just like in the Bind Shell Assignment, we need to redirect the file descriptors stdin (0), stdout (1) and stderr (2) to the socket file descriptor using sys_dup2 syscall:
Call Execve to run /bin/sh
Finally, we use SYS_EXECVE to execute /bin/sh:
After assembling and linking and executing our binary we get a reverse shell on our nc listener on port 4444.
The last objective to accomplish is to make the IP Address and Port number easily configurable. The approach is the same used in Assignment 1: Using objdump to identify the IP Address bytes (marked in red) and the Port number bytes (marked in green).
The Python wrapper receives the IP and Port as arguments, converts them to the shellcode format and outputs the new shellcode.
Just like the last one, the script takes into consideration that it might generate a shellcode containing nulls and in that case it just exits.
The full code can be found in my SLAE Github repository.