- •Оглавление
- •Вступительное слово
- •Введение
- •Фоновые знания
- •HTML инъекция
- •Описание
- •Примеры
- •Итоги
- •HTTP Parameter Pollution
- •Описание
- •Примеры
- •Итоги
- •CRLF-инъекция
- •Описание
- •Итоги
- •Cross Site Request Forgery
- •Описание
- •Примеры
- •Итоги
- •Уязвимости в логике приложений
- •Описание
- •Примеры
- •Итоги
- •Cross Site Scripting Attacks
- •Описание
- •Примеры
- •Итоги
- •SQL инъекции
- •Описание
- •Примеры
- •Итоги
- •Уязвимости Открытого Перенаправления (Open Redirect)
- •Описание
- •Примеры
- •Итоги
- •Захват поддомена
- •Описание
- •Примеры
- •Выводы
- •Уязвимость XML External Entity
- •Описание
- •Примеры
- •Удаленное выполнение кода
- •Описание
- •Примеры
- •Итоги
- •Инъекция в шаблоны
- •Описание
- •Примеры
- •Итоги
- •Подделка запроса на стороне сервера (Server Side Request Forgery)
- •Описание
- •Примеры
- •Итог
- •Память
- •Описание
- •Нарушение целостности памяти
- •Примеры
- •Итоги
- •Приступаем к работе
- •Сеть, Поддомен и сбор ключевой информации
- •Просмотр и понимание приложения
- •Идентифицируйте используемые технологии
- •Погружаемся глубже для поиска уязвимостей
- •Отчёты об уязвимостях
- •Прочитайте рекомендации по раскрытию информации.
- •Добавьте деталей. Затем добавьте больше деталей.
- •Подтвердите уязвимость
- •Проявляйте уважение к компании
- •Вознаграждения
- •Слова напутствия
- •Инструменты Белого Хакера
- •Burp Suite
- •Knockpy
- •HostileSubBruteforcer
- •sqlmap
- •Nmap
- •Shodan
- •What CMS
- •Nikto
- •Recon-ng
- •Wireshark
- •Bucket Finder
- •Google Dorks
- •IPV4info.com
- •Плагины Firefox
- •Ресурсы
- •Онлайн обучение
- •Платформы выплаты вознаграждений за поиск багов
- •Дальнейшее чтение
- •Рекомендованные блоги
- •blog.it-securityguard.com
- •Словарь
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
SQL инъекции
Описание
SQL инъекция, или SQLi, является уязвимостью, которая позволяет хакеру “внедрять” SQL-утверждения в цель и получать доступ к её базе данных. Потенциал здесь довольно большой, что зачастую обнаруживает высокооплачиваемые уязвимости. Например, атакующие могут получить возможность выыполнять все или некоторые из CRUD-действий (Creating, Reading, Updating, Deleting, они же Создание, Чтение, Обновление и Удаление) в отношении информации в базе данных. Атакующие могут даже получить возможность удаленно выполнять команды.
SQLi-атаки обычно являются результатом неэкранированного ввода, передаваемого сайту и используемого как часть запроса к базе данных. Пример может выглядеть так:
1$name = $_GET[’name’];
2$query = ”SELECT * FROM users WHERE name = $name”;
Здесь передаваемое от пользователя значение вставляется прямо в запрос к базе данных. Если пользователь введет test’ OR 1=1, запрос вернет первую запись с name = test ИЛИ 1=1, то есть первую строку. В других случаях у вас может быть что-то такое:
1 $query = ”SELECT * FROM users WHERE (name = $name AND p\
2assword = 12345”);
В этом случае, если вы используете тот же самый код, test’ OR 1=1, ваше утверждение будет выглядеть так:
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
SQL инъекции
98
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
1 $query = ”SELECT * FROM users WHERE (name = ’test’ OR 1\
2=1 AND password = 12345”);
И здесь запрос будет действовать несколько иначе (по крайней мере, с MySQL). Мы получим все записи, где name равно test и все записи, где пароль равен 12345. Это определенно не выполнит нашу цель, которая заключается в поиске первой записи в базе данных. В результате, нам понадобится устранить параметр password и мы можем сделать это с помощью комментария, test’ OR 1=1;–. Что мы сделали: мы добавили точку с запятой, чтобы корректно завершить SQL-утверждение, и тут же добавили два дефиса, чтобы заставить все, что следует за ними, расцениваться как комментарий и не выполняться. Это позволит нам получить тот же результат, что и в изначальном примере.
Примеры
1. SQL инъекция в Drupal
Сложность: Средняя
Url: Любой сайт на Drupal версии ниже 7.32
Ссылка на отчет: https://hackerone.com/reports/31756³
Дата отчета: 17 октября 2014
Выплаченное вознаграждение: $3000
Описание:
Drupal - популярная система управления контентом, используемая для создания сайтов, очень похожая на Wordpress и Joomla. Она написана на PHP и основана на модулях, что
³ https://hackerone.com/reports/31756
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
SQL инъекции
99
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
означает, что новая функциональность может быть добавлена к сайту на Drupal через установку модуля. Сообщество Drupal написало тысячи модулей и сделало их доступными бесплатно. Примеры включают магазины, интеграции со сторонними сервисами, создание контента, и так далее. Однако, каждая установка Drupal содержит один и тот же набор модулей ядра, используемых для запуска платформы и требующих подключения к базе данных. Обычно их называют ядром Drupal.
В 2014 команда безопасности Drupal выпустила срочное обновлени безопасности для ядра Drupal, обозначив, что все сайты на Drupal уязвимы к SQL инъекции, которая может быть осуществлена любым анонимным пользователем. Эффект этой уязвимости мог позволить атакующему захватить любой не обновленный сайт на Drupal.
Стефан Хорст обнаружил, что разработчики Drupal некорректно реализовали оберточную функциональность для осуществления запросов к БД, и она могла быть использована злоумышленниками. Точнее, Drupal использовала PHP Data Objects (PDO) как интерфейс для доступа к БД. Разработчики ядра Drupal написали код, который вызывал эти функции PDO и этот код Drupal использовался каждый раз, когда другие разработчики писали код для взаимодействия с базой данных Drupal. Это обычная практика в разработки программного обеспечения. Причина этого в том, чтобы позволить Drupal быть использованной с различными типами баз данных (MySQL, Postgres, и так далее), устранить сложность и предоставить стандартизацию.
Так вот, как оказалось, Стефан обнаружил, что обертка ядра Drupal делала некорректное предположение о передаваемом SQL-запросу массиве данных. Вот оригинальный код:
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
SQL инъекции
100
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
1foreach ($data as $i => $value) {
2[...]
3 $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)”,\
2array(’: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’]. В результате мы получаем:
1SELECT * FROM users WHERE name IN (:name_0, :name_1)
Пока неплохо. Проблема возникает, когда вы получаете массив, который не содержит цифровых ключей, как следующий:
1db_query(”SELECT * FROM {users} where name IN (:name)”, 2 array(’:name’=>array(’test) -- ’ => ’user1’,’test’ =>\
3’user2’)));
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
SQL инъекции
101
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
В этом случае, :name является массивом и его ключи таковы: ‘test) –’, ‘test’. Вы видите, куда все идет? Когда Drupal получает это и обрабатывает массив, создавая запрос, мы получаем следующее:
1 SELECT * FROM users WHERE name IN (:name_test) -- , :na\
2me_test)
Может быть непросто увидеть, почему это так, так что давайте углубимся в детали. Основываясь на foreach, описанном выше, Drupal пройдется по всем элементам в массиве, один за другим. Далее, для первой итерации $i = test) – и $value = user1. Теперь, $key равен (:name) из запроса, и в сочетании с $i мы получаем name_test) –. Для второй итерации $i = test и $value = user2. В комбинации $key с $i мы получаем name_test. В результате болванка с :name_test, равная user2.
Теперь, когда мы немного разобрались в этом, суть в том, что Drupal оборачивал поступающие объекты PHP PDO, потому что PDO позволяет это для нескольких запросов. Атакующий мог передать вредоносный ввод, вроде настоящего SQLзапроса на создание администраторского пользователя в качестве ключа массива, он был бы интерпретирован и выполнен как множество запросов.