更新配置解析功能,使用BurntSushi/toml库解析TOML格式配置文件,添加流量转储目录创建功能,修改输出目录设置,更新.gitignore以排除新生成的目录,删除不再使用的proxy_log.txt文件,新增VSCode设置文件以支持拼写检查。

This commit is contained in:
wjsjwr 2025-08-21 00:19:30 +08:00
parent 8eefa5848d
commit a561b291e9
8 changed files with 299 additions and 779 deletions

5
.gitignore vendored
View File

@ -20,5 +20,6 @@
# Go workspace file
go.work
traffic_dumps/
*_dumps/
out/
log

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"cSpell.words": [
"goproxy"
]
}

109
config.go
View File

@ -1,21 +1,14 @@
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"github.com/BurntSushi/toml"
)
// Simple TOML parser, only handles basic formats we need
// parseConfig parses the TOML configuration file using BurntSushi/toml
func parseConfig(filename string) (*Config, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
config := &Config{
DomainsOfInterest: []string{},
}
@ -23,79 +16,41 @@ func parseConfig(filename string) (*Config, error) {
// Set default values
config.Proxy.Port = 8080
config.Dump.OutputDir = "traffic_dumps"
config.Dump.DOIDir = "interest_dumps"
scanner := bufio.NewScanner(file)
var currentSection string
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// Skip empty lines and comments
if line == "" || strings.HasPrefix(line, "#") {
continue
}
// Check if it's a section title
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
currentSection = strings.Trim(line, "[]")
continue
}
// Parse key-value pairs
parts := strings.SplitN(line, "=", 2)
if len(parts) != 2 {
continue
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
// Handle array values
if strings.HasPrefix(value, "[") && strings.HasSuffix(value, "]") {
arrayStr := strings.Trim(value, "[]")
if key == "domains_of_interest" {
if arrayStr != "" {
items := strings.Split(arrayStr, ",")
for _, item := range items {
item = strings.TrimSpace(item)
item = strings.Trim(item, "\"")
if item != "" {
config.DomainsOfInterest = append(config.DomainsOfInterest, item)
}
}
}
}
continue
}
// Handle string values
value = strings.Trim(value, "\"")
// Set values based on current section
switch currentSection {
case "proxy":
switch key {
case "port":
if port, err := strconv.Atoi(value); err == nil {
config.Proxy.Port = port
}
}
case "dump":
switch key {
case "output_dir":
config.Dump.OutputDir = value
}
}
// Parse the TOML file
_, err := toml.DecodeFile(filename, config)
if err != nil {
return nil, fmt.Errorf("failed to parse config file %s: %v", filename, err)
}
if err := scanner.Err(); err != nil {
return nil, err
// Create dump directories if they don't exist
if err := createDumpDirectories(config); err != nil {
return nil, fmt.Errorf("failed to create dump directories: %v", err)
}
return config, nil
}
func (c *Config) String() string {
return fmt.Sprintf("Config{DomainsOfInterest: %v, Proxy: {Port: %d}, Dump: {OutputDir: %s}}",
c.DomainsOfInterest, c.Proxy.Port, c.Dump.OutputDir)
// createDumpDirectories creates the dump directories if they don't exist
func createDumpDirectories(config *Config) error {
directories := []string{
config.Dump.OutputDir,
config.Dump.DOIDir,
}
for _, dir := range directories {
if dir != "" {
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("failed to create directory %s: %v", dir, err)
}
}
}
return nil
}
func (c *Config) String() string {
return fmt.Sprintf("Config{DomainsOfInterest: %v, Proxy: {Port: %d}, Dump: {OutputDir: %s, DOI_dir: %s}}",
c.DomainsOfInterest, c.Proxy.Port, c.Dump.OutputDir, c.Dump.DOIDir)
}

View File

@ -1,10 +1,7 @@
# Domains of interest configuration
# Requests and responses for these domains will be printed to stdout
domains_of_interest = [
"example.com",
"httpbin.org",
"api.github.com",
"www.google.com"
"amemv.com"
]
# Proxy server configuration
@ -14,3 +11,4 @@ port = 8080
# Traffic dump configuration
[dump]
output_dir = "traffic_dumps"
DOI_dir = "interest_dumps"

10
go.mod
View File

@ -3,8 +3,14 @@ module mitm
go 1.25
require (
golang.org/x/sys v0.15.0
github.com/elazarl/goproxy v1.7.2
golang.org/x/sys v0.30.0
software.sslmate.com/src/go-pkcs12 v0.4.0
)
require golang.org/x/crypto v0.17.0 // indirect
require (
github.com/BurntSushi/toml v1.5.0
golang.org/x/crypto v0.33.0 // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/text v0.22.0 // indirect
)

24
go.sum
View File

@ -1,6 +1,22 @@
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=
software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=

852
main.go

File diff suppressed because it is too large Load Diff

View File

@ -1,67 +0,0 @@
Starting MITM proxy server...
2025/08/20 01:14:22 Failed to install CA certificate: failed to install certificate: exit status 0x80070005, output: 使用选择的选项需要管理员权限。使用管理员命令提示来完成这些任务。
Root "受信任的根证书颁发机构"
无法打开证书存储。
CertUtil: -addstore 失败: 0x80070005 (WIN32: 5 ERROR_ACCESS_DENIED)
CertUtil: 拒绝访问。
Warning: netsh winhttp reset failed: exit status 1
Warning: netsh winhttp import failed: exit status 1
鉁?System proxy set to 127.0.0.1:8080
鉁?Proxy settings verified in Windows registry
馃攳 Current Proxy Configuration:
ProxyEnable: 1
ProxyServer: 127.0.0.1:8080
ProxyOverride: <local>
WinHTTP Proxy Settings:
Current WinHTTP proxy settings:
Direct access (no proxy server).
鈴?Waiting for server to start...
馃殌 Starting proxy server on port 8080...
馃敡 Starting HTTP server on :8080
鉁?Successfully bound to port :8080
[01:14:23] 馃摜 INCOMING: GET ipv6.msftconnecttest.com /connecttest.txt from 127.0.0.1:53610
[01:14:23] 馃搵 Headers: 2 headers received
[01:14:23] 馃搵 Header: Connection: Close
[01:14:23] 馃搵 Header: User-Agent: Microsoft NCSI
[01:14:23] 馃寪 Full URL: http://ipv6.msftconnecttest.com/connecttest.txt
[01:14:23] 馃寪 Processing HTTP request for ipv6.msftconnecttest.com
[01:14:25] 馃摜 INCOMING: GET crl3.digicert.com /DigiCertAssuredIDRootCA.crl from 127.0.0.1:53613
[01:14:25] 馃搵 Headers: 6 headers received
[01:14:25] 馃搵 Header: User-Agent: Microsoft-CryptoAPI/10.0
[01:14:25] 馃搵 Header: Cache-Control: max-age = 6311
[01:14:25] 馃搵 Header: Proxy-Connection: Keep-Alive
[01:14:25] 馃搵 Header: Accept: */*
[01:14:25] 馃搵 Header: If-Modified-Since: Wed, 13 Aug 2025 21:15:04 GMT
[01:14:25] 馃搵 Header: If-None-Match: "689d0058-435"
[01:14:25] 馃寪 Full URL: http://crl3.digicert.com/DigiCertAssuredIDRootCA.crl
[01:14:25] 馃寪 Processing HTTP request for crl3.digicert.com
[01:14:25] 馃摜 INCOMING: GET crl3.digicert.com /DigiCertGlobalRootCA.crl from 127.0.0.1:53613
[01:14:25] 馃搵 Headers: 6 headers received
[01:14:25] 馃搵 Header: Cache-Control: max-age = 6311
[01:14:25] 馃搵 Header: Proxy-Connection: Keep-Alive
[01:14:25] 馃搵 Header: Accept: */*
[01:14:25] 馃搵 Header: If-Modified-Since: Wed, 13 Aug 2025 21:15:07 GMT
[01:14:25] 馃搵 Header: If-None-Match: "689d005b-30b"
[01:14:25] 馃搵 Header: User-Agent: Microsoft-CryptoAPI/10.0
[01:14:25] 馃寪 Full URL: http://crl3.digicert.com/DigiCertGlobalRootCA.crl
[01:14:25] 馃寪 Processing HTTP request for crl3.digicert.com
[01:14:25] 馃摜 INCOMING: GET crl4.digicert.com /DigiCertHighAssuranceEVRootCA.crl from 127.0.0.1:53613
[01:14:25] 馃搵 Headers: 6 headers received
[01:14:25] 馃搵 Header: If-Modified-Since: Wed, 13 Aug 2025 21:15:07 GMT
[01:14:25] 馃搵 Header: If-None-Match: "689d005b-2e4"
[01:14:25] 馃搵 Header: User-Agent: Microsoft-CryptoAPI/10.0
[01:14:25] 馃搵 Header: Cache-Control: max-age = 3862
[01:14:25] 馃搵 Header: Proxy-Connection: Keep-Alive
[01:14:25] 馃搵 Header: Accept: */*
[01:14:25] 馃寪 Full URL: http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
[01:14:25] 馃寪 Processing HTTP request for crl4.digicert.com
鉁?Proxy server appears to be starting (no immediate errors)
馃攳 Testing basic proxy connectivity...
馃彞 Health check request from 127.0.0.1:53625
鉁?Basic proxy connectivity test passed
馃彞 Health check request from 127.0.0.1:53670
exit status 1