Pages

Sunday, 27 September 2020

mitm proxy


HTTPS man in the middle

Introduction

本项目实现了一个 Man-in-the-middle 代理服务器。支持 HTTP 和 HTTPS 抓包。

It is a Man-in-the-middle proxy server, supports to capture HTTP/HTTPS request and response.

How

对于 HTTP,直接修改头部,并转发请求。

而对于 HTTPS,则是在 CONNECT 请求所建立的 TCP 隧道中,又插入了一个 TLS 服务,并由该 TLS 服务先解析成明文,再进行 TLS 请求。该插入的 TLS 服务器需要为每个域名实时签发证书,故浏览器会提示证书错误。

详细原理介绍

详细原理在我的博客文章:实现基于 HTTPS 代理的中间人攻击


from https://github.com/lyyyuna/mitm

-----


实现基于 HTTPS 代理的中间人攻击


HTTP 隧道代理原理

RFC 为这类代理给出了规范,Tunneling TCP based protocols through Web proxy servers。简单来讲就是通过 Web 代理服务器用隧道方式传输基于 TCP 的协议。HTTP 协议正文部分为客户端发送的原始 TCP 流量,代理发送给远端服务器后,将接收到的 TCP 流量原封不动返回给浏览器。

下面这张图片来自于《HTTP 权威指南》,展示了 HTTP 隧道代理的原理。
HTTP 隧道HTTP 隧道

浏览器首先发起 CONNECT 请求:

CONNECT example.com:443 HTTP/1.1

代理收到这样的请求后,依据 host 地址与服务器建立 TCP 连接,并响应给浏览器这样一个 HTTP 报文:

HTTP/1.1 200 Connection Established

该报文不需要正文。浏览器一旦收到这个响应报文,就可认为与服务器的 TCP 连接已打通,后续可直接透传。

HTTPS 流量中间人攻击

我们很容易想到,HTTPS 代理本质上就是隧道透传,代理服务器只是透传 TCP 流量,与 GET/POST 代理有本质区别。隧道透传是安全的,代理没有私钥来解密 TLS 流量。

这带来一个问题,现在 HTTPS 越来越普遍,测试时不会特意关掉 TLS,做安全测试也就拿不到 URL 及请求参数。那怎么做呢?

首先是来看正常的隧道代理示意图:

TLS 示意图 1TLS 示意图 1

在如图红色的透传流量中,插入我们的中间人

  1. 用一个 TLS 服务器伪装成远端的真正的服务器,接下浏览器的 TLS 流量,解析成明文。
  2. 用明文作为原始数据,模拟 TLS 客户端向远端服务器转发。

示意图如下:

TLS 示意图 2TLS 示意图 2

由于中间人拿到了明文,也就能够继续收集 URL 及相关请求参数。

证书问题

大家知道,HTTP 是需要证书的。浏览器会验证服务器发来的证书是否合法。证书若是由合法的 CA 签发,则称为合法的证书。现代浏览器在安装时都会附带全世界所有合法的 CA 证书。由 CA 证书可验证远端服务器的证书是否是合法 CA 签发的。

在 TLS 示意图 2 中,浏览器会验证假 TLS 服务器的证书:

  1. 第一验证是否是合法 CA 签发。
  2. 第二验证该证书 CN 属性是否是所请求的域名。即若浏览器打开 www.example.com,则返回的证书 CN 属性必须是 www.example.com

对于第一点,合法 CA 是不可能为我们签证书的,否则就是重大安全事件了。我们只能自制 CA,并将自制 CA 导入浏览器信任链。

对于第二点,需要自制 CA 实时为域名 www.example.com 签一个假的证书。

Go 实现

这次的 HTTPS 中间人代理用 Go 实现。源码见 https://github.com/lyyyuna/mitm

结语

上述过程即为 Burp Suite, ZAP 和 fiddler 等进行 HTTPS 抓包的原理。

我自制 HTTPS 中间人代理,主要是想结合 Sqlmap 做一个自动化 SQL 注入系统。由于目前所在 QA 团队并不具备 SQL 注入测试的经验,最大化的自动化所有过程就成了我的目标。目前还有 csrf token 未解决,主要是 csrf 实现千差万别,没有通用解决方法。。。

from http://www.lyyyuna.com/2018/03/16/http-proxy-https/


No comments:

Post a Comment