Источник https://www.kalitutorials.net/2015/02/sql-injection-intermediate-level.html
Это теоретический пост, посвящённый разновидностям атак типа SQL инъекция и самой концепции этого понятия. У атакующего нет прямого способа писать полноценные запросы, поэтому он или она может лишь изменять URL или вводить данные в текстовые формы. Однако понимание MySQL (или любой другой СУБД) части атаки также необходимо. Оно пригодится, когда вы столкнётесь с мощными сайтами, против которых не сработают стандартные атаки, и вам придётся подойти к делу творчески. Прежде чем читать этот пост, возможно будет интересно ознакомиться со следующими тремя статьями:
А теперь перейдём к содержимому публикации:
Типы SQL инъекций
-
Классическая SQLI
-
Слепая SQL инъекция
-
Специфическая для конкретной системы управления базами данных SQLI
-
Составные SQLI
Техническая реализация
Неправильная фильтрация экранирующих символов
Эта форма SQL инъекции происходит, когда данные, введённые пользователем, не проверяются на наличие экранирующих символов и сразу передаются в SQL запрос. Результатом этого может стать манипуляция запросом к базе данных, выполняемая конечным пользователем приложения.
Следующая строка кода иллюстрирует данную уязвимость:
statement = "SELECT * FROM users WHERE name ='" + userName + "';"
Этот SQL код должен получить данные определённого пользователя, хранящиеся в таблице «users». Однако, если переменная «userName» изменена злоумышленником, SQL запрос может сделать гораздо больше, чем хотел автор кода. К примеру, можно указать значение переменной «userName»:
' or '1'='1
или использовать комментарии, чтобы заблокировать остальную часть запроса (существует 3 типа комментариев SQL). При этом в конце каждой строки должен стоять пробел:
' or '1'='1' -- ' or '1'='1' ({ ' or '1'='1' /*
Тогда можно получить один из подобных SQL запросов:
SELECT * FROM users WHERE name = '' OR '1'='1'; SELECT * FROM users WHERE name = '' OR '1'='1' -- ';
Если такой код применить в процедуре аутентификации, он может использоваться для принудительного выбора правильного имени пользователя, поскольку выражение '1'='1' всегда является верным.
Значение переменной «userName» в примере ниже, использующем API, разрешающее выполнять множественные запросы, приведёт к удалению таблицы «users», а также выбору всех данных из таблицы «userinfo» (фактически, раскрывает личные данные всех пользователей):
a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't
Результатом будет финальный SQL запрос такого вида:
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't';
Хотя большинство SQL серверов позволяют выполнять сразу несколько запросов подобным образом, некоторые API, такие как функция mysql_query() в PHP, не разрешают этого делать из соображений безопасности. Таким образом, злоумышленник не сможет внедрять отдельные запросы, но их модификацию это не остановит.
Неправильное обращение с типами данных
Такая форма SQL инъекции происходит, когда предоставленные пользователям текстовые поля не являются типизированными или не проверяются на наличие специальных символов. Такая ситуация может сложиться, когда в SQL запросе используются данные из числового поля, но программист не проверяет, действительно ли эти данные являются числом. К примеру:
statement := "SELECT * FROM userinfo WHERE id =" + a_variable + ";"
Совершенно ясно, что автор этого запроса хотел, чтобы переменная «a_variable» была числовой и соответствовала полю «id». Однако если на её месте окажется строка, конечный пользователь сможет манипулировать запросом по своему желанию и ему даже не понадобятся экранирующие символы. Например, если значением переменной «a_variable» будет строка
1;DROP TABLE users
произойдёт удаление таблицы «users» из базы данных, ведь финальный SQL запрос будет выглядеть так:
SELECT * FROM userinfo WHERE id=1;DROP TABLE users;
Слепая SQL инъекция
Слепые SQL инъекции используются, когда веб-приложение уязвимо к SQL инъекциям, но злоумышленник не видит их результатов. Страница с такой уязвимостью может не отображать данные, но она будет изменяться в зависимости от результата логического утверждения, внедрённого в выполняемый на ней SQL запрос. На совершение подобной атаки может потребоваться немало времени, поскольку, всякий раз после получения новой информации запрос приходится переделывать. Существует несколько инструментов для автоматизации таких атак, но пользоваться ими можно только после выявления целевой информации и нахождения уязвимости.
Условные ответы
Одна из разновидностей слепой SQL инъекции заставляет базу данных оценивать логическое утверждение на обычном экране приложения. Допустим, сайт с обзорами книг использует запрос для определения того, какой именно обзор показывать на экране. Ссылка приведёт к выполнению на сервере запроса
SELECT * FROM bookreviews WHERE ID = 'Value(ID)';
После этого страница будет заполнена данными обзора с параметром «ID» равным 5 из таблицы «bookreviews». Этот запрос исполняется на сервере. Пользователю не известны не только имена базы данных, таблицы и полей, но и структура самого запроса. Он видит лишь, что переход по этому URL приводит к отображению обзора. Хакер может пройти по ссылкам OR 1=1 и AND 1=2, результатом чего могут стать следующие запросы:
SELECT * FROM bookreviews WHERE ID = '5' OR '1'='1'; SELECT * FROM bookreviews WHERE ID = '5' AND '1'='2';
Если изначальный запрос загружается по URL "1=1", а URL "1=2" возвращает пустую страницу или ошибку, а также же сайт не сообщает пользователю о неверном вводе параметра, тогда этот ресурс, скорее всего, уязвим к SQL инъекциям, поскольку в обоих случаях запрос был успешно выполнен. Далее хакер способен выяснить версию MySQL, запущенную на сервере, использовав ссылку
AND substring(@@version,1,1)=4
, которая покажет обзор книги на сервере с MySQL 4. Иначе результатом будет пустая страница или ошибка. Хакер может продолжить внедрять код в URL, получая всё больше и больше информации о сервере, пока не достигнет своей цели или не найдёт другой путь для атаки.
SQL инъекция второго порядка
SQL инъекции второго порядка происходят, когда значения с вредоносными командами не исполняются мгновенно, но сохраняются. В некоторых случаях приложение может корректно закодировать SQL запрос и сохранить его в базе данных. Затем другая часть приложения, не защищённая от SQL инъекций, может выполнить хранимый запрос. Такая атака требует подробных знаний о том, как впоследствии используются введённые данные. Автоматическим сканерам безопасности веб-приложений будет очень сложно выявить такой тип SQL инъекции. Возможно, им придётся вручную дать инструкции о том, где искать признаки совершения подобной атаки.