Chapter 19 Exercises: Injection Attacks
Exercise 1: Identifying Injection Points
Difficulty: Beginner | Time: 20 minutes
For the ShopStack application, list all potential injection points across the following categories. For each, identify the interpreter that the input might reach:
- Search functionality (SQL database)
- File upload feature (OS file system)
- PDF invoice generation (OS shell)
- Product review submission (SQL database / NoSQL if applicable)
- Admin user management (LDAP / SQL)
- Report generation with date range filters (SQL)
For each injection point, describe the HTTP request that carries the user input and the parameter name.
Exercise 2: SQL Error Pattern Matcher
Difficulty: Intermediate | Time: 30 minutes
Write a Python function that takes an HTTP response body as input and identifies the database type from any SQL error messages present. Support at least MySQL, PostgreSQL, MSSQL, Oracle, and SQLite. The function should return the database type and confidence level.
See code/exercise-solutions.py for the solution.
Exercise 3: Manual SQL Injection on DVWA
Difficulty: Beginner | Time: 45 minutes
Set DVWA's security to "Low" and navigate to the SQL Injection page. Complete the following tasks:
- Determine if the input is vulnerable by submitting a single quote (
'). - Determine the number of columns using
ORDER BY. - Use
UNION SELECTto extract the database version. - Extract all table names from
information_schema.tables. - Extract all usernames and password hashes from the
userstable.
Document each step with the exact payload used and the response received.
Exercise 4: Blind SQL Injection Exploration
Difficulty: Intermediate | Time: 45 minutes
On DVWA's Blind SQL Injection page (Low security):
- Confirm boolean-based blind injection by comparing responses for
1' AND 1=1#vs1' AND 1=2#. - Determine the database version's first character using
1' AND SUBSTRING(@@version,1,1)='5'#(adjust for your MySQL version). - Extract the admin user's password hash character by character (first 5 characters is sufficient).
- Calculate how many requests would be needed to extract a full 32-character hash using binary search.
Exercise 5: UNION Column Counter Script
Difficulty: Intermediate | Time: 30 minutes
Write a Python script that automatically determines the number of columns in a SQL query by incrementing ORDER BY values and detecting when an error occurs. The script should report the column count and verify it with a UNION SELECT of NULLs.
See code/exercise-solutions.py for the solution.
Exercise 6: Error-Based Extraction
Difficulty: Intermediate | Time: 30 minutes
Using Burp Suite Repeater against a vulnerable target (DVWA at Medium security or a PortSwigger lab):
- Craft a payload that extracts the database version via a type conversion error.
- Extract the current database name using the same technique.
- Extract the first table name from
information_schema.tables.
Document the exact payloads and responses for each extraction.
Exercise 7: Time-Based Blind Injection
Difficulty: Advanced | Time: 40 minutes
Against DVWA (Low security) or a PortSwigger lab:
- Confirm time-based injection by comparing response times for
1' AND SLEEP(3)#vs1' AND SLEEP(0)#. - Use time-based injection to determine if the database version starts with "5" or "8".
- Extract the first character of the admin password hash using time-based blind injection.
- Discuss why time-based injection is less reliable than boolean-based and what factors affect accuracy.
Exercise 8: sqlmap Proficiency
Difficulty: Intermediate | Time: 45 minutes
Using sqlmap against DVWA's SQL Injection page:
- Run a basic detection scan with
--level=1 --risk=1. - Enumerate all databases with
--dbs. - Enumerate tables in the
dvwadatabase with-D dvwa --tables. - Dump the
userstable with-D dvwa -T users --dump. - Attempt to get an OS shell with
--os-shell. - Route sqlmap through Burp Suite using
--proxy=http://127.0.0.1:8080and examine the requests Burp captures.
Document the commands used and compare sqlmap's automated approach to your manual testing.
Exercise 9: Blind Boolean Extractor Script
Difficulty: Advanced | Time: 60 minutes
Write a Python script that extracts a string value character by character using boolean-based blind SQL injection with binary search optimization. The script should determine string length first, then use binary search (7 requests per character) to extract each character.
See code/exercise-solutions.py for the solution.
Exercise 10: NoSQL Injection Challenge
Difficulty: Intermediate | Time: 40 minutes
Using OWASP Juice Shop's login page or a custom MongoDB application:
- Intercept the login request with Burp Suite.
- Modify the JSON body to inject MongoDB operators (
$ne`, `$gt,$regex). - Attempt authentication bypass using at least three different operator-based techniques.
- Use the
$regexoperator to extract the admin password character by character (first 5 characters).
Exercise 11: Command Injection Lab
Difficulty: Intermediate | Time: 30 minutes
Run the provided example-02-command-injection-demo.py Flask application:
- Test the vulnerable endpoint with the following payloads and document the results:
-
127.0.0.1; whoami-127.0.0.1; cat /etc/passwd-127.0.0.1 && id-127.0.0.1 | ls -la-$(whoami) - Attempt blind command injection with
127.0.0.1; sleep 5. - Test the secure endpoint with the same payloads and verify they are blocked.
- Explain why
subprocess.run([...], shell=False)prevents command injection.
Exercise 12: SSTI Detection and Identification
Difficulty: Advanced | Time: 40 minutes
Using a PortSwigger Web Security Academy SSTI lab or a custom vulnerable application:
- Test for template injection by submitting
{{7*7}}and checking if49appears. - Determine the template engine using engine-specific probes:
-
{{7*'7'}}(Jinja2 returns7777777, Twig returns49) -${7*7}(Freemarker/Mako) -<%= 7*7 %>(ERB) - If Jinja2 is identified, escalate to code execution using class traversal.
- Document the decision tree you used for identification.
Exercise 13: Parameterized Query Converter
Difficulty: Beginner | Time: 20 minutes
Convert the following vulnerable SQL queries to parameterized queries in three languages (Node.js/pg, Python/psycopg2, Java/PreparedStatement):
SELECT * FROM users WHERE username='${username}' AND password='${password}'SELECT * FROM products WHERE name LIKE '%${search}%' AND category=${category_id}INSERT INTO orders (user_id, product_id, quantity) VALUES (${user_id}, ${product_id}, ${quantity})UPDATE users SET email='${email}' WHERE id=${user_id}DELETE FROM sessions WHERE user_id=${user_id} AND token='${token}'
See code/exercise-solutions.py for the solution.
Exercise 14: WAF Bypass Techniques
Difficulty: Advanced | Time: 45 minutes
Against a WAF-protected target (or ModSecurity with CRS in your lab):
- Send a basic SQLi payload (
' OR 1=1 --) and confirm it is blocked. - Attempt bypass with case variation (
' oR 1=1 --). - Attempt bypass with comment insertion (
' O/**/R 1=1 --). - Attempt bypass with URL encoding (
%27%20OR%201=1%20--). - Attempt bypass with alternative syntax (
' HAVING 1=1 --). - Use sqlmap's tamper scripts (
--tamper=space2comment,between,randomcase).
Document which techniques bypass the WAF and which are blocked.
Exercise 15: Second-Order Injection Scenario
Difficulty: Advanced | Time: 40 minutes
Design a test case for second-order SQL injection in ShopStack:
- Identify a feature where user input is stored (e.g., username, display name, shipping address).
- Identify a separate feature where stored data is used in a SQL query (e.g., admin reporting, export).
- Craft a payload that is stored safely (parameterized INSERT) but exploits the second query.
- Write pseudocode demonstrating both the safe storage and unsafe retrieval.
- Propose a detection strategy for second-order injection during code review.
Exercise 16: NoSQL Injection Tester Script
Difficulty: Intermediate | Time: 30 minutes
Write a Python script that tests a JSON API login endpoint for MongoDB operator injection by sending authentication requests with $ne`, `$gt, $regex`, and `$where operators and comparing responses to baseline.
See code/exercise-solutions.py for the solution.
Exercise 17: Injection Defense Implementation
Difficulty: Intermediate | Time: 45 minutes
Implement a complete defense for ShopStack's product search endpoint that includes:
- Input validation (allowlist of acceptable characters, length limit)
- Parameterized query for the SQL database
- Rate limiting (max 30 searches per minute per user)
- Logging of rejected inputs
- Error handling that does not leak database information
Write the full Express.js route handler with all five defensive layers.
Exercise 18: Comparative Injection Analysis
Difficulty: Advanced | Time: 60 minutes
Compare injection techniques across three interpreter types. For each, document the normal syntax, the injection technique, the detection method, and the primary defense:
- SQL (PostgreSQL)
- NoSQL (MongoDB)
- OS Command (Bash)
- LDAP (OpenLDAP)
- Template (Jinja2)
Create a reference table that a penetration tester could use during an assessment.