top of page

SQL-инъекции. Основы | Часть #1

Сегодня мы поговорим о SQL-инъекциях – что это, с чем едят, и что с этим можно делать. Посмотрим на виды инъекций, на то как их можно автоматизировать, что можно добиться и как это все выглядит.

Всем салют, дорогие друзья! Сегодня мы с вами поговорим о SQL-инъекциях – что это, с чем едят, и что с этим можно делать. Посмотрим на виды инъекций, на то как их можно автоматизировать, чего можно добиться и как это все выглядит.


Как бы я не хотел затрагивать стартовые темы по типу “чем опасно составление запросов конкатенацией” или “что означает кавычка в параметре” – боюсь что без этого не обойтись. Все таки, конкретно эта статья рассчитана не тех людей, которые о SQL-инъекциях ранее не слышали вообще, да и в целом - раз уж собрались идти по порядку, пойдем по порядку. Здесь пишу для совсем еще новичков.


Понятно что затронуть тут все, начиная от основ и до последних уровней не выйдет, иначе статья превратится в книгу, поэтому тут разбираемся только с основной базой, на которой все строится. А копать глубже - кто знает, может уже в рамках нового цикла статей будет что-то про продвинутые инъекции.

 

Введение

Итак, давайте рассмотрим как вообще допускаются классические SQL-инъекции и как это все в общем выглядит.


У нас есть сайт/веб-приложение, которое работает с данными. Предположим, это какая-нибудь соцсеть. В этом случае, ей обязательно необходимо хранить данные как минимум одной бизнес-сущности – пользователя, так как вокруг этих персонажей и строится все. Их пол, возраст, имя и фамилия, емейлы, пароли и другая информация – все это необходимо где-то хранить.

Для этого и существую базы данных – некое веб-приложение, которое существует ровно для того, чтобы хранить данные других веб-приложений.

Если сразу смотреть по сути, чтобы не путаться потом в терминологии – База Данных, это общее название для некой абстрактной хреновины, внутри которой хранятся данные.

Но еще есть такая штука как СУБД или Система Управления Базами Данных. И вот это уже по сути имя собственное. СУБД и представляет из себя определенную программу, которая отвечает за то, чтобы доступ к данным можно было легко обеспечить, чтобы туда не лез кто попало и прочие важные функции

  • Проводя аналогию – База Данных, это набор книг в библиотеке, а СУБД – это директор библиотеки, который раздает указания кому какую книгу выдать, где кому ничего не выдавать, что можно передать в детский дом и что в школу, а еще какие книги вообще можно сжечь.

  • И при этом библиотеки могут быть разных названий – Пушкинская, Центральная, Библиотека МГУ и т.д. Но функции у них плюс минус одни и те же и каждая из них - библиотека. Надеюсь, аналогия ясна.

Сами же базы данных бывают двух типов - реляционные и не реляционные. Конкретно здесь нас будут интересовать только первые, реляционные или как раз же SQL базы данных.


Так что же представляют из себя реляционные БД? По сути, каждая база - это просто набор таблиц, содержащих в себе набор данных о каком-то одном определенном объекте. Таблицы могут быть связаны между собой, для того чтобы привязать к одной сущности данные других – например к пользователю список его постов.


Для того чтобы работать с этими данными используется особенный язык запросов. Он так и называется – SQL. Его синтаксис чем-то напоминает обычный английский в приказном тоне.

  • Например, стандартная команда по типу:

SQL:Скопировать в буфер обмена

SELECT ALL FROM USERS WHERE name = ‘John’;

Все достаточно просто и интуитивно, переводится как: выбери мне все записи из пользователей где имя – Джон. То есть, выбрать в табличке всех Джонов и вернуть их данные. Ничего сложного.

  • Так в чем же проблема и как возникает сама уязвимость, о которой так много говорят ?

Суть самой атаки заключается в том, что тот самый запрос, через который приложение обращается к базе, при определенном раздолбайстве разработчика пользователь может начать контролировать. Давайте рассмотрим, как это происходит на двух самых популярных примерах.

 

Обход авторизации

Представим ситуацию – у нас есть приложение, в котором реализована аутентификация по логину и паролю:

Все стандартно. Для того, чтобы понять где здесь может быть SQL-инъекция, нужно себе представить как вообще происходит процесс аутентификации. А происходит он примерно так:

  • Пользователь передает логин и пароль

  • Приложение сверяет эти данные с записями в базе

  • Если есть запись, в которой присутствуют этот логин и пароль – программа разрешает доступ

  • Если записи нет – нет и доступа

