WFP 学习(一)——构架把握

Windows Filtering Platform

Windows Filtering Platform(WFP) 是windows推出的用于TCP/IP协议栈五层各层里面对数据包进行交互操作的基础框架,该框架提供了一系列的API用于实现交互目的。这个框架的作用是为了取代之前的TDI/NDIS/LSP技术。

这个东西能够干啥呢?

使用WFP API,开发者可以实现个人防火墙、入侵检测系统、防病毒程序、流量监控工具。WFP集成了基于进程的防火墙控制功能,但是它自身并非是个防火墙,它只是个数据包过滤的开发框架。

系统要求

Windows Vista,Windows 7,Windows 10
Windows Server 2008以及之后的版本

WFP的架构

下图展示了WFP的架构图:

在这里插入图片描述

WFP是通过集成四个基础实体:Layers,Filters,shims以及Callouts来发挥它的作用的。接下来,将对这四个实体做一些基础的介绍。

Layers

每一个layer都是被filter engine管理的用于将过滤器分门别类。其实就是可以理解为每个layer对应了数据包在协议栈不同的封包/解包时机。这里的layer并不是网络协议栈的模块成分,实际上它把整个网络栈分成很多特别细的阶段。不同阶段对应这不同的layers。
不同的layer对应不同的过滤条件和过滤规则。
例如:FWPM_LAYER_INBOUND_IPPACKET_V4 层,对应的过滤条件就有:

FWPM\_CONDITION\_FLAGS
FWPM\_CONDITION\_INTERFACE\_INDEX
FWPM\_CONDITION\_INTERFACE\_TYPE
FWPM\_CONDITION\_IP\_LOCAL\_ADDRESS
FWPM\_CONDITION\_IP\_LOCAL\_ADDRESS\_TYPE
FWPM\_CONDITION\_IP\_LOCAL\_INTERFACE
FWPM\_CONDITION\_IP\_REMOTE\_ADDRESS
FWPM\_CONDITION\_SUB\_INTERFACE\_INDEX
FWPM\_CONDITION\_TUNNEL\_TYPE

Filters

Filter 字面意思就是过滤器,实际上就是一条用于匹配特定 出/入 流量的规则。规则将告诉 过滤引擎 ,匹配到的特定数据包后的动作。例如匹配到特定的包后就调用一个callout模块来执行深度包检测。
具体的来说就类似于:“Block traffic with a TCP port greater than 1024” or “Call out to IDS for all traffic that is not secured.”

Filters分两类:boot-time filter 和run-time filter. 具体区别查阅:https://docs.microsoft.com/en-us/windows/desktop/fwp/basic-operation

Shims

Shim的含义是中间层、夹片、切片的意思。
当数据包、数据流或者事件流经网络协议栈的时候,shims 把它们转换为具体的可用于分类的条件或数值(例如提取其中的IP地址,端口号),然后调用过滤引擎根据包的信息来在特定的层执行特定的过滤规则。shim然后
收集过滤的结果,最后对流做出最终的动作,例如drop。

Callouts

callouts就是回调函数的意思。callouts就是用于执行特定过滤规则或动作的函数。这些函数是由程序员自定义的,当然也有一些是预定义好的。一般这些callouts可以执行对包的分析、修改功能。

callouts可以在任何WFP内核层进行注册。callouts函数可以返回一个动作值(“Block”、“Permit”、“Need more data”等等),也可以对网络流量进行修改。

一旦一个callout注册好了,它就可以接收到发给进程的数据包。Callouts可以让过滤引擎给shim返回Block,permit动作,也可以返回Continue让其他过滤引擎去处理相应的数据包。

Classification

Classification is the process of applying filters to network traffic (packet, stream, or event) in order to determine a result of “Permit” or “Block” for that traffic. For one packet, stream, or event there is one classification call per layer.

During classification, the properties (for example, source address) of the packet, stream, or event are compared with filter conditions set on filters at the layer where the classification is invoked. When matches are found, the Filter Arbitration algorithm is used to determines the result of the classification process.

A classification request is triggered by a shim.

classification的动作包括:
在这里插入图片描述

WFP的操作流程

