- Вопрос или проблема
- Ответ или решение
- Как узнать, какая база данных используется в веб-приложении?
- Введение: Для чего это нужно?
- 1. Понимание контекста приложения
- 1.1. Язык программирования и фреймворки
- 1.2. Анализ структуры URL и HTTP заголовков
- 2. Проверка ошибок
- 3. Использование SQL-функций для определения базы данных
- 4. Синтаксические различия
- 5. Инструменты и автоматизация
- 6. Наблюдение за поведением приложения
- Заключение
Вопрос или проблема
Я читал, что разные базы данных (mysql, sql server и т.д.) имеют различные уязвимости и что они уязвимы к некоторым специфическим SQL-инъекциям.
Когда злоумышленник пытается осуществить атакy на базу данных против веб-сайта (например, SQL-инъекцию), прежде всего он определяет тип базы данных, а затем выполняет атаку, учитывая обнаруженную базу данных.
Как такая предварительная проверка выполняется злоумышленником? С помощью каких-то специальных запросов? Существуют ли специальные инструменты? Я не нашел никакой информации об этом.
Предположим, у вас есть такой запрос:
$q="SELECT username, joindate FROM users WHERE username LIKE '%" . $search . "%' LIMIT 20";
Теперь представьте, что вы контролируете $search
через параметр. Обычно мы можем сделать так, чтобы он возвращал пароли пользователей в поле joindate
следующим образом:
$search="' UNION SELECT username, password FROM users; -- -";
Таким образом, запрос становится:
SELECT username, joindate FROM users WHERE username LIKE '%' UNION SELECT username, password FROM users; -- - %' LIMIT 20
Часть после двойного дефиса является комментарием, поэтому она игнорируется, и мы получаем все комбинации имени пользователя и пароля, добавленные как новые записи в конце набора данных, после легитимных записей. Здорово!
Но теперь мы хотим адаптировать это так, чтобы мы могли найти имя базы данных для дальнейшего исследования их базы данных. В MySQL мы можем использовать функцию DATABASE()
:
$search="' UNION SELECT DATABASE(), 1; -- -";
Использование 1
здесь предназначено для дополнения поля joindate
, которое мы не используем.
В MSSQL мы можем сделать то же самое, но с DB_NAME()
:
$search="' UNION SELECT DB_NAME(), 1; -- -";
Оба этих трюка добавят одну строку в конец набора результатов, содержащую имя базы данных.
Затем мы можем расширить этот трюк, чтобы использовать VERSION()
в MySQL или @@VERSION
в MSSQL, который возвращает текущую версию базы данных. Для Oracle и PL/SQL вы можете проверить наличие таблицы v$version
, просто выполнив запрос к ней и проверив на наличие ошибки.
В дополнение к другим ответам, один из методов, который я использую для отпечатков базы данных (особенно когда инъекция слепая и данные не возвращаются), – это различия в синтаксисе между движками баз данных. Хороший пример есть на слайде 34 этой презентации, которую я часто использую.
Так что хороший пример – это конкатенация строк. MS-SQL и DB2 используют +, тогда как Oracle PL/SQL и PostGRES используют ||, так что вы можете вставить это в строки и наблюдать за поведением приложения. Если оно ведет себя так, как будто строка была конкатенирована, то это, возможно, инъекция.
Один из самых простых способов для злоумышленника определить, какая база данных используется приложением, заключается в том, чтобы вызвать какую-то ошибку приложения с помощью запроса к базе данных.
Затем, если обработка ошибок не включена в приложении (что часто не так), будет показана ошибка базы данных. Обычно они довольно подробные, и вы можете определить базу данных по этому.
Также стоит учитывать, если вы знаете какой-либо из следующих факторов: язык, на котором написано веб-приложение, используемый фреймворк, использующаяся платформа, хостинг-провайдер и т.д., они могут помочь определить, какая база данных используется. Например, если они используют asp, скорее всего, будет использоваться MSSQL, а если они используют PHP, скорее всего, MySQL. Это не всегда верно, но если вам нужно угадывать, скажем, при слепой SQL-инъекции, это ещё один способ сузить круг.
Существует множество методов для этого. Однако, обратите внимание, что вам не нужно знать тип базы данных, чтобы провести атаку. Знание этого может дать дополнительные или альтернативные векторы атаки, но не является необходимым для SQL-инъекции.
Большинство баз данных предоставляют функции или имеют словарные таблицы, которые можно использовать для определения типа и версии базы данных. Они различаются между поставщиками, но, если вы нашли общий токен SQL-инъекции, вы можете просто попробовать каждую, пока не получите действительный ответ.
Существуют также синтаксические различия между многими различными диалектами SQL. Например, Oracle имеет синтаксис (+) для представления внешних соединений. Часто есть тонкие различия в доступных типах данных, таких как тип текста Postgres (которого нет в Oracle) или в том, как обрабатываются последовательности/автоинкрементируемые столбцы и т.д.
Иногда вы можете это определить, получив информацию о драйверах базы данных или соединителях. В зависимости от окружения, языка и т.д. это может быть тривиально, а может и нет.
Нет универсального способа узнать поставщика базы данных.
Кроме того, это может быть более одной базы данных, например, MySQL + ElastiSearch + Neo4J + Jena + Redis. В противоположном случае может не быть базы данных, например, веб-сайт обслуживается статически.
Я бы следовал следующим шагам:
- Определите приложение. Например, у вас есть Drupal или WordPress?
- Определите список возможных баз данных. Например, если вы обнаружите Drupal, вероятно, он был настроен с MySQL или Postgres, а не с MongoDB.
- Определите крайние случаи, специфичные для приложения, когда приложение ведет себя по-другому. Например, один адрес может возвращать “404 не найдено”, если вы используете Postgres, но тот же самый вернет “403 доступ запрещен”, если используется MySQL.
- Основываясь на ваших оффлайн находках, просканируйте сайт и улучшите свою ситуационную осведомленность.
Если вы используете существующие сканеры, есть вероятность, что владелец приложения знает об этом и может ввести вас в заблуждение. Например, я регулярно заставляю ошибку 404 выглядеть как IIS, если я работаю на Linux/Apache. Это убедит хакера попробовать эксплойты Windows/IIS, в отличие от эксплойтов Apache. Также это не имеет никакого влияния на обычного пользователя.
Ответ или решение
Как узнать, какая база данных используется в веб-приложении?
Введение: Для чего это нужно?
Определение типа базы данных, используемой в веб-приложении, является важным шагом для специалистов по информационной безопасности и злоумышленников, так как разные СУБД имеют свои особенности, уязвимости и поведение, которые могут влиять на методы атаки, такие как SQL-инъекции. В этом ответе мы рассмотрим, как можно выяснить, какая база данных используется, и какие существуют методы и инструменты для этого.
1. Понимание контекста приложения
1.1. Язык программирования и фреймворки
Первым шагом в определении базы данных является анализ языка программирования и используемого фреймворка. Например, если веб-приложение написано на PHP, то наиболее вероятные варианты базы данных могут быть MySQL или PostgreSQL. Аналогично, если используется ASP.NET, в большинстве случаев это будет MS SQL Server.
1.2. Анализ структуры URL и HTTP заголовков
Изучение структуры URL и HTTP заголовков также может дать подсказки о типе используемой базы данных. Например, если URL начинается с wp-
, вероятно, это WordPress, который чаще всего использует MySQL.
2. Проверка ошибок
Одним из самых простых способов определить тип базы данных является вызов ошибки на уровне SQL-запроса. Если обработка ошибок в приложении не настроена, это может привести к выводу подробной информации о базе данных. Например, много СУБД будут генерировать специфичные сообщения об ошибках, которые содержат информацию о типе базы. Некоторые примеры ошибок могут выглядеть так:
- MySQL: "You have an error in your SQL syntax"
- PostgreSQL: "ERROR: syntax error at or near"
- MS SQL Server: "Msg 156, Level 15"
3. Использование SQL-функций для определения базы данных
Нахождение типа базы данных можно выполнить путем инъекции специальных SQL-функций, которые возвращают информацию о базе данных:
- Для MySQL:
' UNION SELECT DATABASE(), 1; -- -
- Для MS SQL Server:
' UNION SELECT DB_NAME(), 1; -- -
- Для PostgreSQL можно использовать:
' UNION SELECT current_database(), 1; -- -
Каждый из этих запросов вставляет дополнительную строку в результат, содержащую имя базы данных.
4. Синтаксические различия
Разные СУБД используют различные синтаксисы для выполнения одних и тех же операций. Например:
- Конкатенация строк: MS SQL и DB2 используют
+
, тогда как Oracle PL/SQL и PostgreSQL используют||
. - Условия соединения: Oracle использует
(+),
в то время как другие системы используютLEFT JOIN
иRIGHT JOIN
.
Использование этих особенностей может помочь определить тип базы данных.
5. Инструменты и автоматизация
Существует множество инструментов для проведения тестирования на уязвимости и определения типа СУБД. Некоторые из них:
- SQLMap: Это инструмент для автоматизации процесса обнаружения и эксплуатации SQL-инъекций, который также способен определять тип базы данных.
- Burp Suite: Позволяет перехватывать трафик и анализировать запросы для поиска уязвимостей.
6. Наблюдение за поведением приложения
При работе с веб-приложениями стоит обращать внимание на поведение приложения в ответ на определенные запросы. Например, различные типы баз данных могут по-разному обрабатывать вводимые данные или предоставлять разные ответы на одинаковые запросы. Это может помочь в создании более широкой картины о том, какая СУБД используется.
Заключение
Определение, какая база данных используется в веб-приложении, требует комплексного подхода, включающего анализ языка программирования, обработки ошибок, использование SQL-функций, понимание синтаксических отличий и использование специальных инструментов. Овладение этими навыками поможет не только специалистам по безопасности, но и разработчикам для лучшего понимания возможных уязвимостей в своих приложениях.