Проблемы, в случае SQL-инъекций возникают на этапе первых двух пунктов. Как вообще проверить наличие пользователя в базе? Логично, что нужно составить запрос, который вернет пользователя с нужным логином и паролем. То есть, запрос будет выглядеть примерно так:

SELECT * FROM Users WHERE login=’user’ AND password=’1234’;

Где user – логин, а password – пароль, введённые пользователем. Ну и казалось бы, в чем проблема? Берем от пользователя данные и просто подставляем их в запрос., примерно вот таким вот образом:

  • Но, проблема есть. И вот в чем она заключается:

Представьте себе ситуацию, что пользователь введет не просто свое имя, а добавит в конец свого логина символ ‘


И если мы подставим его логин напрямую в запрос, запрос станет выглядеть вот так:

SELECT ALL FROM Users WHERE login=’user’’ AND password=’1234’;

Видите? Кавычки стало две – одну добавил пользователь, а вторую мы добавили сами, когда создавали строку запроса. Язык SQL очень чувствителен к таким вещам и такой прикол с лишней кавычкой в запросе ему не понравится. Это вызовет ошибку запроса к бд, запрос выполнен не будет, а это в свою очередь приведет к ошибке на сервере:

А значит, первое что мы можем провернуть при помощи такой атаки – вызывать ошибку на стороне сервера. Это прикольно, но пользы как таковой не несет.


А что, если мы подставим в запрос не только кавычку? В языке SQL, как и в ЯП, есть, например, знаки комментариев, которые делают часть кода невидимой для обработчика.


А теперь представим что мы добавляем вот такой символ вместе с кавычкой: test’ --

  • Таким образом мы получаем уже вот такой запрос. И что же будет, если мы попытаемся выполнить запрос? Неожиданно мы авторизируемся:

Но как так вышло, если мы ввели только имя пользователя, а пароль был неверным? Еще раз взглянем на запрос – по сути, наш символ кавычки сначала закрыл ту секцию, куда попадал логин, а затем наш комментарий отбросил весь оставшийся код вот таким образом:

SELECT ALL FROM Users WHERE login=’user’ -- ’ AND password=’1234’;
 

Вытворяем всякие штуки с базой

Но сайты/веб-приложения ходят в базу не только для того, чтобы вытащить оттуда данные пользователей для авторизации.


Второй популярный пример – поиск. Предположим у нас есть приложение, которое хранит новости. И по новостям реализован поиск. Достаточно тривиальный пример:

Для начала попробуем представить, как будет выглядеть запрос в таком случае.

  • А выглядеть он будет примерно так:

SELECT ALL FROM news WHERE title LIKE '%text%';

Или, если провести аналогию – выбрать все значения из таблицы news, где в заголовке будет присутствовать слово text в любой позиции.


Логично, что уязвимым местом в данном случае будет выступать text, так как его задает пользователь, когда ищет новости.


Казалось бы – ну и что здесь можно сделать? Если попробовать подставить инъекцию из прошлого примера, то мы ничего не добьемся. Параметр то один и закрывать что-то еще нам без надобности. Но на самом деле, на этом этапе все только начинается.


Давайте представим что мы подставили инъекцию из прошлого примера. Запрос тогда будет выглядеть так:

SELECT ALL FROM news WHERE title LIKE ‘%text’  #%';

А теперь обратите внимание на выделенную желтым область. Перед ней закрывается параметр, а после нее стоит комментарий, отбрасывающий весь остальной запрос.


И вот как мы можем это использовать – в языке SQL в одном запросе мы можем записать несколько команд – например вытащить записи из одной таблицы, а потом сразу из другой.


Такие команды в рамках одного запроса разделяются точкой с запятой. Именно поэтому она стоит в конце каждой команды.


Представим что мы подставим в инъекцию следующий набор символов: ‘;#

  • И наш запрос примет вид:

SELECT ALL FROM news WHERE title LIKE ‘%text’;  #%';

И снова внимание на выделенную желтым область – теперь мы можем записывать туда любой запрос и он будет выполнен. Таким образом мы можем творить с базой все что захотим.


Разберемся по порядку. Обычно вся атака происходит в несколько этапов:

  1. Определение уязвимого места и расчистка промежутка

  2. Определение количества полей, которые приложение запрашивает из БД

  3. Определение отображения полей из предыдущего пункта на странице

  4. Определение цели и структуры таблицы

  5. Непосредственно, инъекция

А теперь давайте максимально подробно разберем каждый из 5 этапов... [Продолжение статьи уже завтра]

 

514 просмотров0 комментариев

Недавние посты

Смотреть все
bottom of page