出于某些私人目的,我需要用附加信息丰富 HTTP 标头(这将由 HTTP 服务器端的应用程序处理)。基本思想是修改收到的数据包,将其发送到目的地,而不必关心答案。流量路径的非常简化的方案是
+---+ +------+ +---+
| +<<-----o MDFY +<<------o |
| R | +------+ | S |
| C | | N |
| V | | D |
| o--------------------->>+ |
+---+ +---+
问题出在 TCP SEQ/ACK 编号上。在 TCP 握手之后,发送方发送长度为 4 字节的数据包,到达修改器时长度变为 22,然后数据包到达接收方并发送 ACK 编号 +23,而发送方期望为 +5。这让发送方大吃一惊,会话变得不同步。例如,当我尝试使用 netcat 进行测试时,我会看到这种情况 - 对于未修改的数据包,会话在数据交换后立即关闭,而对于修改过的数据包,会话会长时间失效(实际上,我通过按 Ctrl-C 来停止它)。
我觉得没有简单的方法可以解决这种情况。看起来,一旦在中间修改,整个会话必须由修改者处理,因为发送者对序列号的修改一无所知,并且将依赖于他自己的数字。这样做会严重影响性能并增加复杂性,因为我需要维护每个会话的状态并修改来自双方的每个数据包以维护 SEQ/ACK 编号。
也许除了编写自己的 DPI 之外我找不到其他方法?:-) 欢迎提出任何知识、想法和建议。
谢谢。
答案1
我看到的唯一更简单的选择是使用透明代理。
在这种情况下,客户端将请求发送到目标服务器。代理服务器捕获请求,添加标头并创建另一个发送到目标服务器的请求。目标服务器将响应返回给代理,然后代理将其返回给客户端。
这里的缺点是服务器看不到客户端的原始 IP 地址,而是代理的 IP 地址。
然后,对于 TCP 级别的 MITM 方法,可能存在实现所需功能的工具包,因此不需要完全实现。
答案2
这看起来像某种半成熟的 NAT;而问题恰恰就在于它是半成熟的。
你不能只对 TCP 数据包流的一个方向进行 MITM:你需要处理两个流,正是要处理这种情况(标准 NAT 通常只关心源和目标地址/端口,但原理是一样的;如果你想在传输过程中破坏数据包,并且你希望这种破坏对两个端点都是透明的,你需要得到一切正确的)。
一旦你开始把所有的事情都考虑进去,很快你就会拥有成熟的 NAT:不需要重新发明轮子,因为有很多实现可以让你按照你想要的方式处理数据包。
实际可用的选项当然取决于所使用的操作系统和路由/防火墙软件。