首页
社区
课程
招聘
[分享]学习 Windows Filtering Platform(WFP)
发表于: 2026-3-7 22:14 754

[分享]学习 Windows Filtering Platform(WFP)

2026-3-7 22:14
754

前言

Windows Filtering Platform(WFP)是 Windows 内核提供的一套网络数据过滤与控制框架, 可用于对网络进行 控制 / 过滤 / 监控 网络流量 等功能.Windows 自带防火墙就是基于 WFP 实现的, 第三方防火墙:火绒 / 360 / 电脑管家 / Windows Defender 大概率都基于 WFP.

开始

WFP 运行流程路径会从: 应用层 -> 进入内核 -> 触发WPF -> 传输远端具体流程和 TCP\IP 很像, 但似乎也有一些 OSI 的影子, 具体如下:

Application
 ↓
Winsock API
    例如: send() / connect() / WSASend()
    此时: 还没有进入内核, 还没有触发 WFP
 ↓
进入内核
    这时候: 连接建立 / 数据准备发送 / socket 绑定进程
 ↓
Afd.sys
 ↓
Tcpip.sys(Windows TCP/IP 网络协议栈)
    Windows 网络协议栈(Windows TCP/IP Stack) 是 Windows 内核中负责实现网络协议的一组组件,也可以说是Windows 实现的 TCP/IP 协议程序
    它实现了各种网络协议,例如:IP、TCP、UDP、ICMP、IPv6、ARP
 ↓
进入 WPF (过滤框架)
    数据进入 WFP 后,按照层级触发
 ↓
ALE_AUTH(授权阶段)
    FWPM_LAYER_ALE_AUTH_LISTEN_V4
    FWPM_LAYER_ALE_AUTH_LISTEN_V4_DISCARD
    FWPM_LAYER_ALE_AUTH_LISTEN_V6
    FWPM_LAYER_ALE_AUTH_LISTEN_V6_DISCARD
    FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4
    FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4_DISCARD
    FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6
    FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6_DISCARD
    FWPM_LAYER_ALE_AUTH_CONNECT_V4
    FWPM_LAYER_ALE_AUTH_CONNECT_V4_DISCARD
    FWPM_LAYER_ALE_AUTH_CONNECT_V6
    FWPM_LAYER_ALE_AUTH_CONNECT_V6_DISCARD
    触发时: 还没真正建立连接, 还没发包
    常用于:流量统计、连接跟踪、应用级防火墙、阻止某个程序联网、允许某个程序访问某IP
    可以拿: PID、程序路径、本地IP、远程IP、本地端口、远程端口、协议
 ↓
ALE_FLOW_ESTABLISHED
    FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4
    FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4_DISCARD
    FWPM_LAYER_ALE_FLOW_ESTABLISHED_V6
    FWPM_LAYER_ALE_FLOW_ESTABLISHED_V6_DISCARD
    此时: 连接已经建立, flow 已创建
    常用于:统计连接、连接跟踪、连接级限速、连接状态监控
    可以拿:PID、程序路径、本地IP、远程IP、本地端口、远程端口、协议  
 ↓
STREAM 层 (TCP 专用层)
    FWPM_LAYER_STREAM_V4
    FWPM_LAYER_STREAM_V4_DISCARD
    FWPM_LAYER_STREAM_V6
    FWPM_LAYER_STREAM_V6_DISCARD
    FWPM_LAYER_STREAM_PACKET_V4
    FWPM_LAYER_STREAM_PACKET_V6
    触发时: 仅针对 TCP, 数据是流片段, 数据已经过TCP重组
    常用于: 深度包检测、HTTP检测、SQL注入检测、敏感词检测、数据审计、tcp封包解析
 ↓
DATAGRAM 层 (UDP 专用层)
    FWPM_LAYER_DATAGRAM_DATA_V4
    FWPM_LAYER_DATAGRAM_DATA_V4_DISCARD
    FWPM_LAYER_DATAGRAM_DATA_V6
    FWPM_LAYER_DATAGRAM_DATA_V6_DISCARD
    常用于:DNS过滤、UDP防火墙、游戏封包分析、过滤 DNS、过滤 NTP、udp封包解析
 ↓
TRANSPORT 层(传输层)
    FWPM_LAYER_INBOUND_TRANSPORT_V4:进入本机的 IPv4 TCP/UDP 数据包
    FWPM_LAYER_INBOUND_TRANSPORT_V4_DISCARD:记录被丢弃的 inbound IPv4 transport packet
    FWPM_LAYER_INBOUND_TRANSPORT_V6:与 V4 相同
    FWPM_LAYER_INBOUND_TRANSPORT_V6_DISCARD:与 V4 相同
    FWPM_LAYER_OUTBOUND_TRANSPORT_V4:本机发送 IPv4 TCP/UDP packet
    FWPM_LAYER_OUTBOUND_TRANSPORT_V4_DISCARD:被丢弃的 outbound IPv4 transport packet
    FWPM_LAYER_OUTBOUND_TRANSPORT_V6:与 V4 相同
    FWPM_LAYER_OUTBOUND_TRANSPORT_V6_DISCARD:与 V4 相同
    FWPM_LAYER_INGRESS_VSWITCH_TRANSPORT_V4:进入虚拟交换机的 IPv4 transport packet
    FWPM_LAYER_INGRESS_VSWITCH_TRANSPORT_V6:与 V4 相同
    FWPM_LAYER_EGRESS_VSWITCH_TRANSPORT_V4:离开虚拟交换机的 IPv4 transport packet
    FWPM_LAYER_EGRESS_VSWITCH_TRANSPORT_V6:与 V4 相同
    FWPM_LAYER_INBOUND_TRANSPORT_FAST:高速 inbound packet path
    FWPM_LAYER_OUTBOUND_TRANSPORT_FAST:高速 outbound path
    FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4:IPSec inbound transport packet
    FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V6:与 V4 相同
    FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V4:IPSec outbound encrypt
    FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V6:与 V4 相同
    FWPM_CALLOUT_WFP_TRANSPORT_LAYER_V4_SILENT_DROP:静默丢弃 IPv4 transport packet
    FWPM_CALLOUT_WFP_TRANSPORT_LAYER_V6_SILENT_DROP:与 V4 相同
    此时: TCP/UDP 包已经生成, 进入发送队列
    常用于:端口过滤、简单流量拦截、DDOS过滤
    可以拿: 本地IP、远程IP、本地端口、远程端口、协议、IP Header、TCP Header
    这时候 payload 可能是分片的
    可以拦截封包内容,但不方便需要自己解析(推荐STREAM、DATAGRAM)
 ↓
IPPACKET (WFP最底层)
    FWPM_LAYER_INBOUND_IPPACKET_V4
    FWPM_LAYER_INBOUND_IPPACKET_V4_DISCARD
    FWPM_LAYER_INBOUND_IPPACKET_V6
    FWPM_LAYER_INBOUND_IPPACKET_V6_DISCARD
    FWPM_LAYER_OUTBOUND_IPPACKET_V4
    FWPM_LAYER_OUTBOUND_IPPACKET_V4_DISCARD
    FWPM_LAYER_OUTBOUND_IPPACKET_V6
    FWPM_LAYER_OUTBOUND_IPPACKET_V6_DISCARD
    触发: 直接拿IP包, 没有进程信息, 没有Socket信息, 这是最底层抓包
    常用于:VPN、IPS、NAT、IP伪造检测、IP级防火墙
 ↓
NDIS(Network Driver Interface Specification)
    NDIS 是 Windows 的 网络驱动接口规范,也可以说是 Windows 网络驱动框架
    作用是统一网卡驱动的开发接口,让 TCP/IP 协议栈不需要关心具体网卡型号,让不同厂商网卡驱动能正常工作
 ↓
Miniport Driver (网卡驱动)
 ↓
网卡硬件

后缀分类

  • LISTEN: 监听端口阶段
  • CONNECT: 主动发起连接阶段
  • RECV_ACCEPT: 被动接收连接阶段
  • DISCARD: 被拒绝 / 被丢弃的流量
  • INGRESS_VSWITCH: 虚拟机流入本机 (Hyper-V 虚拟机 / 容器网络 / 虚拟网卡)
  • EGRESS__VSWITCH: 本机流入虚拟机 (Hyper-V 虚拟机 / 容器网络 / 虚拟网卡)
  • FAST: 走高速路径的流量
  • IPSEC_INBOUND: 入站 IPSec , 解密传入应用层
  • IPSEC_OUTBOUND: 出入站 IPSec , 加密传出网卡驱动
  • SILENT_DROP: 静默丢弃, 直接丢弃, 不给上层任何反馈
