-
Notifications
You must be signed in to change notification settings - Fork 8
Dokumentation Honeygrove
Honeygrove ist ein vielseitig einsetzbarer Honeypot und bildet das Kernstück des Projekts. Er bietet verschiedene Services, die Angreifer anlocken und ihre Angriffsstrategien protokollieren. Es sind bewusst Schwachstellen in den Services eingebaut, die zur Ausnutzung durch den Angreifer verleiten. Über die Management-Konsole ist Honeygrove durch einen Benutzer dynamisch konfigurierbar. So können einzelne Services an bestimmten Ports gestartet oder gestoppt werden. Auch einzelne Settings können im laufenden Betrieb über die Management-Konsole verändert werden. Die erfassten Angriffsdaten werden von Honeygrove in einem festgelegten Format zum Incident-Monitoring weitergeleitet und dort ausgewertet.
Folgende Services umfasst Honeygrove:
Das SSH-Protokoll wird komplett implementiert und durch eine selbstgeschriebene Pseudo-Shell ergänzt. Auf Wunsch können die Befehle auch auf der echten Shell ausgeführt werden.
Der HTTP-Service verwendet kein ganz vollständiges HTTP-Protokoll zur Kommunikation. Die gängigen GET und POST Befehle werden unterstützt.
Der FTP-Service simuliert fast vollständig das Verhalten eines FTP-Servers. Alle gängigen FTP-Befehle werden unterstützt.
Der ListenService lauscht auf einer Menge von Ports und erfasst alle eingehenden Daten.
Der TCPFlagSniffer lauscht auf half-open TCP-Connections und kann so SYN-Floods und Portscans erkennen.
- Twisted 17.5.0
- Broker (pybroker /mfischer/broker-multihop)
- Python 3 oder höher
- Ubuntu (getestet ab Version 16.4 mit allen aktuellen Paketen)
- Debian (getestet ab Version 9.1 mit allen aktuellen Paketen)
CPU: ca. 1,4GHz Quad-Core RAM: min. 1 GB RAM Disk: ca. 10 MB
- Ordner "honeygrove" an gewünschtes Verzeichnis kopieren
- honeygrove_install ausführen
- Wird im Normalfall automatisch mit installiert vom honeygrove_install Skript
- Sonst: Manuelle Installation
Alles, was in Honeygrove konfigurierbar ist, wird in der Datei config.py
festgelegt.
-
HPID
- Eindeutige ID für den Honeypot -
machine_name
- Gerätename, der in den Services verwendet werden soll -
hp_description
- Beschreibung des Honeypots wie z.B. Standort -
resources
- Pfad zum Ressourcenordner -
logpath
- Pfad, an dem die lokale Logdatei abgelegt wird -
listenServicePorts
- Liste von Ports, auf denen der ListenService laufen soll -
listenServiceName
- Name, den der ListenService nutzen soll -
tcpFlagSnifferName
- Name, den der TCPFLagSniffer nutzen soll -
httpResponseHeader
- Header, der bei der HTTP Response gesendet wird -
httpHTMLDictionary
- Dict mit den unterstützten HTTP-Seiten. Kann durch Nutzung des HTMLLoader vereinfacht werden -
httpResources
- Pfad zu den Ressourcen für den HTTPService -
httpPort
- Port, auf dem der HTTPService laufen soll -
httpName
- Name, den der HTTPService nutzen soll -
sshPort
- Port, auf dem der SSHService laufen soll -
sshName
- Name, den der SSHService nutzen soll -
ssh_real_shell
- Gibt an, ob die Anfragen an den SSHService an die echte Shell weitergereicht werden sollen. Bietet dadurch mehr Möglichkeiten das Verhalten mitzuschneiden, öffnet das echte System jedoch komplett nach außen. -
ftpPort
- Port, auf dem der FTPService laufen soll -
ftpName
- Name, den der FTPService nutzen soll -
path_to_filesys
- Pfad zu dem XML-Dateisystem, das alle Services für ihre FilesystemParser nutzen -
tokendir
- Pfad zu den Dateien, die im vorgetäuschten Dateisystem auffindbar sein sollen -
tokenDatabase
- Pfad zu der Datei mit den Login-Daten -
honeytokendbGenerating
- Dict mit Services, welche Honeytoken generieren können -
honeytokendbProbabilities
- Dict mit Wahrscheinlichkeiten zur Honeytoken-Generierung -
sshAcceptsFiles
- Gibt an, ob der SSHService Dateien speichern darf (z.B. wget) -
ftpAcceptsFiles
- Gibt an, ob der FTPService Dateien speichern darf (z.B. put) -
quarantineDir
- Pfad zum Verzeichnis, in dem empfangene Dateien gespeichert werden sollen -
startupList
- Liste mit den Namen der Services, die beim Start von Honeygrove automatisch gestartet werden -
noPortSpecificService
- Liste mit den Namen der Services, die auf mehr als einem Port laufen dürfen -
tcpTimeout
- Zeit, nach der nach eine Antwort auf ACK-SYN erfolgen soll -
BrokerComIP
- IP auf der wir lauschen für Broker peerings -
BrokerComPort
- Port auf dem wir lauschen für Broker peerings -
honeygrove_start
- 'active' Service werden beim Start des Honeypots mit gestartet. 'passive' services bleiben ausgeschaltet
Änderungen treten erst nach einem Neustart von Honeygrove in Kraft. Einige Einstellungen lassen sich über die Management-Konsole jedoch auch im laufenden Betrieb ändern.
- Ausführen von honeygrove.sh startet Honeygrove
- Wenn bei der Installation die Links angewählt wurden einfach im Terminal als Befehl
honeygrove
.
Es gibt verschiedene Möglichkeiten die Funktionalitäten von Honeygrove zu testen oder auszuprobieren.
Nach dem Starten des Honeypots im 'active'-Mode (config.honeygrove_start
= 'active'), laufen alle Services an den in der config
festgelegten Ports. Alle Services können also über diese Ports manuell angesprochen werden.
Valide Login-Credentials für SSH
, HTTP
und FTP
finden sich in config.tokenDatabase
. Dort können auch manuell Login-Credentials eingetragen werden.
Es kann sich regulär über SSH verbunden werden, also über das Terminal z.B. mit ssh root@localhost -p 12222
. Nach der Authentifizierung kann auf üblichem Wege über SSH mit dem SSH-Service kommuniziert werden.
Beim gestarteten HTTPService, können die unterstützten Seiten über den Browser ausprobiert werden.
Im Browser muss localhost:port/seiten_url
eingegeben werden.
Beispiel für Port 8080 (HTTP Standart):
- localhost:8080/
- Fritzbox Seite
- localhost:8080/wp-admin
- Wordpress Login
- localhost:8080/ghost
- Ghost Login
- localhost:8080/phpmyadmin
- phpMyAdmin Login
Bei allen default.Seiten, wird man bei einem erfolgreichen Login-Versuch auf eine Dashboard-Seite weitergeleitet.
Es kann sich regulär über FTP verbunden werden, z.B. mit dem Terminal ftp
und dann open localhost 4646
. Nach der Authentifizierung kann über die gängigen FTP-Befehle mit dem Service kommuniziert werden.
Um den TCPFlagSniffer manuell zu testen erzeugt man eine half-open TCP-Connection zum entsprechenden Port. Dazu muss ein TCP Packet mit SYN gesendet werden, dieses wird dann geloggt (Achtung! Es darf kein TCP Packet mit ACK hinterhergeschickt werden).
Um den ListenService zu testen, einfach einen Port an dem der ListenService lauscht mit irgendeinem Protokoll (z.B. SSH) ansprechen. Die Anfrage wird dann geloggt.
In honeygrove.tests
befinden sich die Unittests des Projekts. Es gibt Unittests für jede Komponente in honeygrove.core
und honeygrove.services
. Die TestCases sind wie die Dateien die sie testen und Suffix '_Test' benannt und daher leicht zuzuordnen.
Die Architektur von Honeygrove basiert auf verschiedenen Services, die vom ServiceController
verwaltet werden. Alle Services implementieren das ServiceBaseModel
, daher muss der ServiceController
nur dieses kennen.
Die Steuerung von außen ist durch den HoneyAdapter
realisiert, welcher über den BrokerEndpoint
Nachrichten von der Management-Konsole empfängt und daraufhin entsprechende Methoden am ServiceController
aufruft. Der BrokerEndpoint
ist ebenfalls für das Senden von z.B. Logdateien an Management-Konsole und Incident-Monitoring zuständig.
Die Service-basierte Architektur ermöglicht einen hohen Grad an Modularität, d.h. neue Services können einfach hinzugefügt werden. Hierfür muss dieser ebenfalls im Modul services
angelegt werden und das ServiceBaseModel
ìmplementieren.
Das Honeygrove-Projekt teilt sich in die Module broker
, core
, services
, logging
, resources
und tests
.
Der BrokerEndpoint ist für die Annahme und das Versenden von Broker Nachrichten zuständig. Diese Nachrichten enthalten Befehle von und Antworten an die Management-Konsole, logs und Dateien. Zusätzlich enthält diese Klasse die Funktionalität sich zu anderen Endpunkten zu peeren. Wichtig ist das der BrokerEndpoint nicht für die Bearbeitung zuständig ist, sondern nur für die Übermittlung.
Die Klasse FilesystemParser.py ist für die unmittelbare Verwaltung des simulierten Dateisystems zuständig. Sowohl FTP als auch der SSH Service benutzen den Filesystem Parser (FSP), um Operationen wie das Navigieren durch ein Dateisystem oder Erzeugen neuer Ordnerstrukturen zu ermöglichen.
Dem FSP liegt ein XML Dokument zugrunde, das als ElementTree
eingelesen wird und die Struktur des Dateisystems repräsentiert. Beim Erzeugen einer Instanz des FSP (in den jeweiligen Service Klassen) kann der Pfad zu diesem Dokument als Parameter übergeben werden. Wird kein Pfad angegeben, wird standardgemäß der path_to_filesys
aus der Konfigurationsdatei des Honeypots (config.py) genommen, hinter dem eine Unix ähnliche Ordnerstruktur als XML Dokument zu finden ist (unix.xml
).
Der FSP erwartet einen ähnlichen Aufbau aller XML Dateien, die als Ordnerstruktur dienen sollen. In der ersten Zeile kann in einem XML Kommentar angegeben werden, welcher Ordner als das home Verzeichnis des Benutzers ausgewählt werden soll, um z.B. in SSH künftig als ~ (Tilde) angezeigt werden zu können. Die Syntax der ersten Zeile ist dabei wie folgt:
<!--a, b, c, ..., z-->
Wobei die Buchstaben als Liste von Zahlen verstanden werden können und jeweils durch die Positionen in der XML Hierarchie ersetzt werden müssen.
######## Beispiel:
<!--1, 0-->
<dir name="/">
<dir name="bin"/>
<dir name="home">
<dir name="root">
<file name="hello_world.py"/>
</dir>
<dir name="asdf"/>
</dir>
</dir>
Der äußerste bzw. oberste Ordner (in diesem Beispiel /
) wird standardmäßig ignoriert und ist das home Verzeichnis falls in der ersten Zeile kein entsprechender Kommentar vorhanden ist. Die 1
zeigt somit auf den Ordner home
(da wir bei 0 anfangen zu zählen) und die 0
danach auf das erste Unterverzeichnis in home
nämlich root
.
Wird also ein Service gestartet, dem dieses XML Dokument zugrunde liegt, würde ein ls
Befehl zum Anzeigen aller Dateien im aktuellen Verzeichnis die Datei hello_world.py
liefern. Möchte man stattdessen das home Verzeichnis nicht in root
haben sondern in asdf
, müsste der Kommentar in der ersten Zeile zu <!--1, 1-->
geändert werden, um auf das zweite Unterverzeichnis von home
(nämlich asdf
) zu zeigen.
Darüberhinaus ist zu beachten, dass nur zwei XML-Tags gültig sind: dir
für Ordner und file
für Dateien gefolgt vom Attribut name
, das den Namen des jeweiligen Ordners / Datei enthält.
Die Klasse HoneyAdapter
reagiert auf Befehle der Management-Konsole an den Honeygrove. Die Befehle empfängt der Honeyadapter
im JSON-Format über den BrokerEndpoint
. Sie werden in der Methode handleMessages
geparst und auf Validität überprüft. Im Anschluss werden je nach eingegangenem Befehl die entsprechenden Funktionen am Honeygrove-System aufgerufen oder Änderungen vorgenommen. Dazu verfügt der Honeyadapter
über einen ServiceController
.
Die HoneytokenDB
ist zuständig für das Verwalten von Login-Versuchen. Dazu implementiert sie den twisted.cred.checkers.ICredentialsChecker
. Jeder Service verfügt über eine Instanz der HoneytokenDB
, die er bei seiner Initialisierung an sein twisted.cred.portal.Portal
übergibt. Wird dann am vom jeweiligen Service verwendeten Protokoll ein Login durchgeführt, ist die entsprechende Instanz von HoneytokenDB
für die Überprüfung der Validität der Credentials zuständig. Alle HoneytokenDB
-Instanzen greifen auf die gleiche Datei zu, deren Pfad in der config
unter tokenDatabase
zu finden ist. Dort werden gültige Login-Daten im Format Serv1,Serv2:Username:Passwort:Key
eingetragen. Durch diese zentrale Aufzeichnung ist es der HoneytokenDB möglich, dynamische Honeytoken zu generieren, d.h. einen Login-Versuch zufällig für gültig zu erklären, die damit verbundenen Anmeldedaten in die Datei zu schreiben und diese so auch für andere Services gültig zu machen. Welcher Service auf diese Art Login-Credentials für welche anderen Services generieren darf ist in config.honeytokendbGenerating
im Format {Von: [Für, Für], Von: [Für]}
festgelegt. Mit welcher Wahrscheinlichkeit Honeytoken generiert werden, steht unter config.honeytokendbProbabilities
im Format Service: Wahrscheinlichkeit, Service: Wahrscheinlichkeit
. Um Konflikte (IOError
) beim lesen bzw. verändern der Datei durch mehrere Services zu vermeiden, verfügt jede HoneytokenDB
-Instanz zusätzlich über eine Arbeitskopie der gemeinsamen Datei, die genutzt wird, wenn die gemeinsame Datei blockiert ist.
Der ServiceController ist die Schnittstelle zwischen den Servicen, dem rest vom Honeygrove und ist für die Plugin Funktion der Service zuständig. Er findet automatisch alle Subklassen vom ServiceBaseModel und erstellt eine dann Instanz dieses Services. Er ist außerdem dazu da, Service zu starten, stoppen und die Synchronisation mit dem ListenService aufrechtzuerhalten. Laufende service werden in einen Dict gehalten und können über den jeweiligen Namen angesprochen werden. Durch diese vorgehensweiße, ist es einfach einen neuen Service in Honeygrove zu implementieren.
- Die neue Service-Klasse muss vom ServiceBaseModel erben und deren abstrakte Funktionen implementieren.
- Die Service-Klasse muss im Service Ordner sein
Der Entwickler muss keine weitere Kenntnis über den Rest des Projektes haben, außer er möchte über die Funktionen hinausgehen, die das ServiceBaseModel bietet.
Das log
Modul wird von überall im Projekt aufgerufen, um zu loggen und auf die Konsole auszugeben. Es hat verschiedene Methoden, die zu bestimmten Anlässen aufgerufen werden sollten. Manche Methoden sind nur für das Ausgeben und Schreiben zuständig, andere benutzen den BrokerEndpoint
um die Meldungen an bspw. CIM oder Management-Konsole zu senden.
Das ServiceBaseModel
bildet ein Interface, das von allen Services implementiert werden muss. Möchte man einen neuen Service zum Honeygrove hinzufügen, muss auch dieser ServiceBaseModel
implementieren und in honeygrove.services
platziert werden.
Der SSHService
nutzt für die Realisierung der Verbindung die SSH-Komponenten von Twisted. Er nutzt dafür die SSHFactory
, setzt ihr jedoch mit groveUserauth
ein eigenes ssh-userauth
um das Logging von Anmeldeversuchen zu ermöglichen. Ferner wird das Portal
mit einem eigenen Realm
und Avatar
gesetzt. Als "credentials checker" wird dem Portal
die HoneytokenDB
übergeben. Bei einem Login-Versuch wird nun die HoneytokenDB
aufgerufen, bei Erfolg erzeugt dann das SSHRealm
einen SSHAvatar
. Je nachdem, welchen Service der Angreifer fordert, gibt die SSHSession
ihm bei der direkten Ausführung von Befehlen eine Meldung zurück. Bei der Forderung einer Shell wird der Angreifer mir unserem SSHProtocol
verbunden.
Das SSHProtocol
täuscht dem Angreifer ein Terminal vor. Es erbt dazu von HistoricRecvLine
um das "Erinnern" und Scrollen der letzten Befehle zu ermöglichen. Bei der ersten Verbindung wird connectionMade
aufgerufen, hier werden Session-spezifische Attribute gesetzt. Jedes mal, wenn der Angreifer einen Befehl abschickt, wird lineReceived
aufgerufen. Wenn in der config die Option ssh_real_shell
aktiv ist, werden die Befehle direkt auf der echten Maschine ausgeführt. Ansonsten wird die Zeile analysiert wobei das erste Wort dem Befehl und alle weiteren den Argumenten entsprechen. Es wird dann die jeweilige Funktion ssh_BEFEHLSNAME
aufgerufen und die Argumente als Parameter übergeben. Neue Befehle können hier einfach ergänzt werden.
Der HTTPService
ermöglicht anhand von einigen twisted
Komponenten einem Angreifer, sich über einen Port zu verbinden und eine HTTP Request zu schicken. Es wird ein eigenes, HTTP-ähnliches Protokoll, namens protokoll
erstellt, welches von twisted.internet.protocol.Protocol
erbt. Die ankommenden Requests werden von dem protokoll
als String ausgelesen. Wenn eine gültige URL angefragt wird, wird die dementsprechende HTML-Seite per HTTP Response versendet. Bei den folgenden Login-Versuchen, wird immer ein HTTPAvatar
erstellt. Diesem Avatar werden die Login Daten übergeben und er wird an die HoneytokenDB
weitergereicht. Die HoneytokenDB
dient als "credentials checker" dieses Services. Je nachdem ob die HoneytokenDB
die Login Daten als gültig oder ungültig deklariert, wird die dementsprechende Response rausgeschickt. Bei gültigen Daten, kann eine 'Dashboard' Seite zugefügt werden.
Eine neue Html Seite kann über die Management Konsole hinzugefügt werden. Dies geht über den Befehl add_html. Der benötigt als Parameter einmal die URL unter welcher die Seite erreichbar sein soll und die eigentliche Html Dateien als String. Eine Login-Seite ist verbindlich, diese kann allerdings durch eine optionale Dashboard-Seite ergänzt werden, auf die man weitergeleitet wird, wenn der Login-Versuch erfolgreich war.
Bei den HTML Dateien sind folgende Punkte sehr wichtig und sollten angepasst werden, wenn noch nicht geschehen:
- Alle Bilder, oder Files, die für den Aufbau der Website benötigt werden, sollten in Base64 encoded und direkt in die HTML geschrieben werden. Ansonsten werden die Requests für diese Dateien mit 404-NotFound beantwortet und nicht in die Website geladen!
- In der Login-Page müssen die Login-Felder für Benutzername/Login und Passwort angepasst werden. Das Feld für den Benutzername muss 'name="log"' und das Passwort Feld muss 'name="pwd"' als Attribut bekommen oder dementsprechend umbenannt werden. Ansonsten werden die Credentials nicht erkannt.
- Sämtliches CSS muss in Style-Tags innerhalb der HTML stehen und kann nicht von außen geladen werden.
Der HTTPService holt sich Name, Port, HTTP-Response-Header und URLS für die Seiten direkt aus der config.py
.
Der FTPService
nutzt, um eine Verbindung zu einem Angreifer zu ermöglichen, einige twisted
Komponenten. Er erstellt eine twisted.protocols.ftp.FTPFactory
. An dieser registriert er ein twisted.cred.portal.Portal
, an das wiederum eine Instanz der HoneytokenDB
als twisted.cred.checkers.ICredentialsChecker
und das FTPProtocol
als Protokoll übergeben wird. Verbindet sich nun ein Angreifer an den Port, an dem die FTPFactory
lauscht, wird für je einen Angreifer eine Instanz des FTPProtocol
erzeugt, die auf die Befehle des Angreifers reagiert. Erhält das FTPProtocol
im Zuge der erhaltenen Befehle Login-Credentials vom Angreifer, werden diese mit Hilfe der HoneytokenDB
-Instanz auf ihre Validität überprüft.
Das FTPProtocol
erbt von twisted.protocols.ftp.FTP
. Dieses Protokoll implementiert alle Funktionen eines FTP-Servers vollständig. Da unser Protokoll sich nicht wie ein wirklicher FTP-Server verhalten soll, sind die Funktionen von FTP
, die auf Befehle eines Angreifers reagieren, zu einem Großteil überschrieben. Um über FTP zu kommunizieren verbinden sich Client und Server nicht nur über einen Port zur Kommunikation. Es wird zusätzlich ein DTP-Channel zwischen Client und Server geöffnet um eine Datenübertragung zu ermöglichen. Um diese Funktionalitäten nicht implementieren zu müssen, erbt FTPProtocol
von FTP
.
FTPProtocol
kann auf alle gängigen FTP-Befehle sinnvoll reagieren. Es täuscht dem Angreifer ein Dateisystem und dessen Modifikation vor. Dazu verfügt es über eine Instanz von FileSystemParser
. Auch Datentransfers sind über den geerbten DTP-Kanal möglich. So kann ein Angreifer eine Datei hochladen und scheinbar im Dateisystem platzieren. Genauso kann ein Angreifer den Inhalt von Dateien über den DTP-Kanal herunterladen. Hochgeladene Dateien werden im Quarantäne-Ordner unter config.quarantineDir
gespeichert. Es können nur Dateien heruntergeladen werden, die auch wirklich existieren und im Ordner unter config.tokendir
liegen.
Der ListenService
ist ein spezieller Service, der vom ServiceController auf allen (in der config
eingetragenen) Ports ausgeführt wird, auf denen kein anderer Service läuft. Er nimmt jegliche Art von Verbindung an und loggt die empfangenen Daten über log
, sendet dabei jedoch keine Antwort.
Im TCPFlagSniffer.py sind die Klassen TCPDataStruct
und TCPFlagSniffer
enthalten.
TCPDataStruct
ist eine Klasse, welche die für uns relevanten Informationen eines TCP/IP Paketes speichert.
TCPFLagSniffer
ist die eigentliche Service-Klasse.
Es wird ein RAW Socket erstellet, der den gesamten TCP/IP Verkehr auf des Systems mitliest. Es wird nach Paketen mit einem SYN Flag Ausschau gehalten. Die relevanten Daten (IP, Port, Ankunftszeit) werden in einem Dict von TCPDataStruct
Objekten gespeichert. Falls ein Paket von der selben IP und Zielport, mit einem ACK Flag reinkommt, wird der entsprechende Eintrag im Dict gelöscht. Ein Thread Scannt in einen bestimmten Zeitraum die Liste und schickt eine Nachricht (Titel SYN) raus, wenn zwischen Ankunftszeit des Paketes und Scanzeit ein bestimmter Zeitraum vergangen ist (Standard sind 5 Sekunden).
-
database.txt
- Standardpfad für die Logins in der HoneytokenDB. In der Datei befinden sich bereits einige Beispiele für Login-Credentials.
Standardpfad für "auffindbare Dateien" also Dateien, die durch den Filesystemparser ins vorgetäuschte Dateisystem übernommen werden und vom Angreifer erbeutet werden könnnen. (Das Beispiel-Schlüsselpaar ist in der beispielhaften database.txt bereits verzeichnet.)
-
id_rsa
- Ein Beispiel für einen RSA Private Key -
id_rsa.pub
- Ein Beispiel für einen RSA Public Key
Standardpfad für die Ressourcen des HTTPService. Hier finden sich bereits einige aufbereitete und einsatzbereite Seiten.
-
404_login.html
- Eine standard 404-Seite -
\_content.html
- Eine FRITZ!Box 6490 Dashboard-Seite -
\_login.html
- Eine FRITZ!Box Login-Seite -
ghost_content.html
- Eine Management-Seite der Blogging-Plattform Ghost -
ghost_login.html
- Eine Login-Seite der Blogging-Plattform Ghost -
HTMLDictionary.pkl
- Abgespeicherter Zustand deshttpHTMLDictionary
in derconfig.py
-
HTMLLoader.py
- Hilfsskript um HTML-Seiten dynamisch in dieconig.py
zu laden und aus dieser zu sichern -
phpmyadmin_content.html
- Eine phpMyAdmin Dashboard-Seite -
phpmyadmin_login.html
- Eine phpMyAdmin Login-Sete -
wp-admin_content.html
- Eine Wordpress Dashboard-Seite -
wp-admin_login.html
- Eine Wordpress Login-Seite
-
gnuhelp
- Standard Hilfetext von GNU Bash. Wird vom SSHService genutzt. -
helptexts
- Datei mit den Hilfetexten für die Befehle im SSHService. Hier können eigene Texte für weitere Befehle ergänzt werden, die dann im SSHService entsprechend ausgegeben werden.
-
dir_sys.xml
- Ein Beispiel für eine XML-Datei, die ein Windows-Dateisystem repräsentiert. -
unix.xml
- Ein Beispiel für eine XML-Datei, die ein UNIX-Dateisystem repräsentiert. In der config.py als Standard eingetragen.
Standardpfad zum Abspeichern von empfangenen Dateien. Diese werden hier zur weiteren Verarbeitung verwahrt.
pybroker
base64
-
BrokerEndpoint.
listenEndpoint: Broker Endpunkt über den die Nachrichtenübermittlung geschieht -
BrokerEndpoint.
commandsQueue: Nachrichten Queue die alle Nachrichten an dieses Topic in einer Queue speichert -
BrokerEndpoint.
peerings: Enthält ein peering Objekt des Honeypots. Wird gebraucht um sich von diesen Objekt zu unpeeren
getCommandMessage()
Holt das erste Element der commandsQueue
und gibt es zurück
Returns:
-- Broker.Message
startListening()
Startet das lauschen auf den in der config
definierten IP/Port
sendLogs(jsonString)
Sendet den jsonString als Broker.Message
an das logging topic
Parameter:
-- jsonString: Ein String in JSON-Format.
peerTo(ip, port)
Peert den Honeypot zu der angegebenen ip, port.
Setzt peerings
auf die Ip, Port und peering Objekt
Parameter:
-- ip: (str) IP zu der gepeert werden soll
-- port: (int) Port auf den gepeert werden soll
unpeer(peeringObj=None)
Unpeert den Honeypot. Wenn kein peeringObj
gesetzt ist, wird das erste der peerings
liste genommen
Parameter:
-- peeringObj: Peering Objekt. Die jeweilige zugehörige Verbindung wird getrennt.
sendMessageToTopic(topic, msg)
Sendet an ein bestimmtes topic eine Nachricht
Parameter:
-- topic: (str) Topic an das gesendet werden soll
-- msg: (str, int, float, double) Nachricht die gesendet werden soll
sendFile(filepath)
Sendet eine Datei an das files
topic.
Parameter:
-- filepath: (str) Pfad zur Datei
os
re
xml.etree.ElementTree
-
FilesystemParser.
xml_path: Pfad zu XML-Datei -
FilesystemParser.
tree: Aus Datei in self.xml_path eingelesener ElementTree -
FilesystemParser.
root: Root-Element von self.tree -
FilesystemParser.
current_pos: Aktuelle Position in self.tree -
FilesystemParser.
honeytoken_directory: Pfad zu den Honeytokenfiles, ausconfig.py
-
FilesystemParser.
cd_pattern: Regex für cd-Befehle -
FilesystemParser.
mkdir_pattern: Regex für mkdir-Befehle -
FilesystemParser.
touch_pattern: Regex für touch-Befehle -
FilesystemParser.
ls_pattern: Regex für ls-Befehle -
FilesystemParser.
user_path: Pfad zur User-Directory -
FilesystemParser.
mode: Je nach verwendetem XML 'DOS' oder 'UNIX'
get_position(path)
Gibt die Position im self.tree am Pfad path zurück.
Parameter:
-- path: Pfad (str)
Returns:
-- Position (list)
get_path(position)
Gibt den Pfad für eine Position im self.tree.
Parameter:
-- position: Position (list)
Returns:
-- path: Pfad (str)
get_element(position)
Gibt Element des self.tree an der Position position.
Parameter:
-- position: Position (list)
Returns:
-- Element (xml.etree.Element)
get_absolute_path(rel_path)
Konvertiert einen absoluten oder relativen Pfad zu einem absoluten Pfad.
Parameter:
-- rel_path: Pfad (str)
Returns:
-- Pfad (str)
tree_contains(file_name)
Überprüft ob file_name irgendwo im self.tree existiert.
Parameter:
-- file_name: Dateiname/Ordnername (str)
Returns:
-- True/False (bool)
add_honeytoken_files()
Fügt die Dateien aus self.honeytoken_directory zum self.tree hinzu, wenn dort noch kein gleichnamiges Element enhalten ist.
get_current_path()
Gibt den aktuellen Standort im self.tree als String.
Returns:
-- Pfad (str)
get_formatted_path()
Gibt den aktuellen Standort im self.tree als formatierten String (platform adjusted).
Returns:
-- Pfad (str)
mkdir(path)
Erstellt ein neues 'dir'- Element im self.tree an der Position path.
Parameter:
-- path: Pfad (str)
touch(path)
Erstellt ein neues 'file'- Element im self.tree an der Position path.
Parameter:
-- path: Pfad (str)
create(path, tag)
Hilfsfunktion für touch(path) und mkdir(path). Erstellt einen neues Element-Knoten im self.tree an der Position path mit Tag tag.
Parameter:
-- path: Pfad (str)
-- tag: Tag (str)
ls(path='')
Gibt die Namen aller Kindknoten im self.tree von self.current_pos aus als String.
Parameter:
-- path: Pfad (str)
Returns:
-- Namen aller Kindknoten, getrennt mit '\n' (str)
cd(path)
Ändert self.current_pos im self.tree zum Pfad path.
Parameter:
-- path: Pfad (str)
Returns:
-- Im Falle dass path nicht existiert: Fehlermeldungs-String (str)
valid_directory(path)
Überprüft ob path von self.current_pos aus zu einem Element mit 'dir' als Tag führt.
Parameter:
-- path: Pfad (str)
-- tag: Tag (str)
Returns:
-- True/False (bool)
valid_file(path)
Überprüft ob path von self.current_pos aus zu einem Element mit 'file' als Tag führt.
Parameter:
-- path: Pfad (str)
Returns:
-- True/False (bool)
valid_path(path, tag)
Hilfsfunktion für valid_directory und valid_file. Überprüft ob path von self.current_pos aus zu einem Element mit tag als Tag führt.
Parameter:
-- path: Pfad (str)
-- tag: Tag (str)
Returns:
-- True/False (bool)
delete(path)
Sucht nach einem Element von self.current_pos aus und löscht es wenn es existiert.
Parameter:
-- path: Pfad (str)
move(sourcepath, targetpath)
Bewegt das Element im self.tree, das unter sourcepath liegt, an die Position targetpath.
Parameter:
-- sourcepath: Pfad des Elements davor (str)
-- targetpath: Pfad des Elements danach (str)
Returns:
-- Im Falle dass Pfade nicht valide: Fehlermeldungs-String (str)
rename(from_path, to_name)
Ändert den Namen eines Elements von from_path zu to_name. Verwendet dazu move.
Parameter:
-- from_path: Pfad (str)
-- to_name: Tag (str)
Returns:
-- Im Falle dass Pfade nicht valide: Fehlermeldungs-String (str)
cat(path)
Gibt es an der Position path im self.tree ein Element dessen Namen auch der Name einer Datei in self.honeytoken_directory ist, wird der Inhalt dieser Datei als String zurückgegeben.
Parameter:
-- path: Pfad zum Element (str)
Returns:
-- Inhalt der entsprechenden Datei (str)
threading
time
json
os
os.path.isfile
os.path.join
xml.etree.ElementTree
-
HoneyAdapter.
controller: Instanz von ServiceController -
HoneyAdapter.
start: 'active' wenn Honeygrove inkl. aller Services gestartet werden soll (ausconfig.py
) -
HoneyAdapter.
lock: Instanz von threading.Lock
Lauscht auf eingehende Nachrichten am BrokerEndpoint. Wertet die Nachrichten aus und nimmt am Honeygrove die entsprechenden Änderungen vor.
command_message_loop()
Die Methode startet eine Schleife, in der der Honeyadapter alle 0.1 Sekunden am BrokerEndpoint nach neuen Messages fragt. Erhält der Honeyadapter so eine Message wird diese an handle_messages weitergereicht.
hearbeat()
Die Methode startet eine Schleife, in der der Honeyadapter alle 60 Sekunden einen Heartbeat loggt.
handle_messages(msgs)
In dieser Methode wertet der Honeyadapter die erhaltenen Befehle aus. Je nach Befehl ruft er die entsprechenden Methoden an self.controller auf, verändert Dateien in resources-Modul oder updated config.py
.
Parameter:
-- msgs: Zweifach geschachtelte Liste mit Broker-Message (list)
os
tempfile
shututil
random
zope.interface.implementer
twisted.cred.error
twisted.cred.credentials
twisted.cred.checkers.ICredentialsChecker
twisted.conch.error
twisted.conch.ssh.keys
twisted.internet.defer.Deferred
twisted.python.failure
-
HoneytokenDataBase.
filepath: Pfad zur Datei mit den validen Credentials -
HoneytokenDataBase.
temp_copy_path: Pfad zur Arbeitskopie der Datei bei self.filepath -
HoneytokenDataBase.
sep: Separator im Credentials-Format -
HoneytokenDataBase.
scopeField: Position des Scope-Strings im Credentials-Format -
HoneytokenDataBase.
usernameField: Position des Usernames im Credentials-Format -
HoneytokenDataBase.
passwordField: Position des Passworts im Credentials-Format -
HoneytokenDataBase.
publicKeyField: Position des PublicKeys im Credentials-Format -
HoneytokenDataBase.
allServices: Liste aller Service-Namen -
HoneytokenDataBase.
credentialInterfaces: Liste aller unterstützten Credential-Interfaces -
HoneytokenDataBase.
servicename: Name des Services, der diese Instanz der HDB verwendet -
HoneytokenDataBase.
randomAcceptProbability: Ausconfig.py
, sonst standardmäßig 0.1
Implementiert twisted.cred.checkers.ICredentialsChecker
. Überprüft Login-Credentials auf ihre Validität.
create_temporary_copy(path)
Erstellt eine Kopie der Datei path als temp-File.
Parameter:
-- path: Pfad zur zu kopierenden Datei (str)
Returns:
-- Pfad zur temporären Datei (str)
getActual(user, pw, isKey=False)
Gibt eine Liste der Services, für die user und pw valide Login-Credentials sind.
Parameter:
-- user: Username (str)
-- pw: Passwort (str)
-- isKey: True wenn pw ein SSH-Key ist (bool)
Returns:
-- Liste von Servicenamen (list)
load_credentials()
Lädt die Credentials aus der Datei mit validen Credentials (self.filepath). Ist diese in Benutzung, dann aus der Arbeitskopie(self.temp_copy_path).
Returns:
-- Liste aus Tupeln valider Credentials (list)
readLinesFromFile(file)
Hilfsfunktion für load_credentials(). Liest ein File-Objekt, das Credentials enthält, aus.
Parameter:
-- file: Auszulesendes File-Objekt(file)
Returns:
-- Liste aus Tupeln valider Credentials (list)
writeToDatabase(user, pw, services)
Schreibt die übergebenen Credentials in die Credentials-Datei(self.filepath).
Parameter:
-- user: Username der Credentials (str)
-- pw: Passwort der Credentials (str)
-- services: Services für die die Credentials valide sind. (str)
getUser(username)
Gibt Username, Passwort und Key für einen Usernamen zurück, wenn es Credentials mit Usernamen username gibt, die für self.servicename valide sind.
Parameter:
-- username: Username (str)
Returns:
-- u, p, k: Username, Passwort, Key ((str), (str), (str))
password_match(matched, username)
Wenn matched == True gibt die Funktion username zurück. Wird als Callback-Funktion von requestAvatarId() an ein twisted.internet.defer.Deferred
übergeben.
Parameter:
-- matched: True wenn die vom Angreifer übergebenen Credentials valide waren. (bool)
-- username: Username (str)
Returns:
-- username: Username (str)
requestAvatarId(c)
Hauptmethode der HoneytokenDataBase. Diese Methode wird vom twisted.cred.portal.Portal
aufgerufen sobald dieses Credentials von einem Angreifer erhalten hat.
Die Methode überprüft die Credentials auf ihre Validität und liefert je nach Ergebnis der Überprüfung ein entsprechendes twisted.internet.defer.Deferred
-Objekt.
Parameter:
-- c: Credentials (ICredentials)
Returns:
-- deferred: Deferred-Objekt mit Ergebnis des Cred-Checks (twisted.internet.defer.Deferred)
twisted.internet.reactor
threading
-
ServiceController
.serviceList: Liste der instanziierten Subklassen vonServiceBaseModel
-
ServiceController
.serviceDict: Dict, in dem der Name eines Services der Key und die jeweilige Instanz der Wert ist -
ServiceController
.listen: Instanz vom Listen Service für schnelleren Zugriff -
ServiceController
.runnigServicesDict: Dict, in dem Name des Services der Key und die die Instanz der Wert ist. Enthält nur die Services, die auch gestartet wurden.
class ServiceController.ServiceController()
Sucht alle Unterklassen von ServiceBaseModel
und erstellt jeweils eine Instanz.
Erstellt aus der Liste von Instanzen ein Dictionary.
startService(name)
Startet den Service wenn möglich. Stoppt den ListenService
automatisch auf den Port wo der neue Service starten will.
Parameter
-- name: Name des Services (str)
Returns:
-- True wenn der Service gestartet werden konnte. False wenn nicht. (boolean)
-- stopService(name)
Stoppt den Service wenn möglich. Startet den ListenService
automatisch auf den Port wo der neue Service stoppt.
Parameter
-- name: Name des Services (str)
Returns:
-- True wenn der Service gestoppt werden konnte. False wenn nicht. (boolean)
json
datetime
write(message)
Hilfsmethode zum Schreiben in die Logdatei.
Parameter:
-- message: Die zu schreibende Nachricht (str)
info(message)
Methode zum Loggen von administrativen und informativen Meldungen.
Parameter:
-- message: Die zu loggende Nachricht (str)
err(message)
Methode zum Loggen von Fehlermeldungen.
Parameter:
-- message: Die zu loggende Fehlermeldung (str)
*defer_login(result, args)
Wrapper um login
als Callback für Deferred
Nutzen zu können.
Parameter:
-- result: Ergebnis des vorherigen Callbacks
-- args: Argumente für login
Returns:
-- Reicht result
einfach weiter
login(service, ip, port, successful, user, key=None, actual=None)
Methode zum Loggen von Login-Versuchen.
Parameter:
-- service: Name des Services, an dem der Versuch stattfand (str)
-- ip: IP des Angreifers (str)
-- port: Port, auf dem der Service läuft (str)
-- successful: Ob der Versuch Erfolgreich war (bool)
-- user: Username des Versuchs (str)
-- key: Passwort oder Key des Versuchs (str)
-- actual: Services, für welche der Login gültig gewesen wäre. Nützlich um die Verwendung eines Honeytoken an verschiedenen Services zu ermitteln. (list)
request(service, ip, port, request, user=None, request_type=None)
Methode zum Loggen von Anfragen.
Parameter:
-- service: Name des Services, an den die Anfrage gesendet wurde (str)
-- ip: IP des Angreifers (str)
-- port: Port, auf dem der Service läuft (str)
-- request: Inhalt der Anfrage (str)
-- user: Username (str)
-- request_type: HTTP GET oder POST (str)
response(service, ip, port, request, user=None, statusCode=None)
Methode zum Loggen von Antworten.
Parameter:
-- service: Name des Services, der die Antwort sendet (str)
-- ip: IP des Angreifers (str)
-- port: Port, auf dem der Service läuft (str)
-- response: Inhalt der Antwort (str)
-- user: Username (str)
-- statusCode: Der gesendete Statuscode (z.B. HTTP) (str)
file(service, ip, filename, filepath=None, user=None)
Methode zum Loggen von empfangenen Dateien. Sendet die Datei (falls gespeichert) zusätzlich zur Auswertung über BrokerEndpoint
and das "files"-Topic.
Parameter:
-- service: Name des Services, an den die Datei gesendet wurde (str)
-- ip: IP des Angreifers (str)
-- filename: Name der empfangenen Datei (str)
-- filepath: Pfad zur empfangenen Datei, falls diese gespeichert wurde (str)
-- user: Username (str)
tcp_syn(ip, port)
Methode zum Loggen von einzelnen empfangenen SYN-Paketen (z.B. Portscan).
Parameter:
-- ip: IP des Angreifers (str)
-- port: Port, der das Paket empfangen hat (str)
heartbeat()
Methode zum Senden einer Heartbeat-Message über Broker.
abc.ABC
abc.AbstractMethod
twisted.internet.protocol.Factory
-
ServiceBaseModel
._fService: Instanz von Factory -
ServiceBaseModel
._fService.clients: Leeres Python-Dict -
ServiceBaseModel
._port: None -
ServiceBaseModel
._stop: None -
ServiceBaseModel
._name: None -
ServiceBaseModel
._status: None -
ServiceBaseModel
._transport: None
Prototyp aller Services. Wird von allen Services implementiert.
startService()
Abstrakte Methode. Wird von Subklassen implementiert.
stopService()
Abstrakte Methode. Wird von Subklassen implementiert.
changePort(port)
Ändert self.port zu port und startet den Service am neu gesetzten Port. Ist port bereits besetzt wird der Service nicht gestartet.
Parameter:
-- port: Ein Port oder eine List von Ports (int oder list)
os
re
subprocess
time
datetime
os.path
random
urllib
cryptography.hazmat.backends
cryptography.hazmat.primitives
twisted.conch
twisted.conch.ssh
twisted.cred.portal
twisted.internet
twisted.python
-
SSHService.
_name: Name des Service (ausconfig.py
) -
SSHService.
_port: Port an dem der Service läuft bzw. nach dem Starten laufen soll (ausconfig.py
) -
SSHService.
_fService: Instanz vonSSHFactory
mit eigens gesetztemssh-userauth
Service -
SSHProtocol.
user: Instanz vonSSHAvatar
, die den angemeldeten User repräsentiert -
SSHProtocol.
userName: Username des angemeldeten Users -
SSHProtocol.
name: Name des Service (für Logging) -
SSHProtocol.
port: Port des Service (für Logging) -
SSHProtocol.
_parser: Instanz vonFilesystemParser
-
SSHProtocol.
userIP: IP des angemeldeten Users -
SSHProtocol.
l: Referenz auf den Logger -
SSHProtocol.
current_dir: Das aktuelle Verzeichnis im echten System (für diessh_real_shell
Option)
Implementiert das ServiceBaseModel
, managt also die Verfügbarkeit des SSHProtocol
. Registriert eine SSHFactory
beim Reactor
.
Erbt von twisted.conch.recvline.HistoricRecvLine
und stellt damit ein Terminal dar. Ist verantwortlich für die Behandlung von Anfragen und die Generierung von Antworten.
connectionMade()
Initialisiert die Terminal-Session.
getCommandFunc(cmd)
Holt zu einem Empfangenen Befehl die passende "ssh_" Methode.
Parameter:
-- cmd: Der Empfangene Befehl (str)
Returns:
-- Die entsprechende Function (function)
get_help(cmd)
Holt aus den SSH-Ressourcen den Hilfetext zu einer Funktion.
Parameter:
-- cmd: Der Befehl, für den die Hilfe geholt werden soll (str)
Returns:
-- Den Hilfetext der Funktion (str)
handle_arguments(args)
Hilfsfunktion um Argumente der Form "pfad -optns
" in den Pfad und eine Liste von Buchstaben zu zerlegen.
Parameter:
-- args: Pfad und Argumente (iterable)
Returns:
-- Tupel aus Pfad und Liste von Argumenten (str, list)
lineReceived(line)
Wird aufgerufen, wenn ein Befehl ankommt. Hier wird entschieden, ob der Befehl lokal oder "fake" ausgeführt wird.
Parameter:
-- line: Die Zeile, die bei uns ankommt (bytes)
Returns:
-- Pfad (str)
-- Argumente (list)
print(lines, log=None)
Schreibt eine Zeile oder eine Liste von Zeilen auf das Terminal und loggt dabei.
Parameter:
-- lines: Die zu schreibende(n) Zeile(n) (list), (str)
-- log: Wenn dieser Parameter übergeben wird, wird statt der eigentlich gesendeten Nachricht dieser Wert geloggt (str)
showPrompt()
Zeigt den Prompt im Terminal des Angreifers.
*ssh_cat(args)
Zeigt den Inhalt einer Datei im vorgetäuschten Dateisystem.
Parameter:
-- args: Argumente für cat (iterable)
Returns:
-- Antwort (Meldung oder Dateiinhalt) (str)
*ssh_cd(args)
Wechselt das Verzeichnis im vorgetäuschten Dateisystem.
Parameter:
-- args: Argumente für cd (iterable)
Returns:
-- Eventuell eine Meldung (str)
ssh_clear()
Leert das Terminal
*ssh_echo(args)
Gibt zurück was eingegeben wurde.
Parameter:
-- args: Argumente die zurückgegeben werden sollen (iterable)
Returns:
-- Alles was in args
steht (str)
ssh_exit()
Stößt das beenden der Session an.
ssh_help(cmd='')
Gibt (wenn vorhanden) den Hilfetext für den Befehl, wenn kein Befehl angegeben wurde den allgemeinen Hilfetext.
Parameter:
-- cmd: Befehl für den die Hilfe gezeigt werden soll (str)
Returns:
-- Meldung, Hilfe zu cmd
oder allgemeine Hilfe (str)
-- Wenn allgemeine Hilfe "Help text
" um das Log zu entlasten (str)
*ssh_ll(args)
Alias (Wrapper) für ls -l
.
Parameter:
-- args: Argumente für ls (iterable)
Returns:
-- Was von ls zurückgegeben wird (str)
*ssh_ls(args)
Gibt den Inhalt des aktuellen Verzeichnisses im vorgetäuschten Dateisystem aus.
Parameter:
-- args: Argumente für ls. Wenn "a" nicht dabei ist, werden Dateien und Ordner mit Präfix "." ignoriert. (iterable)
Returns:
-- Ordnerinhalt (list)
-- "ls Text
" um log zu entlasten (str)
*ssh_mkdir(args)
Erstellt ein Verzeichnis im vorgetäuschten Dateisystem.
Parameter:
-- args: Argumente für mkdir (iterable)
Returns:
-- Eventuell Meldung von FilesystemParser
(str)
*ssh_mv(args)
Verschiebt eine Datei im vorgetäuschten Dateisystem.
Parameter:
-- args: Argumente für mv, die ersten beiden werden als source und destination behandelt (iterable)
Returns:
-- Eventuell Meldung von FilesystemParser
(str)
ssh_pwd()
Gibt den aktuellen Pfad im vorgetäuschten Dateisystem.
Returns:
-- Aktueller Pfad (str)
*ssh_rm(args)
Löscht etwas im vorgetäuschten Dateisystem. Wenn "r" und "f" als Argumente angegeben wurden und "/" der Pfad ist, wird die Verbindung beendet. Wenn ein Verzeichnis als Pfad angegeben wurde und "r" nicht in den Argumenten ist, wird eine Meldung ausgegeben.
Parameter:
-- args: Argumente für rm (iterable)
Returns:
-- Eventuell Meldung (str)
*ssh_touch(args)
Erstellt eine Datei im vorgetäuschten Dateisystem.
Parameter:
-- args: Argumente für touch, wird als Pfad behandelt (iterable)
Returns:
-- Eventuelle Meldung vom FilesystemParser
(str)
*ssh_wget(args)
Lädt eine Datei herunter, versendet sie zur Analyse und speichert sie im Quarantäneverzeichnis. Die Datei wird außerdem im vorgetäuschten Dateisystem angezeigt.
Parameter:
-- args: Argumente für wget, wird als URL behandelt (iterable)
ssh_whoami()
Zeigt den Username des aktuellen Users an.
Returns:
-- Username (str)
Erbt von twisted.conch.ssh.session.SSHSession
und repräsentiert einen SSH Channel. Bestimmt, was als nächstes geschieht (Shell, Command Execution, ...)
execCommand(pp, cmd)
Wird aufgerufen, wenn ein Angreifer ohne Shell einen Befehl ausführen will. Loggt den Befehl und weist den Angreifer ab.
Parameter:
-- pp: das Transport Protocol (twisted.internet.protocol.ProcessProtocol) -- cmd: der gewünschte Befehl (bytes)
getPty(terminal, windowSize, attrs)
Wird aufgerufen, wenn der Angreifer ein Pseudo-Terminal fordert. Dies wird ignoriert.
openShell(transport)
Wird aufgerufen, wenn ein Angreifer eine Shell fordert. Verknüpft den transport
mit einem SSHProtocol
.
Parameter:
-- transport: der Transportchannel zum Angreifer (twisted.internet.protocol.ProcessProtocol)
*windowChanged(args)
Wird aufgerufen, wenn sich die Fenstergröße beim Angreifer ändert. Wird ignoriert, könnte aber für Formatierungszwecke genutzt werden.
Parameter:
-- args: die neue Fenstergröße (tuple)
Erbt von SSHService.SSHSession
und ist das Twisted Realm für SSH, d.h. es ist für die Vergabe von Avataren zuständig.
*requestAvatar(avatarId, mind, interfaces)
Gibt einen SSHAvatar mit dem jeweiligen Username und Transport etc. Siehe Dokumentation von Twisted Cred.
Parameter:
-- avatarId: der Servcie, für den der Avatar gilt (bytes) -- mind: der Nutzername (bytes) -- *interfaces: Interfaces, die der Avatar implementieren soll
Returns:
-- Eines der Interfaces (zope.interface.interface)
-- Exemplar eines SSHAvatar
(SSHService.SSHAvatar)
-- Funktion bei Logout (function)
Erbt von twisted.conch.avatar.ConchUser
und repräsentiert einen User für SSH. Siehe Dokumentation von Twisted Cred.
Parameter:
-- Username: Name des Users (bytes) -- service: Service, für den der User gilt (bytes)
Erbt von twisted.conch.ssh.userauth
und ist damit ein Service für die SSHFactory, der Anmeldedaten überprüft. Nur notwendig, um Anmeldeversuche umfassend loggen zu können.
ssh_USERAUTH_REQUEST(packet)
Wird aufgerufen, wenn der Angreifer sich Authentifizieren möchte.
Parameter:
-- packet: das Empfangene Paket, welches den User, den gewünschten Service, die Authentifizierungsmethode und die Login-Daten beinhaltet (bytes)
Returns:
-- Ein Deferred, welcher entsprechende Callbacks für erfolgreiche oder abgelehnte Anmeldung gesetzt hat (twisted.internet.defer.Deferred)
time
builtins.print
datetime.datetime
wsgiref.handlers.format_date_time
twisted.conch.avatar
twisted.cred.error
twisted.internet.reactor
twisted.internet.defer.Deferred
twisted.internet.protocol.Protocol
twisted.python.failure
-
HTTPService.
now: Hält die aktuelle Zeit -
HTTPService.
timeNow: Hält die aktuelle Zeit formatiert -
HTTPService.
responseHeadersOkStatus: Beinhaltet HTTP-Get response header -
HTTPService.
responseHeadersForbidden: Beinhaltet HTTP-Get response header -
HTTPService.
responseHeadersNotFound: Beinhaltet HTTP-Get response header -
HTTPService.
okStatus: Hält den HTTP-OK Status -
HTTPService.
forbiddenStatus: Hält den HTTP-Forbidden Status -
HTTPService.
notFoundStatus: Hält den HTTP-NotFoundStatus Status -
HTTPService.
htdb: Hält die HTTP Login Kombinationen -
HTTPService.
port: Hält den aktuellen Port -
HTTPService.
resourceLocation: Gibt den Pfad zu den HTML Dateien an -
HTTPService.
supportedSites: Gibt an welche HTML Seiten zu erreichen sind -
protokoll.
state: Gibt an in welchen Zustand sich das Protokoll befindet -
protokoll.
peerOfAttacker: Enthält Informationen über den Angreifer -
protokoll.
page: Gibt die aktuelle Seite an -
protokoll.
path: Gibt den aktuellen Pfad zu den Honeygrove Ressourcen an -
protokoll.
attackingSite: Hält Informationen zur login Seite -
protokoll.
loginSuccessfulSite: Hält Informationen zur dashboard Seite -
protokoll.
requestType: Gibt an Ob es sich um POST oder GET handelt -
protokoll.
supportedSites: Hält Informationen zu den erreichbaren Seiten an
Implementiert das ServiceBaseModel
, managt also die Verfügbarkeit des protokoll
.
Erbt von twisted.internet.protocol.Protocol
und implementiert ein eigenes, HTTP-ähnliches Protokoll. Empfängt Daten,
interpretiert sie und antwortet.
connectionMade()
Wenn eine TCP Verbindung über den HTTP-Port erstellt wurde, wird die Aktuelle Verbindung zum Dict hinzugefügt.
dataReceived(data)
Wenn der Angreifer Daten sendet, werden diese Daten interpretiert. Durch die gesendeten Daten kann die Art der Anfrage des Angreifers ausgelesen werden. So kann z.B. zwischen GET und POST Anfragen unterschieden und darauf reagiert werden.
Parameter:
-- data: die empfangenen Daten (bytes)
connectionLost(reason)
Wenn die Verbindung unterbrochen/aufgegeben wird, wird hier der Grund ausgegeben
Parameter:
-- reason: Der grund des Verbindungsabbruches (str)
errorBack(f)
Bei einem Unauthorisierten Login-Versuch, wird die Error Message von der HoneytokenDB getraped und der Fehlerfall behandelt
Parameter:
-- f: failure zum trappen
Erbt von twisted.conch.avatar.ConchUser und repräsentiert einen User für HTTP. Siehe Dokumentation von Twisted Cred.
checkPassword(password)
Überprüft ein Passwort mit der HoneytokenDB.
Parameter:
-- password: das eingegebene Passwort vom User
Returns:
-- True, wenn das Passwort richtig ist, ansonsten False
random
datetime.datetime
twisted.protocols.ftp
twisted.cred.portal.Portal
-
FTPService.
_name: Name des FTP-Services (aus config.py) -
FTPService.
_port: Port an dem der Service läuft bzw. nach dem Starten laufen soll. -
FTPService.
_fService: Instanz von FTPFactory -
FTPService.
protocol: Instanz von FTPProtocol -
FTPService.
credchecker: Instanz von HoneytokenDB -
FTPProtocol.
overwritten_commands_whitelist: Liste aller vom Protokoll überschriebenen FTP-Funktionen -
FTPProtocol.
inherited_commands_whitelist: Liste aller FTP-Funktionen, die vontwisted.protocols.ftp.FTP
geerbt werden -
FTPProtocol.
inherited_responses: Dict unserer individuellen Antworten auf die geerbten FTP-Funktionen -
FTPProtocol.
'honeytokenDirectory: Dateipfad zum Ordner mit den Honeytoken-Dateien (ausconfig.py
) -
FTPProtocol.
receivedDataDirectory: Pfad zum Ordner für erhaltene Dateien (ausconfig.py
) -
FTPProtocol.
lastmodified: Zeit der Erstellung des Protokolls -
FTPProtocol.
user: Aktueller Name des Users -
FTPProtocol.
_parser: Instanz von FileSystemParser -
FTPProtocol.
l: Instanz von log.py
Implementiert das ServiceBaseModel
, kennt das FTPProtocol
und übergibt es an eine twisted.protocols.ftp.FTPFactory
. Registriert die Factory beim Reactor
.
Erbt von twisted.protocols.ftp.FTP
. Reagiert auf eingehende FTP-Befehle entsprechend mit der Modifikation eines simulierten Dateisystems. Generiert erwartete (Standard-)Antworten.
ftp_PWD()
Gibt die aktuelle Position im simulierten Dateisystem zurück.
Returns:
-- Entsprechende FTP-Antwort (tuple)
ftp_CWD(path)
Navigiert im simulierten Dateisystem zum angegebenen Pfad.
Parameter:
-- path: Pfad zu dem navigiert wird (str)
Returns:
-- Entsprechende FTP-Antwort (tuple), wenn der Pfad valide ist
oder
-- (twisted.internet.defer.fail
), wenn der Pfad invalide ist
ftp_DELE(path)
Ist path ein valider Pfad im simulierten Dateisystem, wird die Datei oder der Ordner mit dem Pfad path im simulierten Dateisystem entfernt.
Parameter:
-- path: Pfad der zu löschenden Datei. (str)
Returns:
-- Entsprechende FTP-Antwort (str), wenn der Pfad valide ist
oder
-- (twisted.internet.defer.fail
), wenn der Pfad invalide ist
ftp_LIST(path)
Ist path ein valider Pfad zu einem Ordner im simulierten Dateisystem werden die Namen aller im Ordner enthaltenen Dateien über self.DTPInstance versendet.
Parameter:
-- path: Pfad des zu listenden Ordners. (str)
Returns:
-- Entsprechende FTP-Antwort (tuple), wenn der Pfad valide ist
oder
-- (twisted.internet.defer.fail
), wenn der Pfad invalide ist
ftp_MDTM(path)
Ist path ein valider Pfad zu einer Datei im simulierten Dateisystem wird self.lastmodified zurückgegeben.
Parameter:
-- path: Pfad der Datei zu der der letzte Modifikationszeitpunkt gefragt ist. (str)
Returns:
-- Entsprechende FTP-Antwort (tuple), wenn der Pfad valide ist
oder
-- (twisted.internet.defer.fail
), wenn der Pfad invalide ist
ftp_MKD(name)
Befindet sich im simulierten Dateisystem noch kein Ordner mit Namen name wird dieser hinzugefügt.
Parameter:
-- name: Pfad eines zu erstellen Ordners. (str)
Returns:
-- Entsprechende FTP-Antwort (tuple), wenn der Pfad valide ist
oder
-- (twisted.internet.defer.fail
), wenn der Pfad invalide ist
ftp_RMD(path)
Ist path ein valider Pfad zu einem Ordner im simulierten Dateisystem wird dieser Ordner entfernt.
Parameter:
-- path: Pfad eines zu erstellen Ordners. (str)
Returns:
-- Entsprechende FTP-Antwort (tuple), wenn der Pfad valide ist
oder
-- (twisted.internet.defer.fail
), wenn der Pfad invalide ist
ftp_RNTO(toName)
Über die geerbte Methode ftp_RNFR(fromName) wurde vor Aufruf dieser Methode eine Datei oder ein Ordner gewählt, die oder der umbenannt werden soll. In dieser Methode wird die entsprechende Datei oder der entsprechende Ordner zu toName umbenannt, sofern toName noch nicht vergeben und die gewählte Datei bzw. der gewählte Ordner valide im simulierten Dateisystem ist.
Parameter:
-- toName: Neuer Name der Datei/ des Ordners. (str)
Returns:
-- Entsprechende FTP-Antwort (tuple), wenn toName valide ist
oder
-- (twisted.internet.defer.fail
), wenn toName invalide ist
ftp_SIZE(path)
Ist path ein valider Pfad im simulierten Dateisystem gibt die Funktion in der Antwort eine zufällige Zahl zwischen 20000 und 5000000 für Ordner bzw zwischen 100 und 30000 für Dateien zurück.
Parameter:
-- path: Pfad des Ordners oder der Datei dessen/deren Größe gefragt ist. (str)
Returns:
-- Entsprechende FTP-Antwort (tuple), wenn der Pfad valide ist
oder
-- (twisted.internet.defer.fail
), wenn der Pfad invalide ist
ftp_STOR(path)
Die Funktion empfängt über den DTP-Channel eine Datei und speichert diese in self.receivedDataDirectory. Ist path noch kein valider Pfad im simulierten Dateisystem, wird dort eine Datei hinzugefügt.
Parameter:
-- path: Name der Datei die hochgeladen werden soll. (str)
Returns:
-- Entsprechende FTP-Antwort (tuple), wenn der Pfad valide ist
(*1)
ftp_RETR(path)
Ist path ein valider Pfad zu einer Datei im simulierten Dateisystem und liegt eine Datei des gleichen Namens in .honeytokenDirectory, wird die Datei aus .honeytokenDirectory über den DTP-Channel versandt.
Parameter:
-- path: Name der Datei die heruntergeladen werden soll. (str)
Returns:
-- Entsprechende FTP-Antwort (tuple), wenn der Pfad valide ist
(*1)
processCommands(cmd, params)
Die Funktion wird aufgerufen sobald ein Befehl durch den Angreifer eingeht. Sie analysiert den Befehl und ruft die entsprechenden Funktionen an ihrer Klasse auf.
Parameter:
-- cmd: Übergebener FTP-Befehl (str)
-- params: Übergebene Parameter zu dem Befehl (str)
Returns:
-- Entsprechende FTP-Antwort
(*1)
*(1) Bei den hiermit markierten Funktionen sind große Stücke aus den gleichnamige Methoden aus der Superklasse twisted.protocols.ftp.FTP
übernommen. Da aber doch Einiges in unserem System signifikant anders laufen muss, konnten sie nicht geerbt werden und es mussten auf diese Art kleinere aber notwendige Teile überschreiben.
twisted.internet
twisted.internet.error
twisted.internet.protocol
-
ListenService.
_name: Name des Service (ausconfig.py
) -
ListenService.
_port: Ports an denen der Service läuft bzw. laufen darf (ausconfig.py
) -
ListenService.
_fService: Instanz vonFactory
-
ListenService.
_transport: Dict zum Erfassen dertransport
s -
ListenService.
_stop: Gibt an, ob der Service gestoppt ist -
ListenService.
_active: Gibt an, ob der Service aktiv ist
Implementiert das ServiceBaseModel
, kann sein Protokoll aber anders als andere Services auf viele verschiedene Ports gleichzeitig legen.
startService()
Startet den Service auf allen konfigurierten Ports. Ignoriert Ports, auf denen nicht gestartet werden kann. Fügt die transport
s in _transport
ein.
startOnPort(port)
Startet den Service auf einem bestimmten Port. Ignoriert, wenn auf diesem nicht gestartet werden kann. Fügt den transport
in _transport
ein.
Parameter:
-- port Der Port auf dem gestartet werden soll (int)
stopOnPort(port)
Stoppt den Service auf einem bestimmten Port. Löscht den transport
aus _transport
.
Parameter:
-- port Der Port auf dem nicht mehr gelauscht werden soll (int)
stopService()
Stoppt den Service auf allen laufenden Ports.
Erbt von twisted.internet.protocol
und ist damit ein Verbindungsprotokol auf relativ niedriger Ebene. Seine Einzige Aufgabe ist das Aufzeichnen von allen Daten, die es empfängt.
dataReceived(data)
Wird aufgerufen wenn Daten empfangen werden. Loggt die Daten und macht weiter nichts.
Parameter:
-- data: Die empfangenen Daten (bytes)
struct
socket
threading
time
-
TCPDataStruct
.sourceIP Die IP woher das Packet kommt -
TCPDataStruct
.destPort Der Port wohin das Packer soll -
TCPDataStruct
.inTime Der Zeitpunkt der Ankunft des Pakets -
TCPFlagSniffer
.synConnections Das Dict welches dieTCPDataStruct
Instanzen hält -
TCPFlagSniffer
.synCpnnectionLock Eine Semaphore, die den Zugang zumSynConnections
Dict regelt -
TCPFlagSniffer
.startThread Der Thread welcher den Service startet -
TCPFlagSniffer
.synScannThread Der Thread der in regelmäßigen Abständen dassynConnection
Dict nach den Eingangszeiten der Pakete scannt -
TCPFlagSniffer
.rSock Der RAW Socket welcher alle TCP/IP PAkete an das System abfängt
####class TCPFlagSnifer.TCPFlagSniffer()
Implementiert ServiceBaseModel. Überwacht alle eingehenden TCP/IP Pakete.
startService()
Startet den startThread nach einem root check.
stopService()
Stoppt den Service.
startTCPSniffer()
Diese Funktion wird im startThread
ausgeführt wird. Empfängt TCP/IP Pakete und ruft getTCPPacketInformation
auf.
reInstanceThreads()
Reinstanziiert die Threads.
getTCPPacketInformation(packet)
Parst ein TCP/IP Packet und extrahiert Informationen
Parameter:
-- packet: Das TCP/IP Packet welches geparst werden soll
returns:
-- flags: Die Flags des TCP/IP Paketes -- destPort: Den Zielport der TCP/IP Paketes -- sourceIP: Die Absender IP-Adresse
scanOpenSynConnections()
Wird im synScannThread
ausgeführt. Durchsucht das synConnections
Dict nach eingegangen TCP/IP Paketen mit einem SYN Flag, die älter als standardmäßig 5 Sekunden sind.
User Guides:
- Honeygrove user guide
- Incident-Monitoring user guide
- Management-Console user guide
Documentation:
- Honeygrove documentation
- Incident-Monitoring documentation
- Management-Console documentation
Legacy: