Что такое отпечатки баз данных

«Безопасность — это не знание, какой замок на двери. Безопасность — это понимание, кто, как и зачем может этот замок открыть. Отпечаток СУБД — это не просто название базы данных, это ключ к её внутреннему миру, который для атакующего определяет, какой инструмент достать из арсенала, а для защитника — где спрятать ловушки.»

Идентификация СУБД (Database Fingerprinting)

Любая сложная атака через SQL-инъекцию начинается не с подбора паролей или выгрузки данных. Она начинается с простого вопроса: «А с чем я вообще работаю?» SQL — это стандарт, но его реализация разнится от системы к системе, как диалекты одного языка. Чтобы использовать самые мощные возможности или специфичные уязвимости, сначала нужно точно определить систему управления базами данных (СУБД) на стороне сервера.

Зачем это нужно на практике

Разные базы данных — это разные миры. То, что работает в PostgreSQL, вызовет синтаксическую ошибку в Oracle. Встроенная функция, которая вытащит системную информацию в Microsoft SQL Server, в MySQL просто не существует. Без точной идентификации злоумышленник действует вслепую, а защитник не может правильно настроить правила WAF или мониторинг аномалий. Это фундамент для последующих действий.

Среди распространённых целей могут быть:

  • Oracle Database: Частый гость в крупных государственных и финансовых системах.
  • MySQL / MariaDB: Основа миллионов веб-приложений.
  • PostgreSQL: Популярный выбор для новых корпоративных и геоинформационных систем.
  • Microsoft SQL Server (MSSQL): Часто встречается в инфраструктуре, построенной на стеке Microsoft.
  • SQLite: Используется во встраиваемых системах, мобильных приложениях, десктопном ПО.

Знание конкретной СУБД позволяет:

  1. Формировать рабочие, а не ошибочные, эксплуатационные запросы.
  2. Обращаться к специфичным для базы системным таблицам (например, information_schema в MySQL или pg_catalog в PostgreSQL) для разведки схемы данных.
  3. Использовать «хитрые» функции вроде выполнения команд ОС (например, через xp_cmdshell в MSSQL), если они доступны.
  4. Предсказывать поведение приложения при сложных UNION-атаках или слепых SQL-инъекциях.

Метод 1: Анализ сообщений об ошибках

Самый прямой путь к идентификации. Разработчики часто оставляют вывод ошибок от СУБД в ответах приложения для упрощения отладки. Эти сообщения строго формализованы и являются уникальной подписью.

Характерные шаблоны ошибок

СУБД Типичный формат ошибки Что искать
MySQL You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version... Упоминание «MySQL», коды ошибок вида #1064.
Microsoft SQL Server Unclosed quotation mark after the character string... с префиксом Msg 102, Level 15... или в связке с ASP.NET: Server Error in '/' Application. Префикс «Msg», структура ошибок Microsoft, ссылки на .NET.
Oracle Database ORA-00933: SQL command not properly ended Уникальный префикс ORA-, за которым следует код ошибки.
PostgreSQL ERROR: unterminated quoted string at or near "'" с указанием позиции (Position: 1). Слово ERROR:, часто с детальным указанием позиции в запросе.
SQLite SQLITE_ERROR: SQL error or missing database Прямое упоминание «SQLITE» в тексте.

Важный нюанс: современные фреймворки и ORM (например, Hibernate, Eloquent) могут перехватывать низкоуровневые ошибки СУБД и оборачивать их в унифицированные сообщения. В таких случаях текст может не содержать явных указаний, но структура или код ошибки в JSON-ответе API всё ещё могут быть унаследованы от драйвера базы данных.

Метод 2: Тестирование через синтаксис SQL

Когда ошибки скрыты (режим production), на помощь приходит активное зондирование. Идея в том, чтобы отправить запрос, который по-разному интерпретируется разными СУБД, и по косвенному результату (изменение вывода приложения, временная задержка, факт наличия ошибки) сделать вывод.

Конкатенация строк как индикатор

Оператор для склеивания строк — отличный дифференциатор.

СУБД Стандартный оператор конкатенации Реакция на 'abc'||'def'
Oracle, PostgreSQL, SQLite || (двойная вертикальная черта) Успех, вернёт abcdef (или данные изменятся соответственно).
MySQL CONCAT(). Оператор + работает как сложение чисел. Часто молчаливый провал или результат 0.
Microsoft SQL Server + (плюс). Успех при использовании +. Оператор || вызовет ошибку.

Пример слепого теста: если в уязвимый параметр передать 'abc'||'def' и содержимое страницы изменится (например, склеятся два поля), вероятно, на backend стоит PostgreSQL или Oracle. Если поведение не изменилось или появилась пустая запись — это указывает на MySQL.

Использование специфичных функций и переменных

Можно напрямую «спросить» базу о её версии через заведомо уникальные для каждой СУБД конструкции в составе UNION-запроса или условного оператора.

/* Проверка для MySQL / MariaDB */
SELECT @@version, version()
/* Проверка для Microsoft SQL Server */
SELECT @@VERSION
/* Проверка для PostgreSQL */
SELECT version()
/* Проверка для Oracle */
SELECT banner FROM v$version

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

Метод 3: Анализ через «слепые» техники

В самых жёстких условиях, когда приложение не возвращает ни данных, ни ошибок, работает метод временных задержек (Time-Based Blind SQLi). Принцип: используем функцию, вызывающую паузу, специфичную для конкретной СУБД.


/* Для PostgreSQL: функция pg_sleep() */
1' AND (SELECT pg_sleep(5))--
/* Для MySQL: функция SLEEP() */
1' AND SLEEP(5)--
/* Для Microsoft SQL Server: WAITFOR DELAY */
1'; WAITFOR DELAY '00:00:05'--
/* Для Oracle: dbms_pipe.receive_message() */
1' AND (SELECT CASE WHEN (1=1) THEN dbms_pipe.receive_message('a',5) ELSE 1 END FROM dual)--

Если после отправки такой полезной нагрузки ответ сервера задерживается примерно на указанное время (5 секунд), это не только подтверждает уязвимость, но и чётко идентифицирует СУБД.

Защита и обнаружение: что с этим делать

С точки зрения ФСТЭК и 152-ФЗ, процесс снятия отпечатка — это этап разведки, предшествующий непосредственной атаке. Его сложнее обнаружить, чем саму попытку вставки или удаления данных.

Для защиты:

  • Унификация ошибок: Все ошибки СУБД должны перехватываться на уровне приложения и заменяться на общие сообщения без технических деталей («Произошла внутренняя ошибка»).
  • Параметризованные запросы (prepared statements): Главное средство против SQLi, которое по умолчанию лишает смысла большинство техник снятия отпечатков, так как данные и код запроса разделены.
  • WAF с сигнатурами на разведку: Современные WAF должны детектировать не только UNION SELECT, но и попытки вызвать pg_sleep(), version(), WAITFOR в подозрительном контексте.
  • Мониторинг аномалий: Множество идентичных запросов с небольшими вариациями в SQL-синтаксисе (пробующего то ||, то +, то CONCAT()) — явный сигнал о проводимой разведке.

Идентификация СУБД — это не академическое упражнение, а практический, обязательный шаг в цепочке эксплуатации уязвимости. Понимание её методов позволяет не только лучше атаковать, но и, что гораздо важнее, выстраивать более осмысленную и глубокую защиту, предугадывая следующий шаг потенциального нарушителя.

Оставьте комментарий