SySS-Research/wcfproxy
GitHub: SySS-Research/wcfproxy
一个用于拦截与转发 net.tcp 协议 WCF 流量的代理工具,解决跨平台协议调试与安全测试中的透明转发难题。
Stars: 3 | Forks: 0
# 构建
您既可以编译一次工具然后使用生成的可执行文件,也可以像运行脚本一样运行它(Go 工具链会即时编译)。
对于开发来说,后者更为方便。
对于生产使用,建议编译一次(从 `cli` 目录)并使用生成的可执行文件。
得益于 Go 编译器,您可以从 Linux 或 Windows 构建并运行。
至少需要 Go 1.18 版本进行构建(已用 Go 1.23 测试)。
## 从 Linux 构建
要从 Linux 为 Windows 或 Linux 构建,只需适当设置 `GOOS`(从 `cli` 目录执行):
```
GOOS=windows GOARCH=amd64 go build -o wcfproxy.exe
```
```
GOOS=linux GOARCH=amd64 go build -o wcfproxy
```
## 从 Windows 构建
要从 Windows 构建,执行等效的命令,例如从 PowerShell:
```
$env:GOOS='windows'; $env:GOARCH='amd64'; go build -o wcfproxy.exe
```
```
$env:GOOS='linux'; $env:GOARCH='amd64'; go build -o wcfproxy
```
# 用法
`wcfproxy` 的配置通过 JSON 文件提供。
默认使用配置文件 `config.json`,但可以通过 `-config` 参数指定配置文件路径。
配置文件应包含任意数量的命名配置,示例如下:
```
{
"my-config": {
" ... ": " ... "
}
}
```
命名配置对象的值应与 `Config` 结构体匹配(参见 [配置结构](#config-structure))。
此包含注释的源文件本身也是 `wcfproxy` 配置选项的最准确文档。
在所有提供的配置中,通过 `-enable` 命令行选项指定要使用的配置名称:
```
wcfproxy.exe -config config.json -enable my-config
```
## 配置结构
每个配置对象的顶层结构如下:
```
{
"listen": "[::1]:8000",
"connect": "[::1]:9000",
"retarget": "net.tcp://127.0.0.1:8000/WCFLab/WCFDemoService/nettcp",
"retarget-map": {
"nettcps": "net.tcp://localhost:8210/WCFLab/WCFDemoService/nettcps",
"winauth": "net.tcp://localhost:8220/WCFLab/WCFDemoService/nettcp-winauth"
},
"log-level": "debug|info|warn|error",
"log-file": "path/to/log/file",
"tls-server": {
" ... ": " ... "
},
"tls-client": {
" ... ": " ... "
},
"ntlm": {
" ... ": " ... "
},
"interceptor": {
" ... ": " ... "
},
"ctrl": {
" ... ": " ... "
}
}
```
注意:如果存在 NTLM 配置,则不能提供 TLS 配置(`tls-server` 和/或 `tls-client`)。
### 配置选项
+ `listen` - `wcfproxy` 应监听的 TCP 端点,例如 `127.0.0.1:8000` 或 `[::1]:8000`
+ `connect` - 上游 WCF 服务器的 TCP 端点,例如 `127.0.0.1:9000` 或 `[::1]:9000`
+ `retarget` - 原始目标规范(以及 `retarget-map` 的回退);有关说明请参见 [目标重写](#target-rewriting)
+ `retarget-map` - `retarget` 的泛化;允许对多个端点执行目标重写(仅在同时使用多个 WCF 服务时有用)
+ 如果 `retarget-map` 中的某个键匹配当前目标,则目标 URI 将被替换为给定值用于上游通信
+ 如果 `retarget-map` 中没有键匹配当前目标,则改用 `retarget`
+ `log-level` - 日志级别;可用值:`debug`、`info`(默认)、`warn`、`error`
+ `log-file` - 日志文件路径;如果未提供路径,日志将写入 `stdout`
+ `tls-server` - `TlsServerConfig` 实例(参见 [TLS 服务器配置](#tls-server-configuration));仅在需要支持 TLS 升级时必需
+ `tls-client` - `TlsClientConfig` 实例(参见 [TLS 客户端配置](#tls-client-configuration));仅在需要支持 TLS 升级时相关
+ `ntlm` - `NtlmConfig` 实例(参见 [NTLM 配置](#ntlm-configuration));仅在需要支持 NTLM 升级(直接或通过 SPNEGO)时必需
+ `interceptor` - `InterceptorConfig` 实例(参见 [拦截器配置](#interceptor-configuration));必需
+ `ctrl` - `ControlServerConfig` 实例(参见 [控制服务器配置](#control-server-configuration)),可提供默认 HTTP 回显服务器(与 HTTP 拦截器配合使用)以及用于控制消息流的小型 API(仍在开发中)
### TLS 服务器配置
TLS 服务器端配置控制大多数相关的 TLS 服务器设置。
其结构如下:
```
{
"cert-pem": "path/to/certificate",
"cert-key": "path/to/certificate-key",
"max-version": "1.0|1.1|1.2|1.3",
"min-version": "1.0|1.1|1.2|1.3",
"client-roots": "path/to/client-ca1,path/to/client-ca2",
"client-auth": "none|request|require-any|verify-if-given|require-and-verify",
"keylog": "path/to/keylog-file"
}
```
#### TLS 服务器配置选项
+ `cert-pem` - X.509 证书路径(PEM 格式)
+ `cert-key` - 证书对应的密钥路径
+ `max-version` - 可接受的最大 TLS 版本;取值:`1.0`、`1.1`、`1.2`、`1.3`(默认)
+ `min-version` - 可接受的最小 TLS 版本;取值:`1.0`(默认)、`1.1`、`1.2`、`1.3`
+ `client-roots` - 可接受的客户端根证书(PEM)路径的逗号分隔列表;可选
+ `client-auth` - 客户端认证策略;常用值:`none`(默认)、`require-and-verify`
+ `keylog` - 用于以 NNS 格式写入 TLS 密钥的文件
### TLS 客户端配置
TLS 客户端端配置控制大多数相关的 TLS 客户端设置。
其结构如下:
```
{
"cert-pem": "path/to/certificate",
"cert-key": "path/to/certificate-key",
"max-version": "1.0|1.1|1.2|1.3",
"min-version": "1.0|1.1|1.2|1.3",
"roots": "path/to/root-ca1,path/to/root-ca2",
"server-name": "therealone.local",
"skip-verify": false
}
```
#### TLS 客户端配置选项
+ 类似于 [TLS 服务器配置选项](#tls-server-configuration-options)
+ `roots` - 根 CA 路径的逗号分隔列表;可选,配合 `skip-verify` 使用
+ `server-name` - 服务器名称(SNI);可选
+ `skip-verify` - 布尔值;是否跳过服务器证书验证(默认:`false`)
### NTLM 配置
NTLM 配置指定用于认证的域和服务器名称以及用户凭据。
对于每个需要认证的代理用户,必须提供有效的凭据。
```
{
"domain": "test.local",
"server": "server.local",
"credentials": [
{
" ... ": " ... "
}
]
}
```
#### NTLM 配置选项
+ `domain` - 认证的域,例如 `test.local`;留空则使用服务器名称
+ `server` - 认证的服务器名称;留空则使用当前系统主机名
+ `credentials` - `NtlmCredential` 数组(参见下文)
NTLM 凭据以 `NtlmCredential` 对象数组形式传递,其结构如下:
```
{
"name": "wcflab",
"password": "Sup3rS3cr3t",
"nt-hash": "a8fc07dede90b0ec10bc1ef355f99292",
"lm-hash": "3e9cb63e11a812cbc467021088dc706f"
}
```
+ `name` - 用户名
+ `password` - 用户密码;会从中派生哈希;会覆盖为该用户提供的现有哈希
+ `nt-hash` - 用户的 NT 哈希(十六进制);密码的替代方式
+ `lm-hash` - 用户的 LM 哈希(十六进制);密码的替代方式;在大多数情况下不需要
如果提供了密码,则会计算该密码的 LM 哈希(并非所有密码都支持)和 NT 哈希。
任何为该用户提供的现有哈希值将被计算出的哈希覆盖。
也可以仅提供用户哈希。
在大多数场景中不需要 LM 哈希。
### 拦截器配置
拦截器配置指定应使用的拦截器(按名称)以及可选的拦截器特定参数。
有关拦截器的说明,请参见 [拦截器](#interceptors)。
#### 日志拦截器
要使用日志拦截器,只需使用以下拦截器配置。
输出将写入主要日志位置(可能是文件或 `stdout`),具体取决于 `log-file` 配置。
```
{
"name": "log"
}
```
#### HTTP 拦截器
要使用 HTTP 拦截器,请使用以下拦截器配置,并为 `server-url` 和 `proxy-url` 提供合适的选项。
```
{
"name": "http",
"args": {
"server-url": "http://127.0.0.1:9999/echo",
"proxy-url": "http://127.0.0.1:8080"
}
}
```
+ `args.server-url` - HTTP 服务器拦截端点 URL(例如简单的回显端点);有关 HTTP 拦截器的工作原理请参见 [HTTP 拦截器](#http-interceptor-1)
+ `args.proxy-url` - HTTP 代理 URL;可选
### 控制服务器配置
*wcfproxy* 自带一个内置 Web 服务器,提供两项功能。
首先,它可以提供一个 HTTP 端点,简单地回显发送到它的所有内容。
这在与 [HTTP 拦截器](#http-interceptor-1) 配合使用时非常有用。
```
{
"ctrl": {
"listen": "127.0.0.1:9999",
"enable-control": false,
"enable-echo": true
}
}
```
### 控制服务器配置选项
+ `listen` - 控制服务器应监听的 TCP 端点
+ `enable-contorl` - 启用控制功能,如消息注入或连接建立(参见 [消息注入](#message-injection))
+ `enable-echo` - 在 `http://{listen}/echo` 启用简单的 HTTP 回显服务器
# 细节
以下章节提供一些背景信息,有助于理解 WCF 以及部分配置选项。
## 目标重写
WCF 端点在 net.tcp 前导部分以及传输的 SOAP 封套的 `To` 头部中编码。
服务器可能会检查此端点规范是否与预期匹配。
当客户端被为连接到代理而不是原始服务器时,此端点规范可能会更改,服务器可能会拒绝通信。
因此,通常有必要在传出流量中修正端点规范。
为此,在配置文件中提供原始端点规范(例如从客户端配置中获取)到 `retarget` 选项。
端点规范通常如下所示:`net.tcp://some/endpoint`。
当同时处理多个 WCF 端点时,可能需要对所有端点执行目标重写。
为此,`retarget-map` 选项存在,它定义了目标 URI 之间的映射。
当在 `retarget-map` 中找不到匹配项时,目标 URI 将更改为 `retarget` 中提供的值。
## 类型提示
二进制 XML(按 `MC-NBFX` 规范)在二进制格式中编码基本类型信息(记录类型)。
并非所有这些信息都能轻松地从(文本形式的)二进制 XML 文档中恢复。
因此,*wcfproxy* 在 XML 字符数据(以及某些属性)标记中插入类型提示。
这些类型提示的形式为 `:`,其中 `` 是编码某种类型的短字符串(例如 `i` 表示整数,`ch` 表示字符)。
类型提示的完整列表可以在 [typehint.go](./binxml/typehint.go) 中找到。
不建议篡改类型提示。
## 拦截器
拦截器指定如何处理接收到的流量,并通过 [拦截器配置](#interceptor-configuration) 进行指定。
它们处理双向流量(客户端 -> 服务器和服务器 -> 客户端)。
目前有两种拦截器:**log** 和 **http**。
### 日志拦截器
**log** 拦截器将二进制编码的 SOAP 封套转换为使用常规文本 XML 表示的可读形式。
不执行主动操作(除目标规范重写外)。
输出发送到指定的日志位置(默认为 `stdout`)。
请确保将日志级别设置为 `info`(或 `debug`),否则相关输出将被抑制。
### HTTP 拦截器
**http** 拦截器将二进制 SOAP 封套转换为文本形式并发送到由 `-http-url` 指定的 HTTP 端点。
解码后的 SOAP 消息在请求正文中发送。
HTTP 服务器应返回与传入消息相同格式的有效 SOAP 封套。
这些消息随后被转换回原始二进制格式并发送到上游服务器。
始终反射原始消息是 HTTP 服务器的有效选项。
然而,也可以通过提供执行所需替换的自定义 HTTP 服务器来实现程序化消息操作。
需要注意不要破坏 SOAP 消息的结构。
除非您清楚自己在做什么,否则不建议修改消息格式。
此外,*wcfproxy* 插入的类型提示不应被篡改,因为这可能会破坏将文本形式 SOAP 消息转换回其二进制对应格式或消息解析。
*wcfproxy* 自带一个简单的 HTTP 服务器,仅回显收到的 HTTP 请求正文。
当提供 [控制服务器配置](#control-server-configuration) 并将 `enable-echo` 选项设置为 `true` 时,将启动此服务器。
所需 HTTP 服务器的 URL 通过 [HTTP 拦截器配置](#http-interceptor) 中的 `server-url` 选项提供。
为了允许交互式操作,可以通过 `proxy-url` 选项指定 HTTP 代理(例如 BurpSuite)。
消息随后将通过指定的 HTTP 代理发送到 HTTP 服务器。
请注意,对于每个 WCF 消息(例如客户端 -> 服务器),都会生成一个 HTTP 请求响应对。
为了将消息关联到其来源的 net.tcp 连接,会在请求中插入标头 `X-Wcpf-Conn-Id`。
下图说明了使用 **http** 拦截器的数据流。

## TLS 选项
WCF(通过 net.tcp)可以使用 TLS 进行传输安全。
*wcfproxy* 支持拦截 TLS 连接(仅 TLS 1.0 - 1.3,不支持 SSL)。
服务器端和客户端 TLS 设置可以通过相应的 TLS 配置进行控制(参见 [TLS 服务器配置](#tls-server-configuration) 或 [TLS 客户端配置](#tls-client-configuration))。
## NTLM 选项
*wcfproxy* 支持 NTLM 认证。
目前支持直接 NTLM 认证或通过 SPNEGO 协商。
需要提供将进行认证的用户凭据。
这些凭据以 JSON 格式提供,请参见 [NTLM 配置](#ntlm-configuration)。
支持通过 `nt-hash` 属性传递哈希值。
## 消息注入与连接建立
当 [控制服务器](#control-server-configuration) 启用时,会提供一个小的 HTTP API,用于建立或终止连接以及注入消息到现有连接。
提供以下端点。
### GET `/connection`
列出当前活动的连接。
对于通过 [POST /connection/new](#post-connectionnew) 创建的仅服务器连接,客户端将显示为 `wcfproxy`。
### POST `/connection/new`
创建新连接。
请求体必须是一个 JSON 对象,指定所需的升级(TLS 或 Negotiate (NTLM))以及目标 URI。
#### 示例:无升级
如果不需要升级,可以省略 `upgrade` 属性。
```
{
"target-uri":"net.tcp://127.0.0.1:9510/example/notes-nettcp"
}
```
#### 示例:TLS 升级
要发起 TLS 升级,请指定升级机制 `tls`。
```
{
"target-uri":"net.tcp://wcf-notes.local:9511/example/notes-nettcp-tls",
"upgrade": {
"mechanism":"tls"
}
}
```
#### 示例:NTLM 升级
`upgrade` 对象需要指定 `ntlm` 作为机制以及要认证的用户。
该用户的凭据必须通过 `ntlm` 配置提供。
```
{
"target-uri":"net.tcp://localhost:8203/WCFLab/WCFDemoService/nettcp-winauth",
"upgrade": {
"mechanism": "ntlm",
"ntlmuser": "wcflab"
}
}
```
### POST `/connection/{id}/kill`
销毁由 `{id}` 标识的连接。
### POST `/connection/{id}/inject`
将请求正文中提供的消息注入到由 `{id}` 标识的连接。
请求正文必须与用于向 HTTP 拦截器转发 WCF 消息的格式相同。
因此,最好复制观察到的消息,根据需要进行修改,然后通过此端点注入。
默认情况下,不会显示对注入消息的响应。
但是,如果启用了拦截器,响应应该会出现在其中。
作为便利,当提供查询参数 `retrieve=true` 时,`wcfproxy` 会等待对注入消息的回复并显示它。
## 连接限制
对并发活动连接数施加了人为的上限。
当前限制为 20。
这是为了防止在(误)使用控制 API 时意外耗尽资源(参见 [消息注入与连接建立](#message-injection-and-connection-establishment))。
这通常不会给合法的 WCF 客户端带来问题。
然而,可能存在需要更多并发连接的用例。
在这种情况下,请根据需要修改 [proxy.go](./proxy/proxy.go) 中的 `maxConnections` 常量。
# 示例
以下示例展示 *wcfproxy* 的一些基本用法。
确切的输出可能会有所变化,但应能传达基本思想。
## 使用日志拦截器
此示例展示在 WCF 游乐场环境中使用 *wcfproxy* 进行纯 net.tcp WCF 通信,并使用 **log** 拦截器。
```
{
"wcflab-plain": {
"listen": "127.0.0.1:7201",
"connect": "127.0.0.1:8201",
"retarget": "net.tcp://127.0.0.1:8201/WCFLab/WCFDemoService/nettcp",
"log-level": "debug",
"interceptor": {
"name": "log"
}
}
}
```
使用上述配置(放置在 `config.json` 中),可以按如下方式使用。
通过代理的流量应输出到控制台(`stdout`)。
```
> .\wcfproxy.exe -config .\config.json -enable wcflab-plain
2025/07/10 15:03:59 dbg: local time zone (for DateTime handling): CEST
INFO: Listening on 127.0.0.1:7201 and connecting to 127.0.0.1:8201
INFO: No server certificates given. TLS upgrade not supported.
INFO: No client certificates given. TLS client authentication not supported.
INFO: Retargeting to net.tcp://127.0.0.1:8201/WCFLab/WCFDemoService/nettcp
INFO: [proxy] Handling new connection 0: 127.0.0.1:50216 <-> 127.0.0.1:8201
INFO: [proxy] Connection 0 established (127.0.0.1:50216 <-> 127.0.0.1:8201)
INFO: [proxy] Envelope (Connection 0, Client -> Server):
ch:http://tempuri.org/IWCFDemoService/AddInts
uid:urn:uuid:b2d5fc85-4bcd-6442-b701-164655365198
ch:http://www.w3.org/2005/08/addressing/anonymous
ch:net.tcp://127.0.0.1:8201/WCFLab/WCFDemoService/nettcp
i:1234
i:37
INFO: [proxy] Envelope (Connection 0, Server -> Client):
ch:http://tempuri.org/IWCFDemoService/AddIntsResponse
uid:urn:uuid:b2d5fc85-4bcd-6442-b701-164655365198
ch:http://www.w3.org/2005/08/addressing/anonymous
i:1271
INFO: [proxy] Connection 0 closed (127.0.0.1:50216 <-> 127.0.0.1:8201)
ERROR: [net.tcp] Error readEnvelopeOrFaultI2R: read tcp 127.0.0.1:50217->127.0.0.1:8201: i/o timeout. Entering fault state.
INFO: [proxy] Done handling connection 0: 127.0.0.1:50216 <-> 127.0.0.1:8201
```
## 使用 HTTP 拦截器
以下配置使用 **http** 拦截器,并结合 HTTP 代理使用。
```
{
"wcflab-plain-http": {
"listen": "127.0.0.1:7201",
"connect": "127.0.0.1:8201",
"retarget": "net.tcp://127.0.0.1:8201/WCFLab/WCFDemoService/nettcp",
"log-level": "info",
"ctrl": {
"listen": "127.0.0.1:9999",
"enable-echo": true
},
"interceptor": {
"name": "http",
"args": {
"proxy-url": "http://127.0.0.1:8080"
}
}
}
}
```
使用此配置时,日志不会显示有趣的内容。
```
> go run ./ -config .\config.json -enable wcflab-plain-http
2025/07/10 18:06:02 dbg: local time zone (for DateTime handling): CEST
2025/07/10 18:06:02 DBG - configuring intercrptor: &{http map[proxy-url:http://127.0.0.1:8080]}
INFO: Listening on 127.0.0.1:7201 and connecting to 127.0.0.1:8201
INFO: No server certificates given. TLS upgrade not supported.
INFO: No client certificates given. TLS client authentication not supported.
INFO: Retargeting to net.tcp://127.0.0.1:8201/WCFLab/WCFDemoService/nettcp
INFO: [proxy] Starting control server on 127.0.0.1:9999 (echo enabled: true, control enabled: false)
INFO: [proxy] Handling new connection 0: 127.0.0.1:22664 <-> 127.0.0.1:8201
ERROR: [net.tcp] Error readEnvelopeOrFaultI2R: read tcp 127.0.0.1:22665->127.0.0.1:8201: i/o timeout. Entering fault state.
INFO: [proxy] Done handling connection 0: 127.0.0.1:22664 <-> 127.0.0.1:8201
```
然而,WCF 流量会被转换为(几乎)常规的 SOAP 封套并通过 HTTP 发送。

## 设置(m)TLS 拦截
可以设置 *wcfproxy* 以拦截 mTLS 保护的 WCF 流量,前提是可用的服务器和客户端证书。
对于不带客户端认证的 TLS 配置类似;本例中不需要客户端证书。
以下配置为该用例提供示例:
```
{
"wcflab-mtls": {
"listen": "127.0.0.1:7203",
"connect": "127.0.0.1:8203",
"retarget": "net.tcp://localhost:8203/WCFLab/WCFDemoService/nettcps-mtls",
"interceptor": {
"name": "log"
},
"tls-server": {
"cert-pem": "../testdata/pki/server.pem",
"cert-key": "../testdata/pki/server.key"
},
"tls-client": {
"cert-pem": "../testdata/pki/client.pem",
"cert-key": "../testdata/pki/client.key",
"skip-verify": true
}
}
```
请注意,客户端需要信任服务器证书(`server.pem`)。
此外,服务器必须信任 *wcfproxy* 呈现给它的客户端证书(`client.pem`)。
```
> .\wcfproxy.exe -config .\config.json -enable wcflab-mtls
2025/07/10 15:01:32 dbg: local time zone (for DateTime handling): CEST
INFO: Using client certificate client-01.local (SHA256-fingerprint: 9b258653a4d5f338f2be1dafe0caf892b01d271183e52f0821d80439de4b7564)
INFO: Listening on 127.0.0.1:7203 and connecting to 127.0.0.1:8203
INFO: Using server certificate wcflab.local (SHA256-fingerprint: 7286ff75d3bb6dc4d96c0c8ac08dbac2204af67e0b1814b3d8c59c24d5bd781a)
INFO: Server supports TLS versions 1.0 - 1.3
INFO: Using client certificate client-01.local (SHA256-fingerprint: 9b258653a4d5f338f2be1dafe0caf892b01d271183e52f0821d80439de4b7564)
INFO: Client supports TLS versions 1.0 - 1.3
INFO: Retargeting to net.tcp://localhost:8203/WCFLab/WCFDemoService/nettcps-mtls
INFO: [proxy] Handling new connection 0: 127.0.0.1:50214 <-> 127.0.0.1:8203
INFO: [proxy] Connection 0 established (127.0.0.1:50214 <-> 127.0.0.1:8203)
INFO: [proxy] Initiating TLS upgrade
INFO: [proxy] 127.0.0.1:50214 <-> 127.0.0.1:7203: negotiated TLS 1.2 (TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
INFO: [proxy] 127.0.0.1:50215 <-> 127.0.0.1:8203: negotiated TLS 1.2 (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
INFO: [proxy] Upgrade done
INFO: [proxy] Envelope (Connection 0, Client -> Server):
ch:http://tempuri.org/IWCFDemoService/AddInts
uid:urn:uuid:d36e17be-2cc2-a94f-83a7-cd2442dba24e
ch:http://www.w3.org/2005/08/addressing/anonymous
ch:net.tcp://localhost:8203/WCFLab/WCFDemoService/nettcps-mtls
i:1234
i:37
INFO: [proxy] Envelope (Connection 0, Server -> Client):
ch:http://tempuri.org/IWCFDemoService/AddIntsResponse
uid:urn:uuid:d36e17be-2cc2-a94f-83a7-cd2442dba24e
ch:http://www.w3.org/2005/08/addressing/anonymous
i:1271
INFO: [proxy] Connection 0 closed (127.0.0.1:50214 <-> 127.0.0.1:8203)
ERROR: [net.tcp] Error readEnvelopeOrFaultI2R: read tcp 127.0.0.1:50215->127.0.0.1:8203: i/o timeout. Entering fault state.
INFO: [proxy] Done handling connection 0: 127.0.0.1:50214 <-> 127.0.0.1:8203
```
## 设置 NTLM 认证
假设 WCF 服务依赖 NTLM 认证(直接或通过 SPNEGO),可以使用以下配置来拦截流量:
```
{
"wcflab-ntlm": {
"listen": "[::1]:7204",
"connect": "[::1]:8204",
"retarget": "net.tcp://localhost:8204/WCFLab/WCFDemoService/nettcp-winauth",
"interceptor": {
"name": "log"
},
"ntlm": {
"domain": "DESKTOP-65ITJF5",
"credentials": [
{
"name": "",
"password": ""
}
]
}
}
}
```
请注意,目前更可靠的做法是通过 `server` `domain` 字段提供主机名,而不是依赖自动配置。
此外,在 AD 域上下文中进行身份验证尚未经过测试,因此目前可能无法正常工作。
当使用 SPNEGO 时,目前必须优先使用 NTLM 机制,否则协商会失败。
```
> .\wcfproxy.exe -config .\config.json -enable wcflab-ntlm
2025/07/10 15:15:15 dbg: local time zone (for DateTime handling): CEST
INFO: Listening on [::1]:7204 and connecting to [::1]:8204
INFO: No server certificates given. TLS upgrade not supported.
INFO: No client certificates given. TLS client authentication not supported.
INFO: Retargeting to net.tcp://localhost:8204/WCFLab/WCFDemoService/nettcp-winauth
INFO: [proxy] Handling new connection 0: [::1]:50247 <-> [::1]:8204
INFO: [proxy] Connection 0 established ([::1]:50247 <-> [::1]:8204)
INFO: [proxy] Initiating Negotiate upgrade
INFO: [NTLM server] User wcflab authenticated successfully
INFO: [proxy] [::1]:50247 <-> [::1]:7204: negotiated NTLM
INFO: [proxy] [::1]:50248 <-> [::1]:8204: negotiated NTLM
INFO: [proxy] Upgrade done
INFO: [proxy] Envelope (Connection 0, Client -> Server):
ch:http://tempuri.org/IWCFDemoService/AddInts
uid:urn:uuid:f9cc5af3-3930-9242-be3c-d36d2a0cb09e
ch:http://www.w3.org/2005/08/addressing/anonymous
ch:net.tcp://localhost:8204/WCFLab/WCFDemoService/nettcp-winauth
i:1234
i:37
INFO: [proxy] Envelope (Connection 0, Server -> Client):
ch:http://tempuri.org/IWCFDemoService/AddIntsResponse
uid:urn:uuid:f9cc5af3-3930-9242-be3c-d36d2a0cb09e
ch:http://www.w3.org/2005/08/addressing/anonymous
i:1271
INFO: [proxy] Connection 0 closed ([::1]:50247 <-> [::1]:8204)
ERROR: [net.tcp] Error readEnvelopeOrFaultI2R: read tcp [::1]:50248->[::1]:8204: i/o timeout. Entering fault state.
INFO: [proxy] Done handling connection 0: [::1]:50247 <-> [::1]:8204
```
标签:EVTX分析, Go语言, JSON配置, Linux Windows双平台, NetTcp, .NET 通信, SOC Prime, TCP, WCF, 中间件, 代理, 安全合规, 开发工具, 恶意代码分析, 无文件攻击, 日志审计, 生产部署, 程序破解, 端口转发, 网络代理, 跨平台编译, 配置文件