Способы фильтрации сетевого траффика в Windows 9x/2000/Net.2003 Server

Дата публикации 1 ноя 2003

Способы фильтрации сетевого траффика в Windows 9x/2000/Net.2003 Server — Архив WASM.RU

Введение.

В данной статье даются основные сведения по способам фильтрации сетевого траффика в Windows 9x/2000/Net.2003 Server, даётся описание фильтрации IP-траффика в Windows 2000 на основе Windows 2000 Filter-Hook Driver способа.Также указываются особенности реализации других методов фильтрации.

Часть первая, теоретическая.

Способы фильтрации сетевого трафика .

Существует несколько способов фильтрации сетевого траффика .Для начала кратко рассмотрим основы сетевой подсистемы Windows:

1) NDIS. В 1989 году Microsoft и 3Com совместно разработали Network Driver Interface Specification (NDIS), которая позволяет драйверам сетевых протоколов использовать сервисы сетевых интерфейсов (отправка/прием сетевых пакетов) скрывая детали их реализации. Драйвер сетевого адаптера, разработанный в соответствии с этой спецификацией, принято называть NDIS минипортом (miniport).Одно из преимуществ - то, что код свободно переносится из 9x/ME - winNT/2000 . Детальное описание предмета можно найти в документации DDK (раздел NetworkDrivers), вкратце NDIS описывает правила (интерфейсы и структуры), в соответствии, с которыми должны разрабатываться драйвера сетевых адаптеров, а так же предоставляет библиотеку функций, к которой должен обращаться разработчик вместо прямого использования сервисов ядра.

2) Драйвера сетевых протоколов. Вкратце, драйвер сетевого протокола (такого как, например TCP/IP) для работы с сетевыми интерфейсами использует функции уже упомянутой библиотеки NDIS и может предоставлять TDI (Transport Data Interface) вышележащим уровням (TDI-клиентам, одним из типичных представителей которых в ядре NT/2000/XP является afd.sys - kernel-mode часть Windows Sockets).

3) User-Mode DLL's которые формируют интерфейс WindowsSockets. Это ws2_32.dll, msafd.dll, wshtcpip.dll и другие.

Тех, кто хочет более детально рассмотреть сетевую подсистему Windows , отсылаю к David Solomon, Mark Russinovich : Inside Windows 2000, часть 13.

Технологии фильтрации:

Технологии фильтрации в User-mode автор не рассматривает.

Технологии фильтрации сетевого трафика в режиме ядра:

1) Kernel-mode sockets filter. Эта технология применима для WindowsNT/2000. Основана на перехвате всех вызовов из msafd.dll (самая низкоуровневая user-mode DLL из состава Windows Sockets) к модулю ядра afd.sys (kernel-mode часть WindowsSockets). Данная технология требует аккуратного обращения с интерфейсами AFD , т.к. они изменяются в разных версиях NT. AFD является TDI клиентом и реализует приём/отправку данных через драйвер протокола. Msafd.dll сообщает AFD название протокола для каждого сокета.Для более подробного изучения отправляю в Inside Windows 2000, раздел 13, подраздел Networking APIs.Способ бесполезен при маршрутизации, т.к. она осуществляется внутри TCPIP.SYS(иногда и вне его - поиск по DDK: Fast Forwarding Path - происходит внутри NDIS ) и не доходит до сокетов. Хотя данный способ удобен для шифрования потоков данных и QoS - Quality of Service - предоставляется специальное API (смотреть в MSDN - поиск по QOS Reference).

2) TDI-filter driver. Технология применима как в Windows 9x/ME так и в WindowsNT/2000, хотя конкретные реализации сильно отличаются. Что касается Windows NT/2000, то в случае TCP/IP фильтрации необходимо перехватывать все вызовы, направленные устройствам (devices) созданным модулем tcpip.sys (\Device\RawIp, \Device\Udp, \Device\Tcp). Технология достаточно известная и используется в ряде коммерческих продуктов (например, OutpostFirewall).

