Day 13: Visible error-based SQL injection — Zero to Hero Blind Injection — Portswigger
文章介绍了一个SQL注入漏洞的利用过程,通过分析跟踪cookie的响应和构造payload,成功提取了数据库中管理员用户的密码并登录。 2025-7-2 06:38:20 Author: infosecwriteups.com(查看原文) 阅读量:16 收藏

RayofHope

Hi, my fellow hackers. This is Rayofhope. I have over 5 years of experience and am currently working as a consultant with a Big 4 firm.

It’s Day 13 of posting all the PortSwigger labs, not just the solutions. I’ll break down why we take each step, because once the ‘why’ is clear, the ‘how’ becomes easy.

Let’s Start:

Before you go for this blog, make sure to read the Previous one

Link to Previous Blog: https://medium.com/@arayofhope7/day-12-blind-sql-injection-with-conditional-errors-zero-to-hero-blind-injection-portswigger-e94f9e3977a5

Video Walkthrough — You can watch the video or read the blog, totally up to you. But if you ask me, start with the video, then read the blog to connect all the dots.

This is how the lab looks.

“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.”

Vulnerable Parameter:
Tracking Cookie

End Goals:
1.
Exploit SQLi to output the password of the administrator user
2. Log in as the administrator user.

Request was intercepted and sent to the intruder.

This is what the normal response looks like.

As we know, the cookie parameter is vulnerable. I used a single quote ('), and it returned a 500 Internal Server Error. This indicates that the single quote might be breaking the SQL query, suggesting that the query could be part of custom developer-written code.

In the response, it returned an error, and the error message included the SQL query, which could be really sensitive. Let’s see how we can use it to craft a new payload.
This is what we had in the response body:
Unterminated string literal started at position 52 in SQL SELECT * FROM tracking WHERE id = ‘WPq6tHyy2UpzpneU’’. Expected char

The server is not properly configured to handle errors. Instead of showing a generic error message, it leaks sensitive SQL query details, exposing the backend and increasing the risk of exploitation.

  • If you look at the SQL query revealed by the server, you’ll notice that at the end it uses double single quotes (''). In the above scenario: SQL SELECT * FROM tracking WHERE id = 'WPq6tHyy2UpzpneU''..This suggests that the single quote is not properly closed, and the application is trying to handle it internally by escaping the quote, possibly to prevent SQL Injection.

Now, I used -- and it commented out the rest of the code after the first single quote. Quick tip: you can also use # or -- (with a space and another dash) to comment out the rest of the code.

But it does create a verbose error, which could be the same way we may retrieve the administrator password.

Note: —

The CAST() function is used to convert a syntax from one data type to another
Like: ‘ AND CAST((SELECT 1) AS INT) — —

But wait, we got an error even after using ‘AND CAST((SELECT 1) AS INT)’.

But in the response, we got the solution as well. It says that ‘the argument of AND must be of type boolean, not type integer,’ which clearly explains why we are getting the error.

And there we go, we balanced the syntax: (WPq6tHyy2UpzpneU’ and 1=cast ((select 1) as int) — — ), and it returned a 200 OK.

It forces the query to return a true condition by ensuring that 1=1 is evaluated. Here, we used the result of select 1 to an integer, making the comparison work as expected.

Used ' AND 1=CAST((SELECT username FROM users) AS INT)--. Let's see if the error message returned the username.

There we have a verbose error, but not the username. However, we know that the syntax we are using is correct.

Let’s see if the response reveals the username.

It’s a generic error, likely because the query is attempting to retrieve more columns than expected, which is why the username isn’t being returned. Let’s try using LIMIT to restrict the results and see if that helps.

Executed the payload ‘ AND 1=cast((select username FROM users LIMIT 1) as INT) — — , and it successfully returned the username in the response.

Used the payload ' AND 1=CAST((SELECT password FROM users LIMIT 1) AS INT)--, and it successfully returned the password qpqb5nyimb0azddj2ahz in the response.


文章来源: https://infosecwriteups.com/day-13-visible-error-based-sql-injection-zero-to-hero-blind-injection-portswigger-3da2241a1672?source=rss----7b722bfd1b8d--bug_bounty
如有侵权请联系:admin#unsafe.sh