0x02 SLAE - Reverse TCP
Introduction
In the second assignment, the goal is pretty similar to the first one. Instead of connecting to the remote socket, we will create a socket that will connect to us. This will open a tunnel of communication between the remote host. A reverse shell is really useful when we want to evade firewall. Indeed, the remote host is connecting to us. In this way, we just need to open a port on our side. In this demo, we will not need to do that because we will test locally. This is just to explain the difference between the reverse and the bind shell.
C Program
The C program is really close to the first assignment C program. However, we have to set an ip address to connect back to our listener. In the next part, I will explain each section as I did for the first assignment. In the first place, I had to initialize the parameter for the sockaddr_in
struct. So, I had to set the ip address and the port.
Create a socket
To be able to connect to our remote listener, we have to create a socket. The socket will take the following parameter : socket(int domain, int type, int protocol);
from the man page of socket. The domain
represent the protocol family. Since, we are using IPv4 internel protocol, we will set this parameter to AF_INET
. The second parameter is the communication semantics. We need to have a two-way connection. So, we will set the parameter to SOCK_STREAM
. The last parameter is the type of protocol and we will set it to 0
as we did for the bind tcp.
Connect
The connect function require also 3 parameters which are similar to the arguments that we pass in the bind function in C. Here is the connect function definition int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
.
The first parameter sockfd
is the return value of our socket function call. The second parameter is the struct that we initlialize upper and the last parameter is the size of our struct.
Redirect stdin, stdout and stderr
This is similar to what I did in the bind tcp. Here we just need to redirect the input, output and error using the dup2 function. As I detailed in the first assignment, there is :
stdin : 0
stdout : 1
stderr : 2
The first parameter of dup2 is the return value of the socket function. The second parameter is the value of the std which is 0, 1 or 2. Since, we need the three std type, we will call dup2 three time.
Open a shell
Finally, we will call the execve function to open a shell on the remote host.
The final C program
Assembly version
The assembly version will be pretty straight forward since it is similar to the first assignement but instead we will need less syscall and some adjustement for setting a custom ip and port.
Create a socket
First, we will clean the registers before starting to write our first syscall. This help us to already zeored the registers and be ready to use them.
Then, we are going to use the syscall socketcall
. The assembly code will be exactly the same as the assembly for the bind tcp. In that way, I will not go into details since it is explained in the first blog post.
Connect to the listener
This part is different from the bind shell. Instead of listening for connection, we will connect to a listener.
In the first part, we will initialize the structure serv_addr
. It is also important to mention that if we put zero value in our assembly, this would add null bytes in the shellcode. For example, if we add 127.0.0.1
it will contain zero in the shellcode. In this way, the shellcode will not work. The solution to that problem, is to create a key that will xor the value. Xoring the value with the key will remove the zero or null byte and the shellcode will work properly. Let’s see what it looks like :
In the assembly code above, we can see that the key is equal to 0xaaaaaaaa
. Before explaining the xor, we need to transform the ip address in correct format. The value 127.0.0.1
in hex is equal to 0x7f00001
. However, we need to reverse that value to put it in the assembly code. So, the ip address become : 0x100007f
. Then, we xor 0xaaaaaaaa
with 0x100007f
which give 0xabaaaad5
. And now, we don’t have any zero or null byte.
After the initialization, we can now use SYS_CONNECT
from socketcall
.
We will need to clean the registers because they contains value and we need to reset them to be able to reuse it. In the code above, we will use SYS_CONNECT
which the value is 3
from the definition in the file /usr/include/linux/net.h
. Then, we will push the size of the struct which is 16. And finally, push the struct to the stack which contains our arguments for the ip address, port number and AF_INET
.
Redirect stdin, stdout, stderr
This part is exactly the same as the part for the bind shell. We will use the dup2 syscall which is the value 63. The three following syscall is the syscall for stdin, stdout and stderr.
Open a shell
The last part is exactly the same as the bind shell. We will use the syscall execve
which will execute /bin/sh
on the remote host that is connecting to us.
The final assembly version
Now, let’s generate our shellcode and test if it work. I created a simple script that do all the stuff to test and generate our shellcode correctly. Here is the screenshot of the output of the shellcode.
From the screenshot above, it looks like our shellcode has been generated correctly. Let’s test if it work.
The first window in the image above, is representing the execution of the shellcode and the window above is the listener. We can see from the image above that our reverse shell is working as expected.
The configurable ip and port number script
In my first assignment, we had to adjust manually the port number in the python script. In this one, we just have to insert the ip address and the port number as an argument when running the python script. This is a lot more efficient and easier to generate our shellcode. The python script will also automatically execute the shellcode as you can see in the image below.
Here is the result of the running script above.
Conclusion
In the second assignment, I have learned how to create a reverse shell tcp in assembly and shellcode. I also created a configurable ip a port script that generate automatically the shellcode which is much more simple than the first script in the assignment 1. I also feel more familiar with assembly. Let’s go for the third assignment. Thanks for reading me.
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-1374
Last updated
Was this helpful?