Фильтрация определённых портов
От: Аноним  
Дата: 28.12.07 12:13
Оценка:
Всем доброго времени суток!

Возникла необходимость запретить определённым приложениям посылать пакеты на порты Netbios (то есть, outbpound). Тут нужно делать элементарный TDI-фильтр и встроить в стек устройств. Примеры есть, ничего сложного в них нет. Единственное но- не могу найти формат IPv6 пакетов. Никто не мог бы подсказать их? Кстати, как вы можете оценить возможносмть реализации подобной функциональности путём фильтрации ZwDeviceIoControl-пакетов на устройства afd, udp, tcp и rawip?
Re: Фильтрация определённых портов
От: TarasCo  
Дата: 28.12.07 13:24
Оценка:
А>Возникла необходимость запретить определённым приложениям посылать пакеты на порты Netbios (то есть, outbpound). Тут нужно делать элементарный TDI-фильтр и встроить в стек устройств. Примеры есть, ничего сложного в них нет. Единственное но- не могу найти формат IPv6 пакетов. Никто не мог бы подсказать их? Кстати, как вы можете оценить возможносмть реализации подобной функциональности путём фильтрации ZwDeviceIoControl-пакетов на устройства afd, udp, tcp и rawip?

Начните с wiki, там есть ссылки на любой вкус:
http://en.wikipedia.org/wiki/Ipv6

Вот док от MS ( если сылка не рабочая, ищите файл IPv6.doc )
http://www.microsoft.com/downloads/details.aspx?familyid=cbc0b8a3-b6a4-4952-bbe6-d976624c257c&displaylang=en&tm

Только врядли Вам понадобится структура 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?
Re[3]: Фильтрация определённых портов
От: TarasCo  
Дата: 29.12.07 08:34
Оценка:
А>Насколько я понимаю в меру своей некомпетентности, мне нужно перехватывать 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...
Re[5]: Фильтрация определённых портов
От: TarasCo  
Дата: 29.12.07 19:02
Оценка:
А>А 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 данную информацию?
Re[7]: Фильтрация определённых портов
От: TarasCo  
Дата: 02.01.08 20:47
Оценка:
А>Да? Здорово! А нельзя ли подсказать ключевые строчки, по которым можно найти в 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 мне при любом раскладе вешать необходимо, без этого не обойтись, поэтому реализовать всё в рамках одного идеологического подхода будет проще с точки зрения разработки и дальнейшей поддержки в любом случае.

Большое спасибо за помощь!
Re[9]: Фильтрация определённых портов
От: TarasCo  
Дата: 03.01.08 14:26
Оценка:
А>Понял. Большое спасибо. А, кстати, вопрос- в IPv6 обращение идёт к \\Device\\Tcp6. А к какому тогда Afd идёт обращение в этом случае? Или там просто в структуре указывается, что у нас IP 128-битный?

Точно не скажу, я не использовал никогда ipv6 под XP, а под Vista устройства \device\tcp6 нет — и ipv4 и ipv6 адреса обслуживаются устройством \device\tcp ( которое к слову принадлежит драйверу tdx.sys а не tcpip.sys ) и все идет через afd.sys.
Да пребудет с тобою сила
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.