Building Our Own Hacking Tool in Python, Part 1 (Getting a Shell)
This part will be dedicated to major step in the hacking process : getting access to a shell on the target, which will allow you to execute commands and basically get control of the computer. What we are going to set up can be summed up with this simple drawing :
The Python program we are going to code is itself pretty short but I assume there are beginners among us, that's why I will take some time to recap the basic information we have to know on networks in order to make a backdoor. This part is not absolutely necessary but I highly recommend you to read it. If you don't your backdoor should still work and you might even be able to customize it but the goal about making our own tools is to understand how they work right ?
So as you can see on step 2 we have to establish a connection between attacker and target in order to exchange information. This can be done with a basic server/client configuration.
In order to send data from one machine to another we use protocols, they are a set of rules that define how communication is made on a network. They are in some way the "language" our machines are using to send packets (bits of data). To name it, the protocol we are going to use here is TCP/IP.
Detailed information about protocols :
- Wikibook page about protocols (really dense but all you might need is here)
- Wikipedia article about protocols
- How-to Geek article about TCP & UDP protocols
Sockets are an abstraction used to send packets of data in a practical way, their Python implementation is quite handy and easy to learn.
Detailed information about Python socket implementation :
Let's have a look at the main obstacle we have to cross before reaching the target from our computer and how to deal with it.
As you can see on the following network drawing we have to go through at least 4 firewalls.
Software firewall is in general windows default one, where the user can handle which software can have access to the internet or not and how. Because we are of course able to manage our own network we can get rid of the two attacker's side firewalls. Getting rid of target's software firewall requires privilege escalation which will be explained in another tutorial, in this part we are only going focus on how to deal with the target hardware firewall.
Hardware firewall is generally implemented in an internet router, so if the target is on the same network you won't have to worry about it. In general it allows to outgoing connections while it blocks incommoding connections. To allow connections from the outside you have to port forward connections to your computer, the process is made directly via a service provided by your internet service provider (ISP).
So, our network drawing could look like that :
Bind or Reverse shell ?
A client has to bind with a server to establish connection, now you have to options :
- The target is the server host listening for connection. The attacker then connects to the victim machine, this is called a bind shell
- The attacker is the server and the target will bind to it, this is called a reverse shell
Incoming and outgoing connections are allowed on your computer and outgoing connections are only allowed on the target. So in a bind shell configuration you see there is a problem. Indeed hardware firewall will prevent you from getting an acess to the computer.
However, if you host the server and the target tries to connect to you everything will work great. Only problem we can see here it that the target will probably have to connect frequently to our computer to establish connection, which can be quite loudly on the log, but we will see how to deal with that in an upcoming tutorial.
So what we are doing here is basically creating our socket object and setting up the server to listen on a specific port. Then we are going to enter a pretty explicit loop that will send commands to the client and print the output until 'quit' command is entered by the attacker.
Now we can clean a bit the program by adding a few verbose debug lines and some exceptions to deal with bad inputs. Here is our final server code (that can of course still be implemented a lot).
We are going to create a socket with the same syntax that we used for the server and connect to the server. Then we are going to enter a loop that will receive commands from the server, execute them with subprocess.Popen() and send back the output. Here we have to be supra carefull because for some specific command this will not work, for example 'cd ..' will stuck the program so we have to implement it manually using os.chdir(). In fact i recommand you to make a list of « authorized command » that would work and make the program block the others.
Same as before we add a few verbose debugging and and exceptions to prevent bad inputs and here is our final code.
Now we are going to test our program locally with two command prompts, the left one represents the attacker and the right one the target. We first run the server, then the client and check if commands are sent properly.
Here are a few interesting features that could be implemented in the program :
- make the client connect periodically so that it can reach you at any time
- filtering incomming connections
Thank you for following this tutorial, hope you enjoyed it, do not hesistate to leave a comment if you have ideas on how I could improve the code or the article and I will update it. In the next tutorial we will see how to esalate priviledge in order to prevent software firewalls from blocking outgoing connexions on the target machine among letting us do many other things.