Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion pkg/transport/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ func DialTLS(network, address string, config *tls.Config) (*tls.Conn, error) {
}

// Dialer is a value-typed dialer suitable for APIs that expect a struct with a
// Dial method (e.g. pkg/smb, pkg/ldap). Respects the configured proxy.
// Dial or DialContext method (e.g. pkg/smb, pkg/ldap, go-msrpc/dcerpc).
// Respects the configured proxy.
type Dialer struct {
TimeoutSec int
}
Expand All @@ -81,6 +82,13 @@ func (d *Dialer) Dial(network, address string) (net.Conn, error) {
return DialTimeout(network, address, d.TimeoutSec)
}

// DialContext establishes a TCP connection, honoring ctx for cancellation and
// deadline. Routes through the proxy if configured. Satisfies the
// go-msrpc/dcerpc.Dialer interface.
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
return DialContext(ctx, network, address)
}

func splitHostPort(address string) (host, port string, err error) {
host, port, err = net.SplitHostPort(address)
if err != nil {
Expand Down
10 changes: 8 additions & 2 deletions tools/dcomexec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import (
"github.com/mandiant/gopacket/pkg/kerberos"
"github.com/mandiant/gopacket/pkg/session"
"github.com/mandiant/gopacket/pkg/smb"
"github.com/mandiant/gopacket/pkg/transport"
)

// IDispatch invoke flags
Expand Down Expand Up @@ -330,8 +331,13 @@ func (e *DCOMExec) connect() error {
host = e.creds.DCIP
}

// Route DCE/RPC TCP connects through gopacket's transport so -proxy /
// proxychains take effect. Without this, upstream falls back to net.Dialer
// which bypasses both the SOCKS5 dialer and the libc connect() hook.
dialer := dcerpc.WithDialer(&transport.Dialer{})

// Connect to endpoint mapper (port 135)
conn, err := dcerpc.Dial(e.ctx, net.JoinHostPort(host, "135"))
conn, err := dcerpc.Dial(e.ctx, net.JoinHostPort(host, "135"), dialer)
if err != nil {
return fmt.Errorf("failed to connect to endpoint mapper: %v", err)
}
Expand Down Expand Up @@ -400,7 +406,7 @@ func (e *DCOMExec) connect() error {
}

// Connect to the OXID endpoint
oxidConn, err := dcerpc.Dial(e.ctx, host, endpoints...)
oxidConn, err := dcerpc.Dial(e.ctx, host, append([]dcerpc.Option{dialer}, endpoints...)...)
if err != nil {
return fmt.Errorf("failed to connect to OXID endpoint: %v", err)
}
Expand Down
23 changes: 15 additions & 8 deletions tools/wmiexec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import (
"github.com/mandiant/gopacket/pkg/kerberos"
"github.com/mandiant/gopacket/pkg/session"
"github.com/mandiant/gopacket/pkg/smb"
"github.com/mandiant/gopacket/pkg/transport"
)

var (
Expand Down Expand Up @@ -193,9 +194,14 @@ func main() {

ctx := gssapi.NewSecurityContext(context.Background())

// Route DCE/RPC TCP connects through gopacket's transport so -proxy /
// proxychains take effect. Without this, upstream falls back to net.Dialer
// which bypasses both the SOCKS5 dialer and the libc connect() hook.
dialer := dcerpc.WithDialer(&transport.Dialer{})

// 1. Connect to Endpoint Mapper (Port 135)
log.Info().Msgf("Connecting to %s:135", target.Host)
cc, err := dcerpc.Dial(ctx, net.JoinHostPort(target.Host, "135"))
cc, err := dcerpc.Dial(ctx, net.JoinHostPort(target.Host, "135"), dialer)
if err != nil {
fmt.Fprintf(os.Stderr, "[-] Dial 135 failed: %v\n", err)
os.Exit(1)
Expand Down Expand Up @@ -249,7 +255,7 @@ func main() {
os.Exit(1)
}

wcc, err := dcerpc.Dial(ctx, target.Host, endpoints...)
wcc, err := dcerpc.Dial(ctx, target.Host, append([]dcerpc.Option{dialer}, endpoints...)...)
if err != nil {
fmt.Fprintf(os.Stderr, "[-] Dial WMI failed: %v\n", err)
os.Exit(1)
Expand Down Expand Up @@ -510,15 +516,16 @@ func (e *WMIExec) retrieveOutput(filename string) (string, error) {
content, err := smbClient.Cat(filename)
if err == nil {
// Delete the output file
smbClient.Rm(filename)
if err := smbClient.Rm(filename); err != nil {
// If sharing violation, command is still running
if strings.Contains(err.Error(), "share access flags are incompatible") {
e.log.Debug().Msg("Output file in use, waiting...")
continue
}
}
return content, nil
}

// If sharing violation, command is still running
if strings.Contains(err.Error(), "STATUS_SHARING_VIOLATION") {
e.log.Debug().Msg("Output file in use, waiting...")
continue
}

// If file not found, keep waiting
if strings.Contains(err.Error(), "STATUS_OBJECT_NAME_NOT_FOUND") {
Expand Down
10 changes: 8 additions & 2 deletions tools/wmipersist/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import (
"github.com/mandiant/gopacket/pkg/flags"
"github.com/mandiant/gopacket/pkg/kerberos"
"github.com/mandiant/gopacket/pkg/session"
"github.com/mandiant/gopacket/pkg/transport"
)

var (
Expand Down Expand Up @@ -289,9 +290,14 @@ func main() {
connectAddr = target.IP
}

// Route DCE/RPC TCP connects through gopacket's transport so -proxy /
// proxychains take effect. Without this, upstream falls back to net.Dialer
// which bypasses both the SOCKS5 dialer and the libc connect() hook.
dialer := dcerpc.WithDialer(&transport.Dialer{})

// 1. Connect to Endpoint Mapper (Port 135)
log.Info().Msgf("Connecting to %s:135", connectAddr)
cc, err := dcerpc.Dial(ctx, net.JoinHostPort(connectAddr, "135"))
cc, err := dcerpc.Dial(ctx, net.JoinHostPort(connectAddr, "135"), dialer)
if err != nil {
fmt.Fprintf(os.Stderr, "[-] Dial 135 failed: %v\n", err)
os.Exit(1)
Expand Down Expand Up @@ -350,7 +356,7 @@ func main() {
os.Exit(1)
}

wcc, err := dcerpc.Dial(ctx, connectAddr, endpoints...)
wcc, err := dcerpc.Dial(ctx, connectAddr, append([]dcerpc.Option{dialer}, endpoints...)...)
if err != nil {
fmt.Fprintf(os.Stderr, "[-] Dial WMI failed: %v\n", err)
os.Exit(1)
Expand Down
10 changes: 8 additions & 2 deletions tools/wmiquery/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import (
"github.com/mandiant/gopacket/pkg/flags"
"github.com/mandiant/gopacket/pkg/kerberos"
"github.com/mandiant/gopacket/pkg/session"
"github.com/mandiant/gopacket/pkg/transport"
)

// WBEM flags
Expand Down Expand Up @@ -204,9 +205,14 @@ func main() {

ctx := gssapi.NewSecurityContext(context.Background())

// Route DCE/RPC TCP connects through gopacket's transport so -proxy /
// proxychains take effect. Without this, upstream falls back to net.Dialer
// which bypasses both the SOCKS5 dialer and the libc connect() hook.
dialer := dcerpc.WithDialer(&transport.Dialer{})

// 1. Connect to Endpoint Mapper (Port 135)
log.Info().Msgf("Connecting to %s:135", target.Host)
cc, err := dcerpc.Dial(ctx, net.JoinHostPort(target.Host, "135"))
cc, err := dcerpc.Dial(ctx, net.JoinHostPort(target.Host, "135"), dialer)
if err != nil {
fmt.Fprintf(os.Stderr, "[-] Dial 135 failed: %v\n", err)
os.Exit(1)
Expand Down Expand Up @@ -265,7 +271,7 @@ func main() {
os.Exit(1)
}

wcc, err := dcerpc.Dial(ctx, target.Host, endpoints...)
wcc, err := dcerpc.Dial(ctx, target.Host, append([]dcerpc.Option{dialer}, endpoints...)...)
if err != nil {
fmt.Fprintf(os.Stderr, "[-] Dial WMI failed: %v\n", err)
os.Exit(1)
Expand Down