Как происходит эксплуатация слепой SQL-инъекции путем запуска условных ответов
![](https://webcf.waybackmachine.org/web/20230601194155/https://habrastorage.org/getpro/habr/upload_files/007/269/958/007269958ca0ab9f624cf0282873cb9d.png)
Начнем с того, что такое слепая инъекция
Слепая инъекция SQL - это тип атаки SQLi, которая задает базе данных истинные или ложные вопросы и определяет истинность на основе ответа приложений. Эта атака часто используется, когда веб-приложение настроено на отображение общих сообщений об ошибках, но при этом не фильтрует код, уязвимый для внедрения SQL.
Отличия слепой инъекции от обычной в том, что в обычной данные извлекаются из базы данных. Когда база данных не выводит данные на веб-страницу, злоумышленник может попробовать выкрасть данные, задавая базе данных ряд истинных или ложных вопросов.
Теперь разберем в деталях
К примеру, есть веб-приложение, которое использует файлы cookie, которые в свою очередь отслеживают и собирают аналитику использования приложением.
Запросы к веб-приложению включают такой заголовок cookie:
Cookie:TrackingId=u5YD3PapBcR4lN3e7Tj4
Когда мы отправляем запрос к файлу TrackingId, приложение определяет, является ли пользователь "известным" для этого приложения, с помощью подобного SQL-запроса:
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'
Результаты запроса не возвращаются пользователю. Однако приложение ведет себя по-разному в зависимости от того, возвращает ли запрос какие-либо данные. Если он возвращает данные (поскольку был отправлен распознанный TrackingId), то на странице условно отображается сообщение 'Добро пожаловать обратно'.
Этого достаточно для использования уязвимости слепой SQL-инъекции и извлечения информации, вызывая различные ответы условно, в зависимости от введенного условия. Как это работает, на примере: предположим, что два запроса отправлены по очереди, содержат следующие значения cookie TrackingId:
…xyz' AND '1'='1
…xyz' AND '1'='2
Первый запрос вернет результаты, поскольку введенное условие AND '1'='1 истинно, и поэтому будет отображаться сообщение 'Добро пожаловать'. Второй запрос не вернет никаких результатов, поскольку введенное условие является ложным, и поэтому сообщение 'Добро пожаловать обратно' не будет отображаться. Это дает возможность определить ответ на любое введенное условие и, таким образом, извлекать данные по одному биту за раз.
Например, есть таблица 'Пользователи' со столбцами 'Имя пользователя' и 'Пароль'. А также пользователь с именем 'Администратор'. Мы можем систематически определять пароль для нужного нам пользователя, отправляя серию входных данных для проверки пароля по одному символу за раз.
Cледующий ввод запроса будет таким:
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
Такой процесс эксплуатации слепой инъекции дает возможность систематически определять полный пароль для пользователя-администратора.
Далее тема использования слепых SQL-инъекций путем запуска временных задержек.
Мы можем изменить условия из предыдущих примеров. Теперь приложение перехватывает ошибки базы данных и корректно их обрабатывает. Запуск ошибки базы данных при выполнении введенного 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-запросах, и к разным типам баз данных применяются разные методы.