In our walk in linux, there comes a point where we need to hack ( pentest ) in a safe environment. The first thing we usually do is install Virtualization Softwares and install all the distros our system can take. In stages of hacking, to compromise the victim machine, we need some sort of program to infect the system. The down-side is: AntiVirus products have signatures of favourite Metasploit files and to successfully compromise the victim, we need to disable this products which isn’t what we will be doing in real life. This calls for the development of our own program. Today, we touch on one of the many programs ( payloads actually ), that is, a reverse tcp program.
Reverse TCP: In a normal forward connection, a client connects to a server through the server’s open port, but in the case of a reverse connection, the client opens the port that the server connects to. The most common way a reverse connection is used is to bypass firewall and router security restrictions.
For example, a backdoor running on a computer behind a firewall that blocks incoming connections can easily open an outbound connection to a remote host on the Internet. Once the connection is established, the remote host can send commands to the backdoor.This method of communication is helpful because starting a local shell on a victim machine can be easily and even without user control be detected by the system itself.
In this series, we will be developing a reverse tcp program in python. Why should this be in parts ? This is because, with every part we introduce a new function or command or code into our shell making it more flexible. We are going to build our shell from ground up into a devastaing awesome fantastic fabulous catastrophic delicious … ( I think thats enough ) shell.
In today’s tutorial, we are going to make the shell a little nice abit. Lets begin with the server ( attacker ) script.
SCRIPTING: THE IMPORT STATEMENTS
This will be our new import statement
#!/usr/bin/env python
import socket, sys, os
Nice !!
SCRIPTING: THE SCRIPT COLOUR FUNCTION
This function is going to spawn our shell into a beautiful shell.
This function decorates any text passed to it with the specified colour. It accepts:
- “r” or “red” - Red
- “g” or “green” - Green
- “b” or “blue” - Blue
- “y” or “yellow” - Yellow
- “lgray” - Light Gray
- “underline” - Underline Text
- “strike” - Strikes Text
SCRIPTING: THE BANNER FUNCTION
All these introduced functions are not necessary but improve the user experience. We ( You ) can customize it as we ( you ) please.
EDIT: I changed my “lgray” to “gray”. As I stated earlier, we can change it as we please.
This function as you already understand returns the text to the caller.
SCRIPTING: THE MAIN CONTROL FUNCTION
This function takes over the server socket. In the previous tutorial, we didn’t use any function and wrote raw codes. Those raw codes are now written into this function with some pretty good modifications.
Don’t panic yet. A close look at the code brings understanding. Lets break it down, shall we ?
- We accept the socket information and pass it to the respective variables host and port
- If no error is caught, we print “Framework Started Successfully” with the help of the script_color function.
- Next is the banner() function which is printed to the screen.
- We setup the sockets, bind and listen.
- Usually we pass the host as an empty string. If that be the case, we change the host string to “localhost” after we setup the socket
- We print “Listening on host address:port number …”
- We begin accepting connections.
- If all goes well and a client comes through, we enter into the console function passing the connection stream and the host address as an argument.
- Should the function exit, we close our socket
That wasn’t difficult right !!!. Moving on.
SCRIPTING: THE CONSOLE FUNCTION
The frustrating part of all but if we can stick together on this one, we are going to sail through. Lets write.
Pretty Long. First, we print a string saying Connection Established from the remote host. We then receive
data from the stream, this data is information about the remote system ( We will deal with that in the client side). We then sort out the data, this is the layout of the data:
System Type
Computer Name ( Node Name )
Release Version
System Version
Machine Architecture
Username
All these information are inherited from the uname() and getlogin() in the os module ( We will get to that on the client side ).
We move on to create a custom prompt name for our shell using the information received, for example, [email protected].
We then enter into our command loop. This loop contains commmands for the connection. We are defining our own custom commands therefore commands such as “ls -l” and other linux commands won’t work.
These are our first 5 ( five ) built in commands.
- exec - Accepts a command as an argument and executes the command on the remote host. This is where our everyday linux commands can come to play, for example, exec ls -l
- cls - Clears the Terminal screen. Uses the default linux clear command
- help - Calls the help function and prints the help text ( We will get there in a moment )
- sysinfo - Prints the received remote system information
- exit() - Sends a halt command to the remote shell and also exits locally
- Any non-specified command is not accepted and an error message will be printed in the else statement
In the inbuilt exec command, should no argument be passed, an error is printed. We have a new function in the exec command which is send_data. It accepts the connection stream and the command to execute. It automatically deals with sending and receiving of the data.
I would rather you write the code as you see it. You can modify it after it works. Modifying during writing can cause alot of problems ( trust me ).
SCRIPTING: THE HELP FUNCTION
All commands built into the framework ( script ) are to be entered here.
This function prints the help_list in a sorted way and also formats the help_list.
SCRIPTING: THE SEND DATA FUNCTION
This function as stated earlier automatically sends and receives the data.
Now, lets tie the knot ( not marriage ).
CALLING EVERYTHING TOGETHER
We know functions don’t execute thems and need callers.
We are partly done. Lets now reflect our changes into the client script.
THE CLIENT SIDE
The client also needs to obey some rules and commands such as the exec command in the server script. Our import statement should change to:
#!/usr/bin/env python
import socket, subprocess as sp, sys, os
Our first function would be the connect function.
THE CONNECT FUNCTION
This function as the name implies connects to the specified address. It also sends the system information after a connection is established.
It then calls the interactive_session function passing the connection stream as an argument.
THE INTERACTIVE SESSION FUNCTION
This function runs a loop accepting and executing commands based on the “if” instructions.
The function uses another function send_data to send the data.
THE SEND DATA FUNCTION
This function calculates the length of the data and sends it along with the data.
This function will be helpful in future modifications. Lets tie the knot.
CALLING EVERYTHING TOGETHER
We write the magic line as the functions won’t execute themselves.
Lets execute our attacker ( server ) script and see what we’ve got
root@Sploit:~/Desktop# python reverseTcp.py ‘’ 8000
The client should connect passing the host information on the command line.
root@Sploit:~/Desktop# python connect.py 127.0.0.1 8000
Here is a screenshot of the attacker’s server script:
Exploring the help options
From the nmap result on the remote system, I think we opened a port on a registered service. As expected, the client console should be empty because we aren’t printing anything.
LETS END IT - CONCLUSION
I think we have accomplished something in this tutorial.
Corrections, Modifications, Updates are welcome.