Sysco
Challenge Lab (Medium) - by LainKusanagi
The following post by 0xb0b is licensed under CC BY 4.0
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.
Objectives and Scope
The core objective of this external penetration test is to simulate a realistic, determined adversary to achieve Domain Administrator privileges within Sysco's Active Directory (AD) environment. Starting from an external position, we will focus on obtaining an initial foothold, performing lateral movement, and executing privilege escalation while successfully evading Antivirus (AV) and other security controls. This is a red-team exercise to find security weaknesses before a real attacker does.
Summary
Recon
We use rustscan -b 500 -a sysco.hs -- -sC -sV -Pn to enumerate all TCP ports on 10.1.79.70, piping the discovered results into Nmap which runs default NSE scripts -sC, service and version detection -sV, and treats the host as online without ICMP echo -Pn.
A batch size of 500 trades speed for stability, the default 1500 balances both, while much larger sizes increase throughput but risk missed responses and instability.
rustscan -b 500 -a sysco.hs -- -sC -sV -Pn
With the results of our RustScan we identify a Windows host named DC01 on domain SYSCO.LOCAL exposing DNS (Simple DNS Plus) on 53, HTTP (Apache 2.4.58 / PHP 8.2.12) on 80, Kerberos on 88, Active Directory LDAP on 389 (AD), LDAPS/tcpwrapped on 636, kpasswd5 on 464, Microsoft RPC / MSRPC endpoints on 135, NetBIOS/SMB on 139 and 445 (SMB2 message signing required), RPC-over-HTTP on 593 and 49675, .NET message framing on 9389, RDP (Microsoft Terminal Services) on 3389 (cert: DC01.SYSCO.LOCAL), and several ephemeral MSRPC ports 49664, 49667, 49676, 49722.

WEB
We first look at the website manually and find only a static one.

When we scroll down to the team section, we find the first and last names of three team members.

For now, we'll make a note of these and save them in team.txt.
greg shields
sarah jhonson
jack dowland
lainey mooreIn the footer, we find another email address for contact. The domain sysco.local is also used here.

We continue with a recursive directory scan using Feroxbuster. In addition to the directories of the static site, we also find a Roundcube instance.
feroxbuster -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -u 'http://sysco.hs'

SMB
First, we try to authenticate with the guest account, but the account is disabled.
nxc smb sysco.hs -u guest -p '' 
But we are able to athenticate anonymously.
nxc smb sysco.hs -u '' -p '' 
We can use that to generate our /etc/hosts entry via NetExec.
nxc smb sysco.hs -u '' -p '' --generate-hosts-file hosts
Kerberos
We now have some names, but no usernames yet. We can generate a series of potential usernames using Username Anarchy.
We don't have passwords either, so we could try to create emails from the usernames we created and the information in the footer of the email, and then brute force them in Roundcube. However, this would be a very extensive task.
However, we also have a domain controller and Kerberos available. We could therefore first brute force valid usernames using kerbrute.
But first, we create a list of possible usernames using UsernameAnarchy and the names we have identified.
username-anarchy -i team.txt > usernames.txt
Next, we use kerbrute to test for valid usernames. And we are able to detect three.
kerbrute userenum --domain SYSCO.LOCAL --dc dc01.sysco.local usernames.txt
We save those to a file called users.txt.
greg.shields
lainey.moore
jack.dowlandAccess as jack.dowland
The mind map from Orange Cyber Defense provides useful guidance on how to proceed in an Active Directory engagement depending on the information available:
One option that does not require passwords but does require valid usernames is ASREPRoasting.
AS-REP roasting is an attack where a Kerberos account with the Do not require preauthentication flag set allows to request an AS-REP authentication response from the KDC and extract an offline-crackable AS-REP ciphertext (an encrypted blob) of the user's password.
To ASREProas we will also use NetExec and are able to retrieve the blob of jack.dowland :
nxc ldap SYSCO.LOCAL -u users.txt -p '' --asreproast output.txt
Next, we try to crack the blob using hashcat and are successful. We now have the credentials of jack.dowland.
hashcat -m18200 -a0 output.txt /usr/share/wordlists/rockyou.txt 
We test the credentials using NetExec and are able to list shares.
nxc smb SYSCO.LOCAL -u 'jack.dowland' -p 'REDACTED'nxc smb SYSCO.LOCAL -u 'jack.dowland' -p 'REDACTED' --shares
Since the IPC$ share is readable we can try an rid brute force to enumerate further users. But here we are only able to spot the three we already know. A password spray to the other users is unsuccessful.
nxc smb SYSCO.LOCAL -u 'jack.dowland' -p 'REDACTED' --rid
Bloodhound Enumeration
Now that we have the credentials of a user we can use bloodhound to enumerate the domain:
bloodhound-ce.py --zip -c All -d SYSCO.LOCAL -u jack.dowland -p 'REDACTED' -dc DC01.SYSCO.LOCAL -ns 10.0.27.111
But unfortunately the user jack.dowland has no interesting group membership or outbound object control that we can use to escalate our privileges.

