Возникла необходимость запретить определённым приложениям посылать пакеты на порты Netbios (то есть, outbpound). Тут нужно делать элементарный TDI-фильтр и встроить в стек устройств. Примеры есть, ничего сложного в них нет. Единственное но- не могу найти формат IPv6 пакетов. Никто не мог бы подсказать их? Кстати, как вы можете оценить возможносмть реализации подобной функциональности путём фильтрации ZwDeviceIoControl-пакетов на устройства afd, udp, tcp и rawip?
А>Возникла необходимость запретить определённым приложениям посылать пакеты на порты Netbios (то есть, outbpound). Тут нужно делать элементарный TDI-фильтр и встроить в стек устройств. Примеры есть, ничего сложного в них нет. Единственное но- не могу найти формат IPv6 пакетов. Никто не мог бы подсказать их? Кстати, как вы можете оценить возможносмть реализации подобной функциональности путём фильтрации ZwDeviceIoControl-пакетов на устройства afd, udp, tcp и rawip?
Только врядли Вам понадобится структура IPv6 пакетов, Вы их все равно не увидите на TDI уровне. Тут Вы будете видеть примерно тоже самое, как если б вы перехватили сокетные функции — только данные, адрес следования отдельно, никаких сетевых пакетов. Если хочется именно пакетной фильтрации — нужен NDIS фильтр.
Да пребудет с тобою сила
Re[2]: Фильтрация определённых портов
От:
Аноним
Дата:
28.12.07 17:50
Оценка:
Здравствуйте, TarasCo, Вы писали:
TC>Только врядли Вам понадобится структура IPv6 пакетов, Вы их все равно не увидите на TDI уровне. Тут Вы будете видеть примерно тоже самое, как если б вы перехватили сокетные функции — только данные, адрес следования отдельно, никаких сетевых пакетов. Если хочется именно пакетной фильтрации — нужен NDIS фильтр.
Насколько я понимаю в меру своей некомпетентности, мне нужно перехватывать TDI_CONNECT и вытаскивать из параметров структурку TDI_ADDRESS_IP. А вот в ней у нас есть адрес и порт. Мне, собственно, нужен только порт. Вопрос лишь в том, прилетит ли мне данный запрос в случае IPv6 либо же, если прилетит, не будет ли структура TDI_ADDRESS_IP отличаться кроме длины адреса IP?
А>Насколько я понимаю в меру своей некомпетентности, мне нужно перехватывать TDI_CONNECT и вытаскивать из параметров структурку TDI_ADDRESS_IP. А вот в ней у нас есть адрес и порт. Мне, собственно, нужен только порт. Вопрос лишь в том, прилетит ли мне данный запрос в случае IPv6 либо же, если прилетит, не будет ли структура TDI_ADDRESS_IP отличаться кроме длины адреса IP?
Тут не так все просто.
1. Вы наверное не совсем четко формулируете задачу и скорее всего хотите запретить работу клиенту сетей Microsoft ( проще говоря, доступ к чужим шарам ) и службу доступа к файлам сетей Microsoft ( к своей шаре ) для определенных ip адресов. Для этого Вам понадобиться фильтровать исходящие соединения на 445/139 порты ( это можно сделать путем перехвата TDI_CONNECT ) а также фильтровать входящие соединения на свои порты. Последнее сложнее — нужно перехватить установку нотификатора ClientEventConnect и дальше в перехватчике производить фильтрацию. Кроме того, если Вы пожелаете, чтобы удаленный хост не видел Вас в своем сетевом окружении, Вам придется еще организовать довольно интеллектуальную фильтрацию UDP портов 137, 138. Я даже с ходу затрудняюсь сказать как их именно нужно фильтровать
2.Вам нужно расстаться с иллюзией, что Вам удасться сделать фильтрацию по приложениям. Все сетевые операции будут происходит в контексте SYSTEM. Фильтрацию по приложениям можно видимо осуществить только путем фильтрации файловых операций на уровне редиректора/серевра.
3. Теперь о TDI_CONNECT. Тут зависит от системы. На Viste при корректной установке ( http://tarasc0.blogspot.com/2007/07/tdi-vista.html ) вы будете получать запросы TDI_CONNECT установив фильтр на устройство \device\tcp ). На системах 5.x Вам нужно дополнительно фильтровать устройство \device\tcp6 ( если оно вообще есть ). В обработчик TDI_CONNECT придет адрес в форме TA_ADDRESS — в ней будет указан тип адреса ( ipv4 или ipv6 ) по нему можно определить тип структуры к которой нужно приводить адрес ( TDI_ADDRESS_IP или TDI_ADDRESS_IP6 ).
Да пребудет с тобою сила
Re[4]: Фильтрация определённых портов
От:
Аноним
Дата:
29.12.07 10:41
Оценка:
Здравствуйте, TarasCo, Вы писали:
TC>1. Вы наверное не совсем четко формулируете задачу и скорее всего хотите запретить работу клиенту сетей Microsoft ( проще говоря, доступ к чужим шарам ) и службу доступа к файлам сетей Microsoft ( к своей шаре ) для определенных ip адресов.
Не совсем так. Как раз задачу я себе представляю абсолютно чётко .Мне нужно сделать следующее- для определённого набора приложений нужно запретить доступ к 445 и 139 портам любого IP, задачи фильтрации входящего траффика вообще не стоит, это не моя задача. При этом нужно сделать так, чтобы разделять те запросы, которые пришли с уровня приложений (через устройства afd, tcp udp и rawip) и те, что пришли от системы (через подсистемы Pipe/Mailslot).
TC>2.Вам нужно расстаться с иллюзией, что Вам удасться сделать фильтрацию по приложениям. Все сетевые операции будут происходит в контексте SYSTEM. Фильтрацию по приложениям можно видимо осуществить только путем фильтрации файловых операций на уровне редиректора/серевра.
А TDI_CONNECT разве не синхронная? Ну, Completion Routine- тут всё понятно, а вот сам вызов?
TC>3. Теперь о TDI_CONNECT. Тут зависит от системы. На Viste при корректной установке ( http://tarasc0.blogspot.com/2007/07/tdi-vista.html ) вы будете получать запросы TDI_CONNECT установив фильтр на устройство \device\tcp ). На системах 5.x Вам нужно дополнительно фильтровать устройство \device\tcp6 ( если оно вообще есть ). В обработчик TDI_CONNECT придет адрес в форме TA_ADDRESS — в ней будет указан тип адреса ( ipv4 или ipv6 ) по нему можно определить тип структуры к которой нужно приводить адрес ( TDI_ADDRESS_IP или TDI_ADDRESS_IP6 ).
Может, тогда будет проще просто раскокать формат пакетов connect'а на Afd, идущих через DeviceIoControl'ы? В Коберниченко описан формат прямых пакетов connect на TDI-устройства, так что остаётся только Afd...
А>А TDI_CONNECT разве не синхронная? Ну, Completion Routine- тут всё понятно, а вот сам вызов?
Во-первых TDI_CONNECT естественно асинхронная ( для устройства \Device\udp — синхронная ) и всегда ( за исключением быть может локального случая ) вернет STATUS_PENDING c завершением по факту установления соединения. Во-вторых, вызов происходит в контексте системного процесса. Т.е так происходит при работе стандартного клиента сетей микросфот. Когда приложение открывает файл на шаре \\shara1\file1 соответствующая операция попадает в универсальный редиректор ( rdbss.sys ). Если файла нет в кеше, происходит запрос к соответствующему сетевому редиректору (обычно это mrxsmb.sys ), и этот запрос уже происходит в контексте системного процесса. Далее запрос идет в транспортный драйвер NetBios ( ntbt.sys ), который в свою очередь обращается к устройству \Device\tcp и устанавливает соединение с соответствующим хостом. Стоит отметить, что Netbios поддерживает постоянные соединения с довольно длительным таймаутом ( задается в реестре, по-моему 2 часа по умолчанию ). Таким образом фильтруя запросы на уровне TDI Вы никогда не узнаете кто инициировал запрос ( если только приложение не работает с драйвером tcpip.sys напрямую, реализуя весь протокол самостоятельно ) и по какой причине. Т.е соединение может быть установлено из-за активности FAR а, а потом использовано для передачи файлов Explorer ом и понять это на TDI уровне невозможною
А>Может, тогда будет проще просто раскокать формат пакетов connect'а на Afd, идущих через DeviceIoControl'ы? В Коберниченко описан формат прямых пакетов connect на TDI-устройства, так что остаётся только Afd...
Зачем их "раскокивать" если это все есть в DDK. Потом еще раз повторю: обычный клиент сетей микрософт не использует устройство afd.sys.
Да пребудет с тобою сила
Re[6]: Фильтрация определённых портов
От:
Аноним
Дата:
31.12.07 18:11
Оценка:
Здравствуйте, TarasCo, Вы писали:
TC>Во-первых TDI_CONNECT естественно асинхронная ( для устройства \Device\udp — синхронная ) и всегда ( за исключением быть может локального случая ) вернет STATUS_PENDING c завершением по факту установления соединения. Во-вторых, вызов происходит в контексте системного процесса.
Понял. Интересно. Большое спасибо за разъяснения. Да, стоит только выйти за пределы своей специализации в ядре, как понимаешь, как мало ты понимаешь
TC>Т.е так происходит при работе стандартного клиента сетей микросфот. Когда приложение открывает файл на шаре \\shara1\file1 соответствующая операция попадает в универсальный редиректор ( rdbss.sys ).... Таким образом фильтруя запросы на уровне TDI Вы никогда не узнаете кто инициировал запрос ( если только приложение не работает с драйвером tcpip.sys напрямую, реализуя весь протокол самостоятельно ) и по какой причине
Очевидно, я был немного недопонят. Именно самопальные реализации протокола мне и нужно контролировать (точнее, блокировать, чтобы не могли работать в обход стандартного протокола). Но к file sharing оно вообще никакого отношения не имеет, хотя и работает на сетевом уровне через один (445) порт.
А>>Может, тогда будет проще просто раскокать формат пакетов connect'а на Afd, идущих через DeviceIoControl'ы? В Коберниченко описан формат прямых пакетов connect на TDI-устройства, так что остаётся только Afd...
TC>Зачем их "раскокивать" если это все есть в DDK. Потом еще раз повторю: обычный клиент сетей микрософт не использует устройство afd.sys.
Да? Здорово! А нельзя ли подсказать ключевые строчки, по которым можно найти в DDK данную информацию?
А>Да? Здорово! А нельзя ли подсказать ключевые строчки, по которым можно найти в DDK данную информацию?
форматы структур — tdi.h, они одинаковые что для \device\tcp, что для \device\afd. Различаются только IOCTL, для afd они есть в ntddtdi.h. Существует функция для перекодировки IOCTL — TdiMapUserRequest.
А>Очевидно, я был немного недопонят. Именно самопальные реализации протокола мне и нужно контролировать (точнее, блокировать, чтобы не могли работать в обход стандартного протокола). Но к file sharing оно вообще никакого отношения не имеет, хотя и работает на сетевом уровне через один (445) порт.
В таком случае, нужно фильтровать устройство \device\tcp, поскольку фильтрация \device\afd не обеспечит полного "прикрытия". Кроме того, мне довольно трудно представить, что кому то взбредет в голову самому реализовать NetBIOS протокол, поскольку выгоды от этого не очевидны . И метод борьбы довольно прост — проверьте, что обращение к 139/445 портам происходит не в контексте system и верните ACCESS_DENIED.
Да пребудет с тобою сила
Re[8]: Фильтрация определённых портов
От:
Аноним
Дата:
03.01.08 10:42
Оценка:
Здравствуйте, TarasCo, Вы писали:
TC>форматы структур — tdi.h, они одинаковые что для \device\tcp, что для \device\afd. Различаются только IOCTL, для afd они есть в ntddtdi.h. Существует функция для перекодировки IOCTL — TdiMapUserRequest.
Понял. Большое спасибо. А, кстати, вопрос- в IPv6 обращение идёт к \\Device\\Tcp6. А к какому тогда Afd идёт обращение в этом случае? Или там просто в структуре указывается, что у нас IP 128-битный?
TC>В таком случае, нужно фильтровать устройство \device\tcp, поскольку фильтрация \device\afd не обеспечит полного "прикрытия".
Ага, и RawIp также.
TC>Кроме того, мне довольно трудно представить, что кому то взбредет в голову самому реализовать NetBIOS протокол, поскольку выгоды от этого не очевидны
Ну, как способ обхода моей HIPS- вполне.
TC>И метод борьбы довольно прост — проверьте, что обращение к 139/445 портам происходит не в контексте system и верните ACCESS_DENIED.
В любом случае, фильтрация на уровне DeviceIoControl будет предпочтительнее с точки зрения совместимости с текущим кодом- хуки на SSDT мне при любом раскладе вешать необходимо, без этого не обойтись, поэтому реализовать всё в рамках одного идеологического подхода будет проще с точки зрения разработки и дальнейшей поддержки в любом случае.
А>Понял. Большое спасибо. А, кстати, вопрос- в IPv6 обращение идёт к \\Device\\Tcp6. А к какому тогда Afd идёт обращение в этом случае? Или там просто в структуре указывается, что у нас IP 128-битный?
Точно не скажу, я не использовал никогда ipv6 под XP, а под Vista устройства \device\tcp6 нет — и ipv4 и ipv6 адреса обслуживаются устройством \device\tcp ( которое к слову принадлежит драйверу tdx.sys а не tcpip.sys ) и все идет через afd.sys.