HTTP被动扫描代理的那些事
代理看起来工作正常,我们使用不到 40 行代码就实现了一个简易的 HTTP 代理!代码中的 req 就是做被动代理扫描需要用到的请求,把请求复制一份扔给扫描器就可以了。这也就是上面说的第一种情况, 即http_proxy=http://。那么如果直接使用上述实现访问 https 的站点会发生什么呢? TLS 与隧道代理
使用上面的方式访问 baidu 时,出现了比较奇怪的事情——通过代理读到的客户端请求不是原来的请求,而是一个 CONNECT 请求:
这是 HTTP 代理的另一种形式,称为隧道代理。隧道代理的过程如下: 隧道代理的出现是为了能在 HTTP 协议基础上传输非 HTTP 的内容。如果你用过 websocket,一定对 Connection: Upgrade 这个头不陌生。这个头是用来告诉 server,客户端想把当前的 HTTP 的连接转为 Websocket 协议通信的连接。类似的,这里的 CONNECT是一种协议转换的请求,但这种转换更像是一种 Degrade,因为握手完成后,这个链接将退化为原始的 Socket Connection,可以在其中传输任意数据。用文字描述下整个过程如下:
有个点需要注意下,转换后的连接是可以传输任意数据的,并非只是 HTTPS 流量,可以是普通的 HTTP流量,也可以是其他的应用层的协议流量。那么我们回到被动代理扫描这个话题,如何获取隧道代理中的请求并用来扫描? 这是一个比较棘手的问题,正是由于隧道中的流量可以是任意应用层协议的数据,我们无法确切知道隧道中流量用的哪种协议,所以只能猜一下。查看 TLS 的 RFC 可以发现,TLS 协议开始于一个字节 0×16,这个字节在协议中被称为 ClientHello,那么我们其实就可以根据这第一个字节将协议简单区分为 TLS 流量和非 TLS 流量。对于被动扫描器而言,为了简单起见,我们认为 TLS 的流量就是 HTTPS 流量,非 TLS 流量就是 HTTP 流量。后者和普通代理下的 MITM 一致,可以直接复用代码,而 HTTPS 的情况需要多一个 TLS 握手的过程。用伪代码表示就是:
这里有个细节是读出的这一个字节不要忘记“塞回去”,因为少了一个字节,后面的会操作会失败。 (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |