ffalcinelli/pydivert

GitHub: ffalcinelli/pydivert

PyDivert 是 Windows 网络驱动 WinDivert 的 Python 绑定,支持在内核层面实时捕获、修改和丢弃网络流量数据包。

Stars: 238 | Forks: 44

# PyDivert [![github-actions](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/e1d1433508122845.svg)](https://github.com/ffalcinelli/pydivert/actions/workflows/ci.yml) [![codecov](https://img.shields.io/codecov/c/github/ffalcinelli/pydivert/main.svg)](https://codecov.io/gh/ffalcinelli/pydivert) [![latest_release](https://img.shields.io/pypi/v/pydivert.svg)](https://pypi.python.org/pypi/pydivert) [![docs](https://img.shields.io/badge/docs-pdoc-blue.svg)](https://ffalcinelli.github.io/pydivert/) [![python_versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue.svg)](https://pypi.python.org/pypi/pydivert) [![windows](https://img.shields.io/badge/os-windows%2011-blue.svg)](https://pypi.python.org/pypi/pydivert) [![license](https://img.shields.io/pypi/l/pydivert.svg)](https://github.com/ffalcinelli/pydivert/blob/main/LICENSE) [![snyk](https://img.shields.io/badge/snyk-security-violet)](https://security.snyk.io/package/pip/pydivert) **PyDivert** 是 [WinDivert](https://reqrypt.org/windivert.html) 的一个强大的 Python 绑定。WinDivert 是一个 Windows 驱动程序,允许用户模式应用程序捕获、修改和丢弃发送到或来自 Windows 网络栈的网络数据包。 ## 特性 - **捕获**匹配特定过滤器的网络数据包。 - **动态修改**数据包的头部和有效载荷。 - **丢弃**不需要的数据包。 - **注入**新的或修改过的数据包到网络栈中。 - **现代 Python 支持**:与 `asyncio` 和结构化模式匹配 (PEP 634) 全面集成。 - **支持 WinDivert 2.2+** 的高级功能(FLOW、SOCKET 和 REFLECT 层)。 - **内置二进制文件**:无需手动安装 WinDivert;已包含 64 位的 DLL 和驱动程序。 ## 要求 - **Python 3.10+** (64 位) - **Windows 11** (64 位) - **管理员权限**(与 WinDivert 驱动程序交互所需) ## 安装说明 使用 `pip` 安装 PyDivert: ``` pip install pydivert ``` 或者使用 [uv](https://github.com/astral-sh/uv): ``` uv add pydivert ``` ## 快速入门 主要的入口点用于捕获的 `pydivert.WinDivert` 和用于操作的 `pydivert.Packet`。 ### 基本捕获和重新注入 ``` import pydivert # 仅捕获目标端口为 80 的 TCP 数据包(HTTP 请求) with pydivert.WinDivert("tcp.DstPort == 80") as w: for packet in w: print(f"Captured: {packet}") w.send(packet) # Re-inject the packet back into the stack ``` 当你调用 `.recv()`(或对 `WinDivert` 对象进行迭代)时,数据包会从 Windows 网络栈中**移出**。除非你显式调用 `.send(packet)`,否则它将无法到达其目的地。 ### 一流的 `asyncio` 支持 PyDivert 3.0+ 使用现代的 `async with` 和 `async for` 语法原生支持 `asyncio`。 ``` import asyncio import pydivert async def main(): # Asynchronously capture packets async with pydivert.WinDivert("tcp.DstPort == 80") as w: async for packet in w: print(f"Async captured: {packet}") await w.send_async(packet) if __name__ == "__main__": asyncio.run(main()) ``` ## 常见用例 ### 1. 结构化模式匹配 (PEP 634) 使用简洁的 `match/case` 语法过滤和分析数据包。 ``` import pydivert from pydivert.packet import Packet from pydivert.packet.tcp import TCPHeader with pydivert.WinDivert("tcp") as w: for packet in w: match packet: case Packet(tcp=TCPHeader(dst_port=80)): print("HTTP Traffic") case Packet(tcp=TCPHeader(dst_port=443)): print("HTTPS Traffic") w.send(packet) ``` ### 2. 简单防火墙(丢弃数据包) 只需不调用 `.send(packet)`,即可有效地丢弃该数据包。 ``` import pydivert # 阻止来自特定 IP 地址的所有流量 with pydivert.WinDivert("ip.SrcAddr == 1.2.3.4") as w: for packet in w: print(f"Blocking packet from {packet.src_addr}") # Packet is dropped here ``` ### 3. 有效载荷修改 你可以检查或修改数据包有效载荷的原始字节。 ``` import pydivert # 筛选带有 payload 的 TCP 数据包 with pydivert.WinDivert("tcp.PayloadLength > 0") as w: for packet in w: if b"secret-token" in packet.payload: # Redact the token packet.payload = packet.payload.replace(b"secret-token", b"REDACTED") w.send(packet) ``` ## 数据包完整性与校验和 PyDivert 可以自动验证和重新计算网络校验和。 - **`packet.is_checksum_valid`**:如果数据包中的所有校验和(IP、TCP、UDP、ICMP)都正确,则返回 `True`。 - **`packet.recalculate_checksums()`**:根据当前的头部和有效载荷值重新计算所有校验和。 ``` if not packet.is_checksum_valid: print("Corrupted packet detected!") packet.recalculate_checksums() ``` ## 常见数据包属性 `pydivert.Packet` 对象提供了对常见字段的便捷访问: - **IP 层**:`packet.src_addr`、`packet.dst_addr`、`packet.ip.ttl`、`packet.ip.protocol` - **TCP/UDP 层**:`packet.src_port`、`packet.dst_port`、`packet.tcp.flags` - **有效载荷**:`packet.payload`(字节) - **元数据**: - **`timestamp`**:捕获时间 (QueryPerformanceCounter)。 - **`is_loopback`**、**`is_impostor`**、**`is_sniffed`**:布尔标志。 - **`interface`**:捕获接口的索引。 - **`direction`**:`Direction.INBOUND` 或 `Direction.OUTBOUND`。 详细的协议头可以通过 `packet.ipv4`、`packet.ipv6`、`packet.tcp`、`packet.udp` 和 `packet.icmp` 访问。 ## 高级用法 ### WinDivert 层 - `Layer.NETWORK`(默认):IP 数据包。 - `Layer.FLOW`:连接事件。 - `Layer.SOCKET`:套接字级别的事件。 - `Layer.REFLECT`:反射事件。 ### 标志 - `Flag.SNIFF`:监控模式(嗅探)。 - `Flag.DROP`:默认丢弃数据包。 - `Flag.FRAGMENTS`:捕获所有 IP 分片。 - `Flag.RECV_ONLY` / `Flag.SEND_ONLY`:受限句柄。 ## 过滤器语言 PyDivert 使用 WinDivert 过滤器语言来选择要捕获的数据包。有关语法和可用字段的详细参考,请参阅[过滤器语言指南](#windivert-filter-language)。 有关原始的技术参考,请访问[官方 WinDivert 文档](https://reqrypt.org/windivert-doc.html#filter_language)。 ## WinDivert 版本兼容性 | PyDivert | WinDivert | | --- | --- | | 3.0.0+ | 2.2.2 (捆绑) - 完全支持现代元数据和层 | ## 开发 1. 克隆仓库。 2. 安装依赖:`uv sync --extra test --extra docs` 3. 运行测试(需要管理员权限):`uv run pytest` ### 使用 Vagrant 进行测试 由于 WinDivert 需要 Windows 环境,请使用 **Vagrant** 在 Windows 11 虚拟机上运行测试: ``` vagrant up vagrant powershell -c '$env:UV_PROJECT_ENVIRONMENT="C:/pydivert_venv"; cd C:/pydivert; uv run pytest' ``` ## API 参考 完整的 API 文档可在 [https://ffalcinelli.github.io/pydivert/](https://ffalcinelli.github.io/pydivert/) 获取。 ## 许可证 PyDivert 在 [LGPL-3.0-or-later](https://github.com/ffalcinelli/pydivert/blob/main/LICENSE-LGPL-3.0-or-later) 和 [GPL-2.0-or-later](https://github.com/ffalcinelli/pydivert/blob/main/LICENSE-GPL-2.0-or-later) 下双重许可。 ## 安全 PyDivert 致力于安全保障,并使用 [Snyk](https://snyk.io/) 进行持续的漏洞扫描。有关我们的安全实践以及如何报告漏洞的更多详细信息,请参阅[安全政策](#security-policy)。
标签:asyncio, ATT&CK 框架, MacOS取证, Python, Python绑定, Wildcard支持, WinDivert, Windows 11, Windows驱动, 中间人攻击, 异步IO, 数据包注入, 数据包过滤, 无后门, 欺骗, 流量控制, 系统权限, 网络嗅探, 网络安全, 网络层, 网络开发, 网络拦截, 网络数据包, 计算机取证, 逆向工具, 防御绕过, 防火墙, 隐私保护