
Этот проект генерирует DNS zone-файлы с пользовательскими параметрами NSEC3 для воспроизведения и оценки атак в CVE-2023-50868.
Этот проект генерирует DNS-зонные файлы с пользовательскими параметрами NSEC3 для воспроизведения и оценки атак, описанных в CVE-2023-50868.
Python3 (протестировано на Python3.10)
Установленные зависимости Python:
lib: Вспомогательные модули Python, включающие:
keys.py: Функции-обёртки для загрузки/сохранения ключей в файлыnsec.py: Реализация хешей NSEC для DNSSECdnssec.py: Модифицированные/исправленные функции dnspython с поддержкой NSEC3config.py: Утилиты загрузки конфигурацииkeys: PEM-файлы с предварительно сгенерированными ключами (созданы с помощью gen_keys.py)zones: Зонные файлы (созданы с помощью gen_zones.py)config.json: Пример конфигурацииНастройте, какие зоны NSEC3 должны быть созданы, изменив config.json (см. Config)
Сгенерируйте ключи:
$ ./gen_keys.py
Для каждой зоны генерируются KSK и ZSK. Ключи переиспользуются при изменении конфигурации, если имена зон в конфигурации остаются неизменными.
Сгенерируйте зонные файлы:
$ ./gen_zones.py -c
Опция -c включает экспорт файлов конфигурации (в настоящее время только для BIND9)
Используйте --help для дополнительных опций.
Структура конфигурации содержит два элемента:
default: Параметры по умолчанию для зон (на данный момент поддерживаются не все)zones: Список всех экспортируемых зонЗона содержит:
name (обязательно): Имя, используемое при ссылке на зону и в качестве имени файла при экспортеorigin (обязательно): Каноническое доменное имя начала зоныparent: Имя родительской зоны (не начало зоны), к которому добавляются NS, A, DS и NSEC3PARAM записи этой зоныkeysize (обязательно): Размер ключа RSA (пока поддерживается только RSA)nsec3: Параметры NSEC3:
iterations: по умолчанию 0salt: по умолчанию ''algorithm: Целое число, в настоящее время поддерживается только SHA-1 (1)tight: Специальный логический параметр, который контролирует, нужно ли добавлять NSEC3 записи сразу после начала зоны, а также до и после *.origin. Например, если для *.origin есть NSEC3 запись 1d..ua.origin., то записи для 1d..u0.origin. и 1d..ub.origin. также добавляются в зонный файл. Это гарантирует, что каждое доказательство NXDOMAIN для поддомена origin (например, a.origin.) требует три NSEC3 записи, так как NSEC3 записи, покрывающие origin и wildcard, имеют очень маленький диапазон до next_hashns: Сервер(ы) имён этой зоны. Одно значение или список:
ns: Доменное имя сервера имён, по умолчанию ns1.originip: IPv4-адрес (IPv6 пока не поддерживается), по умолчанию 172.0.0.1soa: RDATA записи SOArrsets: Список дополнительных наборов RR, заданный в виде списка из 5 элементов [domain name, ttl, class, type, rdata], где все значения (кроме, опционально, ttl) задаются строкамиДля воспроизведения атаки NSEC3 в этом разделе показана возможная пользовательская настройка, состоящая из DNS-сервера имён и резолвера-жертвы. Прежде чем продолжить, убедитесь, что в системном окружении настроен брандмауэр, чтобы не подвергать публичные серверы атакующим зонным файлам.
Установите сервер имён NSD (текущую версию)
Перейдите на сайт NLNetlabs (https://nsd.docs.nlnetlabs.nl/en/latest/installation.html) для получения инструкций по установке.
Рекомендуется развернуть сервер имён в виртуальной машине или контейнере. В качестве отправной точки в docker/nsd есть небольшой Dockerfile.
Соберите контейнер с помощью docker build -t <tag> <path_to_dockerfile>, например:
cd docker/nsd && docker build -t nsd .
Запустите контейнер с помощью docker run -it --name <name> nsd bash, чтобы открыть консоль внутри контейнера.
Далее сервер имён необходимо настроить для размещения атакующих зонных файлов.
Это требует правильной настройки генерируемых зонных файлов (самое главное, чтобы IP-адрес, указанный в NS-записях, соответствовал IP-адресу контейнера).
Если сеть не была настроена, IP-адрес контейнера можно посмотреть с помощью:
docker container inspect <name> | grep IPAddress
Сгенерируйте зоны с выводом конфигурации (./gen_zones.py -c, см. выше) и скопируйте папку с выведенными зонами из каталога репозитория в контейнер Docker:
docker cp ./zones <name>:/etc/nsd
В консоли контейнера необходимо дополнить конфигурацию NSD /etc/nsd/nsd.conf следующими строками:
verify:
enable: no
remote-control:
control-enable: no
include: "/etc/nsd/zones/nsd.conf"
Наконец, запустите NSD из командной оболочки контейнера с помощью команды
/usr/sbin/nsd -d -c /etc/nsd/nsd.conf
Включите вывод журнала с помощью опции -V 4.
Теперь, если не возникло проблем, авторитетный сервер имён должен работать. Вы можете проверить это, выполнив запрос к одному из доменов зон с хост-системы с помощью dig:
dig @<ip-addr-of-nsd-container> <domain>
Установите резолвер. В этой демонстрации мы показываем возможный подход для Unbound 1.17.1.
Официальный Dockerfile можно найти здесь: https://github.com/NLnetLabs/pythonunbound
Мы включили модифицированную версию этого Dockerfile в docker/unbound с обновлённой версией Ubuntu и предварительной настройкой под Unbound 1.17.1.
Клонируйте репозиторий, перейдите в его каталог и соберите контейнер Unbound:
docker build -t <tag> .
Запустите контейнер с помощью:
docker run --name <name> -it <tag> bash
Далее Unbound нужно настроить так, чтобы он мог найти авторитетный сервер имён NSD.
Это делается путём изменения файла unbound.conf в рабочем каталоге контейнера.
Для этого убедитесь, что запись server.module-config удалена из конфигурации.
Для включения проверки DNSSEC необходимо вручную настроить DNSKEY-записи родительской зоны атакующего. Это должен быть тот же ключ, который использовался для генерации подписей, например:
server:
chroot: ""
do-ip6: no
trust-anchor: "attack.er. DNSKEY 257 3 7 AwEAAdqDN3rJYlmGP3jJs5lCZq5NYrCn pCVlV0ko17JnbfYfLCroEF4reO/Xy0MK C9AVvSRTk83MHDuzMYXogm7m/gcn3Mh0 MwB2InP8jkPw5not+TMH/Wrbs31xkT2n RIBJJ+1lPF+e2AvwWvgREcEVTRbdhIqQ iM1StWXoTVudry4V"
Кроме того, необходимо настроить stub-зону, чтобы резолвер Unbound мог найти авторитетный сервер имён NSD.
Это достигается добавлением следующего в файл unbound.conf:
stub-zone:
name: "attack.er."
stub-prime: yes
stub-addr: <ip-addr-of-nsd-container>
Запустите unbound в контейнере с помощью:
unbound -vvv (используйте -dd, чтобы предотвратить демонизацию)
Теперь вы должны иметь возможность запросить unbound с помощью dig и наблюдать время ответа:
dig @127.0.0.1 attack.er
Если у вас возникнут какие-либо проблемы с этим руководством, свяжитесь с нами для получения дальнейших указаний.