Socket / 应用
 ↓
TCP 重组
 ↓
TCP 层
 ↓
IP 层
 ↓
Ethernet
 ↓
网卡

回调

解决完选择层之后, 回调看似都是一样的, 其实 inFixedValues 字段里的内容每个类型都不同 图片描述 图片描述可以看到选择了其中一项ALE_AUTH_CONNECT里面可以获取ip / port / id 等等信息, 并且很友好的做了自适应版本适配 图片描述可以看到切到IPPACKET就完全没用ip 端口这些信息了, 这就是每个层能获取的数据是不一致的

各层关联链

ALE_AUTH_CONNECT
    取 transportEndpointHandle
    保存连接信息
        ↓
ALE_FLOW_ESTABLISHED
    再取 transportEndpointHandle
    找到之前保存的记录
    创建 FlowContext
    取 flowHandle
    FwpsFlowAssociateContext(flowHandle)
        ↓
STREAM / DATAGRAM
    直接得到 flowContext
           ALE_AUTH_CONNECT
                   │
                   │ transportEndpointHandle
                   ▼
        CONNECT_CONTEXT (connectTable)
                   │
                   │ match
                   ▼
        ALE_FLOW_ESTABLISHED
                   │
                   │ flowHandle
                   ▼
              FLOW_CONTEXT
                   │
                   │ FwpsFlowAssociateContext
                   ▼
          STREAM / DATAGRAM
                   │
                   ▼
               flowContext

WFP 层触发顺序

ALE_AUTH_CONNECT_V4
    触发条件:connect()
    作用:判断程序是否允许连接
    可获得信息:应用程序路径、PID、本地IP、远程IP、远程端口、协议
    常见用途:应用防火墙、程序联网控制
    例如:禁止 chrome 访问 1.2.3.4
        ↓
ALE_FLOW_ESTABLISHED_V4
    触发条件:TCP 三次握手完成
    典型用途:记录连接、统计流量、绑定上下文
        ↓
TRANSPORT_V4
    触发条件:TCP packet 进入/离开 TCP/IP
    特点:每个 TCP 包都会触发、能看到 TCP header
    可获取:源IP、目标IP、端口、TCP flags
        ↓
STREAM_V4
    触发条件:TCP 数据流重组完成
    处理:HTTP、TLS、协议解析
    特点:数据连续、不会被 TCP 分片
        ↓
IPPACKET_V4
    触发条件:IP packet 发送/接收
    特点:最底层
    用途:抓包、修改IP头、NAT

服务器执行顺序:

socket()
bind()
listen()
accept()

TCP 时序图

客户端                           服务器

socket
connect
   │
   │  ALE_AUTH_CONNECT
   │
SYN ───────────────────────────→
                                │
                                │ ALE_AUTH_RECV_ACCEPT
                                │
SYN-ACK ←───────────────────────
ACK ───────────────────────────→
   │
   │ ALE_FLOW_ESTABLISHED
   │
send
   │
   │ TRANSPORT
   │ STREAM
   │ IPPACKET

服务器启动流程

socket
bind
listen
   │
   │ ALE_AUTH_LISTEN
   │
等待连接

UDP 流程

UDP 没有连接

socket
sendto
recvfrom

触发:

ALE_AUTH_CONNECT (可选)
DATAGRAM
TRANSPORT
IPPACKET

不会有:

LISTEN
FLOW_ESTABLISHED
STREAM

总结

WFP 这个框架提供确实很友好, 减轻了大量开发的工作量, 在有足够的了解后完全可以实现一个属于自己的封包拦截器, 当然在了解了微软对网络的分层后 对直接HOOK底层函数或者自己做解析也是行得通的


[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2026-3-13 18:46 被mb_binusgki编辑 ,原因: 补充内容
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回