3) NDIS Intermediate Driver Способ очень неудобен в инсталляции и программировании. Желающие могут изучить DDK. Ниже приведён пример кода, показывающего громоздкость программирования :

Код (Text):
  1.  
  2. local status:       NTSTATUS
  3. local PChars:       NDIS_PROTOCOL_CHARACTERISTICS
  4. local MChars:       NDIS_MINIPORT_CHARACTERISTICS
  5.     local Param:        PNDIS_CONFIGURATION_PARAMETER
  6.     local Name1:        NDIS_STRING
  7.     local WrapperHandle:NDIS_HANDLE
  8.     local DriverHandler:    NDIS_HANDLE
  9.     local ProtHandler:  NDIS_HANDLE
  10.     mov DriverHandler,NULL
  11.     mov ProtHandler,NULL
  12.     invoke NdisInitializeWrapper,addr WrapperHandle,pDriverObject, pusRegistryPath,NULL
  13.     invoke RtlZeroMemory,addr MChars,sizeof NDIS_MINIPORT_CHARACTERISTICS
  14.     mov MChars.MajorNdisVersion,        5
  15.     mov MChars.MinorNdisVersion,        NULL
  16.     mov MChars.InitializeHandler,       offset MPInitialize
  17.     mov MChars.QueryInformationHandler, offset MPQueryInformation
  18.     mov MChars.SetInformationHandler,   offset MPSetInformation
  19.     mov MChars.ResetHandler,            offset MPReset
  20.     mov MChars.TransferDataHandler,     offset MPTransferData
  21.     mov MChars.HaltHandler,         offset MPHalt
  22.     mov MChars.CheckForHangHandler,     NULL
  23.     mov MChars.SendHandler,         offset MPSend
  24.     mov MChars.ReturnPacketHandler,     offset MPReturnPacket
  25.     invoke NdisIMRegisterLayeredMiniport,WrapperHandle,addr MChars, sizeof MChars,\
  26. addr DriverHandler
  27.     .if eax == STATUS_SUCCESS
  28.         invoke NdisMRegisterUnloadHandler,WrapperHandle,offset Unload
  29.         invoke RtlZeroMemory,addr PChars, sizeof NDIS_PROTOCOL_CHARACTERISTICS
  30.         mov PChars.MajorNdisVersion,    5
  31.         mov PChars.MinorNdisVersion,    0
  32.         invoke RtlInitUnicodeString,addr PChars.Name_,addr stroka
  33.         mov PChars.OpenAdapterCompleteHandler,  offset PtOpenAdapterComplete
  34.         mov PChars.CloseAdapterCompleteHandler, offset PtCloseAdapterComplete
  35.         mov PChars.SendCompleteHandler ,        offset PtSendComplete
  36.         mov PChars.TransferDataCompleteHandler ,    offset PtTransferDataComplete
  37.         mov PChars.ResetCompleteHandler ,   offset PtResetComplete
  38.         mov PChars.RequestCompleteHandler,  offset PtRequestComplete
  39.         mov PChars.ReceiveHandler ,     offset PtReceive
  40.         mov PChars.ReceiveCompleteHandler , offset PtReceiveComplete
  41.         mov PChars.StatusHandler,           offset PtStatus
  42.         mov PChars.StatusCompleteHandler,   offset PtStatusComplete
  43.         mov PChars.BindAdapterHandler ,     offset PtBindAdapter
  44.         mov PChars.UnbindAdapterHandler ,   offset PtUnbindAdapter
  45.         mov PChars.UnloadHandler ,      NULL
  46.         mov PChars.ReceivePacketHandler ,   offset PtReceivePacket 
  47.         mov PChars.PnPEventHandler,     offset PtPNPHandler
  48.  
  49.         invoke NdisRegisterProtocol,addr status,addr ProtHandler,addr PChars,\
  50.                     sizeof NDIS_PROTOCOL_CHARACTERISTICS
  51.         .if eax==STATUS_SUCCESS
  52.             invoke NdisIMAssociateMiniport,DriverHandler,ProtHandler
  53.             mov eax,STATUS_SUCCESS
  54.             ret
  55.         .endif
  56.     .endif

