畸形报文如何拦截丢弃

wen 开源项目 29

本文目录导读:

畸形报文如何拦截丢弃

  1. 主机层面(操作系统/IPtables/防火墙软件)
  2. 网络设备层面(路由器/交换机/负载均衡器)
  3. 应用层面(WAF / 反向代理 / 中间件)
  4. 开发框架 / 库层面(代码层处理)
  5. 关键原则:纵深防御
  6. 技术实现参考(以 Golang 处理自定义协议为例)

针对“畸形报文”(Malformed Packets)的拦截与丢弃,需要根据你所在的网络层级(如网络层、传输层、应用层)以及控制位置(如主机防火墙、路由器、交换机、Web服务器)来采取不同的策略。

以下是几种常见的拦截与丢弃方案:

主机层面(操作系统/IPtables/防火墙软件)

这是最直接的方式,适用于保护单台服务器或PC。

  • Linux 系统(使用 nftables / iptables)

    • 丢弃非法标志位组合:例如同时设置了 SYN 和 FIN 标志,或 SYN 且 RST 标志。

      # 丢弃同时设置了 SYN 和 FIN 标志的包
      iptables -A INPUT -p tcp --tcp-flags ALL SYN,FIN -j DROP
      # 丢弃Xmas Tree包(设置了 FIN, URG, PSH)
      iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
      # 丢弃Null包(没有任何标志位)
      iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
    • 校验和错误检查:Linux内核默认会做TCP/UDP/IP校验和验证,如果硬件网卡不支持校验和卸载(Checksum Offloading)或关闭了该功能,内核会自动丢弃校验和错误的包,通常无需额外配置。

    • 太小/太大的包:可以使用iptables-m length匹配长度异常的IP报文(例如小于最小IP头长度20字节)。

  • Windows 系统(高级安全Windows Defender防火墙)

    • 在“入站规则”的属性中,进入“协议及端口”选项卡,点击“ICMP设置”或“TCP设置”,可以指定丢弃不符合特定特征(如特定标志位组合)的报文。
    • 更底层的方案:使用 WFP(Windows Filtering Platform)开发的第三方防火墙软件。

网络设备层面(路由器/交换机/负载均衡器)

用于在网络入口处拦截畸形包,防止它们进入内网。

  • 常见 ACL(访问控制列表)规则(Cisco/Juniper/华为)

    • 丢弃带源路由选项(Source Route)的IP包(这是经典畸形包攻击)。
    • 丢弃IP TTL为0或1的包(如果不是期望的)。
    • 片段攻击防御
      # 拒绝长度小于特定值的IP片段(如TCP头在片段中被截断)
      access-list 101 deny ip any 192.168.1.0 0.0.0.255 fragments
    • L4端口校验:丢弃源端口或目的端口为0的TCP/UDP包(RFC规定端口0无效)。
  • 专用 DDoS/IPS 设备(如 Radware, F5, Palo Alto)

    • 协议异常检测:启用“协议异常(Protocol Anomaly)”检测引擎,系统会自动识别并丢弃:
      • 畸形TCP标志位组合(如SYN-RST-FIN)。
      • 包含非法选项(如重复的TCP SACK选项)的包。
      • 重叠IP片段且内容矛盾的报文。
      • IP头长度字段与真实计算长度不符的包。

应用层面(WAF / 反向代理 / 中间件)

如果应用协议本身(如HTTP/2, WebSocket)中存在畸形报文,需要在应用层处理。

  • Web 应用防火墙(WAF)

    • 请求体校验:丢弃不符合RFC规范的HTTP/1.1请求(如包含Host头缺失、非法的Chunked编码格式、超长URL、HTTP方法名包含特殊字符)。
    • 内容类型匹配:检测请求体声明为application/json但实际传的是二进制乱码,可直接丢弃。
    • HTTP/2 帧校验:丢弃长度异常的帧、流ID为0但携带标志位的控制帧、伪头字段(如 path)包含null字符的帧。
  • API 网关或反向代理(Nginx / Envoy)

    • 校验:使用 Lua 或 WASM 插件对请求体进行格式校验。
    • 协议版本限制:拒绝不支持的HTTP版本(如HTTP/0.9或异常的HTTP/4.0)。

开发框架 / 库层面(代码层处理)

作为最后一道防线,特别是在解析用户输入时。

  • 序列化/反序列化库:使用强类型库(如 protobufflatbuffers)时,畸形报文通常会被直接丢弃或抛出解析异常。
  • 输入验证:对接收到的原始字节流的边界、长度、格式进行严格校验。
    • 检查接收到的数据是否至少包含完整的协议头(如最小TLV长度)。
    • 如果报文字段指示“后续还有100字节”,而实际接收只有20字节,应直接丢弃整个包或发起连接重置。

关键原则:纵深防御

只在一层拦截是不安全的,建议采用分层拦截策略:

  1. 网络设备(最外层):丢弃明显的畸形包(标志位组合、长度异常)。
  2. 主机防火墙:丢弃校验和错误、非法片段的包。
  3. 应用层WAF:解析HTTP/SIP/WebRTC等应用协议,丢弃格式不合规的请求。
  4. 代码层:在解析逻辑中,捕获异常并主动重置/丢弃连接。

技术实现参考(以 Golang 处理自定义协议为例)

如果你是自己编程处理原始报文:

// 伪代码:丢弃畸形报文
func HandlePacket(data []byte) {
    // 1. 检查最小长度
    if len(data) < HeadSize {
        fmt.Println("丢弃:报文长度小于头部", HeadSize)
        return
    }
    header := ParseHead(data)
    // 2. 校验魔数
    if header.Magic != 0xAABB {
        fmt.Println("丢弃:魔数无效")
        return
    }
    // 3. 校验长度一致性(防止溢读)
    if len(data) < int(header.TotalLength) {
        fmt.Println("丢弃:实际长度小于声明长度")
        return
    }
    // 4. 端口/协议字段有效性
    if header.PayloadType < 1 || header.PayloadType > 10 {
        fmt.Println("丢弃:非法协议类型")
        return
    }
    // ... 继续解析Payload ...
}
  • 核心思路验证一切! 不要信任网络传来的任何字段。
  • 最快速度网络设备上的 ACL 和 IPS 引擎(通常基于 P4/硬件 Offload)处理最快。
  • 最细粒度应用层 WAF 或代码逻辑处理最精确。
  • 掉落策略:对于异常包,推荐使用 DROP(直接丢弃,不回复 RST/ICMP),这种策略会减慢攻击者的探测速度(因为它需要等待超时,而不是立刻得到响应)。

抱歉,评论功能暂时关闭!