SQL иньекции. Виды и примеры использования. Уроки хакинга. Глава 8.

SQL инъекция, или SQLi, является уязвимостью, которая позволяет хакеру “внедрять” SQL-утверждения в цель и получать доступ к её базе данных. Потенциал здесь довольно большой, что зачастую обнаруживает высокооплачиваемые уязвимости. Например, атакующие могут получить возможность выыполнять все или некоторые из CRUD-действий (Creating, Reading, Updating, Deleting, они же Создание, Чтение, Обновление и Удаление) в отношении информации в базе данных. Атакующие могут даже получить возможность удаленно выполнять команды.

SQL иньекции

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

  $name = $_GET[’name’];
  $query = ”SELECT * FROM users WHERE name = $name”;

Здесь передаваемое от пользователя значение вставляется прямо в запрос к базе данных. Если пользователь введет test’ OR 1=1, запрос вернет первую запись с name = test ИЛИ 1=1, то есть первую строку. В других случаях у вас может быть что-то такое:

  $query = ”SELECT * FROM users WHERE (name = $name AND p
  assword = 12345”);

В этом случае, если вы используете тот же самый код, test’ OR 1=1, ваше утверждение будет выглядеть так:

$query = ”SELECT * FROM users WHERE (name = ’test’ OR 1
  =1 AND password = 12345”);

И здесь запрос будет действовать несколько иначе (по крайней мере, с MySQL). Мы получим все записи, где name равно test и все записи, где пароль равен 12345. Это определенно не выполнит нашу цель, которая заключается в поиске первой записи в базе данных. В результате, нам понадобится устранить параметр password и мы можем сделать это с помощью комментария, test’ OR 1=1;–. Что мы сделали: мы добавили точку с запятой, чтобы корректно завершить SQL-утверждение, и тут же добавили два дефиса, чтобы заставить все, что следует за ними, расцениваться как комментарий и не выполняться. Это позволит нам получить тот же результат, что и в изначальном примере.

[ad name=»Responbl»]

Примеры SQL инъекции в Drupal

Сложность: Средняя
Url: Любой сайт на Drupal версии ниже 7.32
Ссылка на отчет: https://hackerone.com/reports/3175634 Дата отчета: 17 октября 2014
Выплаченное вознаграждение: $3000
Описание:

Drupal популярная система управления контентом, используемая для создания сайтов, очень похожая на WordPress и Joomla. Она написана на PHP и основана на модулях, что означает, что новая функциональность может быть добавлена к сайту на Drupal через установку модуля. Сообщество Drupal написало тысячи модулей и сделало их доступными бесплатно. Примеры включают магазины, интеграции со сторонними сервисами, создание контента, и так далее. Однако, каждая установка Drupal содержит один и тот же набор модулей ядра, используемых для запуска платформы и требующих подключения к базе данных. Обычно их называют ядром Drupal.

SQL иньекции

В 2014 команда безопасности Drupal выпустила срочное обновлени безопасности для ядра Drupal, обозначив, что все сайты на Drupal уязвимы к SQL инъекции, которая может быть осуществлена любым анонимным пользователем. Эффект этой уязвимости мог позволить атакующему захватить любой не обновленный сайт на Drupal.

Стефан Хорст обнаружил, что разработчики Drupal некорректно реализовали оберточную функциональность для осуществления запросов к БД, и она могла быть использована злоумышленниками. Точнее, Drupal использовала PHP Data Objects (PDO) как интерфейс для доступа к БД. Разработчики ядра Drupal написали код, который вызывал эти функции PDO и этот код Drupal использовался каждый раз, когда другие разработчики писали код для взаимодействия с базой данных Drupal. Это обычная практика в разработки программного обеспечения. Причина этого в том, чтобы позволить Drupal быть использованной с различными типами баз данных (MySQL, Postgres, и так далее), устранить сложность и предоставить стандартизацию.

SQL иньекции

Так вот, как оказалось, Стефан обнаружил, что обертка ядра Drupal делала некорректное предположение о передаваемом SQL-запросу массиве данных. Вот оригинальный код:

foreach ($data as $i => $value) {
 [...]
$new_keys[$key . ’_’ . $i] = $value; 4}

Видите ошибку (я не увидел)? Разработчики предположили, что массив данных всегда будет содержать цифровые ключи, такие, как 0, 1, 2, и так далее. (значение $i) и они присоединили переменную $key к $i и сделали его равным $value. Вот как выглядит типичный запрос от функции db_query, встроенной в Drupal:

1  db_query(”SELECT * FROM {users} WHERE name IN (:name)”,
2   array(’:name’=>array(’user1’,’user2’)));

