HTB - Appointment (SQL Injection)

I think it’s only right that this blog starts where it all began for me: HackTheBox. In this mini-series I will be going through some of the starting point challenges from a fresh account. In the future I plan to publish writeups about retired machines, challenges, and sherlocks.

In accordance with HTB TOS, I will not be publishing writeups of active challenges until after they’re retired.

With that out of the way, let’s begin!

Our first box: Appointment

Overview

The Appointment box is a mockup of a common web-application. Let’s visit the given IP 10.129.197.202 and see what’s there.

Looks like we have a basic login page (basic is a strong word, a full login card with a color gradient, onHover button animations, and a muted background image? noice). The tags for the box include PHP and SQL Injection, so I think it’s safe to assume that there’s a SQL injection vulnerability in this login.

So… how does SQL Injection work?

SQL Injection

This vulnerability works by exploiting unsanitized inputs to change the intended function of a SQL query running in the background.

For example, suppose the login form above uses the following SQL query to return the user account for a given username and password combination from the database.

Where the username entered is user and the password entered is pass.

If there is improper sanitization of the inputs, an attacker can enter user for the username and ' OR '1'='1 as the password.

Which leads to the following query being executed instead:

Resulting in a successful login for whichever user is passed to the username field (even admin).

Another variation of SQL injection uses the semicolon ;. Allowing attackers to use batch statements to execute multiple commands at once.

This example specifically would allow anyone to delete all the users from your database on a whim - no bueno. They can technically add any additional SQL statement they want, so the extent of the damage is up to their imagination.

AHH SCARY VULN HOW FIX?

This kind of vulnerability can easily be secured with input sanitization on the username and password fields that only allow for characters in the English alphabet to be used, unlike quotation marks and semicolons. However, the preferred way of securing against this kind of vulnerability is by using prepared statements aka parameterized queries.

Prepared statements are a feature in database management systems that allow you to pre-compile a SQL query with placeholders for data values that are supplied later. The separation of SQL code and data offers both security and performance benefits.

The actual syntax can vary depending on the system, in PHP with MySQLi you would use the following:

The input values from the login fields have been replaced by question marks in the original SQL command. Then using bind_param we set the values of those question marks to be the inputs from the form fields.

The advantage here is that any user-supplied value in the form fields (even if it contains SQL syntax or malicious code) is strictly treated as data. The database will never execute user input as part of the original SQL command. For example, if an attack were to try to inject user'; DROP TABLE Users; -- like in the previous example, the database simply searches for that exact string instead of executing it as a command.

With this in mind, let’s get back to the box.

Enumeration

It’s always good to start with an nmap scan to find the open ports on the target machine.

We’re using the -sC and -sV flags here to perform a script scan and enable version detection respectively. It’s good to note that the -sC and -sV flags are considered noisy flags, meaning there is a good chance that any monitoring on the network would catch this.

From the scan we can see an Apache instance running on port 80, this is responsible for serving the web-application.

Exploitation

Back to the web interface, let’s try using the what we know about SQL injection to gain access to the admin account.

Here we are entering admin for the username and ' OR '1'='1 for the password.

Success! We got the flag!

Just for fun, let’s try a different injection string. This time we will enter the username admin'# and any password we want.

In PHP # denotes a comment. So, in theory, we should be able to enter admin'# for the username and circumvent the need for a password by commenting out the rest of the query.

Something like this:

Let’s try it

Success!

HackTheBox SQL-Injection