SQL Injection

https://book.hacktricks.xyz/pentesting-web/sql-injection

SQL Injection

Examples

SQL Injection LabSQL InjectionGalleryLesson Learned?Plotted-TMS

Second-Order SQL Injection

Examples

Advanced SQL Injection

Filter Evasion Techniques

Examples

Advanced SQL Injection

Out-of-band SQL Injection

Examples

Advanced SQL Injection

Test SQL Injection with Burp

Examples

Lesson Learned?

List

Bruteforce fields

Good wordlist to use. You would do this if you discovered one field already, than you just replace it(in the example below you change password) with your list.

Find amount of fields

Examples

Madeye's CastleSQL Injection

Example List

Find SQL Version

Examples

Madeye's Castle

Burp

Find Tables

Examples

Madeye's CastleThe MarketplaceTryHack3M: Sch3Ma D3Mon

Get fields

Examples

Madeye's CastleThe MarketplaceTryHack3M: Sch3Ma D3Mon

Burp

Get field info

Examples

Madeye's CastleThe MarketplaceTryHack3M: Sch3Ma D3Mon

SYS_EVAL

You can use sys_eval to run commands

Examples

TryHack3M: Sch3Ma D3Mon

URL

Get field info

In-Band/Error Based - Curl Method

We can also do this using curl, with the same authentication bypass technique. To automate the process of finding which one works I copied the examples from the cheatsheet here to a file:

Then used a simple loop in BASH to read each line and try it against the website:

As you can see quite a few different ones worked.

In-Band/Error Based - Burp Method

We can use Burp to intercept the browser request. First make sure you have FoxyProxy on and set to use Burp, then use anything for the username:

sqhell-foxy-config

With Intercept set to On in Burp, when you click the Login button in your browser it gets redirected and caught:

sqhell-burp-intercept

Right click anywhere on the text and chose Send to Intruder. Check the last line has something within $ set against the username field, this is the variable that Burp will replace with our word list:

sqhell-burp-1

Switch to the Payloads tab and load a list of bypass techniques to try. I used the same file I’d copied them in to for the above curl method:

sqhell-burp-intruder

Click the Start Attack button and wait for burp to try everything from your list. Looking at the results you’ll see a few lines with a smaller length to the others. If you switch to the response tab you can see these are the responses containing our flag:

sqhell-burp-results

In-Band/Error Based - SQLMap Method

The last method to look at is arguably the easiest. Once you know how to use SQLMap it makes the process of discovery and enumeration much easier. If we pretend we don’t know the login page is vulnerable then let’s follow the process we could use to exploit the page. This is a useful post on using SQLMap for SQLi.

First we run an initial scan to see what SQLMap can discover about the database behind the logon page:

There’s a lot of information, the key point is:

With the information gathered we can tell SQLMap to use the username and password fields, set the database to mysql, and dump the databases it can find:

Again, a lot of information but the important part is the database it found:

Next we can ask SQLMap to dump the contents of that database:

With the password found for the admin user we can either login in via the browser or use curl again to get the flag:

Ok, that was four different ways to get flag 1. Let’s move on to the next flag.

In-Band/Union - Browser Method

The next easiest flag is number five. For this one we’ll be using parameter tampering and a UNION based exploit. I did another TryHackMe room called Jurassic Park where I used the same techniques as follows, you can see that post here.. There’s also helpful articles here and here that are worth a read.

First let’s see what we have:

sqhell-posts

We’re looking at one of the posts and can see it has a parameter on the end of the URL, in this case it’s ID=1. There’s lots of ways to check if this is vulnerable, probably the easiest is to add a ‘ on the end:

sqhell-apostrophe]

It says there’s an error in our syntax, which tells us our extra character on the end wasn’t removed. We could also do something simple like AND 1=1:

sqhell-and1=1

As before we can see the statement was evaluated with our extra part on the end. In this instance AND 1=1 is true so the page appears as normal. Now we know it’s vulnerable we can start to dig deeper.

First we want to know how many columns are in the table. We start at 1 and add columns until we get an error:

sqhell-columns

So here I did ORDER BY 1 then ORDER BY 1,2 and so on until I got to 5. The error at that point tells us there are four columns. Next we want to see which of those columns are useable:

