What is windows filtering platform

About Windows Filtering Platform

Windows Filtering Platform (WFP) is a network traffic processing platform designed to replace the Windows XP and Windows Server 2003 network traffic filtering interfaces. WFP consists of a set of hooks into the network stack and a filtering engine that coordinates network stack interactions.

The WFP components

Filter Engine

The core multi-layer filtering infrastructure, hosted in both kernel-mode and user-mode, that replaces the multiple filtering modules in the Windows XP and Windows Server 2003 networking subsystem.

  • Filters network traffic at any layer in the system over any data fields that a shim can provide.
  • Implements the «Callout» filters by invoking callouts during classification.
  • Returns «Permit» or «Block» actions to the shim that invoked it for enforcement.
  • Provides arbitration between different policy sources. For example, determines priority when an application is configured to secure any network traffic related to it, but the local firewall is configured to prevent application secured traffic.

Base Filtering Engine (BFE)

A service that controls the operation of the Windows Filtering Platform. It performs the following tasks.

  • Accepts filters and other configuration settings for the platform.
  • Reports the current state of the system, including statistics.
  • Enforces the security model for accepting configuration in the platform. For example, a local administrator can add filters but other users can only view them.
  • Plumbs configuration settings to other modules in the system. For example, IPsec negotiation polices go to IKE/AuthIP keying modules, filters go to the filter engine.

Shims

Kernel-mode components that reside between the Network Stack and the filter engine. Shims make the filtering decision by classifying against the filter engine. Following is a list of available shims.

  • Application Layer Enforcement (ALE) shim.
  • Transport Layer Module shim.
  • Network Layer Module shim.
  • Internet Control Message Protocol (ICMP) Error shim.
  • Discard shim.
  • Stream shim.

Callouts

Set of functions exposed by a driver and used for specialized filtering. Besides the basic actions of «Permit» and «Block», callouts can modify and secure inbound and outbound network traffic. See the Windows Filtering Platform Callout Drivers topic in the Windows Driver Kit (WDK) documentation for more information on callouts. WFP provides built-in callouts that accomplish the following tasks.

  • Perform IPsec processing.
  • Adjust stateful filtering behavior.
  • Perform stealth mode filtering (silent drop of packets that were not requested).
  • Control TCP chimney offload.
  • Interact with the Teredo service.

The filter engine allows third-party callouts to register at each of its kernel-mode layers.

Application Programming Interface

A set of data types and functions available to the developers to build and manage network filtering applications. These data types and functions are grouped into multiple API sets.

Windows Filtering Platform

Purpose

Windows Filtering Platform (WFP) is a set of API and system services that provide a platform for creating network filtering applications. The WFP API allows developers to write code that interacts with the packet processing that takes place at several layers in the networking stack of the operating system. Network data can be filtered and also modified before it reaches its destination.

By providing a simpler development platform, WFP is designed to replace previous packet filtering technologies such as Transport Driver Interface (TDI) filters, Network Driver Interface Specification (NDIS) filters, and Winsock Layered Service Providers (LSP). Starting in Windows Server 2008 and Windows Vista, the firewall hook and the filter hook drivers are not available; applications that were using these drivers should use WFP instead.

With the WFP API, developers can implement firewalls, intrusion detection systems, antivirus programs, network monitoring tools, and parental controls. WFP integrates with and provides support for firewall features such as authenticated communication and dynamic firewall configuration based on applications’ use of sockets API (application-based policy). WFP also provides infrastructure for IPsec policy management, change notifications, network diagnostics, and stateful filtering.

Читайте также:  Классический вид windows 10 shell

Windows Filtering Platform is a development platform and not a firewall itself. The firewall application that is built into Windows Vista, Windows Server 2008, and later operating systems Windows Firewall with Advanced Security (WFAS) is implemented using WFP. Therefore, applications developed with the WFP API or the WFAS API use the common filtering arbitration logic that is built into WFP.