We also check for the other users and see that lainey.moore is part of the REMOTE MANAGEMENT USERS group, that would allow us low privilege access to the domain controller.

We query for Shortest Path To Domain Admins and see that greg.shields has GenericWrite permissions on DEFAULT DOMAIN POLICY as being part of the DOMAIN POLICY CREATOR OWNERS group. This would allow us to escalate our priviliges. More on that later.

Shell as lainey.moore
Since we cannot escalate our privileges for now via the permissions and relationships of the user jack.dowland we can try to check if that user reused the credentials for RoundCube. 

We are able to log in as jack.dowland with the credentials found ealier and spot a mail in the sent directory about issues with a router config. Furthermore the mail was sent to lainey.moore@sysco.local.

We download the attached router config and find Cisco Type 5 Secret.

Cisco Type 5 Secret:

Next, we try to crack it using hashcat and are successful.
 hashcat -m500 -a0 'REDACTED' /usr/share/wordlists/rockyou.txt --show 
We are now able to perform another password spray with the recovered password and identified users. And are able to authenticate as lainey.moore.
nxc smb SYSCO.LOCAL -u users.txt -p 'REDACTED' --continue-on-success
We use evil-winrm to log on to the target as lainey.moore...
evil-winrm -i SYSCO.LOCAL -u lainey.moore -p REDACTED 
... and find the user flag at C:\Users\lainey.morre\user.txt.

Access as greg.shields
In addition to the user flag on the desktop, we find a note, a putty executable, and a link in the Documents folder. The note is about tasks that need to be completed on the router and mentions SSH, among other things. That's probably why the Putty client is included.

If we take a look at the link file, we can see at a glance that it can be used to connect to the router via SSH. The SSH credentials are stored there.

However, we want to illustrate this a little better and download the link file.
Next, we install liblnk-utils to examine the link file in more detail using linkinfo.
sudo apt install liblnk-utilsWe inspect the link file with linkinfo and can now easily see the password.
lnkinfo "Putty - HS Router login.lnk"
We perform another password spray using NetExec with the identified usernames and the newly discovered password. And we are able to authenticate as greg.shields.
nxc smb SYSCO.LOCAL -u users.txt -p 'REDACTED' --continue-on-success
Shell as local admin
Recalling our Bloodhound Enumeration we know that greg.shields has GenericWrite permissions on the DEFAULT DOMAIN POLICY GPO.

We can easily Google how to exploit these and find ourselves on hackers.recipes:
google: "generic write on default domain policy"With pyGPOabuse we can update an existing GPO and a a local admin:
pyGPOabuse, update an existing GPO - add a local admin pygpoabuse 'domain'/'user':'password' -gpo-id "12345677-ABCD-9876-ABCD-123456789012"
We could now add either greg.shields or lainey.moore to the local Administrators group, both are in the REMOTE MANAGEMENT USERS group. We add greg.shields to the local Administrators group.
pygpoabuse.py 'SYSCO.LOCAL'/'greg.shields':'REDACTED' -gpo-id '31B2F340-016D-11D2-945F-00C04FB984F9' -command 'net localgroup Administrators greg.shields /add'pygpoabuse.py 'SYSCO.LOCAL'/'greg.shields':'REDACTED' -gpo-id '31B2F340-016D-11D2-945F-00C04FB984F9' -command 'net localgroup Administrators lainey.moore /add'
Next, we log in as greg.shields and issue gpupdate /force to force the update via the GPOs present.
evil-winrm -i SYSCO.LOCAL -u greg.shields -p 'REDACTED'gpupdate /force
We are now in the local administrators group on the domain controller...

... and are able to access the final flag at C:\Users\Administrator\Desktop\root.txt.

Last updated
Was this helpful?

