一种 HTTP 会话劫持的防御方法

HTTP 会话劫持也是 TCP 会话劫持,它是利用了 TCP Seqnum 的可预见性来伪造有效的响应包,并抢先响应客户端同时使得客户端主动丢弃原服务器的响应包。在这个层面想区分哪一个响应包是伪造的是有困难的,但结合实际情况考虑问题也还有一些思路。

我们以劫持程序的设计者角度考虑:
1. 劫持程序不是什么都劫持了,只有符合条件被命中的 HTTP 请求才会劫持的,那也就是说劫持程序需要一个完整或至少包含它需要的信息的请求才可以劫持,我想 Host, QueryString, Referer 这些应该少不了。
2. 劫持程序不希望维护 TCP 上下文进行流重组。因为维护起来成本比较高。
3. 基于上一点来说,劫持程序也就不希望一个 HTTP 请求被拆分在两个或多个包中传输。

从实际检测来看,大多数的 HTTP 请求还是包含在一个独立的 TCP 包中传输的,只有很少的情况被拆分了。我想你一定想到了什么了,对!我们就假设当前在用的劫持程序都没有维护 TCP 传输上下文进行流重组,那么人为对前向链路上的流进行强制拆分,就应该能够逃过被劫持。

实现的方式应该会有很多,我在应用层代理层面实现了一个简单的原型,方式是将前向链路的 Buffer size 强制在了 16 字节。代码托管在 Github => https://github.com/heiher/hev-socks5-proxy/tree/anti-hijack

从抓包来看,HTTP 请求在传输时被拆分了:

packet 0:[syn]
packet 1: GET / HTTP/1.1\r\n
packet 2: Host: xxxx
packet 3: ...

Over!

Leave a Reply

Your email address will not be published. Required fields are marked *