使用 Go 進行 HTTP 流量重放測試
在 Web 安全測試、API 調試、流量回歸測試中,HTTP 流量重放(HTTP Traffic Replay)是一項重要的技術。它可以幫助我們復現問題、測試系統兼容性、進行安全研究等。在這篇文章中,我們將簡單探討 HTTP 流量重放的原理,並通過 Go 語言實現不同的流量重放方案,同時介紹常見的開源工具。(身爲一個在小公司裏的網安牛馬,總得幹些雜活🐂🐎)
HTTP 流量重放的原理
HTTP 流量重放的基本流程如下:
-
捕獲 HTTP 請求:記錄 HTTP 請求的方法、URL、頭部、請求體等信息。
-
存儲 HTTP 請求數據:可以存儲爲 JSON、文本、數據庫或 PCAP 文件等格式。
-
重放 HTTP 請求:按照捕獲的請求信息,重新發送 HTTP 請求,並接收服務器響應。
-
比對響應結果(可選):檢查重放的響應是否與原始請求一致,驗證系統的穩定性。
HTTP 流量重放廣泛應用於:
-
API 調試:捕獲生產環境的 API 請求,在測試環境重放以排查問題。
-
迴歸測試:確保新版 API 兼容舊版請求。
-
安全測試:重放攻擊流量,測試 WAF(Web 應用防火牆)的防禦能力。
-
性能分析:通過流量回放進行壓測。
使用 Go 語言實現 HTTP 流量重放
直接使用 httputil.DumpRequest 進行重放
Go 標準庫 net/http 提供了 httputil.DumpRequestOut,可以用來捕獲和重放 HTTP 請求。
示例代碼
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"net/http/httputil"
)
func main() {
url := "https://httpbin.org/post"
// 構造原始請求
originalReq, _ := http.NewRequest("POST", url, bytes.NewBuffer([]byte(`{"key": "value"}`)))
originalReq.Header.Set("Content-Type", "application/json")
// 記錄請求數據
dump, _ := httputil.DumpRequestOut(originalReq, true)
fmt.Println("Captured Request:\n", string(dump))
// 重新發送請求
client := &http.Client{}
resp, err := client.Do(originalReq)
if err != nil {
fmt.Println("Request failed:", err)
return
}
defer resp.Body.Close()
// 讀取響應
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("Response:\n", string(body))
}
代碼解析
-
使用 http.NewRequest 創建一個 HTTP 請求對象。
-
httputil.DumpRequestOut 記錄完整的請求信息(包括 URL、頭部、Body)。
-
直接使用 http.Client 重新發送該請求。
-
讀取並打印服務器的響應。
📌 適用場景:適用於簡單的 HTTP 請求重放,但無法攔截 HTTPS 流量。
使用 httptrace 監聽 HTTP 交互過程
如果你想更深入地分析 HTTP 交互過程,比如 DNS 解析、連接建立、TLS 握手,可以使用 httptrace。
示例代碼
package main
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptrace"
)
func main() {
url := "https://httpbin.org/post"
req, _ := http.NewRequest("POST", url, bytes.NewBuffer([]byte(`{"key": "value"}`)))
req.Header.Set("Content-Type", "application/json")
trace := &httptrace.ClientTrace{
GotConn: func(info httptrace.GotConnInfo) {
fmt.Println("Connected to:", info.Conn.RemoteAddr())
},
}
req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Request failed:", err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("Response:\n", string(body))
}
代碼解析
-
httptrace.ClientTrace 可以監聽 HTTP 請求的不同階段,比如 DNS 解析、TCP 連接、TLS 握手等。
-
GotConn 事件會在連接建立時打印遠程服務器的 IP 地址。
-
適用於調試 HTTP 交互過程,但不適用於大規模流量回放。
使用 go-mitmproxy 進行流量攔截和重放
對於 HTTPS 站點,直接抓取請求數據進行重放是不行的,因爲 TLS 保護了傳輸數據。要攔截 HTTPS 流量,可以使用 go-mitmproxy 作爲中間人代理。
安裝 go-mitmproxy,命令如下所示:
go install github.com/lqqyt2423/go-mitmproxy/cmd/go-mitmproxy@latest
啓動 go-mitmproxy,直接使用 go-mitmproxy 命令就可以了,運行如下所示:
go-mitmproxy 也提供了可視化的 web 界面
設置瀏覽器或系統代理爲 http://127.0.0.1:9080,然後抓取 HTTPS 流量。當然啦,我們還可以爲其編寫擴展插件實現一些符合我們實際操作的功能。
📌 適用場景:
-
適用於 HTTPS 流量重放。
-
需要手動配置代理,適合抓取瀏覽器或 API 流量。
使用 gor 進行生產環境流量回放
Gor 是一個強大的 HTTP 流量回放工具,適用於大規模生產流量回放。
步驟
- 捕獲 8080 端口的 HTTP 流量:
sudo ./gor --input-raw :8080 --output-file requests.gor
- 重放請求到測試環境:
sudo ./gor --input-file requests.gor --output-http "http://localhost:8080"
📌 適用場景:
-
回放真實生產環境流量,測試新版本 API 兼容性。
-
流量回放壓力測試。
我認爲的最佳實踐
-
生產環境流量重放:使用 gor 進行大規模流量採集和回放。
-
API 調試:使用 httputil.DumpRequest 記錄和重放 API 請求。
-
HTTPS 站點:使用 go-mitmproxy 進行流量攔截和分析。
-
排查 HTTP 連接問題:使用 httptrace 監聽請求生命週期。
結語
HTTP 流量重放在 API 調試、安全測試、流量回歸等領域非常有價值。Go 語言提供了豐富的庫來實現流量捕獲與重放,同時 go-mitmproxy 和 gor 這樣的工具可以幫助我們更高效地進行 HTTPS 攔截和生產流量回放。當然啦,以上所提及到的還不是全部,實際上還有更好的。今天的內容到此就結束了,感謝您的收看🌹🌹🌹。如果本文對你有所幫,歡迎關注➕,點贊👍,收藏⭐️和轉發🚀🚀🚀🦀🦀🦀
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/HWCmYOxWM80ZxSuMnua41Q