Вкратце способ заключается в создании виртуального адаптера и его установки таким образом,что при каждом вызове реального адаптера сначала шло обращение к виртуальному.Т.е мы как бы накладываем наш виртуальный адаптер на реальный.

Вся обработка поступивших вызовов идёт в MP* и Pt* функциях. Где MP* -относится к Miniport, т.е. к нашему виртуальному адаптеру, а Pt* - к Protocol , протоколу, реализуемуму нашим адаптером.

Т.е если мы хотим фильтровать TCP/IP , Protocol должен уметь обрабатывать IP - пакеты .

4) Windows 2000 Filter-Hook Driver. Метод описан в документации DDK и применим только в Windows 2000 и выше, его мы и будем рассматривать в практической части.

5) NDIS Hooking Filter Driver.Способ сводится к перехвату некоторых функций NDIS библиотеки, которые в дальнейшем позволяют отследить регистрацию всех протоколов установленных в операционной системе и открытие ими сетевых интерфейсов. Используется в небезызвестном ZoneAlarm. Для Windows 2000 достаточно перехватить 4 функции:

  • NdisRegisterProtocol
  • NdisDeregisterProtocol
  • NdisOpenAdapter
  • NdisCloseAdapter

6) Packet Filtering API. На данный момент доступно в Windows 2000 Server и Windows .NET Server 2003.

Насчёт пунктов 2,3,5 : автор надеется осветить их в отдельной обширной статье по NDIS и TDI.

Часть вторая, практическая.

Использование Windows 2000 Filter-Hook Driver

Начиная с Windows 2000 Microsoft включила возможность фильтрации IP траффика в контексте IP Filter driver - стандартного сервиса Windows 2000. Как написано в DDK ,драйвера , используемые IP Filter driver сервисом, могут обрабатывать и фильтровать IP траффик, т.е расширять возможности IP Filter driver сервиса.

Правда при этом необходимо учитывать нюанс - только один драйвер может использоваться при фильтрации.

Драйвер для фильтрации траффика представляет собой обычный Kernel Mode Driver, реализующий определённую функцию фильтрации , которую он и регестрирует в IP Filter driver сервисе .Фильтруются как исходящий, так и входящий траффик.

Вот исходный текст простейшего драйвера для IP Filter driver, драйвер просто drop -ает все пакеты :