sqhell-union-all

The UNION ALL statement is used to show us which column appears where on the page. We want the output to be visible, otherwise we won’t be able to see the data we retrieve. We can see column three is the main section of the page, so plenty of room for our output. We’ll use that one for all our subsequent commands.

Let’s get the database name:

sqhell-union-database

Now we want the tables in the database:

sqhell-union-tables

Finally we see the tables in the database, flag sounds like the one we’re looking for. Let’s have a look at the contents of it:

sqhell-union-flag

We have the flag. Let’s move on to a different method.

In-Band/Union - Curl Method

I went in to detail on the last flag on using curl instead of the browser. If you can use a browser you would because it’s easier, but in case it’s not possible here’s how to do this flag using curl.

First check how many columns we have:

We have four columns, as before we check to see which one is useable to display the data we retrieve:

I use grep to filter the output down to just the body of the response. We see column three is the one to use. Let’s find the database name:

Now find the tables in it:

Then get the flag from the table:

In-Band/Union - SQLMap Method

Moving on to SQLMap and like flag 1, this is pretty simple. First check for the post page parameter for vulnerability and find any databases:

As before, we’ve found the database is called sqhell_5, now dump everything:

We have the flag with only two runs of SQLMap, nice and simple!

Let’s move on to the next flag.

Blind/Boolean - Browser Method

I found this guide, which is a good in depth look at blind or boolean based attacks.

First looking at the Register page to see what we are dealing with:

sqhell-register

If we try admin as the user we see a message saying it’s taken:

sqhell-admin

If we try test as the user we see a message saying it’s available:

sqhell-test

Looking at the source code for the page we see how this works:

The script section calls a function called user-check to see if the name you’ve entered is available. We can visit this endpoint directly:

sqhell-user-check

Here we see the JSON output showing us the username isn’t available. First we test for SQLi:

sqhell-test-user

We still see available is false so we know we can perform SQLi and use the true/false response to confirm our query. Now we know this works our first task is to find the database name. We could continue in the browser, but for speed I’ll switch to curl.

Blind/Boolean - Curl Method

Let’s test how many characters are in the database name:

This tells us the database name length isn’t 1 character long. Next we try two characters:

Same answer for two characters, so we continue adding one and testing until we get a false:

This tells us the length of the name of the database is eight characters. Now we want to find what those eight characters are, we can cheat a little as we can guess it’s in the same format as the previous flags. So with the knowledge that it is probably sqhell_3 let’s test the first character. To do this we need to know the ASCII code for lower case s, which is 115 known by looking at this handy table.

Let’s see if the first character is equal to s:

False tells us the letter isn’t available, or in other words there is a match. So we’ve confirmed the first character is s, let’s check for q:

Note we are checking the second character and seeing if it is equal to 113. Again the false result means it’s a match. Looking good lets do the rest:

We’ve confirmed the database is called sqhell_3. Next we would use the same technique to get the table names in the database, of course that would be a long a laborious process. If you search online for boolean or blind SQLi scripts you’ll find plenty of examples. These just automate what we did above, to speed this up I’ve written one for this flag:

This is just a loop searching each character in the flag table to match it against an ascii code, just like we did manually before. Copy and paste the above code in to a file and run it with python3 to get the following output:

It takes a little while, but you get the idea!

Blind/Boolean - SQLMap Method

Lastly for this flag let’s use SQLMap. The other methods are for scenarios where we can’t use SQLMap, if we can then there’s no reason to spend all that time on it. I can get the flag in one minute and three seconds using one command!

Let’s do it:

Ok that was too easy. Let’s move on to the next flag

Blind/Time - Curl Method

Flag 2 has a hint on the room description, it says:

Let’s see what we have:

sqhell-t&c

It mentions logging the visitors IP. A search online found this that explains the process:

A further search on how to exploit XFF for time based SQLi I found lots of articles. This is a good one, with plenty of detail and examples. And also this one. First let’s try to manually check using curl:

Here I’ve taken the same curl command we used on flag three, where we are testing using ASCII codes. I’m assuming the first character of the flag is T like all the others. 84 is the ASCII value of T, and I’m sending that via the X-Forwarded-For header. The sleep(5) will visibly pause the output for 5 seconds, so we know there was a match if we get a delay.

