mirror of
https://github.com/jfjallid/go-smb
synced 2026-06-08 15:02:50 +00:00
cb9f559549
Add the relay/ package: listen for inbound SMB or HTTP NTLM authentications, forward them to one or more upstream targets (SMB, HTTP/S, LDAP/S), pool the resulting authenticated sessions, and optionally expose the pool to local tools through a SOCKS5 proxy. Provides RelayServer (long-running multi-target listener with a session pool, post-auth actions and optional fake-server handoff) and RelayClient (one-shot listener returning a single authenticated *smb.Connection), replacing the retired in-package smb.NewRelayConnection. Add the smb.Connection hooks the relay drives: MarkAuthenticated promotes a manually-driven SessionSetup to authenticated state, and SendRawPDU forwards an opaque SMB2 PDU on a pooled connection (re-stamping MessageID and applying signing/encryption).
79 lines
2.1 KiB
Go
79 lines
2.1 KiB
Go
// MIT License
|
|
//
|
|
// Copyright (c) 2026 Jimmy Fjällid
|
|
|
|
package relay_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jfjallid/go-smb/relay"
|
|
"github.com/jfjallid/go-smb/smb"
|
|
)
|
|
|
|
// ExampleRelayServer shows the minimum configuration: one SMB target, an
|
|
// SMB inbound listener on the default port, and an OnCapture hook that
|
|
// receives one finalized record per inbound auth — no separate
|
|
// OnCredentialCaptured/OnRelaySuccess correlation needed.
|
|
//
|
|
// Bind to ":0" (or pass -listen) for tests/labs to avoid the privileged
|
|
// port :445.
|
|
func ExampleRelayServer() {
|
|
rs := &relay.RelayServer{
|
|
Config: relay.ServerConfig{
|
|
Targets: []string{"smb://10.0.0.5"},
|
|
ListenAddr: ":0",
|
|
OnCapture: func(c relay.CapturedAuth) {
|
|
fmt.Printf("captured %s\\%s status=%s\n", c.Domain, c.Username, c.Status)
|
|
},
|
|
},
|
|
}
|
|
if err := rs.Start(); err != nil {
|
|
// In a real program: handle the error; we just exit the example.
|
|
return
|
|
}
|
|
defer func() {
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
defer cancel()
|
|
_ = rs.Shutdown(ctx)
|
|
}()
|
|
|
|
// In a real workflow you'd block here (signal handler, REPL) while
|
|
// captures stream in. Example exits immediately.
|
|
}
|
|
|
|
// ExampleRelayServer_socks demonstrates exposing the captured pool through
|
|
// a local SOCKS5 proxy. Tools that dial through 127.0.0.1:1080 piggyback
|
|
// the corresponding pooled SMB/HTTP/LDAP session.
|
|
func ExampleRelayServer_socks() {
|
|
rs := &relay.RelayServer{
|
|
Config: relay.ServerConfig{
|
|
Targets: []string{"smb://dc01"},
|
|
ListenAddr: ":0",
|
|
SocksAddr: "127.0.0.1:0",
|
|
},
|
|
}
|
|
_ = rs.Start
|
|
_ = rs.Shutdown
|
|
}
|
|
|
|
// ExampleRelayServer_postAuth runs an EnumShares action against each
|
|
// upstream session immediately after a successful relay.
|
|
func ExampleRelayServer_postAuth() {
|
|
rs := &relay.RelayServer{
|
|
Config: relay.ServerConfig{
|
|
Targets: []string{"smb://dc01"},
|
|
ListenAddr: ":0",
|
|
PostAuthActions: []relay.PostAuthAction{
|
|
relay.EnumSharesAction{},
|
|
},
|
|
OnRelaySuccess: func(target string, _ *smb.Connection, cred *relay.Credential) {
|
|
fmt.Println("relayed to", target, "as", cred.Username)
|
|
},
|
|
},
|
|
}
|
|
_ = rs
|
|
}
|