The WFP API consists of a user-mode API and a kernel-mode API. This section provides an overview of the entire WFP and describes in detail only the user-mode portion of the WFP API. For a detailed description of the kernel-mode WFP API, see the Windows Driver Kit online help.

Developer audience

The Windows Filtering Platform API is designed for use by programmers using C/C++ development software. Programmers should be familiar with networking concepts and design of systems using user-mode and kernel-mode components.

Run-time requirements

The Windows Filtering Platform is supported on clients running Windows Vista and later, and on servers running Windows Server 2008 and later. For information about the run-time requirements for a specific programming element, see the Requirements section of the reference page for that element.

In this section

Topic Description
What’s New in Windows Filtering Platform Information on new features and APIs in Windows Filtering Platform.
About Windows Filtering Platform An overview of Windows Filtering Platform.
Using Windows Filtering Platform Example code using the Windows Filtering Platform API.
Windows Filtering Platform API Reference Documentation for the Windows Filtering Platform functions, structures, and constants.

Additional resources

To ask questions and have discussions about using the WFP API, visit the Windows Filtering Platform Forum.

What’s New in Windows Filtering Platform

WindowsВ 8 and Windows ServerВ 2012 introduce new Windows Filtering Platform programming elements. New functionality includes the following:

  • Layer 2 filtering: Provides access to the L2 (MAC) layer, allowing filtering of traffic at that layer.
  • vSwitch filtering: Allows packets traversing a vSwitch to be inspected and/or modified. WFP filters or callouts can be used at the vSwitch ingress and egress.
  • App container management: Allows access to information about app containers and network isolation connectivity issues.
  • IPsec updates: Extended IPsec functionality including connection state monitoring, certificate selection, and key management.

The Windows Driver Kit also includes information on WFP Changes for WindowsВ 8.

Windows 8 API updates

Many new APIs have been added for WindowsВ 8 and Windows ServerВ 2012.

New functions

New structures

New enumerated types

New filtering layer identifiers

  • FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET
  • FWPM_LAYER_OUTBOUND_MAC_FRAME_ETHERNET
  • FWPM_LAYER_INBOUND_MAC_FRAME_NATIVE
  • FWPM_LAYER_OUTBOUND_MAC_FRAME_NATIVE
  • FWPM_LAYER_INGRESS_VSWITCH_ETHERNET
  • FWPM_LAYER_EGRESS_VSWITCH_ETHERNET
  • FWPM_LAYER_INGRESS_VSWITCH_TRANSPORT_V4 / FWPM_LAYER_INGRESS_VSWITCH_TRANSPORT_V6
  • FWPM_LAYER_EGRESS_VSWITCH_TRANSPORT_V4 / FWPM_LAYER_EGRESS_VSWITCH_TRANSPORT_V6

New filtering condition identifiers

  • FWPM_CONDITION_INTERFACE_MAC_ADDRESS
  • FWPM_CONDITION_MAC_LOCAL_ADDRESS
  • FWPM_CONDITION_MAC_REMOTE_ADDRESS
  • FWPM_CONDITION_ETHER_TYPE
  • FWPM_CONDITION_VLAN_ID
  • FWPM_CONDITION_NDIS_PORT
  • FWPM_CONDITION_NDIS_MEDIA_TYPE
  • FWPM_CONDITION_NDIS_PHYSICAL_MEDIA_TYPE
  • FWPM_CONDITION_L2_FLAGS
  • FWPM_CONDITION_MAC_LOCAL_ADDRESS_TYPE
  • FWPM_CONDITION_MAC_REMOTE_ADDRESS_TYPE
  • FWPM_CONDITION_ALE_PACKAGE_ID
  • FWPM_CONDITION_MAC_SOURCE_ADDRESS
  • FWPM_CONDITION_MAC_DESTINATION_ADDRESS
  • FWPM_CONDITION_MAC_SOURCE_ADDRESS_TYPE
  • FWPM_CONDITION_MAC_DESTINATION_ADDRESS_TYPE
  • FWPM_CONDITION_IP_SOURCE_PORT
  • FWPM_CONDITION_IP_DESTINATION_PORT
  • FWPM_CONDITION_VSWITCH_ID
  • FWPM_CONDITION_VSWITCH_NETWORK_TYPE
  • FWPM_CONDITION_VSWITCH_SOURCE_INTERFACE_ID
  • FWPM_CONDITION_VSWITCH_DESTINATION_INTERFACE_ID
  • FWPM_CONDITION_VSWITCH_SOURCE_VM_ID
  • FWPM_CONDITION_VSWITCH_DESTINATION_VM_ID
  • FWPM_CONDITION_VSWITCH_SOURCE_INTERFACE_TYPE
  • FWPM_CONDITION_VSWITCH_TENANT_NETWORK_ID