Здесь функция db_query принимает запрос к БД SELECT * FROM {users} where name IN (:name) и массив значений, чтобы заменить болванки в запросе. В PHP, когда вы объявляюте массив как array(‘value’, ‘value2’, ‘value3’), он на самом деле создает [0 ⇒ ‘value’, 1 ⇒ ‘value2’, 2 ⇒ ‘value3’], где каждое значение доступно по цифровому ключу. В этом случае, переменная :name была заменена значениями в массиве [0 ⇒ ‘user1’, 1 ⇒ ‘user2’]. В результате мы получаем:

SELECT * FROM users WHERE name IN (:name_0, :name_1)

Пока неплохо. Проблема возникает, когда вы получаете массив, который не содержит цифровых ключей, как следующий:

1  db_query(”SELECT * FROM {users} where name IN (:name)”,
2    array(’:name’=>array(’test) -’ => ’user1’,’test’ =>
3   ’user2’)));

В этом случае, :name является массивом и его ключи таковы: ‘test) –’, ‘test’. Вы видите, куда все идет? Когда Drupal получает это и обрабатывает массив, создавая запрос, мы получаем следующее:

SELECT * FROM users WHERE name IN (:name_test) -, :name_test)

Может быть непросто увидеть, почему это так, так что давайте углубимся в детали. Основываясь на foreach, описанном выше, Drupal пройдется по всем элементам в массиве, один за другим. Далее, для первой итерации $i = test) – и $value = user1. Теперь, $key равен (:name) из запроса, и в сочетании с $i мы получаем name_test) –. Для второй итерации $i = test и $value = user2. В комбинации $key с $i мы получаем name_test. В результате болванка с :name_test, равная user2.

[ad name=»Responbl»]
Теперь, когда мы немного разобрались в этом, суть в том, что Drupal оборачивал поступающие объекты PHP PDO, потому что PDO позволяет это для нескольких запросов. Атакующий мог передать вредоносный ввод, вроде настоящего SQLзапроса на создание администраторского пользователя в качестве ключа массива, он был бы интерпретирован и выполнен как множество запросов.

Выводы

SQLi становится труднее найти, по крайней мере, судя по отчетам исследователей для этой книги. Этот пример был интересен, поскольку дело не просто в отправке одиночной кавычки и порче запроса. Скорее, дело в том, как код Drupal обрабатывал передаваемые внутренним функциям массивы. Это непросто заметить при слепом тестировании (где у вас нет доступа к коду). Вывод из этого следующий: ищите возможности к изменению структуры передаваемого сайту ввода. Там, где URL принимает ?name в качестве параметра, попробуйте передать массив вроде ?name[], чтобы посмотреть, как сайт с этим справится. Это может не выявить SQLi, но может привести к другому интересному поведению.

[ad name=»Responbl»]

SQL иньекции Итоги

SQLi может быть довольно значимым и опасным для сайта. Обнаружение этого типа уязвимости может привести к полному CRUD доступу к сайту. В некоторых случаях это может привести даже к возможности удаленного исполнения кода. Пример из Drupal был как раз таким случаем, где атакующие выполняли код через уязвимость. При поиске таких уязвимостей вы не только должны быть внимательны к возможностям передачи неэкранированных одиночных и двойных кавычек запросу, но так же и к возможностям передачи данных неожиданными способами, вроде замены параметров массива в данных POST.

Оглавление:

Базовые знания о HTTP протоколе. Глава 1

Что такое HTML иньекция. Уроки хакинга. Глава 2.

Что такое HPP (HTTP Parameter Pollution) атака? Уроки хакинга. Глава 3

Что такое CRLF инъекция, примеры использования. Уроки хакинга, Глава 4.

Уязвимости в логике приложений. Уроки хакинга. Глава 6

Уязвимости в логике работы приложений. Примеры.

Что такое XSS атака (Cross Site Scripting Attacks). Уроки хакинга. Глава 7.

SQL иньекции. Виды и примеры использования. Уроки хакинга. Глава 8.

Уязвимости Открытого Перенаправления. Уроки хакинга. Глава 9

Click to rate this post!
[Total: 11 Average: 4.1]

Специалист в области кибер-безопасности. Работал в ведущих компаниях занимающихся защитой и аналитикой компьютерных угроз. Цель данного блога - простым языком рассказать о сложных моментах защиты IT инфраструктур и сетей.

3 comments On SQL иньекции. Виды и примеры использования. Уроки хакинга. Глава 8.

Leave a reply:

Your email address will not be published.