Post

PortSwiggerlabs: Visible error-based SQL injection

PortSwiggerlabs: Visible error-based SQL injection

Information :

This lab contains a SQL injection vulnerability. The application uses a tracking cookie for analytics, and performs a SQL query containing the value of the submitted cookie. The results of the SQL query are not returned.

The database contains a different table called users, with columns called username and password. To solve the lab, find a way to leak the password for the administrator user, then log in to their account.

Solution :

First let’s make a normal request :

image

We see this tracking ID , (tried injecting the category parameter but that didn’t work) , if we inject the tracking ID parameter :

image

We get a verbose message , which shows us the query made to the server . First let’s confirm the SQLi by commenting the rest :

image

We see that we no longer have an error which confirms the vulnerability .

Now here we can use a Condition Based SQLi :

The condition we will be using is CAST : which is convert this value to a specific type Eg : CAST(‘1’ AS INT) this should work perfectly since 1 is an INT .

But if we tried CAST(ADMIN AS INT) this will return an error .

Now this is our condition , we should verify if it’s true : 1=CAST(1 AS INT) : This condition should return TRUE , and the query shouldn’t break so let’s test it :

1
'AND 1=CAST('1' AS INT)-- - : This shouldn't return any errors .

image

Now let’s test a different one to confirm that this is a Condition based SQLi :

1
'AND 1=CAST('a' AS INT)-- - : This should result in an error .

image

Perfect, this confirms the Condition based SQLi .

Now how can we abuse this? We already know there is a table called users that has username and password columns .

We can use CAST and inside of it we make a condition that will return an error , but will still execute something and return it back as part of the error .

1
1=CAST((SELECT username FROM users LIMIT 1) AS INT) 

This will select the first Row only (LIMIT 1) then try and transform it to an INT , which will result in an error and in the error it should give us the content of the first SELECT we made :

1
TrackingId=' AND 1=CAST((SELECT username FROM users LIMIT 1) AS INT)--

image

Perfect we get our username . Now to retrieve the password , same thing :

1
 1=CAST((SELECT password from users where username = 'administrator') AS INT)

image

I kept trying to make it work but i couldn’t , probably since it’s too big .

Another way around it , we already know the first Row was for administrator , LIMIT1 , so if we do the same thing and dump first Row of passwords we should get the admin’s password .

1
 1=CAST((SELECT password from users LIMIT 1) AS INT)

image

That way we got the admin’s password :

image

Once we login as the admin , we should see that the lab was solved .

That was all for this lab, see you in the next one .

This post is licensed under CC BY 4.0 by the author.