对于流入的数据包:

  1. 一个数据包流入网络协议栈
  2. 网络协议栈寻找并调用shim
  3. 在特定的layer上,shim调用classification处理模块
  4. 在classfication过程中,进行过滤规则的匹配,并确定相应的动作。
  5. 如果某个callout过滤规则被匹配,则调用相应的callout函数
  6. shim执行最后的包动作。

学习目标

本次学习的最终目标是基于WFP,开发一款基于进程的主动包测量的Demo。具体来说,就是可以修改特定进程的数据包的某个特定的位。

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个 WFP 的 demo,您可以参考以下代码: #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <wfp.h> #pragma comment(lib, "Fwpkclnt.lib") int main(int argc, char* argv[]) { FWPM_SESSION session = { }; FWPM_FILTER filter = { }; FWPM_FILTER_CONDITION filterConditions[1] = { }; FWPM_PROVIDER provider = { }; FWPM_SUBLAYER subLayer = { }; HANDLE engineHandle = NULL; UINT64 filterId = ; DWORD errorCode = ERROR_SUCCESS; // 初始化 WFP 引擎 errorCode = FwpmEngineOpen(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engineHandle); if (errorCode != ERROR_SUCCESS) { printf("Failed to open WFP engine. Error code: %d\n", errorCode); return -1; } // 创建 WFP 提供程序 provider.displayData.name = L"My WFP Provider"; provider.displayData.description = L"Demo WFP Provider"; provider.providerKey = (GUID) { x12345678, x1234, x1234, { x12, x34, x12, x34, x12, x34, x12, x34 } }; errorCode = FwpmProviderAdd(engineHandle, &provider, NULL); if (errorCode != ERROR_SUCCESS) { printf("Failed to add WFP provider. Error code: %d\n", errorCode); FwpmEngineClose(engineHandle); return -1; } // 创建 WFP 子层 subLayer.displayData.name = L"My WFP SubLayer"; subLayer.displayData.description = L"Demo WFP SubLayer"; subLayer.subLayerKey = (GUID) { x12345678, x1234, x1234, { x12, x34, x12, x34, x12, x34, x12, x34 } }; subLayer.weight = FWP_EMPTY; errorCode = FwpmSubLayerAdd(engineHandle, &subLayer, NULL); if (errorCode != ERROR_SUCCESS) { printf("Failed to add WFP sublayer. Error code: %d\n", errorCode); FwpmProviderDeleteByKey(engineHandle, &provider.providerKey); FwpmEngineClose(engineHandle); return -1; } // 创建 WFP 过滤器条件 filterConditions[].fieldKey = FWPM_CONDITION_IP_REMOTE_ADDRESS; filterConditions[].matchType = FWP_MATCH_EQUAL; filterConditions[].conditionValue.type = FWP_BYTE_ARRAY16_TYPE; filterConditions[].conditionValue.byteArray16 = (FWP_BYTE_ARRAY16) { x01, x02, x03, x04, x05, x06, x07, x08, x09, xA, xB, xC, xD, xE, xF, x10 }; // 创建 WFP 过滤器 filter.providerKey = provider.providerKey; filter.subLayerKey = subLayer.subLayerKey; filter.displayData.name = L"My WFP Filter"; filter.displayData.description = L"Demo WFP Filter"; filter.action.type = FWP_ACTION_BLOCK; filter.weight.type = FWP_EMPTY; filter.filterCondition = filterConditions; filter.numFilterConditions = ARRAYSIZE(filterConditions); errorCode = FwpmFilterAdd(engineHandle, &filter, NULL, &filterId); if (errorCode != ERROR_SUCCESS) { printf("Failed to add WFP filter. Error code: %d\n", errorCode); FwpmSubLayerDeleteByKey(engineHandle, &subLayer.subLayerKey); FwpmProviderDeleteByKey(engineHandle, &provider.providerKey); FwpmEngineClose(engineHandle); return -1; } // 关闭 WFP 引擎 FwpmFilterDeleteById(engineHandle, filterId); FwpmSubLayerDeleteByKey(engineHandle, &subLayer.subLayerKey); FwpmProviderDeleteByKey(engineHandle, &provider.providerKey); FwpmEngineClose(engineHandle); return ; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值