Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / white-hat-hacking-ru.pdf
Скачиваний:
15
Добавлен:
19.04.2024
Размер:
6.49 Mб
Скачать

 

 

 

 

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запроса на создание администраторского пользователя в качестве ключа массива, он был бы интерпретирован и выполнен как множество запросов.