TryHackMe SQL Injection Lab
This page will be divided into tasks , Each task will have it's own idea.
Authentication Bypass
Lab 1 [ Non-string Input ]

We can see that there is a simple form that requires from us ID
and password
we need to bypass this authentication .
If we tried this simple query : 1' OR 1=1-- -;
we get this response :

This is because the ID
input is not string , hence we don't need to close the query using a quote , so by using this payload : 1 OR 1=1-- -;

We successfully bypass the authentication .
Lab 2 [ String Input ]

Now we have a string input box , so we need to use the single quote to bypass the authentication as follow : 1' OR 1=1-- -;

Lab 3 [ URL Injection ]

Now the parameters are in the URL , This will not make a big difference in our query except for the URL encoding

And this can easily bypass the authentication for us :

Lab 4 [ POST Injection ]
In this lab we cannot see our parameters in the URL because they are passed as POST parametes , so by intercepting the request we can manipulate the parameters to inject our payload

We can see that we are being redirected to the home, so we have ssuccessfully bypassed the authentication .

SQL Injection In UPDATE Statement
SQL Injection isn't meant only to bypass login panels , but also retrieve information. In this case the web application has a section for updating our info , due to improper validation on the updated info we can inject malicious SQL queries which will be executed within UPDATE
statement
Analysis
We are given credentials to login 10
& toor

We can see the "Edit Profile" Section up there

Let's try to confirm the injection in the nickname field , This can done by using string concatenation , so if i provided the nickname as follow : Khalid'||'Emad
and we found that it got concatenated then it is an injection point

Now for further exploitation we can retrieve info , The very first basic thing we can try is to get the version , but since we don't know the DBMS we should use different functions for the version , eventually it was sqlite
and the function was sqlite_version()
, we can retrieve the version as follow : KhalidEmad'||(SELECT sqlite_version())||'

Now let;s try to dump the database tables, the following payload can be used to dump the tables :
SELECT tbl_name FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'
But if we used it just like we would find that it only returns one table , this because the database returns more than one row in vertical way but we need it to return the results in horizontal way and this can be done using group_concat()
function , so the payload at the end is :
SELECT group_concat(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'

Now we can dump the columns of this "secrets" table using this payload :
SELECT group_concat(sql) FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='secrets'

We see that it has a column called secret which seems important , so let's select it :
'||(SELECT group_concat(secret) from secrets)||'

And here are the secrets 😄
Vulnerable Startup Challenges
Broken Authentication 1

A single login form and we need to bypass the authentication , let's start simple :
admin' or 1=1-- -;

We can't see any messages , let's use another payload admin'--
so this simply will comment the rest of the query and login as admin without checking the password

Broken Authentication 2 ( Union Attack )
The login page is still vulnerable to SQL injection , so we can easily login as admin however there is no valuable info . So we need to escalate further more .
We have the register page which we can test for it , First of all we need to determine the number of columns returned by the database .
Registering with => ' union select 1-- -;
gives us " Invalid username or password"
Registering with 'union select 1,2-- -;
gives us :

So we now know that there are 2 columns returned not just that but also column number 2 is displayed on the web app , so let's select the version for example => ' union select 1, sqlite_version()-- -;
:

The injection now is confirmed , so let's try to dump the tables considering the group_concat()
:
' union SELECT 1,group_concat(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%-- -;'

Let's try to dump the columns in it :
' union SELECT 1,group_concat(sql) FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='users'-- -;

We can see that it has a column called password, so let's select it :
' union select 1,group_concat(password) from users-- -;

Broken Authentication 3 ( Blind Attack )
This time there are no output displayed on the page but still the login page is vulnerable to Blind SQL injection , We know that based on the web application response in the case of true and false conditions .
In this case if we asked the database a true condition the web application will respond with 302 status code (redirection) if not it will respond with 200 ok


Now we can abuse this behavior to dump the password from the database ( we know the column name which is "password" and the table name which is "users" ) [ Check portswigger lab #11 solution to understand more about blind sql injection] .
The only thing here is that the web app converts the letters to lower case so if the flag contains upper case letter we won't get it, but this can be solved using unicode()
function in sqlite which returns the ASCII code of the character .
A python script to solve it can be found here => https://github.com/khaled1000emad/CTFs-With-Python-Scripts/blob/main/Tryhackme-SQL-Injection-Lab/BAC3/script.py

Vulnerable Notes
This time the login page is not vulnerable any more to SQL injection , the developer has implemented new feature which is adding notes .
Put in mind that the register function might be still vulnerable to SQL injection , so let's start our analysis.
We can register as normal users using khalid:khalid
credentials

We can see that the parameters in the register form are being processed within SQL prepared statements , hence these fields are not vulnerable .
When we login and in the notes section , the notes are being retreived from the database as follow :

As you can notice that it selects the username within a normal sql statement .
Now what if we would make it retrieve the notes as follow :
SELECT title, note FROM notes WHERE username = 'khalid' OR 1=1--
So it would display all the notes for us , Can we ? ... let's try to register with a vulnerable username as follow khalid' or 1=1--
hence we will achieve the above query :

When we go to the notes section :

Nice , we got all the notes from other users , we even got an important one for the flag .
Now let's use UNION
attack to get the flag , we may be already know the table name which users and the column name which is password , so let's register as :
khalid' union select 1,group_concat(password) from users--

Change Password
The developer patched the login page and the notes page so we can't exploit them any more, But he added another feature which is update password .
Let's try to take the normal user path to see what is hapenning , First we will create a normal user and attempt to change our password :

Notice how the password changed , the username parameter can be easily exploited if we forced the query to act as follow :
UPDATE users SET password = ? WHERE username = 'test' or 1=1--
By this way all passwords of the users will be changed to our new password and we can login as admin easily .

When we logged in as test' or 1=1--
and changed the password the query worked as we want , now let's login as admin :

Book Title
The developer add new feature to the web application which is searching for books using titles .

We can see a GET parameter called title and returns the result based on it's value .

And here is the query which is being executed , to escape this query we need to first provide a quote then )
to escape it , then --
to comment the rest of the query

Now we can confirm the injection , let's quickly see how may columns are returned :

So it returns 4 columns only the last 3 are displayed , let's select the password column from users table as follow :
test') UNION SELECT 1,2,3,group_concat(password) FROM users--

Book Title 2
Like the previous challenge we can search for book titles using the GET parameter title, but we realize that their are 2 queries executed , the result of the first is reflected into the second :

So basically the first query selects the id depending on the name of the title, this id then is used to select the books .
It would make sense to escape the first query and force the second one to select what we need

Here we can notice that when i escaped the first query and selected "1" it got reflected in the second query and the book was selected based on this value of the id .
Now to escalate further we need to perform another union attack , since the id is selected as a string not integer so we will enclose it between quotations as follow => '1'
and then to escape the id query we will add another quotation to it => '1''
and we can now perform the complete union attack as follow :
' union select '1'' union select 1-- -;

We can see that the query is perfectly escaped but nothing occurred , so maybe it needs more column numbers :

By increasing the number to 4 we found that it expects 4 columns and also the lat 3 are reflected on the web page . Flag now can be easily selected as follow :
' union select '1'' union select 1,2,group_concat(password),4 from users-- -;

Last updated