PortBender源代码深度解读:理解TCP数据包拦截与重定向的核心逻辑
【免费下载链接】PortBenderTCP Port Redirection Utility项目地址: https://gitcode.com/gh_mirrors/po/PortBender
PortBender是一款功能强大的TCP端口重定向工具,专为网络安全测试和红队操作设计。这款工具通过深度拦截和修改网络数据包,实现了灵活的端口重定向功能,让安全研究人员能够模拟复杂的攻击场景和测试网络防御机制。在本文中,我们将深入剖析PortBender的源代码,揭示其TCP数据包拦截与重定向的核心实现逻辑。
🔍 PortBender的基本架构设计
PortBender的核心架构基于Windows Filtering Platform (WFP)和WinDivert库构建。整个项目采用模块化设计,主要包含以下几个关键组件:
核心类结构
在src/PortBender/PortBender/PortBender.h中,我们可以看到PortBender类的核心定义:
class PortBender { public: PortBender(UINT16 FakeDstPort, UINT16 RedirectPort); PortBender(UINT16 FakeDstPort, UINT16 RedirectPort, std::string Password); void Start(); private: enum class OperatingMode { REDIRECTOR, BACKDOOR }; UINT16 FakeDstPort; OperatingMode Mode; std::string Password; UINT16 RedirectPort; PVOID ProcessPacket(Packet* packet, BOOL redirect); };PortBender支持两种操作模式:重定向模式(REDIRECTOR)和后门模式(BACKDOOR)。重定向模式将所有目标端口的流量转发到另一个端口,而后门模式则只在收到特定密码包时才激活重定向功能。
🛠️ WinDivert驱动层的拦截机制
数据包拦截过滤器
在src/PortBender/PortBender/PortBender.cpp的Start()方法中,PortBender创建了一个精密的过滤器规则:
sprintf_s(filter, sizeof(filter), "((inbound and tcp.DstPort == %d )" " or (outbound and tcp.SrcPort == %d ))", this->FakeDstPort, this->RedirectPort);这个过滤器逻辑非常巧妙:
- 入站流量:拦截目标端口为
FakeDstPort的TCP数据包 - 出站流量:拦截源端口为
RedirectPort的TCP数据包
这样的设计确保了双向流量的完整拦截和重定向。
WinDivert初始化
在src/PortBender/PortBender/WinDivert.cpp中,WinDivert类的构造函数负责初始化驱动连接:
WinDivert::WinDivert(char *filter) { this->handle = WinDivertOpen(filter, WINDIVERT_LAYER_NETWORK, 0, 0); // 设置数据包队列参数 WinDivertSetParam(this->handle, WINDIVERT_PARAM_QUEUE_LEN, 8192); WinDivertSetParam(this->handle, WINDIVERT_PARAM_QUEUE_TIME, 2048); }这里设置了8192个数据包的队列长度和2048毫秒的队列时间,确保在高流量环境下也能稳定运行。
📦 数据包解析与处理
Packet类的设计
在src/PortBender/PortBender/Packet.h中,Packet类封装了拦截到的网络数据包:
class Packet { public: unsigned char packet[MAXBUF]; UINT packet_len; WINDIVERT_ADDRESS addr; PWINDIVERT_IPHDR ip_header; PWINDIVERT_IPV6HDR ipv6_header; PWINDIVERT_ICMPHDR icmp_header; PWINDIVERT_ICMPV6HDR icmpv6_header; PWINDIVERT_TCPHDR tcp_header; PWINDIVERT_UDPHDR udp_header; PVOID payload; UINT payload_len; };这个结构体包含了完整的数据包信息,从原始字节数据到各个协议层的头部指针,为后续的数据包修改提供了便利。
数据包接收与解析
在WinDivert::Receive()方法中,数据包的接收和解析过程如下:
Packet* WinDivert::Receive() { Packet *packet = new Packet(); // 接收原始数据包 WinDivertRecv(this->handle, packet->packet, sizeof(packet->packet), &packet->addr, &packet->packet_len); // 解析协议头部 WinDivertHelperParsePacket(packet->packet, packet->packet_len, &packet->ip_header, &packet->ipv6_header, &packet->icmp_header, &packet->icmpv6_header, &packet->tcp_header, &packet->udp_header, &packet->payload, &packet->payload_len); return packet; }🔄 端口重定向的核心算法
数据包修改逻辑
PortBender的核心重定向逻辑在ProcessPacket()方法中实现。当检测到需要重定向的连接时,工具会修改数据包的端口信息:
入站数据包修改:
- 将目标端口从
FakeDstPort改为RedirectPort - 更新TCP和IP校验和
- 记录连接信息到连接管理器
- 将目标端口从
出站数据包修改:
- 将源端口从
RedirectPort改回FakeDstPort - 确保响应数据包能够正确返回到原始客户端
- 将源端口从
连接状态管理
在src/PortBender/PortBender/ConnectionManager.h中,ConnectionManager类负责跟踪所有被重定向的连接状态:
class ConnectionManager { public: BOOL IsRedirectedConnection(Packet* packet); BOOL IsBackdoorClient(Packet* packet); void AddBackdoorClient(std::string ip); void RemoveBackdoorClient(std::string ip); private: std::vector<Connection*> connections; std::vector<std::string> backdoor_clients; };连接管理器维护了两个重要列表:
connections:当前活跃的重定向连接backdoor_clients:已认证的后门客户端IP地址
🚪 后门模式的智能认证机制
密码包检测逻辑
PortBender的后门模式实现了一种巧妙的隐蔽通信机制。在Start()方法中,后门认证逻辑如下:
if (this->Mode == OperatingMode::BACKDOOR) { std::string ip = Utilities::AddressToString(packet->ip_header->SrcAddr); if (packet->tcp_header->Syn && packet->tcp_header->Rst && !packet->tcp_header->Ack) { if (packet->payload != NULL) { if (this->Password.length() == packet->payload_len) { if (memcmp(this->Password.c_str(), packet->payload, packet->payload_len) == 0) { // 认证成功,添加或移除客户端 } } } } }这个检测机制有几个精妙之处:
- TCP标志位组合:使用
SYN+RST且没有ACK的标志位组合,这是一个非法的TCP状态,正常通信中很少出现 - 密码长度匹配:要求密码长度与数据包载荷长度完全一致
- 内存比较:使用
memcmp进行快速密码验证
客户端管理
后门客户端的管理采用白名单机制:
- 当收到正确的密码包时,将客户端IP添加到
backdoor_clients列表 - 再次收到相同密码包时,从列表中移除该客户端
- 只有白名单中的客户端流量才会被重定向
🔧 实用工具函数
地址转换工具
在src/PortBender/PortBender/Utilities.cpp中,Utilities类提供了网络地址转换功能:
std::string Utilities::AddressToString(UINT32 addr) { struct in_addr ip_addr; ip_addr.S_un.S_addr = addr; return std::string(inet_ntoa(ip_addr)); }这个函数将32位IP地址转换为点分十进制字符串表示,便于日志输出和客户端管理。
🎯 性能优化与错误处理
数据包队列优化
PortBender通过合理设置WinDivert参数来优化性能:
- 队列长度8192:避免在高流量下丢失数据包
- 队列时间2048ms:平衡延迟和吞吐量
健壮的错误处理
在整个代码中,PortBender实现了完善的错误处理机制:
if (this->handle == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_INVALID_PARAMETER) { std::cout << "Error invalid filter syntax was used" << std::endl; ExitProcess(0); } // 其他错误处理... }每个关键操作都有相应的错误检查和清理逻辑,确保工具在异常情况下也能优雅退出。
📊 实际应用场景分析
SMB中继攻击模拟
PortBender最常见的应用场景是模拟SMB中继攻击。通过将445端口的流量重定向到攻击者的8445端口,安全团队可以:
- 测试网络中的SMB签名配置
- 验证中继攻击的可行性
- 评估防御机制的响应能力
隐蔽后门模拟
后门模式模拟了高级威胁行为者的持久化技术,特别适合:
- 红队演练中的隐蔽访问维持
- 安全产品的检测能力测试
- 网络监控系统的告警验证
🛡️ 安全考虑与最佳实践
使用注意事项
- 权限要求:PortBender需要管理员权限运行,因为WinDivert驱动需要加载到内核
- 网络影响:重定向操作会影响正常的网络通信,应在测试环境中使用
- 兼容性:确保使用正确架构的WinDivert驱动(32位或64位)
部署建议
- 测试环境验证:先在隔离环境中测试配置
- 流量监控:部署期间监控网络流量变化
- 清理操作:测试完成后及时停止工具,恢复网络正常状态
💡 技术亮点总结
PortBender的实现展示了几个重要的网络安全编程技术:
- 内核级数据包拦截:通过WinDivert实现高性能的数据包捕获和修改
- 状态ful连接跟踪:准确管理TCP连接状态,避免数据包混乱
- 隐蔽通信机制:创新的密码包设计实现隐蔽的后门激活
- 双向流量处理:完整处理入站和出站流量,确保通信完整性
🚀 扩展与定制可能性
基于PortBender的架构,安全研究人员可以进行多种扩展:
- 协议扩展:支持UDP或其他协议的重定向
- 条件重定向:基于数据包内容或流量的智能重定向
- 日志增强:更详细的数据包分析和审计日志
- 分布式部署:多节点协同的重定向网络
通过深入理解PortBender的源代码,我们不仅掌握了TCP数据包拦截与重定向的核心技术,还能更好地应用这些技术于实际的网络安全测试和防御工作中。这款工具的设计思想和实现细节为网络安全工具开发提供了宝贵的参考价值。
【免费下载链接】PortBenderTCP Port Redirection Utility项目地址: https://gitcode.com/gh_mirrors/po/PortBender
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考