HttpCanary实现对HTTP2协议的抓包和注入(原理篇)

今天发布了HttpCanary2.0版本,除了修复了部分bug以及优化性能外,最主要的是支持了HTTP2协议。

HttpCanary是什么?Android平台第二强大的HTTP抓包和注入工具,不了解的同学可以阅读下关于HttpCanary的介绍:juejin.im/post/5c1e37…

HttpCanary2.0已经发布到GooglePlay,欢迎大家下载并给予评价建议,传送门:play.google.com/store/apps/…

干货为主,废话不多说,下面开始本篇的正文。

HTTP2.0和HTTP1.x的区别

先简单介绍一下HTTP2.0协议的概况,熟悉的同学可以跳过。

HTTP2.0协议是由SPDY协议进化而来,标准于2015年5月正式发布,算起来不到四年时间,属于比较新的技术。所以部分主流的抓包工具都不支持HTTP2,比如Fiddler,而Charles则是在4.0版本后开始支持。

HTTP2.0协议和HTTP/1.x协议在请求方法、状态码乃至URI和绝大多数HTTP头部字段等部分保持高度兼容性,即常说的请求行、请求头、请求体、响应行、响应头、响应体这些格式都具有一致性。

但是,HTTP2.0协议在对头部数据的压缩、多路复用、服务器主动推送三个方面做了支持和优化。

  • 头部数据压缩。对请求行、请求头、响应行、响应头这些头部数据进行压缩,采用Hpack算法。
  • 多路复用。每个connection以stream的形式组织,数据包按照frame(数据帧)的形式通信,同时增加了流量控制等功能。
  • 服务器主动推送。HTTP2.0协议支持双向通信,以及half-close这种单向通信。

HTTP2.0协议虽然没有明确要求加密,但目前的实现都是默认使用TLS加密,所以可以认为使用HTTP2.0则必须使用HTTPS。

为了实现对HTTP1.x的兼容,HTTP2.0协议为此额外定义了应用层协商标准(Application-Layer Protocol Negotiation,简称ALPN),以便客户端和服务端能够从HTTP/1.0、HTTP/1.1、HTTP/2乃至其他非HTTP协议中做出选择。ALPN衍生于SPDY协议的NPN标准,都是基于TLS的扩展标准。

Android是从5.0开始支持ALPN,而Java是从OpenJDK 8和JDK 9开始支持,可以认为从这些时候开始才真正支持HTTP2.0协议。

HttpCanary的HTTP2之旅

我在发布HttpCanary2.0的同时,已经将HTTP2.0协议的实现代码更新到了github,也就是HttpCanary的核心库NetBare,对代码感兴趣的可以对照着本文理解。

HTTP2.0的支持难点主要有三个:

  • 如何进行应用层协议协商,即ALPN协商。
  • 对请求和响应头部进行Hpack解码并重新编码。
  • 将HTTP2.0的stream、frame并还原成HTTP1.x协议格式并重新生成stream、frame,以及多路复用的分离。

下面,讲解NetBare是如何解决这四个难题,从而实现对HTTP2.0协议的抓包和注入的。

1. ALPN协商

Android从5.0开始支持ALPN协商,NetBare库的最低支持版本也是5.0,所以在理论上是完全可以实现的。

1.1 ALPN协商图解

简单概括ALPN协商的过程:SSL握手的时候,Client将支持的协议版本列表发给Server,Server务端从列表中选择一个协议版本并发给Client作为协商版本,SSL握手完成后,Client和Server都使用协商版本进行通信。ALPN的协商是在Client发给Server的ClientHello握手包以及Server回给Client的ServerHello握手包两步直接完成的。

下图是ALPN协商的图解:

粗略一看非常简单,但是由于HTTP2.0协议强制使用TLS/SSL加密,所以只能使用中间人MITM方式进行解密抓包。而中间人MITM又分为中间人Client和中间人Server,所以ClientHello握手包的通信流程是Client -> MITM Server -> MITM Client -> Server,而ServerHello握手包的通信流程则是 Server -> MITM Client -> MITM Server -> Client,由原先的一来一回两步,变成了来回六步,复杂性上增加了许多。

增加了MITM层的ALPN协商的图解:

这里有个小技巧,最开始的ClientHello报文并没有直接交给MITM Server开始握手,而是通过一个Parser直接解析出list of protocols并交给MITM Client,让MITM Client先和Server进行握手。获取到selected protocol后,MITM Server在和Client开始握手。这样的设计的目的主要是,降低两组SSL握手之间的逻辑依赖。

接下来,按照这个图解流程,实现新的ALPN协商过程。

1.2 解析ClientHello报文

第一个核心步骤,MITM Server需要解析出ClientHello握手包中的协议列表(list of protocols)。由于ALPN extension是基于TLS的extension标准,所以解析方式类似于SNI的解析方式。

TLS extensions数据区位于ClientHello包的Compression Method之后,TLS extensions(注意复数s)是支持多个extension扩

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值