
Un proxy per il traffico WCF basato su net.tcp.
È possibile compilare lo strumento una volta e poi utilizzare il binario risultante, oppure eseguirlo "come uno script" (la toolchain Go lo compilerà al volo).
Per lo sviluppo, quest'ultima opzione è comoda.
Per l'uso produttivo, si consiglia di compilarlo una volta (dalla directory cli) e utilizzare l'eseguibile risultante.
Grazie al compilatore Go, è possibile compilare da e per Linux o Windows.
È richiesta almeno la versione 1.18 di Go per la compilazione (testato con Go 1.23).
Per compilare da Linux per Windows o Linux, basta impostare GOOS opportunamente (eseguire dalla directory cli):```
GOOS=windows GOARCH=amd64 go build -o wcfproxy.exe
nc -u -l -p 4444```
GOOS=linux GOARCH=amd64 go build -o wcfproxy
Per buildare da Windows, esegui i comandi equivalenti, ad esempio da PowerShell:``` $env:GOOS='windows'; $env:GOARCH='amd64'; go build -o wcfproxy.exe
Lo strumento supporta sia la modalità di rilevamento manuale che automatica. In modalità manuale, gli utenti possono specificare i parametri direttamente. La modalità automatica sfrutta modelli di machine learning per identificare potenziali minacce senza intervento dell'utente.
## Caratteristiche
- Monitoraggio in tempo reale
- Analisi dei dati storici
- Creazione di regole personalizzate
- Integrazione con sistemi SIEM
### Installazione
```bash
pip install threat-detector
$env:GOOS='linux'; $env:GOARCH='amd64'; go build -o wcfproxy
# Utilizzo
La configurazione per `wcfproxy` viene fornita tramite un file JSON.
Per impostazione predefinita, viene utilizzato il file di configurazione `config.json`, ma il percorso di un file di configurazione può essere specificato con il parametro `-config`.
Il file di configurazione è progettato per contenere un numero arbitrario di configurazioni nominate, come segue:```json
{
"my-config": {
" ... ": " ... "
}
}
Il valore degli oggetti di configurazione nominati dovrebbe corrispondere alla struct Config (vedi Config structure).
Questo file sorgente con i commenti inclusi funge anche da documentazione più accurata per le opzioni di configurazione di wcfproxy.
Di tutta la configurazione fornita, quella da utilizzare viene identificata per nome tramite l'opzione da riga di comando -enable:```
wcfproxy.exe -config config.json -enable my-config
## Struttura della configurazione
La struttura di primo livello di ogni oggetto di configurazione è la seguente:```json
{
"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": {
" ... ": " ... "
}
}
Nota che la configurazione TLS (tls-server e/o tls-client) non può essere fornita se è presente una configurazione NTLM.
listen - l'endpoint TCP su cui wcfproxy deve ascoltare, ad es. 127.0.0.1:8000 o [::1]:8000connect - l'endpoint TCP del server WCF a monte, ad es. 127.0.0.1:9000 o [::1]:9000retarget - specifica del target originale (e fallback per retarget-map); per una spiegazione vedi Riscrittura del targetretarget-map - generalizzazione di retarget; permette di eseguire la riscrittura del target per più endpoint (utile solo se si lavora con più servizi WCF sulla stessa porta)
retarget-map corrisponde al target corrente, l'URI del target verrà sostituito con il valore dato per la comunicazione a monteretarget-map corrisponde al target corrente, verrà usato La configurazione lato server TLS dà controllo sulle impostazioni del server TLS più tipicamente rilevanti. Ha la seguente struttura:```json { "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" }
#### Opzioni di configurazione del server TLS
+ `cert-pem` - percorso del certificato X.509 (in formato PEM)
+ `cert-key` - percorso della chiave corrispondente per il certificato
+ `max-version` - versione TLS massima accettabile; una tra `1.0`, `1.1`, `1.2`, `1.3` (predefinita)
+ `min-version` - versione TLS minima accettabile; una tra `1.0` (predefinita), `1.1`, `1.2`, `1.3`
+ `client-roots` - elenco separato da virgole di percorsi di certificati radice accettabili (PEM) per l'autenticazione client; opzionale
+ `client-auth` - politica di autenticazione client; valori più utili: `none` (predefinito), `require-and-verify`
+ `keylog` - file in cui scrivere i segreti TLS in formato NNS
### Configurazione TLS lato client
La configurazione del lato client TLS fornisce il controllo sulle impostazioni client TLS più comunemente rilevanti.
Ha la seguente struttura:```json
{
"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
}
roots - percorso verso un elenco di percorsi separati da virgola di CA radice (PEM); opzionale con skip-verifyserver-name - nome del server (SNI); opzionaleskip-verify - booleano; se il client deve saltare la verifica del certificato del server (predefinito: false)La configurazione NTLM specifica il dominio e il nome del server insieme alle credenziali utente. Per ogni utente che deve essere in grado di autenticarsi tramite il proxy, devono essere fornite credenziali valide.```json { "domain": "test.local", "server": "server.local", "credentials": [ { " ... ": " ... " } ] }
#### Opzioni di configurazione NTLM
+ `domain` - dominio a cui autenticarsi, ad es. test.local; se lasciato vuoto, verrà utilizzato il nome del server
+ `server` - nome del server a cui autenticarsi; se lasciato vuoto, verrà utilizzato il nome host del sistema corrente
+ `credentials` - array di oggetti `NtlmCredential` (vedi sotto)
Le credenziali NTLM vengono passate come un array di oggetti `NtlmCredential`, che hanno la seguente struttura:```json
{
"name": "wcflab",
"password": "Sup3rS3cr3t",
"nt-hash": "a8fc07dede90b0ec10bc1ef355f99292",
"lm-hash": "3e9cb63e11a812cbc467021088dc706f"
}
name - nome utentepassword - password dell'utente; da essa verranno derivati gli hash; sovrascrive gli hash forniti per un utentent-hash - NT hash (esadecimale) della password dell'utente; alternativa alla passwordlm-hash - LM hash (esadecimale) della password dell'utente; alternativa alla password; non dovrebbe essere richiesto nella maggior parte dei casiSe viene fornita una password, l'LM hash (non possibile per tutte le password) e l'NT hash vengono calcolati da essa. Qualsiasi valore hash fornito per questo utente verrà sovrascritto dagli hash calcolati. È anche possibile fornire solo gli hash dell'utente. L'LM hash non dovrebbe essere richiesto nella maggior parte degli scenari.
La configurazione dell'interceptor specifica l'interceptor (per nome) che deve essere utilizzato e opzionalmente argomenti specifici dell'interceptor. Per una spiegazione degli interceptor vedere Interceptors.
Per utilizzare l'interceptor di log, utilizzare semplicemente la seguente configurazione dell'interceptor.
L'output viene scritto nella posizione di logging principale, che può essere un file o stdout, a seconda della configurazione di log-file.```json
{
"name": "log"
}
#### Http interceptor
Per utilizzare l'HTTP interceptor, utilizzare la seguente configurazione con opzioni appropriate per `server-url` e `proxy-url`.```json
{
"name": "http",
"args": {
"server-url": "http://127.0.0.1:9999/echo",
"proxy-url": "http://127.0.0.1:8080"
}
}
args.server-url - URL del tuo endpoint di intercettazione del server HTTP (ad esempio un semplice endpoint echo); per i dettagli su come funziona l'intercettatore HTTP vedi HTTP Interceptorargs.proxy-url - URL del proxy HTTP; opzionalewcfproxy è dotato di un server web integrato che serve due funzioni. Prima di tutto può fornire un endpoint HTTP che riflette semplicemente tutto il contenuto che gli viene inviato. Ciò è utile in combinazione con l'HTTP interceptor.```json { "ctrl": { "listen": "127.0.0.1:9999", "enable-control": false, "enable-echo": true } }
> [!WARNING]
> Chiunque abbia accesso all'API può autenticarsi utilizzando le credenziali fornite (certificati client NTLM o TLS).
> Su sistemi condivisi questo può essere rilevante anche se l'API è disponibile solo localmente.
### Control server configuration options
+ `listen` - il punto di terminazione TCP dove il server di controllo deve ascoltare
+ `enable-contorl` - abilita le funzionalità di controllo come l'iniezione di messaggi o la creazione di connessioni (vedi [Iniezione di messaggi](#message-injection))
+ `enable-echo` - abilita un semplice server HTTP echo all'indirizzo `http://{listen}/echo`
# Dettagli
Le sezioni seguenti forniscono alcune informazioni di base che possono aiutare a comprendere meglio WCF e alcune opzioni di configurazione.
## Target rewriting
L'endpoint WCF previsto è codificato nel preambolo net.tcp e nell'intestazione `To` trasportata negli involucri SOAP.
I server possono verificare che questa specifica dell'endpoint corrisponda a quella prevista.
Quando il client viene manipolato per connettersi al proxy invece che al server originale, questa specifica dell'endpoint probabilmente cambierà e il server potrebbe rifiutare la comunicazione.
Pertanto, di solito ha senso correggere la specifica dell'endpoint nel traffico in uscita verso il server.
Per fare ciò, fornire la specifica dell'endpoint originale (ad esempio ottenuta dalla configurazione del client) nell'opzione `retarget` nel file di configurazione.
La specifica dell'endpoint di solito è simile a questa: `net.tcp://some/endpoint`.
Quando si lavora con più endpoint WCF contemporaneamente, potrebbe essere necessario eseguire il re-targeting per tutti.
A questo scopo esiste l'opzione `retarget-map` che definisce la mappatura tra URI di destinazione.
Quando non viene trovata una corrispondenza in `retarget-map`, l'URI di destinazione verrà modificato con il valore fornito in `retarget`.
## Suggerimenti di tipo
L'XML binario, come specificato da `MC-NBFX`, codifica le informazioni di base sul tipo nel formato binario (tipi di record).
Non tutte queste informazioni sono facilmente recuperabili dalla rappresentazione XML (testuale) di un documento XML binario.
Per questo motivo, *wcfproxy* inserisce suggerimenti di tipo nei token di dati carattere XML (e alcuni attributi).
Questi suggerimenti di tipo assumono la forma `<h>:` dove `<h>` è una stringa breve che codifica un tipo (ad es. `i` per intero, `ch` per caratteri).
Un elenco completo dei suggerimenti di tipo si trova in [typehint.go](https://github.com/syss-research/wcfproxy/blob/HEAD/binxml/typehint.go).
Non è consigliabile manomettere i suggerimenti di tipo.
## Intercettori
Gli intercettori specificano come viene gestito il traffico ricevuto e sono specificati tramite la [configurazione dell'intercettore](#interceptor-configuration).
Gestiscono il traffico inviato in entrambe le direzioni (client -> server e server -> client).
Attualmente ci sono due intercettori: **log** e **http**.
### Intercettore log
L'intercettore **log** converte gli involucri SOAP codificati in binario nelle loro controparti leggibili codificate utilizzando XML testuale normale.
Non viene eseguita alcuna manipolazione attiva (tranne la riscrittura della specifica di destinazione).
L'output viene inviato alla posizione di log specificata (`stdout` per impostazione predefinita).
Assicurati di impostare il livello di log su `info` (o `debug`), altrimenti l'output pertinente viene soppresso.
### Intercettore http
L'intercettore **http** converte gli involucri SOAP binari nelle loro controparti testuali e li invia a un endpoint HTTP specificato da `-http-url`.
I messaggi SOAP decodificati vengono inviati nel corpo della richiesta.
Il server HTTP dovrebbe restituire un involucro SOAP valido nello stesso formato dei messaggi in arrivo.
Questi messaggi vengono poi ritrasformati nel formato binario originale e inviati al server upstream.
Semplicemente riflettere il messaggio originale è sempre un'opzione valida per il server HTTP.
Tuttavia, la manipolazione programmatica dei messaggi può essere ottenuta anche fornendo un server HTTP personalizzato che esegua le sostituzioni desiderate.
Bisogna fare attenzione a non rompere la struttura dei messaggi SOAP.
Si consiglia di non manomettere il formato dei messaggi a meno che non si sappia cosa si sta facendo.
Inoltre, i suggerimenti di tipo inseriti da *wcfproxy* non dovrebbero essere manomessi, poiché ciò potrebbe rompere la trasformazione dei messaggi SOAP testuali nelle loro controparti binarie o l'analisi dei messaggi sull'endpoint legittimo (client o server).
*wcfproxy* include un semplice server HTTP che riflette semplicemente il corpo delle richieste HTTP ricevute.
Questo server verrà avviato quando viene fornita una [configurazione del server di controllo](#control-server-configuration) e l'opzione `enable-echo` è impostata su `true`.
L'URL del server HTTP desiderato viene fornito tramite l'opzione `server-url` nella [configurazione dell'intercettore http](#http-interceptor).
Per consentire la manipolazione interattiva, è possibile specificare un proxy HTTP (ad esempio BurpSuite) tramite l'opzione `proxy-url`.
I messaggi verranno quindi inviati al server HTTP tramite il proxy HTTP specificato.
Si noti che per ogni messaggio WCF (ad esempio client -> server), viene prodotta una coppia richiesta-risposta HTTP.
Per correlare i messaggi alla connessione net.tcp da cui hanno avuto origine, l'intestazione `X-Wcpf-Conn-Id` viene inserita nelle richieste generate dall'intercettore **http**.
L'immagine seguente illustra il flusso di dati con l'intercettore **http**.

## Opzioni TLS
WCF (su net.tcp) può utilizzare TLS per la sicurezza del trasporto.
*wcfproxy* supporta l'intercettazione delle connessioni TLS (solo TLS 1.0 - 1.3, nessun SSL).
Le impostazioni TLS lato server e lato client possono essere controllate con la corrispondente configurazione TLS (vedi [Configurazione server TLS](#tls-server-configuration) o [Configurazione client TLS](#tls-client-configuration)).
## Opzioni NTLM
*wcfproxy* supporta l'autenticazione NTLM.
Attualmente, è supportata l'autenticazione NTLM diretta o la negoziazione tramite SPNEGO.
È necessario fornire le credenziali degli utenti che si autenticheranno.
Queste credenziali sono fornite in formato JSON, vedi [Configurazione NTLM](#ntlm-configuration).
È supportato il passaggio di hash fornendo hash tramite la proprietà `nt-hash`.
## Iniezione di messaggi e creazione di connessioni
Quando il [server di controllo](#control-server-configuration) è abilitato, viene fornita una piccola API HTTP che può essere utilizzata per stabilire o terminare connessioni e iniettare messaggi in connessioni esistenti.
Sono disponibili i seguenti endpoint.
### GET `/connection`
Elenca le connessioni attualmente attive.
Per le connessioni solo server (create tramite [POST /connection/new](#post-connectionnew)), il client verrà mostrato come `wcfproxy`.
### POST `/connection/new`
Crea una nuova connessione.
Il corpo deve essere un oggetto JSON che specifica l'upgrade previsto (TLS o Negotiate (NTLM)), se presente.
L'URI dell'endpoint viene fornito tramite la proprietà `target-uri`.
#### Esempio: Nessun upgrade
Se non è richiesto alcun upgrade, la proprietà `upgrade` può essere omessa.```json
{
"target-uri":"net.tcp://127.0.0.1:9510/example/notes-nettcp"
}
Per avviare un aggiornamento TLS, specifica il meccanismo di aggiornamento tls.```json
{
"target-uri":"net.tcp://wcf-notes.local:9511/example/notes-nettcp-tls",
"upgrade": {
"mechanism":"tls"
}
}
#### Esempio: upgrade NTLM
L'oggetto `upgrade` deve specificare `ntlm` come meccanismo e l'utente con cui autenticarsi.
Le credenziali per l'utente devono essere fornite con la configurazione `ntlm`.```json
{
"target-uri":"net.tcp://localhost:8203/WCFLab/WCFDemoService/nettcp-winauth",
"upgrade": {
"mechanism": "ntlm",
"ntlmuser": "wcflab"
}
}
/connection/{id}/killDistrugge la connessione identificata da {id}.
/connection/{id}/injectInietta il messaggio fornito nel corpo di questa richiesta nella connessione identificata da {id}.
Il corpo deve essere nello stesso formato utilizzato per inoltrare i messaggi WCF agli intercettori HTTP.
Pertanto è consigliabile copiare un messaggio osservato, modificarlo secondo necessità e poi iniettarlo tramite questo endpoint.
Per impostazione predefinita, le risposte ai messaggi iniettati non vengono mostrate.
Tuttavia, se un intercettore è attivo, le risposte dovrebbero apparire lì.
Per comodità, quando il parametro di query retrieve=true viene fornito, wcfproxy attende la risposta al messaggio iniettato e la visualizza.
Viene imposto un limite superiore artificiale al numero di connessioni contemporaneamente attive.
Questo limite è attualmente impostato a 20.
Ciò serve a evitare un esaurimento accidentale delle risorse quando si utilizza (o si abusa) dell'API di controllo (vedi Iniezione di messaggi e stabilimento di connessioni).
Ciò dovrebbe raramente costituire un problema per i client WCF legittimi.
Tuttavia, potrebbero esserci casi d'uso che richiedono più connessioni contemporanee.
In tal caso, modificare la costante maxConnections in proxy.go come necessario.
I seguenti esempi mostrano alcuni usi di base di wcfproxy. L'output esatto può essere soggetto a modifiche, ma l'idea dovrebbe essere chiara.
Questo esempio mostra l'uso di wcfproxy nell'ambiente di test WCF per la comunicazione WCF semplice su net.tcp utilizzando l'intercettore log.```json { "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" } } }
Con la configurazione sopra (posizionata in `config.json`), possiamo usarla come mostrato di seguito.
Il traffico attraverso il proxy dovrebbe quindi essere riversato sulla console (`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):
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="c:1">ch:http://tempuri.org/IWCFDemoService/AddInts</a:Action>
<a:MessageID>uid:urn:uuid:b2d5fc85-4bcd-6442-b701-164655365198</a:MessageID>
<a:ReplyTo>
<a:Address>ch:http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="c:1">ch:net.tcp://127.0.0.1:8201/WCFLab/WCFDemoService/nettcp</a:To>
</s:Header>
<s:Body>
<AddInts xmlns="http://tempuri.org/">
<a>i:1234</a>
<b>i:37</b>
</AddInts>
</s:Body>
</s:Envelope>
INFO: [proxy] Envelope (Connection 0, Server -> Client):
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="c:1">ch:http://tempuri.org/IWCFDemoService/AddIntsResponse</a:Action>
<a:RelatesTo>uid:urn:uuid:b2d5fc85-4bcd-6442-b701-164655365198</a:RelatesTo>
<a:To s:mustUnderstand="c:1">ch:http://www.w3.org/2005/08/addressing/anonymous</a:To>
</s:Header>
<s:Body>
<AddIntsResponse xmlns="http://tempuri.org/">
<AddIntsResult>i:1271</AddIntsResult>
</AddIntsResponse>
</s:Body>
</s:Envelope>
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
La seguente configurazione utilizza l'http interceptor e in combinazione con un proxy HTTP.```json { "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" } } } }
Con questa configurazione, il log non mostra nulla di interessante.```
> 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
Tuttavia, il traffico WCF viene convertito in buste SOAP (quasi) regolari inviate via HTTP.

wcfproxy può essere configurato per intercettare il traffico WCF protetto da mTLS, a condizione che siano disponibili certificati server e client adatti. La configurazione per TLS senza autenticazione del client è simile; i certificati client non sono richiesti in questo caso. La seguente configurazione fornisce un esempio per questo caso d'uso:```json { "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 } }
Nota che i client devono fidarsi del certificato del server (`server.pem`).
Inoltre, il server deve fidarsi del certificato presentato dalla parte client di *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):
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="c:1">ch:http://tempuri.org/IWCFDemoService/AddInts</a:Action>
<a:MessageID>uid:urn:uuid:d36e17be-2cc2-a94f-83a7-cd2442dba24e</a:MessageID>
<a:ReplyTo>
<a:Address>ch:http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="c:1">ch:net.tcp://localhost:8203/WCFLab/WCFDemoService/nettcps-mtls</a:To>
</s:Header>
<s:Body>
<AddInts xmlns="http://tempuri.org/">
<a>i:1234</a>
<b>i:37</b>
</AddInts>
</s:Body>
</s:Envelope>
INFO: [proxy] Envelope (Connection 0, Server -> Client):
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="c:1">ch:http://tempuri.org/IWCFDemoService/AddIntsResponse</a:Action>
<a:RelatesTo>uid:urn:uuid:d36e17be-2cc2-a94f-83a7-cd2442dba24e</a:RelatesTo>
<a:To s:mustUnderstand="c:1">ch:http://www.w3.org/2005/08/addressing/anonymous</a:To>
</s:Header>
<s:Body>
<AddIntsResponse xmlns="http://tempuri.org/">
<AddIntsResult>i:1271</AddIntsResult>
</AddIntsResponse>
</s:Body>
</s:Envelope>
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
Supponendo che il servizio WCF si basi su NTLM per l'autenticazione (direttamente o tramite SPNEGO), la seguente configurazione può essere utilizzata per intercettare il traffico:```json { "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": "" } ] } } }
Si noti che attualmente è più robusto fornire il nome host tramite il campo `server` o `domain` piuttosto che affidarsi alla configurazione automatica.
Inoltre, l'autenticazione in un contesto di dominio AD non è stata testata e quindi è probabilmente non funzionante per il momento.
Quando viene utilizzato SPNEGO, attualmente il meccanismo NTLM deve essere quello preferito, altrimenti la negoziazione fallirà.```
> .\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):
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="c:1">ch:http://tempuri.org/IWCFDemoService/AddInts</a:Action>
<a:MessageID>uid:urn:uuid:f9cc5af3-3930-9242-be3c-d36d2a0cb09e</a:MessageID>
<a:ReplyTo>
<a:Address>ch:http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="c:1">ch:net.tcp://localhost:8204/WCFLab/WCFDemoService/nettcp-winauth</a:To>
</s:Header>
<s:Body>
<AddInts xmlns="http://tempuri.org/">
<a>i:1234</a>
<b>i:37</b>
</AddInts>
</s:Body>
</s:Envelope>
INFO: [proxy] Envelope (Connection 0, Server -> Client):
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="c:1">ch:http://tempuri.org/IWCFDemoService/AddIntsResponse</a:Action>
<a:RelatesTo>uid:urn:uuid:f9cc5af3-3930-9242-be3c-d36d2a0cb09e</a:RelatesTo>
<a:To s:mustUnderstand="c:1">ch:http://www.w3.org/2005/08/addressing/anonymous</a:To>
</s:Header>
<s:Body>
<AddIntsResponse xmlns="http://tempuri.org/">
<AddIntsResult>i:1271</AddIntsResult>
</AddIntsResponse>
</s:Body>
</s:Envelope>
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
retargetlog-level - livello di log; valori disponibili: debug, info (default), warn, errorlog-file - percorso del file di log; se non viene fornito un percorso, il log viene scritto su stdouttls-server - istanza di TlsServerConfig (vedi Configurazione del server TLS); richiesto solo se è supportato l'upgrade TLStls-client - istanza di TlsClientConfig (vedi Configurazione del client TLS); rilevante solo se è supportato l'upgrade TLSntlm - istanza di NtlmConfig (vedi Configurazione NTLM); richiesto solo se è supportato l'upgrade NTLM (direttamente o tramite SPNEGO)interceptor - istanza di InterceptorConfig (vedi Configurazione dell'interceptor); richiestoctrl - istanza di ControlServerConfig (vedi Configurazione del server di controllo) che può fornire un server echo HTTP predefinito (utile insieme all'interceptor HTTP) oltre a una piccola API per controllare il flusso dei messaggi (ancora in sviluppo)