This worked for the first letter of the flag, let’s do the second one which will be a H:

We test 72 which is the ASCII value of H and again get a five second delay. This tells us we have a match, and like before we can continue on this path to manually work out the flag. Of course that would be incredibly time consuming, so let’s write a script to automate it:

Just like the last script this is a simple loop, repeating the same time based check using the XFF header as we did with curl:

It’s not the fastest but it will get you the flag eventually!

Blind/Time - SQLMap Method

That was fun writing our own scripts, but realistically we’d probably just use SQLMap if we have it available. With knowledge from before about trying X-Forwarded-For as a method to exploit the website, let’s do the same initial test with SQLMap to check:

In less than a minute we get the above lengthy response from SQLMap, the key part being:

Now we know it’s vulnerable we can run SQLMap again and get it to dump the database:

Just like before, using SQLMap to dump the data makes it really easy.

Blind/Time - Python Script Method

Examples

Retrieving database name from boolean sqli

So, the plan is to know the name of the database. However, manual attempts will be terribly time-consuming, so I decided to practice scripting. After some time spent trying different payloads, this one worked:

Statement

Was able to get the database name using this script

Kali

script.py

Kali

Table enumeration

Statement

script.py

Kali

Password enumeration

We already know the username “kitty,” so let’s go straight to the password.

Statement

script.py

Kali

Out-of-band - Browser Method

I’ve left flag four till last as it’s the hardest to understand. We have another hint, this time is says:

A quick search of that reveals it’s a quote from the movie Inception:

I didn’t know where to start with this one, but searching for “SQLi inception” found this article. And the basic idea is we are looking at a UNION query inside a UNION query.

So first let’s look at the last page which we haven’t visited yet:

sqhell-users

We see her just like on the posts page there is a parameter. Let’s test to see if we can inject like before:

sqhell-users-or

Adding AND 1=1 results in a true statement which proves we can inject here. Now we need to determine the number of columns in the table just like we did for flag 5. We do this the same way using the ORDER BY statement.

So just like before we start with ORDER BY 1, then ORDER BY 2, and so on until we get to ORDER BY 4 where we see an error:

sqhell-users-order

Now we know how many columns we have we can use a UNION statement to test which ones are visible:

sqhell-users-union

Here we’ve used a false ID, which would result in an error but instead we’ve used the UNION statement to retrieve the column numbers. Now we know column one and two are useable we can retrieve the user and database:

sqhell-users-db

Next we want to see the tables in the database and can use the same query as before:

However this time when we ask for all tables using group_concat we only see the one user table:

sqhell-users-users

We know a different database contains the posts table, but we find the expected flag table can’t be queried here. It’s at this point that we need to go back to the hint about running a query inside a query. And we again need to determine the number of columns:

sqhell-users-order

Here I’ve just added an ORDER BY query to the end of the UNION SELECT 1, and enclosed it in quotes so it gets evaluated. As before we keep adding columns until we something changes:

sqhell-users-orderby5

We can see at five columns the posts disappear. This tells us there are four columns. Now we can use the same query as before to get the flag from the flag table:

sqhell-users-flag

At last we have our flag.

Out-of-band - Curl Method

If we hadn’t got a browser available we can do the same process using Curl. I won’t go through all the steps again as they are just the same methodology as we did with Firefox.

Here we have that final query we ended with, now done via Curl:

Out-of-band - SQLMap Method

In all other flags we’ve seen how simple SQL injection and data retrieval is using SQLMap. For this particular flag we’ve found we need to use a query within a query to extract the flag. I’m not sure if there is a way to achieve this with SQLMap, but if there is I can’t find the answer.

We can start the process as before:

SQLMap has found the database behind the page is sqhell_4. Let’s try to dump it:

We see SQLMap has only found the users table just like we did in the browser. In this instance the username and password are useless, so we’d have to take the payload it’s used and start manually investigating.

SQLMap

Examples

SQLSQL InjectionExposeSQLMap

Kali

Get databases

Kali

Get tables

Kali

Get fields for table users

Kali

From SQHell, go over and put in notes

On this page

NoSQL Injection

Examples

NoSQL Injection

Last updated