New filtering condition flags

  • FWP_CONDITION_FLAG_IS_PROXY_CONNECTION
  • FWP_CONDITION_FLAG_IS_APPCONTAINER_LOOPBACK
  • FWP_CONDITION_FLAG_IS_NON_APPCONTAINER_LOOPBACK
  • FWP_CONDITION_FLAG_IS_HONORING_POLICY_AUTHORIZE
  • FWP_CONDITION_L2_IS_NATIVE_ETHERNET
  • FWP_CONDITION_L2_IS_WIFI
  • FWP_CONDITION_L2_IS_MOBILE_BROADBAND
  • FWP_CONDITION_L2_IS_WIFI_DIRECT_DATA
  • FWP_CONDITION_L2_IS_VM2VM
  • FWP_CONDITION_L2_IS_MALFORMED_PACKET
  • FWP_CONDITION_L2_IS_IP_FRAGMENT_GROUP
  • FWP_CONDITION_L2_IF_CONNECTOR_PRESENT

Windows 7 updates to the Windows Filtering Platform

The document What’s New in Windows Filtering Platform details many of the updates made for WindowsВ 7. Information is also available in the Windows Driver Kit on WFP Changes for WindowsВ 7.

Windows Filtering Platform в защите и нападении

Содержание статьи

Начиная с Server 2008 и Vista в винду был встроен механизм WFP,
представляющий собой набор API и системных сервисов. С помощью него стало можно
запрещать и разрешать соединения, управлять отдельными пакетами. Эти
нововведения были предназначены для упрощения жизни разработчиков различных
защит. Внесенные в сетевую архитектуру изменения затронули как kernel-mode, так
и user-mode части системы. В первом случае необходимые функции экспортируются
fwpkclnt.sys, во втором — fwpuclnt.dll (буквы «k» и «u» в названиях библиотек
означают kernel и user соответственно). В этой статье мы расскажем о применении
WFP для перехвата и фильтрации трафика, а после ознакомления с основными
определениями и возможностями WFP мы напишем свой простой фильтр.

Основные понятия

Перед началом кодинга нам совершенно необходимо ознакомиться с терминологией
Microsoft — и для понимания статьи будет полезно, и дополнительную литературу
читать будет проще :). Итак, поехали.

Классификация — процесс определения того, что нужно делать с пакетом.
Из возможных действий: разрешить, блокировать или вызвать callout.

Callouts — это набор функций в драйвере, которые проводят инспекцию
пакетов. Они имеют специальную функцию, выполняющую классификацию пакетов. Эта
функция может принять следующее решение:

  • разрешить (FWP_ACTION_PERMIT);
  • блокировать (FWP_ACTION_BLOCK);
  • продолжить обработку;
  • запросить больше данных;
  • прервать соединение.

Фильтры (Filters) — правила, указывающие, в каких случаях вызывается
тот или иной callout. Один драйвер может иметь несколько callout’ов, а
разработкой драйвера с callout’ом мы и займемся в этой статье. Кстати, колауты
есть и встроенные, например, NAT-callout.

Layer — это признак, по которому объединяются различные фильтры (или,
как говорят в MSDN, «контейнер»).

