Внедрение кода или инъекция SQL — это уязвимость системы безопасности в Интернете, позволяющая злоумышленнику завладеть доступом к SQL-запросам в базу данных. Так он может получить конфиденциальную информацию о структуре базы данных, таблицах, столбцах или полях вместе со всеми данными, которые там есть.
Вот пример. Предположим, приложение использует следующий запрос на получение чьих-либо учётных данных:
SELECT USERNAME,PASSWORD from USERS where USERNAME='<username>' AND PASSWORD='<password>';
Здесь имя пользователя username
и пароль password
— это данные, вводимые пользователем. Допустим, злоумышленник в оба поля введёт ' OR '1'='1
. SQL-запрос будет выглядеть так:
SELECT USERNAME,PASSWORD from USERS where USERNAME='' OR '1'='1' AND PASSWORD='' OR '1'='1';
На запрос приходит true, и доступ получен. Это пример самой простой SQL-инъекции.
Инъекция SQL может быть использована где угодно, и с её помощью можно получить любую, даже самую секретную информацию, хранящуюся в базе данных.
Примечание: пример максимально упрощён и приводится здесь исключительно в ознакомительных целях. В реальной жизни таких случаев практически не найти.
Можете заглянуть в эту шпаргалку и узнать, как выполнять запросы в базы данных SQL разных поставщиков.
Как нащупать уязвимость?
В большинстве случаев уязвимость обнаруживается введением неверных параметров, например: '
, '' a' or 1=1--
, "a"" or 1=1--"
, or a = a
, a' waitfor delay '0:0:10'--
, 1 waitfor delay '0:0:10'--
, %26
, ' or username like '%
и т.д. После чего проявляются изменения в поведении приложения.
Можно проанализировать длину ответа сервера и время, требующееся для отправки этого ответа. Такая полезная нагрузка, как '
, a' or 1=1--
и т.д., может свидетельствовать об изменениях в ответе сервера баз данных. Но в случае отсутствия изменений мы можем попробовать запустить задержки по времени, используя полезную нагрузку a' waitfor delay '0:0:10'--
. Так можно задержать отправку ответа сервера на определённое время.
Узнав, подвержен ли сайт SQL-инъекции
, мы можем попытаться вытащить из базы данных интересующую нас информацию.
Но прежде надо определить количество столбцов
, возвращаемых на SQL-запрос. Это важно, так как при несовпадении количества столбцов, которые мы пытаемся вытащить, с тем, что мы получим в ответе, нам вернётся ошибка.
Количество столбцов можно определить командой order by
. Например:
www.onlineshopping.com/products.php?pid=8 order by 1 -- //
www.onlineshopping.com/products.php?pid=8 order by 2 -- //// Если параметр - строка, то надо добавить после него значок «'».www.onlineshopping.com/products.php?usr=b' order by 3 -- //
www.onlineshopping.com/products.php?usr=a' order by 4 -- //
Комментарии в SQL начинаются вот с такой комбинации символов --
. Чтобы сохранить пробел
после --
, просто добавляем любой символ: так пробел
не будет игнорироваться в HTTP-запросе
. Для комментариев могут использоваться также #
или /* */
в зависимости от поставщика базы данных SQL.
Продолжаем этот процесс, пока не появится ошибка. Если ошибка случилась во время использования полезной нагрузки order by 5
, а не order by 4
, значит, запрос возвращает 4
столбца.
Как использовать уязвимости
Обнаружив уязвимость приложения и определив количество столбцов, попробуем найти необходимую информацию о базе данных (БД): имя БД
, имя пользователя БД
, версия БД
, имена таблиц
, имена столбцов
той или иной таблицы и т.д. Загляните в шпаргалку по инъекциям в SQL: там есть соответствующие запросы.
Типы SQL-инъекций
- На основе ошибки: этот тип SQL-инъекции использует
сообщения об ошибке
, выбрасываемой сервером базы данных. Такие сообщения могут дать полезную информацию о структуре базы данных. - С использованием
UNION
: эта техника задействует оператор SQLUNION
для объединения результатов двух запросовSELECT
в единую таблицу. Так злоумышленник может получить информацию из других таблиц добавлением результатов к исходному запросу, выполненному в базу данных. - «Слепая» инъекция: имеет место, когда приложение подвержено
SQL-инъекции
, но результатыSQL-запроса
не возвращаются вHTTP-ответе
. В этом случае в базу данных выполняется запрос на любой из операторов true/false, и отслеживаются изменения для условий true и false. Этот тип подразделяется на два подтипа: - а) На основе данных в ответе сервера: здесь на сервер базы данных выполняется запрос с любым условным оператором, а
ответ
от сервера анализируется на наличие расхождений при отправке условияtrue
иfalse
. - б) С использованием времени ответа сервера: эта техника основана на добавлении SQL-запроса, который замедляет базу данных на определённое время в зависимости от указанного условия. Будет запрос true или false — зависит от времени ответа сервера.
- С использованием особенностей сервера: редкий тип
SQL-инъекции
, зависит от конкретных характеристик сервера базы данных. Использует способность сервера базы данных выполнять веб-запросы типаHTTP
,DNS
иftp
для отправки данных злоумышленнику.
Как защитить код от SQL-инъекции?
- Никогда не формируйте запрос непосредственно из пользовательских данных. Делайте это через параметризованные запросы. Онисоздают условия для того, чтобы данные, добавляемые в SQL-запросы, были в безопасности.
- Не будет лишним очистить данные перед сохранением в базе данных. Ну и нужно провести проверку вводимых данных: например, в имени не должно быть цифр, а в номере телефона — букв. Хотя и такие меры защиты не всегда помогают.
- Используйте безопасный драйвер для взаимодействия с БД SQL, такие как SQLAlchemy для Python, автоматически предотвращающие все атаки с применением SQL-инъекции.
Полезные ссылки
- SQL Map — инструмент с открытым исходным кодом, который
автоматизирует
процессвыявления
ииспользования
уязвимостей типа SQL-инъекций. - Репозиторий с целой кучей информации по
SQL-инъекциям
. Здесь можно найти шпаргалки и полезные нагрузки, которые пригодятся в самых разных ситуациях.
Читайте также:
Перевод статьи Ashwin Goel: A Beginner’s Guide to SQL Injection