Повторное использование парсера MySQL
Вопрос
Я работаю над SQL система обнаружения вторжений (IDS) и мне нужно выполнить синтаксический анализ входящих SQL-запросов.Написание собственного анализатора SQL - это долгосрочная задача, и она никогда не будет точно отражать логику, используемую в собственном анализаторе.Я узнал, что в MySQL есть лексический анализатор с основным исходным файлом sql/sql_lex.cc
и синтаксический анализатор, построенный с помощью bison из sql/sql_yacc.y
.Я действительно заинтересован в повторном использовании этого надежного решения.Я создаю свои идентификаторы на C / C ++, поэтому я ищу какой-нибудь способ подключить анализатор MySQL к моей системе обнаружения.
Мне было интересно, возможно ли повторно использовать анализатор MySQL (лексический + синтаксический анализатор), чтобы получить структуру SQL-запроса в некоторой логической форме, напримерсинтаксическое дерево.Было бы ли это возможно?Есть ли какой-нибудь связанный текст, учебные пособия или проекты?
Спасибо
Решение
Я закончил первую версию своих удостоверений личности в рамках моего бакалаврского проекта.Он реализован как плагин для MySQL.
Ниже я перечислю свои основные источники для понимания внутренних компонентов MySQL.Затем я кратко опишу подход, который я использовал в своих IDS.
Тексты документации MySQL
- Я нашел книги Эксперт MySQL Автор: Чарльз Белл и Понимание внутренних компонентов MySQL Автор: Саша Пачев (как написал пользователь3822447), чтобы быть очень хорошей отправной точкой для понимания внутренностей MySQL.
- Разработка плагина MySQL 5.1 Автор: Эндрю Хатчингс и Сергей Голубчик это тоже очень полезно.
- Тот Самый Руководство по внутренним функциям MySQL также содержит некоторую базовую информацию, с которой полезно начать.
- После всего прочитанного я сделал сом отладка (используя VS) и обнаружил, как выглядит древовидная структура запроса.
Мое решение для идентификаторов
Исходный код моего решения можно найти по адресу кузница- источник.Я планирую подробнее задокументировать это в своей wiki.
Основной точкой входа является audit_ids_notify()
функция в audit_ids.cc
.Плагин берет дерево запросов, сгенерированное внутренним анализатором MySQL, и создает его упрощенную версию (для экономии памяти).Затем он выполняет обнаружение аномалий - у него есть список известных древовидных структур запросов и сохраняется некоторая статистическая информация о каждой параметризуемой части каждой древовидной структуры запросов.Выходные данные записываются в специальный файл журнала в каталоге данных MySQL.
Я попытался сделать решение модульным и расширяемым.Начальная версия является своего рода демонстрацией, и производительность не оптимизирована, особенно в модуле хранения SQL.
Тип плагина MySQL
Я определил 2 возможных подхода и использовал первый.
- плагин для аудита
- Тип оболочки в моем плагине для решения следующий плагин для аудита.
- Я использовал плагины этого типа, несмотря на то, что они использовались для отчетов о работе сервера (напримеррегистрировать запросы или ошибки).
- Я выбрал этот тип плагина, потому что обнаружил, что это единственный поддерживаемый плагин, который вызывается, когда дерево запросов находится после завершения (т. е.проанализирован) и до того, как он будет освобожден из памяти (для MySQL 5.6.17).
- Недостаток:вышесказанное не полностью гарантировано в будущих версиях MySQL, но, на мой взгляд, это не должно измениться в ближайшем будущем.
- Преимущество:MySQL не нуждается в перекомпиляции.Этого достаточно для сборки и установки плагина.
- плагин для перезаписи запросов
- Существует также альтернативный подход, делающий это с использованием неродного типа плагина запрос-перезапись.Он предоставил plugin API для изменения запроса, а следовательно, и для его чтения.
- Недостаток:для поддержки этого плагина API сервер MySQL должен быть перекомпилирован с помощью API.Я думаю, что это может стать частью производственного дистрибутива MySQL.
- Преимущество:тип плагина, предназначенный для чтения / перезаписи внутреннего дерева запросов.
Если есть какие-то вопросы / проблемы, связанные с этой темой, на которые я мог бы ответить, не стесняйтесь спрашивать ;)
Другие советы
Я верю, что это возможно.Попробуйте ознакомиться с книгой "Продвинутые внутренности MySQL", такой как "Эксперт MySQL" Чарльза Белла или "Понимание внутренностей MySQL" Саши Пачева.MySQL использует пользовательский лексер ручной сборки и универсальный синтаксический анализатор, совместимый с Bison, с которым совместим их лексер.
Помимо этого, вы можете найти более простое решение, чем синтаксический анализ запроса, например:
- Стратегия №1:Выбросьте запрос и просто посмотрите на содержимое строк внутри запроса.Ищите возможные векторы атаки, такие как ключевые слова SQL.Это может привести к обнаружению попыток атаки.
- Стратегия №2:Выбросьте весь пользовательский ввод и составьте список остального содержимого запроса.Составьте список всех шаблонов запросов по ключевым словам и сравните их друг с другом.Ищите запросы с аномальной структурой, которые указывают на то, что кто-то успешно изменил запрос.
Я не гуру SQL, но самая базовая стратегия - просто использовать параметризованные запросы и игнорировать попытки проникновения.Большинство таких попыток в Интернете являются общими, случайными запросами, предназначенными для выявления очевидных слабых мест, и их можно безопасно игнорировать, если вы повсюду будете следовать базовым правилам безопасности.