По правде говоря, документация от Microsoft, выглядит достаточно мутно, пока
не заглянешь в примеры в WDK. Поэтому, если вдруг надумаешь разрабатывать что-то
серьезное, нужно непременно с ними ознакомиться. Ну что ж, теперь плавно
перейдем к практике. Для успешной компиляции и тестов тебе потребуется WDK (Windows
Driver Kit), VmWare, виртуальная машина с установленной Вистой и отладчик WinDbg.
Что касается WDK, то у меня лично установлена версия 7600.16385.0 — там есть все
необходимые либы (поскольку мы будем разрабатывать драйвер, нам нужны только
fwpkclnt.lib и ntoskrnl.lib) и примеры использования WFP. Ссылки на весь
инструментарий уже неоднократно приводились, поэтому повторяться не будем.

Coding

Для инициализации callout’а я написал функцию BlInitialize. Общий алгоритм
создания callout и добавления фильтра таков:

  1. FWPMENGINEOPEN0 осуществляет открытие сеанса;
  2. FWPMTRANSACTIONBEGIN0 — начало операции с WFP;
  3. FWPSCALLOUTREGISTER0 — создание нового callout;
  4. FWPMCALLOUTADD0 — добавление объекта callout’а в систему;
  5. FWPMFILTERADD0 — добавление нового фильтра(ов);
  6. FWPMTRANSACTIONCOMMIT0 — сохранение изменений (добавленных
    фильтров).

Обрати внимание, что функции оканчиваются на 0. В Windows 7 некоторые из этих
функций были изменены, например, появилась FwpsCalloutRegister1 (при
сохраненной FwpsCalloutRegister0). Отличаются они аргументами и, как следствие,
прототипами классифицирующих функций, но для нас это сейчас неважно — 0-функции
универсальны.

FwpmEngineOpen0 и FwpmTransactionBegin0 не особо нам интересны — это
подготовительный этап. Самое интересное начинается с функции
FwpsCalloutRegister0:

Прототип FwpsCalloutRegister0

NTSTATUS NTAPI FwpsCalloutRegister0
(
__inout void *deviceObject,
__in const FWPS_CALLOUT0 *callout,
__out_opt UINT32 *calloutId
);

Я уже говорил, что callout — это набор функций, теперь пришло время
рассказать об этом подробнее. Структура FWPS_CALLOUT0 содержит указатели на три
функции — классифицирующую (classifyFn) и две уведомляющие (о
добавлении/удалении фильтра (notifyFn) и закрытии обрабатываемого потока (flowDeleteFn)).
Первые две функции являются обязательными, последняя нужна только в случае, если
ты хочешь мониторить сами пакеты, а не только соединения. Также в структуре
содержится уникальный идентификатор, GUID колаута (calloutKey).

Код регистрации callout

FWPS_CALLOUT sCallout = <0>;
sCallout.calloutKey = *calloutKey;
sCallout.classifyFn = BlClassify;
// классифицирующая функция
sCallout.notifyFn = (FWPS_CALLOUT_NOTIFY_FN0)BlNotify;
// функция, уведомляющая о добавлении/удалении фильтра
// создаем новый колаут
status = FwpsCalloutRegister(deviceObject, &sCallout, calloutId);

Далее нужно добавить объект-callout в систему и присоединить его к
определенному уровню (layer) с помощью функции FwpmCalloutAdd0:

DWORD WINAPI FwpmCalloutAdd0(
__in HANDLE engineHandle,
__in const FWPM_CALLOUT0 *callout,
__in_opt PSECURITY_DESCRIPTOR sd,
__out_opt UINT32 *id
);
typedef struct FWPM_CALLOUT0_ <
GUID calloutKey;
FWPM_DISPLAY_DATA0 displayData; // описание callout
UINT32 flags;
GUID *providerKey;
FWP_BYTE_BLOB providerData;
GUID applicableLayer;
UINT32 calloutId;
> FWPM_CALLOUT0;

