HackTheBox - Cicada
I demonstrate how I pwned Cicada on HackTheBox.
This box mostly emphasizes two important skills:
- Enumrating Active Directory’s RIDs for potential list of valid usernames
- Abusing the backup operators group
first nmap scan:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
~/htb/cicada$ nmap -sC -sV -Pn -vv -p- -oN scan.nmap 10.10.11.35
# Nmap 7.94SVN scan initiated Sun Oct 13 00:57:02 2024 as: nmap -sC -sV -Pn -T4 -v -oN scan.nmap 10.10.11.35
Increasing send delay for 10.10.11.35 from 0 to 5 due to 11 out of 25 dropped probes since last increase.
Host is up (0.094s latency).
Not shown: 65522 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-10-08 02:15:51Z)
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: cicada.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=CICADA-DC.cicada.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:CICADA-DC.cicada.htb
| Not valid before: 2024-08-22T20:24:16
|_Not valid after: 2025-08-22T20:24:16
|_ssl-date: TLS randomness does not represent time
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: cicada.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=CICADA-DC.cicada.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:CICADA-DC.cicada.htb
| Not valid before: 2024-08-22T20:24:16
|_Not valid after: 2025-08-22T20:24:16
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: cicada.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=CICADA-DC.cicada.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:CICADA-DC.cicada.htb
| Not valid before: 2024-08-22T20:24:16
|_Not valid after: 2025-08-22T20:24:16
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: cicada.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=CICADA-DC.cicada.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:CICADA-DC.cicada.htb
| Not valid before: 2024-08-22T20:24:16
|_Not valid after: 2025-08-22T20:24:16
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
55209/tcp open msrpc Microsoft Windows RPC
Service Info: Host: CICADA-DC; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2024-10-08T02:16:41
|_ start_date: N/A
|_clock-skew: 7h00m00s
So it is pure AD enum, after adding cicada.htb
to hosts file I get to work
SMB Enumeration
I started with enumerating the SMB shares with null session:
HR share was public so I connected to it and found Notice from HR.txt
After downloading and reading it I had a Password:
I need to obtain a user list in order to validate this password, so I attempted kerbrute, but it was slow and didn’t yield many results.
So we can enumerate users by RIDs if we had access to. We can use impacket-lookupsid
, Metasploit
or there is a cool switch I discovered earlier in NetExec:
with some bash we can extract valid users into a file to check with the obtained pass
1
cat users.txt | cut -d ':' -f 2 | cut -d '\' -f 2 | cut -d ' ' -f 1 | uniq >> potential_users.txt
And we got a hit on mark.wrightson
Before moving forward, let’s review what RIDs are.
RID Bruteforcing
In Windows, every object, including users and groups, is identified by a Security Identifier (SID). A SID is composed of:
- A domain identifier that stays the same for all users within the domain.
- A RID that uniquely identifies a user or group within the domain.
Example Breakdown:
SID: S-1-5-21-3623811015-3361044348-30300820-500
- Domain SID:
S-1-5-21-3623811015-3361044348-30300820
- RID: 500 (the built-in Administrator account)
So SID = Domain Identifier + RID.
Regular user accounts generally start at 1000. So what any of the above tools do is increment the RID by one to get the associated user.
Why This Works?
Windows doesn’t necessarily block the querying of SIDs, and if the system doesn’t have proper restrictions, it will return details about valid users based on the provided RIDs.
Mitigation
To mitigate RID enumeration attacks:
- Accounts: Guest account status:
Disabled
- Network access: Let Everyone permissions apply to anonymous users:
Disabled
- Network access: Restrict anonymous access to Named Pipes and Shares:
Enabled
- Use group policies to restrict SID enumeration by untrusted users.
As shown it is disabled by default.
Back to pwning..
LDAP Enumeration
Now I have a valid user and password. After alot of enumerating I queried a ldap query to see users description cause it usually contains passwords.
So I got another valid user and pass:
I discovered that this user did have access to brand-new SMB share. It is DEV, which I wasn’t previously able to access it.
It included a script file, which I downloaded and looked at to discover another user with her password.
WINRMing to get the first flag
PrivEsc
First thing I did was checking her groups:
I leveraged her membership in the Backup Operators group to extract the SAM and system registry files.
1
2
reg save hklm\sam c:\Temp\sam
reg save hklm\system c:\Temp\system
Used Impacket-secretsdump
to dump admin hash
WINRMing using the admin hash to get the root flag
Happy pwning!