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:

  1. Search functionality (SQL database)
  2. File upload feature (OS file system)
  3. PDF invoice generation (OS shell)
  4. Product review submission (SQL database / NoSQL if applicable)
  5. Admin user management (LDAP / SQL)
  6. 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:

  1. Determine if the input is vulnerable by submitting a single quote (').
  2. Determine the number of columns using ORDER BY.
  3. Use UNION SELECT to extract the database version.
  4. Extract all table names from information_schema.tables.
  5. Extract all usernames and password hashes from the users table.

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):

  1. Confirm boolean-based blind injection by comparing responses for 1' AND 1=1# vs 1' AND 1=2#.
  2. Determine the database version's first character using 1' AND SUBSTRING(@@version,1,1)='5'# (adjust for your MySQL version).
  3. Extract the admin user's password hash character by character (first 5 characters is sufficient).
  4. 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):

  1. Craft a payload that extracts the database version via a type conversion error.
  2. Extract the current database name using the same technique.
  3. 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:

  1. Confirm time-based injection by comparing response times for 1' AND SLEEP(3)# vs 1' AND SLEEP(0)#.
  2. Use time-based injection to determine if the database version starts with "5" or "8".
  3. Extract the first character of the admin password hash using time-based blind injection.
  4. 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:

  1. Run a basic detection scan with --level=1 --risk=1.
  2. Enumerate all databases with --dbs.
  3. Enumerate tables in the dvwa database with -D dvwa --tables.
  4. Dump the users table with -D dvwa -T users --dump.
  5. Attempt to get an OS shell with --os-shell.
  6. Route sqlmap through Burp Suite using --proxy=http://127.0.0.1:8080 and 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:

  1. Intercept the login request with Burp Suite.
  2. Modify the JSON body to inject MongoDB operators ($ne`, `$gt, $regex).
  3. Attempt authentication bypass using at least three different operator-based techniques.
  4. Use the $regex operator 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:

  1. 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)
  2. Attempt blind command injection with 127.0.0.1; sleep 5.
  3. Test the secure endpoint with the same payloads and verify they are blocked.
  4. 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:

  1. Test for template injection by submitting {{7*7}} and checking if 49 appears.
  2. Determine the template engine using engine-specific probes: - {{7*'7'}} (Jinja2 returns 7777777, Twig returns 49) - ${7*7} (Freemarker/Mako) - <%= 7*7 %> (ERB)
  3. If Jinja2 is identified, escalate to code execution using class traversal.
  4. 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):

  1. SELECT * FROM users WHERE username='${username}' AND password='${password}'
  2. SELECT * FROM products WHERE name LIKE '%${search}%' AND category=${category_id}
  3. INSERT INTO orders (user_id, product_id, quantity) VALUES (${user_id}, ${product_id}, ${quantity})
  4. UPDATE users SET email='${email}' WHERE id=${user_id}
  5. 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):

  1. Send a basic SQLi payload (' OR 1=1 --) and confirm it is blocked.
  2. Attempt bypass with case variation (' oR 1=1 --).
  3. Attempt bypass with comment insertion (' O/**/R 1=1 --).
  4. Attempt bypass with URL encoding (%27%20OR%201=1%20--).
  5. Attempt bypass with alternative syntax (' HAVING 1=1 --).
  6. 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:

  1. Identify a feature where user input is stored (e.g., username, display name, shipping address).
  2. Identify a separate feature where stored data is used in a SQL query (e.g., admin reporting, export).
  3. Craft a payload that is stored safely (parameterized INSERT) but exploits the second query.
  4. Write pseudocode demonstrating both the safe storage and unsafe retrieval.
  5. 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:

  1. Input validation (allowlist of acceptable characters, length limit)
  2. Parameterized query for the SQL database
  3. Rate limiting (max 30 searches per minute per user)
  4. Logging of rejected inputs
  5. 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:

  1. SQL (PostgreSQL)
  2. NoSQL (MongoDB)
  3. OS Command (Bash)
  4. LDAP (OpenLDAP)
  5. Template (Jinja2)

Create a reference table that a penetration tester could use during an assessment.