В структуре FWPM_CALLOUT0 нам интересно поле applicableLayer — уникальный
идентификатор уровня, на который добавляется callout. В нашем случае это
FWPM_LAYER_ALE_AUTH_CONNECT_V4. «v4» в названии идентификатора означает версию
протокола Ipv4, есть также FWPM_LAYER_ALE_AUTH_CONNECT_V6 для Ipv6. Учитывая
малую распространенность Ipv6 на настоящий момент, работать мы будем только с
Ipv4. CONNECT в названии означает, что мы контролируем только установку
соединения, о входящих и исходящих на этот адрес пакетах речи не идет! Вообще
уровней, помимо использованного нами, много — они объявлены в заголовочном файле
fwpmk.h из WDK.

Добавление объекта-callout в систему

// название callout
displayData.name = L»Blocker Callout»;
displayData.description = L»Blocker Callout»;
mCallout.calloutKey = *calloutKey;
mCallout.displayData = displayData;
// описание callout
//FWPM_LAYER_ALE_AUTH_CONNECT_V4
mCallout.applicableLayer = *layerKey;
status = FwpmCalloutAdd(gEngineHandle, &mCallout, NULL, NULL);

Итак, после того, как callout успешно добавлен в систему, нужно создать
фильтр, то есть указать, в каких случаях будет вызываться наш callout, а именно
— его классифицирующая функция. Новый фильтр создается функцией FwpmFilterAdd0,
которой в качестве аргумента передается структура FWPM_FILTER0.

В FWPM_FILTER0 есть одна или несколько структур FWPM_FILTER_CONDITION0 (их
число определяется полем numFilterConditions). Поле layerKey заполняется GUID’ом
уровня (layer), к которому мы хотим присоединиться. В данном случае указываем
FWPM_LAYER_ALE_AUTH_CONNECT_V4.

Теперь подробнее рассмотрим заполнение FWPM_FILTER_CONDITION0. Во-первых, в
поле fieldKey нужно явно указать, что мы хотим контролировать — порт, адрес,
приложение или что-то еще. В данном случае WPM_CONDITION_IP_REMOTE_ADDRESS
указывает системе, что нас интересует IP-адрес. Значение fieldKey определяет,
значения какого типа будут в структуре FWP_CONDITION_VALUE, входящей в
FWPM_FILTER_CONDITION0. В данном случае в ней содержится ipv4-адрес. Идем
дальше. Поле matchType определяет, каким образом будет производиться сравнение
значения в FWP_CONDITION_VALUE с тем, что пришло по сети. Тут вариантов много:
можно указать FWP_MATCH_EQUAL, что будет означать полное соответствие условию, а
можно — FWP_MATCH_NOT_EQUAL, то есть, фактически, мы можем добавить таким
образом исключение фильтрации (адрес, соединение с которым не отслеживается).
Еще есть варианты FWP_MATCH_GREATER, FWP_MATCH_LESS и другие (см. энум
FWP_MATCH_TYPE). В данном случае у нас стоит FWP_MATCH_EQUAL.

Я не стал сильно заморачиваться и просто написал условие на блокирование
одного выбранного IP-адреса. В случае, когда какое-то приложение попытается
установить соединение с выбранным адресом, будет вызвана классифицирующая
функция нашего callout’а. Код, обобщающий сказанное, ты можешь посмотреть на
врезке «Добавление фильтра в систему».

Добавление фильтра в систему

filter.flags = FWPM_FILTER_FLAG_NONE;
filter.layerKey = *layerKey;
filter.displayData.name = L»Blocker Callout»;
filter.displayData.description = L»Blocker Callout»;
filter.action.type = FWP_ACTION_CALLOUT_UNKNOWN;
filter.action.calloutKey = *calloutKey;
filter.filterCondition = filterConditions;
// одно условие фильтрации
filter.numFilterConditions = 1;
//filter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL;
filter.weight.type = FWP_EMPTY; // auto-weight.
// добавляем фильтр на удаленный адрес
filterConditions[0].fieldKey = FWPM_CONDITION_IP_REMOTE_ADDRESS;
filterConditions[0].matchType = FWP_MATCH_EQUAL;
filterConditions[0].conditionValue.type = FWP_UINT32;
filterConditions[0].conditionValue.uint32 = ntohl(BLOCKED_IP_ADDRESS);
// добавляем фильтр
status = FwpmFilterAdd(gEngineHandle, &filter, NULL, NULL);