Код (Text):
  1.  
  2. .386
  3. .model flat, stdcall
  4. ;                                         I N C L U D E   F I L E S
  5. ;#########################################################################
  6. include D:\masm32\include\w2k\ntstatus.inc
  7. include D:\masm32\include\w2k\ntddk.inc
  8. include D:\masm32\include\w2k\pfhook.inc
  9. include D:\masm32\include\w2k\ntoskrnl.inc
  10. include D:\masm32\Macros\Strings.mac
  11. includelib D:\NTDDK\libfre\i386\ntdll.lib
  12. includelib D:\NTDDK\libfre\i386\ntoskrnl.lib
  13. ;                       P R O T O
  14. ;##########################################################################
  15. set_hook PROTO  :PacketFilterExtensionPtr
  16. ;                        D A T A
  17. ;##########################################################################
  18. .data
  19. CCOUNTED_UNICODE_STRING "\\Device\\IPFILTERDRIVER" ,drvsmbl,4
  20. ipfilter_name UNICODE_STRING
  21. hook_nfo PF_SET_EXTENSION_HOOK_INFO
  22. status NTSTATUS ?
  23. devobj PDEVICE_OBJECT ?
  24. isb IO_STATUS_BLOCK
  25. fileobj PFILE_OBJECT NULL
  26. myirp PIRP NULL
  27. ;                                                    C O D E
  28. ;############################################################################
  29. .code
  30. ;                                             DriverEntry
  31. ;############################################################################
  32. DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
  33.     mov eax,offset hookproc
  34.     invoke set_hook, eax
  35.     .if eax != STATUS_SUCCESS
  36.                 ret
  37.             .endif
  38.          mov eax, pDriverObject
  39.              assume eax:PTR DRIVER_OBJECT
  40.          mov [eax].DriverUnload,offset Unload
  41.              assume eax:nothing
  42.          mov eax,STATUS_SUCCESS
  43.              ret
  44. DriverEntry endp
  45. ;                   Windows 2000 hook (built in)
  46. ;###############################################################################
  47. Unload proc p1DriverObject:PDRIVER_OBJECT
  48.     invoke set_hook,NULL
  49.     ret
  50. Unload endp
  51. ;###############################################################################
  52. set_hook proc hook_fn:PacketFilterExtensionPtr
  53.  
  54.         invoke IoGetDeviceObjectPointer,addr drvsmbl,STANDARD_RIGHTS_ALL,\
  55. addr fileobj,addr devobj
  56.  
  57.     mov status,eax  
  58.         .if eax != STATUS_SUCCESS
  59.             jmp exit
  60.         .endif
  61.  
  62.         mov eax,hook_fn
  63.         mov hook_nfo.ExtensionPointer,eax
  64.      
  65.         invoke IoBuildDeviceIoControlRequest,IOCTL_PF_SET_EXTENSION_POINTER(),\
  66. devobj, addr hook_nfo,\
  67.                         sizeof hook_nfo, NULL, 0, FALSE, NULL,addr isb
  68.  
  69.     mov myirp,eax
  70.  
  71.         .if eax == NULL
  72.             mov status ,STATUS_INSUFFICIENT_RESOURCES
  73.             jmp exit
  74.         .endif
  75.  
  76.         invoke IoCallDriver,devobj,myirp
  77.  
  78.         mov myirp,NULL
  79.         mov eax,STATUS_SUCCESS
  80.         ret
  81. exit:
  82.  
  83.     .if fileobj!=NULL
  84.         invoke ObDereferenceObject,fileobj
  85.     .endif
  86.  
  87.     mov eax,status
  88.     ret
  89.    
  90. set_hook endp
  91. ;###############################################################################
  92. hookproc proc PacketHeader:PTR BYTE, Packet:PTR BYTE, PacketLength:WORD,
  93.         RecvInterfaceIndex:WORD,SendInterfaceIndex:WORD,RecvLinkNextHop:DWORD,
  94.         SendLinkNextHop:DWORD
  95.        
  96.         mov eax,PF_DROP
  97.     ret
  98. hookproc endp
  99.  
  100. end DriverEntry

Для компиляции потребуется masm32 by hutch ,последний KMDKit by Four-F, Update KMDKit by van (пока состоит из pfhook.inc и неполного ndis.inc).

Рассмотрим более подробно данный код.

1) CCOUNTED_UNICODE_STRING "\\Device\\IPFILTERDRIVER" ,drvsmbl,4 - название нашего IP Filter driver сервиса.

2) hook_nfo PF_SET_EXTENSION_HOOK_INFO - структура , содержащая указатель типа PacketFilterExtensionPtr, т.е на нашу функцию фильтрации. Все остальные типы описаны в MSDN и KMD by Four-F.

3)

Код (Text):
  1.  
  2. mov eax,offset hookproc
  3. invoke set_hook, eax
  4. .if eax != STATUS_SUCCESS
  5. ret
  6. .endif

Вызываем set_hook , в качестве параметра выступает offset нашей функции фильтрации.

Если хук не удалось установить, выходим.

4)

Код (Text):
  1.  
  2. mov eax, pDriverObject
  3. assume eax:PTR DRIVER_OBJECT
  4. mov [eax].DriverUnload,offset Unload
  5. assume eax:nothing
  6. mov eax,STATUS_SUCCESS
  7. ret

Стандартная процедура регистрации функции выхода.

5)

Код (Text):
  1.  
  2. Unload proc p1DriverObject:PDRIVER_OBJECT
  3.     invoke set_hook,NULL
  4.     ret
  5. Unload endp

Устанавливаем указатель на функцию фильтрации в IP Filter driver сервисе в NULL

6)

Код (Text):
  1.  
  2.     set_hook proc hook_fn:PacketFilterExtensionPtr
  3.  
  4.     invoke IoGetDeviceObjectPointer,addr drvsmbl,STANDARD_RIGHTS_ALL,addr fileobj,
  5.                                     addr devobj

Наша функция установки фильтра.

IoGetDeviceObjectPointer - возвращает указатель в devobj на Device и file object , соответсвующий ему , название которого в drvsmbl . При условии, что доступ к нему разрешён.

7)

Код (Text):
  1.  
  2.            invoke IoBuildDeviceIoControlRequest,IOCTL_PF_SET_EXTENSION_POINTER(),devobj, \
  3.                   addr hook_nfo ,sizeof hook_nfo, NULL, 0, FALSE, NULL,addr isb

Данная функция подробно описана в Walter Oney's Programming the Microsoft Windows Driver Model.

Макрос IOCTL_PF_SET_EXTENSION_POINTER() определён в pfhook.inc

Результат - устанавливаем irp для нашего драйвера.

Все остальные функции в данном разделе описаны в DDK и Programming the Microsoft Windows Driver Model.

8)

Код (Text):
  1.  
  2.     hookproc proc PacketHeader: DWORD , Packet: DWORD, PacketLength:WORD,
  3.                   RecvInterfaceIndex:WORD,SendInterfaceIndex:WORD,RecvLinkNextHop:DWORD,
  4.                   SendLinkNextHop:DWORD
  5.        
  6.         mov eax,PF_DROP
  7.         ret
  8. hookproc endp

Наш фильтр. Как видно, перед нами внутренности пакета.Заголовок и содержимое.

Возвращаем PF_DROP.

В pfhook.inc определены следующие константы для работы с IP пакетами:

Код (Text):
  1.  
  2. PF_FORWARD      EQU 0t
  3. PF_DROP         EQU 1t
  4. PF_PASS         EQU 2t
  5. PF_ICMP_ON_DROP EQU 3t

PF_FORWARD - форвардит пакет. Т.е. если destination address != наш адрес и включена маршрутизация, то немедленно посылается forward response в IP стек.

PF_PASS - пропускает пакет на наш компьютер.

PF_ICMP_ON_DROP - дропает пакет и отправляет ICMP - сообщение.

Данная константа недокументирована, хотя и определена.

Как установить наш драйвер ?

Автор использовал утилиту instdrv из NT DDK . К сожалению, в Win2000 DDK она отсутсвует.

Итак, набираем в консоли:

Код (Text):
  1.  
  2. net start ipfilterdriver
  3.  
  4. instdrv filter  D:\projects\asm\filter\filter.sys
  5.  
  6. ping 127.0.0.1
  7.  
  8.     Destination host unreachable.   ; host unreachable,    
  9. Destination host unreachable.   ; что и следовало ожидать,
  10. Destination host unreachable.   ; потому что все пакеты
  11. Destination host unreachable.   ; уничтожены, ICMP - сообщение  
  12. Ping statistics for 127.0.0.1:      ; не отправлялось.
  13.     Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
  14. Approximate round trip times in milli-seconds:
  15.     Minimum = 0ms, Maximum =  0ms, Average =  0ms
  16. .        
  17. instdrv filter remove

Заключение.

Автор не претендует на полноту изложения , он постарался дать лишь общее представление о предмете. Автор также надеется , что данная статья позволит самостоятельно создавать firewall'ы на основе IP Filter driver сервиса и данного сэмпла.

Рекомендуемая литература:

Walter Oney's Programming the Microsoft Windows Driver Model.
David Solomon, Mark Russinovich : Inside Windows 2000

Благодарности: Volodya /wasm.ru , за то, что терпел и наставлял меня , и за instdrv.
Four-F/wasm.ru ,за KMDKit и замечательные статьи.
gl00my , за моральную поддержку.

Файлы:

© van

0 1.367
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532