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
Filter Evasion Techniques
Examples
Out-of-band SQL Injection
Examples
Test SQL Injection with Burp
Examples
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
Example List


Find SQL Version
Examples

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
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:

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

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:

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:

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:

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:

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:
]
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:

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:

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:

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:

Now we want the tables in the database:

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:

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:

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

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

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:

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

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:

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:

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

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:

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

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:

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:

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:

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:

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:

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
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
Last updated