Вообще, конечно, фильтрующих условий может быть много. Например, можно
указать блокирование соединений с определенным удаленным или локальным портом (FWPM_CONDITION_IP_REMOTE_PORT
и FWPM_CONDITION_IP_LOCAL_PORT соответственно). Можно вылавливать все пакеты
определенного протокола или определенного приложения. И это еще не все! Можно,
например, заблокировать трафик определенного пользователя. В общем, есть где
разгуляться.

Впрочем, вернемся к фильтру. Классифицирующая функция в нашем случае просто
блокирует соединение с указанным адресом (BLOCKED_IP_ADDRESS), возвращая
FWP_ACTION_BLOCK:

Код нашей classify-функции

void BlClassify(
const FWPS_INCOMING_VALUES* inFixedValues,
const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
VOID* packet,IN const FWPS_FILTER* filter,
UINT64 flowContext,FWPS_CLASSIFY_OUT* classifyOut)
<
// заполняем структуру FWPS_CLASSIFY_OUT0
if(classifyOut) < // блокируем пакет
classifyOut->actionType =
FWP_ACTION_BLOCK;
// при блокировании пакета нужно
сбрасывать FWPS_RIGHT_ACTION_WRITE
classifyOut->rights&=

На практике функция классификации также может установить FWP_ACTION_PERMIT,
FWP_ACTION_CONTINUE и др.

И в заключение при выгрузке драйвера нужно удалить все установленные
callout’ы (угадай, что будет, если система попытается вызвать callout
выгруженного драйвера? Правильно, BSOD). Для этого существует функция
FwpsCalloutUnregisterById. В качестве параметра ей передается 32-битный
идентификатор callout’а, возвращенный функцией FwpsCalloutRegister.

Завершение работы callout’а

NTSTATUS BlUninitialize() <
NTSTATUS ns;
if(gEngineHandle) <
FwpmEngineClose(gEngineHandle);

>
if(gBlCalloutIdV4) <
ns =FwpsCalloutUnregisterById(gBlCalloutIdV4);
>
return ns;
>

Как видишь, программирование WFP-фильтра — не такая сложная задача, поскольку
MS предоставили нам весьма удобный API. Кстати, в нашем случае мы устанавливали
фильтр в драйвере, но это можно делать и из юзермода! Например, семпл из wdk
msnmntr (монитор трафика MSN Messenger-а) так и поступает — это позволяет не
перегружать kernel-mode часть фильтра.

Свой GUID

Для регистрации callout ему нужен уникальный идентификатор. Для того, чтобы
получить свой GUID (Globally Unique Identifier), используй guidgen.exe, входящий
в Visual Studio. Лежит тулза в (VS_Path)\Common7\Tools. Вероятность коллизии
очень мала, поскольку длина GUID составляет 128 бит, и всего доступно 2^128
идентификаторов.

Отладка фильтра

Для отладки дров удобно использовать связку Windbg+VmWare. Для этого нужно
настроить как гостевую систему (в виде которой выступает Vista), так и отладчик
WinDbg. Если у WinXP для удаленной отладки нужно было редактировать boot.ini, то
для Vista+ есть консольная утилита bcdedit. Как обычно, нужно включить отладку:

BCDedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200 BCDedit /debug
ON (или BCDedit /set debug ON)

Далее нужно настроить последовательный порт удаленной системы (см.
соответствующую иллюстрацию).

Теперь все готово! Запускаем батник с нижеприведенным текстом:

start windbg -b -k com:pipe,port=\\.\pipe\com_1,resets=0

и лицезреем отладочный вывод в окне windbg (см. картинку).

Заключение

Как видишь, область применения WFP довольно широка. Тебе решать, как
применить эти знания — во зло или во благо 🙂

Читайте также:  Gi on linux notabug
Оцените статью