[Mac/Linux] 使用 mitmproxy 監看 HTTPS 的連線內容

[Mac/Linux] 使用 mitmproxy 監看 HTTPS 的連線內容

最近想要看一下專案程式打出去的 HTTPS 連線,內容有沒有正確,

想起了之前瞄過的 mitmproxy,決定這次就來試試看了。

試了一下發現還蠻好用的~

 

1. 安裝 mitmproxy

在 Mac 上可以用 Homebrew 安裝:

brew install mitmproxy

 

在 Ubuntu Linux 上可以用 apt 安裝:

sudo apt install mitmproxy

 

裝好之後,應該會有三個程式可以用,分別是:

  • mitmproxy
  • mitmweb
  • mitmdump

 

以介面來說,當然是 mitmweb 會最容易操作,

不過像我是透過 SSH 連線來操作的話,用 mitmproxy 是比較合適的選擇~

 

2. 使用 mitmproxy 觀察 HTTPS 連線

首先在終端機裡執行  mitmproxy ,這就會將 mitmproxy 跑起來,

並預設監聽在 8080 port。

 

假設這時我想要用 curl 連線到 https://www.google.com,

可以加上 -x http://127.0.0.1:8080 的參數,讓連線透過這個 proxy 出去。

不過此時通常會失敗,因為 mitmproxy 的 CA 並不被 curl 或系統信任:

$ curl -L -v -x http://127.0.0.1:8080 https://www.google.com

*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to www.google.com:443
> CONNECT www.google.com:443 HTTP/1.1
> Host: www.google.com:443
> User-Agent: curl/7.64.1
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

 

在 curl 裡可以再加上 -k 參數來忽略所有的 HTTPS 驗證錯誤,

這時 HTTPS 連線就可以成功透過 mitmproxy 連出去了:

$ curl -k -L -v -x http://127.0.0.1:8080 https://www.google.com

*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to www.google.com:443
> CONNECT www.google.com:443 HTTP/1.1
> Host: www.google.com:443
> User-Agent: curl/7.64.1
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=www.google.com
*  start date: Dec 17 20:54:42 2021 GMT
*  expire date: Dec 19 20:54:42 2022 GMT
*  issuer: CN=mitmproxy; O=mitmproxy
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fcc4280c600)
> GET / HTTP/2
> Host: www.google.com
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200
< date: Sun, 19 Dec 2021 12:55:28 GMT
......

 

這時在執行 mitmproxy 命令的終端機上,可以看到這個 GET 連線:

 

按下 ? 可以顯示快捷鍵,不過我平常用的就只有 <Enter> 顯示資料、

和 <q> 退出目前顯示資料、以及用上下方向鍵來選擇連線:

 

在最外面的連線列表,對某個連線按下 <Enter> 鍵後,

就會出現如下畫面,可以看到請求 (Request)、回應 (Response)、以及細節的部分:

 

在細節的部分,可以看到伺服器傳回來的簽章 (certificate) 資訊:

 

如果是自己寫的 Go 程式的話,在 mitmproxy 的 CA 不被信任時,

使用  http.client 通過 mitmproxy 的連線都會失敗。

這時可以在  tls.Config 裡設定  InsecureSkipVerify ,

來略過簽章的驗證錯誤,這樣連線通過 mitmproxy 時才會成功:

config := &tls.Config{
    InsecureSkipVerify: true
}

 

使用 mitmproxy 的話,就可以清楚看到 HTTPS 連線裡的內容,

真的是很方便的好工具喔~

 

(本頁面已被瀏覽過 1,132 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料