
Db Инструмент оценки баз данных
Инструмент оценки безопасности баз данных DbDat
DbDat выполняет множество проверок базы данных для оценки безопасности. Категории проверок: конфигурация, привилегии, пользователи и информация. Проверки выполняются путём выполнения запросов или чтения файлов конфигурации базы данных. Цель этого инструмента — выявить проблемы, требующие немедленного внимания, и определить настройки конфигурации, которые следует пересмотреть на предмет соответствия. Этот инструмент не предназначен для выявления уязвимостей SQL-инъекций в приложениях — для этого уже есть хорошие инструменты (например, https://github.com/sqlmapproject). Кроме того, этот инструмент не пытается определить, какие CVE могут повлиять на версию целевой базы данных (но, возможно, будет делать это в будущем). Скорее, этот инструмент поможет вам лучше понять потенциальное влияние успешной атаки SQL-инъекции из-за слабой конфигурации или контроля доступа. Большинство проверок основаны на эталонных показателях безопасности CIS (https://cisecurity.org) для баз данных, так что спасибо CIS! Документы с эталонными показателями можно найти здесь: https://benchmarks.cisecurity.org/downloads/browse/index.cfm?category=benchmarks.servers.database
Я настоятельно рекомендую загрузить эталонный документ для вашей целевой базы данных, так как он содержит дополнительную информацию о выполняемых проверках.
Наконец, DbDat задуман как платформа, позволяющая легко создавать новые плагины и проверки. Вклад сообщества специалистов по безопасности или даже администраторов баз данных сделает этот инструмент великолепным. Текущий набор проверок ни в коем случае не является полным; нужно сделать гораздо больше. Пожалуйста, вносите свой вклад!
Разработка новых проверок баз данных
Запросы на слияние приветствуются! Проверки организованы по типу базы данных (например, MySQL, Oracle, MS SQL и т.д.) в папке plugins. Каждая проверка представляет собой отдельный файл Python, имя которого должно начинаться с check_. Каждый файл содержит класс с методом do_check. Этот метод является основной логикой проверки. Быстрый способ начать — скопировать существующий файл проверки и изменить его. Однако подробнее см. раздел «Разработка плагинов» ниже.
etc/dbdat.conf для каждой базы данных, которую вы хотите оценить.python dbdat.py -p <имя профиля>python -m SimpleHTTPServer 9000 (или выберите предпочитаемый номер порта). Затем откройте браузер и перейдите по адресу http://localhost:9000.Чтобы увидеть список дополнительных аргументов командной строки, выполните python dbdat.py -h
Отчёт упорядочивает результаты по уровням: КРАСНЫЙ, ЖЁЛТЫЙ, ОРАНЖЕВЫЙ, СЕРЫЙ и ЗЕЛЁНЫЙ.
На данный момент DbDat протестирован в Debian Linux, CentOS Linux и Windows 7 с Python 2.7.
Выполните: pip install MySQL-python
Или в Debian выполните: apt-get install python-mysqldb
Выполните: pip install psycopg2
Выполните: pip install cx_Oracle
Примечание: для работы необходимо установить клиентские библиотеки Oracle.
Выполните: pip install pymssql
Выполните: pip install ibm_db или easy_install ibm_db
Примечание: необходимо убедиться, что пользователь, запускающий DbDat, имеет доступ к выполнению команд CLP DB2 (например, db2 и db2level).
Выполните: pip install pymongo
Для поддержки YAML-файлов конфигурации MongoDB выполните: pip install pyyaml
Выполните: pip install couchdb
В папке plugins есть папка для каждого типа базы данных, и каждая папка содержит файлы проверок. Это очень простая структура, но вы также можете просмотреть папку plugins, чтобы ознакомиться: https://github.com/foospidy/DbDat/tree/master/plugins
Папки базы данных содержат:
__init.py — файл инициализации содержит операторы импорта для каждого файла проверки.check_ файлы — это собственно файлы, выполняющие проверки базы данных. Файл и класс, определённый в файле, должны иметь одно и то же имя.helper.py — файл, содержащий общие функции. Файлы проверок могут импортировать helper.py для использования общих функций.При добавлении нового файла проверки необходимо добавить оператор импорта в соответствующий файл __init__.py директории плагина. Шаблон кода для проверок довольно единообразен. Просмотрите существующие файлы, чтобы понять их структуру. Обратите внимание на разницу между проверками типа sql и configuration_file.
Существуют разные «типы» проверок, которые можно определить. Тип проверки определяется переменной TYPE и может быть sql, configuration_file, nosql или clp. Ниже приведены примеры реализации для различных сценариев типа проверки.
Для проверок sql сигнатура метода do_check должна быть: do_check(self, *results)
https://github.com/foospidy/DbDat/blob/master/plugins/mysql/check_user_empty_password.py
В этом примере нам нужна переменная appuser из вызывающего родительского класса. appuser должен быть динамически добавлен в SQL-запрос, поэтому переменная self.SQL устанавливается в методе __init__. Кроме того, поскольку этому методу do_check необходимо выполнить SQL, нам также нужен курсор БД (соединение), который устанавливается в методе __init__ с помощью self.dbcurs = parent.dbcurs.
https://github.com/foospidy/DbDat/blob/master/plugins/mysql/check_privilege_user_grants.py
Для проверок configuration_file сигнатура метода do_check должна быть: do_check(self, configuration_file)
https://github.com/foospidy/DbDat/blob/master/plugins/mysql/check_configuration_general_log.py
В этом примере файл конфигурации PostgreSQL не имеет разделов (например, [section_name]), поэтому вспомогательный модуль в папке PostgreSQL содержит функцию, которая это обрабатывает. См. функцию get_config_value, определённую в helper.py.
Для других форматов файлов конфигурации вам потребуется определить собственную логику разбора.
Для проверок nosql сигнатура метода do_check должна быть: do_check(self)
Запросы NoSQL необходимо выполнять внутри метода do_check, поэтому метод класса __init__ должен реализовывать self.db = parent.db. Переменная self.db затем может использоваться для выполнения запросов NoSQL внутри метода do_check.
https://github.com/foospidy/DbDat/blob/master/plugins/mongodb/check_information_banner.py
Для проверок clp сигнатура метода do_check должна быть: do_check(self, *results). Проверки clp необходимы для баз данных IBM DB2, чтобы можно было выполнить процессор командной строки db2 для получения информации о базе данных. Однако этот тип проверки можно использовать для выполнения любой произвольной команды командной строки. Все выходные данные командной строки можно анализировать из переменной results, передаваемой в метод do_check. Кроме того, необходимо определить метод класса CMD. Эта переменная представляет собой список команды и связанных с ней аргументов.
https://github.com/foospidy/DbDat/blob/master/plugins/db2/check_privilege_group_entitlements.py
Каждая проверка должна иметь категорию, указанную с помощью переменной CATEGORY. Категория — это способ организации проверок. Возможные категории: Information, Configuration, Privilege и User. Укажите категорию, наиболее соответствующую контексту проверки.
Это примерный образец, демонстрирующий шаблон, которому должен следовать файл проверки:
# (ОПЦИОНАЛЬНО): Добавьте операторы импорта, включите любые необходимые модули для поддержки этой проверки
import helper
# (ОБЯЗАТЕЛЬНО): Определите класс, класс должен иметь то же имя, что и его файл.
class check_configuration_evaluate_something():
# (ОБЯЗАТЕЛЬНО): Добавьте документацию, предоставьте информацию об этой проверке, так как она будет отображаться в отчёте.
"""
check_configuration_evaluate_something:
Какое-то описание здесь!
"""
# (ОПЦИОНАЛЬНО): Добавьте ссылки, это только комментарии в коде, добавление ссылок полезно для других.
# References:
# https://www.percona.com/blog/2012/12/28/auditing-login-attempts-in-mysql/
# https://dev.mysql.com/doc/refman/5.7/en/password-security-user.html
# (ОБЯЗАТЕЛЬНО): Добавьте стандартный набор переменных
TITLE = 'Client Password'
CATEGORY = 'Configuration'
TYPE = 'configuration_file'
SQL = None
verbose = False
skip = False
result = {}
# (ОПЦИОНАЛЬНО): Добавьте любые пользовательские переменные, специфичные для этой проверки
custom_var = 'custom_val'
# (ОБЯЗАТЕЛЬНО): Определите метод do_check, это фактическая логика проверки, вызываемая основной программой.
def do_check(self, *results):
# (ОБЯЗАТЕЛЬНО): здесь находится логика проверки, обязательно установите значения для self.result['level'] и self.result['output']
# Результаты из переменной SQL можно обработать с помощью:
for rows in results:
for row in rows:
# (ОБЯЗАТЕЛЬНО):
# Всегда устанавливайте переменные self.result['level'] и self.result['output'] перед возвратом.
if row[0] == 'bad':
self.result['level'] = 'RED'
self.result['output'] = 'Результат: %s' % (row[0])
elif row[0] == 'needs review':
self.result['level'] = 'YELLOW'
self.result['output'] = 'Результат: %s' % (row[0])
else:
self.result['level'] = 'GREEN'
self.result['output'] = 'Результат: %s' % (row[0])
# Всегда возвращайте self.result
return self.result
# (ОБЯЗАТЕЛЬНО): как минимум метод __init__ должен выводить выполняемую проверку.
def __init__(self, parent):
print('Выполнение проверки: ' + self.TITLE)
# получить значения из вызывающего родительского класса
self.verbose = parent.verbose