]> Untitled Git - articles.git/commitdiff
Написал на половину первую статью
authorNikolay Shaplov <dhyan@nataraj.su>
Fri, 18 Apr 2025 15:30:40 +0000 (18:30 +0300)
committerNikolay Shaplov <dhyan@nataraj.su>
Fri, 18 Apr 2025 15:30:40 +0000 (18:30 +0300)
SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/0. Ð\92ведеение.md [new file with mode: 0644]
SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/1. PowerDNS.imgs/resources_0.png [new file with mode: 0644]
SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/1. PowerDNS.md [new file with mode: 0644]
SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/README.md [new symlink]

diff --git a/SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/0. Ð\92ведеение.md b/SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/0. Ð\92ведеение.md
new file mode 100644 (file)
index 0000000..ee2bb42
--- /dev/null
@@ -0,0 +1,23 @@
+
+# Taint-анализ средсвтами Natch
+# Знакомство с инструментом на небанальных примерах
+
+## Введение
+
+В данной статье приведен мой опыт освоения инструмента полносистемного Taint-анализа Natch созданного Институтом Системного Программирования РАН.
+Главным фундаментальным недостатком этого инструмента является закрытость кода, ситуация с которой вряд-ли когда либо изменится.
+Однако сам факт закрытости кода не мешает освоению принципов taint-анализа, и есть надежда по мере роста популярности этого метода (а именно популяризации и посвящена эта статья) будут развиваться и свободные инструменты. Использование несвободного инструмента для освоения новых технологий для которых еще нет свободных решений - не грех.
+
+Данная статья не является руководством по использованию Natch, но инструкцией по тому как собрать ряд свободных проектов для последующего taint-анализа и как правильно поставить эксперимент.
+Саму инструкцию по использованию Natch вы можете найти [здесь](https://github.com/ispras/natch/tree/release/docs)
+
+В качестве проектов для исследования мной были выбраны два проекта внутреннее устройство которых мне было мало что известно, а именно PowerDNS и интерпретатор Perl, а о внутреннем устройстве третьего проекта PostgreSQL я кое что знаю.
+Задача исследования состояла в том, чтобы в первых двух случаях используя помеченные данные быстро и просто узнать о внутренней структуре проекта и иерархии вызовов, в третьем же случае, был выбран более сложный заранее известный data-flow, и цель была убедиться, что natch успешно справляется с анализом сложной траекторией движения помеченных данных
+
+Примеры в данных статьях даны с детализацией достаточной для самостоятельного быстрого воспроизведения, при условии предварительного знакомства с инструментом Natch, объяснено почему были выбраны те или иные условия эксперимента, и продемонстрированы результаты экспериментов и даны пояснения к ним.
+
+### Приборы и материалы
+
+Эксперимент проводился на ноутбуке с Ubuntu 24.04 и виртуальной машиной с Debian 12 внутри.
+
+В настройки сети виртуальной машины по сравнению с рекомендованной в документации была добавлена опция `hostfwd=tcp::2222-:22` которая пробрасывает 2222й порт с хост-машины на 22й порт виртуалки, что позволяет работать внутри виртуальной машины, подключившись к ней привычным терминалом, полноценно пользоваться буфером обмена хост-машины в процессе настройки и т.п. Настоятельно рекомендую.
diff --git a/SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/1. PowerDNS.imgs/resources_0.png b/SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/1. PowerDNS.imgs/resources_0.png
new file mode 100644 (file)
index 0000000..b390690
Binary files /dev/null and "b/SDL/2025-04 Taint-\320\260\320\275\320\260\320\273\320\270\320\267 \321\201\321\200\320\265\320\264\321\201\321\202\320\262\320\260\320\274\320\270 Natch. \320\227\320\275\320\260\320\272\320\276\320\274\321\201\321\202\320\262\320\276 \321\201 \320\270\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\320\276\320\274 \320\275\320\260 \320\275\320\265\320\261\320\260\320\275\320\260\320\273\321\214\320\275\321\213\321\205 \320\277\321\200\320\270\320\274\320\265\321\200\320\260\321\205/1. PowerDNS.imgs/resources_0.png" differ
diff --git a/SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/1. PowerDNS.md b/SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/1. PowerDNS.md
new file mode 100644 (file)
index 0000000..83617be
--- /dev/null
@@ -0,0 +1,225 @@
+## PowerDNS
+
+PowerDNS -- DNS сервер для массового обслуживания с хранением информации об обслуживаемых зонах в СУБД.
+Когда-то в прошлой жизни я его использовал в проекте DNS-хостинга.
+PowerDNS был выбран пример ПО с ярко выраженной поверхностью атаки: есть сетевое соединение обслуживающие анонимных пользователей посылающих серверу нетривиальные запросы.
+(Надо отметить что в том DNS-хостиге мы прятали наш PowerDNS за более общепринятым bind9 работающем в режиме трансляции запросов)
+Условия экзамена по обучающей программе предполагали использование Natch для обнаружение функций лежащих на поверхности атаки и подлежащих первоочередной обработки фаззингом.
+Когда поверхность атаки ярко выраженная, это сделать проще всего.
+
+### План эксперимента   
+
+
+Предполагается 
+* выполнить сборку PowerDNS из исходников
+* настроить тестовую DNS-зону
+* запустить сервер в режиме авторитативного мастера,
+* пометить данные приходящие на 53й порт по tcp и udp 
+* отправить к серверу запросы по tcp и udp протоколу
+* изучить как помеченные данные перемещались через иерархию вызова функций.
+
+### Сборка и установка
+
+1. Получаем исходники последней версии PowerDNS:
+
+```
+git clone https://github.com/PowerDNS/pdns.git
+```
+
+В моем случае используется ветка master находящаяся на коммите d4ccf7673a от 9 апреля 2025г.
+
+2. Устанавливаем зависимости необходимые для сборки проекта
+
+```
+apt-get build-dep pdns-server
+```
+
+3. Конфигурируем проект и запускаем сборку
+
+
+```
+./configure --with-modules="gpgsql"
+
+make
+
+sudo make install
+```
+
+Если обратить внимание на финальный вывод скрипта `./configure` то можно заметить, что PowerDNS по умолчанию собирается с отладочной информацией (ключ `-g`) и никаких дополнительных действий для сборки с покрытием предпринимать не надо.
+
+Сборка осуществляется с модулем `gpgsql` который позволяет хранить информацию о зонах и записях в СУБД PostgreSQL, мне с ней привычнее работать.
+
+### Настройка
+
+#### 1. Устанавливаем PostgreSQL из пакетной системы Debian:
+
+```
+sudo apt-get install postgresql
+```
+
+
+#### 2. Создаем пользователя и базу данных для хранения данных PowerDNS
+
+```
+sudo su postgres
+createuser -P pdns_user
+# Вводим пароль
+createdb pdns -O pdns_user
+```
+
+#### 3. Создание схемы базы данных
+
+Копируем схему базы данных из [документации](https://doc.powerdns.com/authoritative/backends/generic-postgresql.html#default-schema) в буфер
+(та же схема есть в исходниках по пути `modules/gpgsqlbackend/schema.pgsql.sql`)
+
+Подключаемся консолью `psql` к базе `pdns` и переключаемся в пользователя `pdns_user`
+
+```
+psql pdns
+set role pdns_user;
+
+```
+
+Вставляем из буфера обмена в консоль код схемы скопированный выше из документации, нажимаем Enter.
+
+В консоли появится много строк начинающихся со слова `CREATE`.
+
+Выходим из консоли `psql`, выходим из `shell`-консоли пользователя `postgres`
+
+```
+exit
+exit
+```
+
+####  4. Создание конфигурации PowerDNS
+
+Копируем пример файла конфигурации в актуальный конфигурационный файл
+
+```
+cp /usr/local/etc/pdns.conf-dist /usr/local/etc/pdns.conf
+```
+
+Добавляем в файл `/usr/local/etc/pdns.conf` строки
+
+```
+launch=gpgsql
+gpgsql-host=127.0.0.1
+gpgsql-user=pdns_user
+gpgsql-password=[ваш пароль]
+gpgsql-dbname=pdns
+```
+В значение параметра `gpgsql-password` записываете пароль который вы указали при создании пользователя pdns.
+
+### Тестирование
+#### 1. Проверяем что вообще запускается
+
+По неизвестной мне причине бинарник `pdns_server` в `/usr/local/bin` при `make install` не установился, но при наличии правильного конфигурационного в ожидаемом месте можно запускать бинарник прямо из директории сборки
+
+```
+sudo pdns/pdns_server
+```
+
+Если все было сделано правильно сервер запустится, сообщит что присоединился  к каким-то портам и перейдет в режим ожидания соединения. 
+Если была допущена какая-то ошибка надо ее устранить и добиться того чтобы сервер запустился.
+Сервер пока останавливаем нажав Ctrl+C
+
+#### 2. Создаем тестовую зону.
+
+В директории сборки в папке `/psql` есть утилита для управления зонами и записями PowerDNS. Используем ее для создания зоны.
+
+```
+pdns/pdnsutil create-zone example.com
+pdns/pdnsutil add-record example.com test A '8.8.8.8'
+```
+
+Этими командами мы создаем A-запись, которая указывает, что доменное имя `test.example.com` привязана к IP-адресу `8.8.8.8`
+
+Можно зайти обратно в `psql` и убедиться, что таблицах `domains` и `records` были созданы соответсвующие записи:
+
+```
+select * from domains;
+select * from records;
+```
+
+#### 3. Локальное тестирование 
+
+Запустим сервер как в п.1
+
+```
+sudo pdns/pdns_server
+```
+
+в соседней консоли еще раз зайдем на виртуалку и выполним команды
+
+```
+dig @127.0.0.1 test.example.com
+
+dig @127.0.0.1 test.example.com +tcp
+```
+
+Эти команды выполнят запросы к нашему DNS-серверу по UDP и TCP протоколам. Правильный ответ должен содержать строку
+
+```
+test.example.com.      3600    IN      A       8.8.8.8
+```
+
+А так же в разделе `flags:` должен присутствовать флаг `aa`, говорящий что это ответ от сервера отвечающего за зону, а не ретранслированный.
+
+#### 4. Пробрасывание 53 порта наружу
+
+Теперь нам надо сделать так, чтобы порт по которому PowerDNS обслуживает клиентов, оказался доступен на host-машине.
+
+Для этого в скрипт запуска виртуалки в опции настройки сети добавим параметры `hostfwd=udp::15353-:53,hostfwd=tcp::15353-:53`, в результате чего в теории 53 порт внутри виртуалки будет замэплен на порт 15353 хост машины и по TCP и по UDP.
+Проделав это перезапустим виртуалку.
+
+9. Тестирование извне виртуалки
+
+Зайдя в виртуалку запускаем DNS-свервер как в п.1
+
+```
+sudo pdns/pdns_server
+```
+
+И на хост-машине делаем TCP и UDP DNS-запросы по порту 15353 локального интерфеса:
+```
+dig @127.0.0.1 -p15353 test.example.com +tcp
+dig @127.0.0.1 -p15353 test.example.com
+```
+
+Результат должен оказаться такой же как в п.3.
+
+
+### Запись трассы
+
+На основании созданного образа виртуальной машины мы создаем два проекта natch для пометки данных по протоколу TCP и для пометки данных по протоколу UDP.
+Процесс создания проектов в достаточной мере отражен в документации, обозначу лишь ключевые нюансы:
+
+* Создаем два отдельных проекта, один для перехвата TCP, другой для перехвата UDP
+* Для случая TCP в консольном диалоге запрашиваем проброс наружу 53го порта, в `tainted.cfg` в разделе `[Ports]` указываем `ip_protocol=6`, `dst=53`, `rc=53`, и все должно заработать
+* Для случая UDP, после создания проекта, необходимо руками во всех конфигах заменить `hostfwd=tcp` на `hostfwd=udp`,  в `tainted.cfg` в разделе `[Ports]` указать `ip_protocol=17`, а `src` и `dst` не указывать вовсе. 
+
+Выяснить, читая конфиги на какой из внешних портов замэплен находящийся внутри виртуалки 53 порт. А потом все более или менее по инструкции:
+
+* Включаем запись сценария `natch record`
+* Логинимся в виртуалку, уже через графическое окно qemu
+* Делаем первый снэпшот
+* Запускаем сервер, как это делали при тестировании
+* С хост машины отправляем запрос на TCP или UDP порт на который был замаплен 53 порт виртуалки (значение добывается из конфигов натча), так же как это делали при тестировании, номер порта только надо будет поменять.
+* Получаем ответ
+* Делаем второй снепшот
+* Выходим.
+
+Далее командой `natch replay` снимаем трассу между первым и вторым снепшотом и загружаем ее в snatch.
+
+### Анализ результатов.
+
+Данные пришедшие в систему 53 TCP или UDP порта, были помечены, и при помощи программы визуализации snatch можно посмотреть как они распространялись по системе
+
+#### Resources
+
+Посмотрев на вкладку Resources мы можем следать вывод, что помеченные данные проходили через сам процесс pdns_server'а и через процесс ядра (имеют право) и через другие процессы не проходили
+
+![...](1. PowerDNS.imgs/resources_0.png)
+
diff --git a/SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/README.md b/SDL/2025-04 Taint-анализ Ñ\81Ñ\80едÑ\81Ñ\82вами Natch. Ð\97накомÑ\81Ñ\82во Ñ\81 инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82ом на небаналÑ\8cнÑ\8bÑ\85 пÑ\80имеÑ\80аÑ\85/README.md
new file mode 120000 (symlink)
index 0000000..f02194f
--- /dev/null
@@ -0,0 +1 @@
+0. Введеение.md
\ No newline at end of file