diff options
author | Bryan McNulty <bryanmcnulty@protonmail.com> | 2025-03-04 03:05:53 -0600 |
---|---|---|
committer | Bryan McNulty <bryanmcnulty@protonmail.com> | 2025-03-04 03:05:53 -0600 |
commit | a5c860b8ab24c198b7390fbde90044754e35c1c5 (patch) | |
tree | 3118b27b5c76cab44bb61d83df750a9f00b4be00 /internal/client | |
parent | 5a3bf6315aab33e6488734a579977836042b4aa1 (diff) | |
parent | f98989334bbe227bbe9dc4c84a2d0e34aa2fb86f (diff) | |
download | goexec-a5c860b8ab24c198b7390fbde90044754e35c1c5.tar.gz goexec-a5c860b8ab24c198b7390fbde90044754e35c1c5.zip |
Simple fixes
Diffstat (limited to 'internal/client')
-rw-r--r-- | internal/client/dcerpc/client.go | 11 | ||||
-rw-r--r-- | internal/client/dcerpc/dcerpc.go | 106 | ||||
-rw-r--r-- | internal/client/dcerpc/smb.go | 13 |
3 files changed, 130 insertions, 0 deletions
diff --git a/internal/client/dcerpc/client.go b/internal/client/dcerpc/client.go new file mode 100644 index 0000000..d9d8d71 --- /dev/null +++ b/internal/client/dcerpc/client.go @@ -0,0 +1,11 @@ +package dcerpc + +import ( + "context" + "github.com/RedTeamPentesting/adauth" +) + +type Client interface { + Connect(ctx context.Context, creds *adauth.Credential, target *adauth.Target) error + Close(ctx context.Context) error +} diff --git a/internal/client/dcerpc/dcerpc.go b/internal/client/dcerpc/dcerpc.go new file mode 100644 index 0000000..5c9a734 --- /dev/null +++ b/internal/client/dcerpc/dcerpc.go @@ -0,0 +1,106 @@ +package dcerpc + +import ( + "context" + "errors" + "fmt" + "github.com/RedTeamPentesting/adauth" + "github.com/RedTeamPentesting/adauth/dcerpcauth" + "github.com/oiweiwei/go-msrpc/dcerpc" + "github.com/oiweiwei/go-msrpc/msrpc/epm/epm/v3" + "github.com/oiweiwei/go-msrpc/msrpc/scmr/svcctl/v2" + "github.com/oiweiwei/go-msrpc/smb2" + "github.com/oiweiwei/go-msrpc/ssp/gssapi" + "github.com/rs/zerolog" +) + +const ( + DceDefaultProto string = "ncacn_np" + DceDefaultPort uint16 = 445 +) + +type DCEClient struct { + Port uint16 + Proto string + + log zerolog.Logger + conn dcerpc.Conn + opts []dcerpc.Option + authOpts dcerpcauth.Options +} + +func NewDCEClient(ctx context.Context, insecure bool, smbConfig *SmbConfig) (client *DCEClient) { + client = &DCEClient{ + Port: DceDefaultPort, + Proto: DceDefaultProto, + log: zerolog.Ctx(ctx).With().Str("client", "DCE").Logger(), + authOpts: dcerpcauth.Options{}, + } + client.opts = []dcerpc.Option{dcerpc.WithLogger(client.log)} + client.authOpts = dcerpcauth.Options{Debug: client.log.Trace().Msgf} + + if smbConfig != nil { + if smbConfig.Port != 0 { + client.Port = smbConfig.Port + client.opts = append(client.opts, dcerpc.WithSMBPort(int(smbConfig.Port))) + } + } + if insecure { + client.log.Debug().Msg("Using insecure DCERPC connection") + client.opts = append(client.opts, dcerpc.WithInsecure()) + } else { + client.log.Debug().Msg("Using secure DCERPC connection") + client.authOpts.SMBOptions = append(client.authOpts.SMBOptions, smb2.WithSeal()) + } + return +} + +func (client *DCEClient) OpenSvcctl(ctx context.Context) (ctl svcctl.SvcctlClient, err error) { + if client.conn == nil { + return nil, errors.New("DCE connection not open") + } + if ctl, err = svcctl.NewSvcctlClient(ctx, client.conn, dcerpc.WithInsecure()); err != nil { + client.log.Debug().Err(err).Msg("Failed to open Svcctl client") + } + return +} + +func (client *DCEClient) DCE() dcerpc.Conn { + return client.conn +} + +func (client *DCEClient) Connect(ctx context.Context, creds *adauth.Credential, target *adauth.Target, dialOpts ...dcerpc.Option) (err error) { + if creds != nil && target != nil { + authCtx := gssapi.NewSecurityContext(ctx) + + binding := fmt.Sprintf(`%s:%s`, client.Proto, target.AddressWithoutPort()) + mapper := epm.EndpointMapper(ctx, fmt.Sprintf("%s:%d", target.AddressWithoutPort(), client.Port), dcerpc.WithLogger(client.log)) + dceOpts := []dcerpc.Option{dcerpc.WithLogger(client.log), dcerpc.WithSeal()} + + if dceOpts, err = dcerpcauth.AuthenticationOptions(authCtx, creds, target, &client.authOpts); err == nil { + dceOpts = append(dceOpts, mapper) + dceOpts = append(dceOpts, client.opts...) + dceOpts = append(dceOpts, dialOpts...) + + if client.conn, err = dcerpc.Dial(authCtx, binding, dceOpts...); err == nil { + client.log.Debug().Msg("Bind successful") + return nil + } + client.log.Debug().Err(err).Msg("DCERPC bind failed") + return errors.New("bind failed") + } + return errors.New("unable to parse DCE authentication options") + } + return errors.New("invalid arguments") +} + +func (client *DCEClient) Close(ctx context.Context) (err error) { + if client.conn == nil { + client.log.Debug().Msg("Connection already closed") + } else if err = client.conn.Close(ctx); err == nil { + client.log.Debug().Msg("Connection closed successfully") + } else { + client.log.Error().Err(err).Msg("Failed to close connection") + } + return +} diff --git a/internal/client/dcerpc/smb.go b/internal/client/dcerpc/smb.go new file mode 100644 index 0000000..cab82eb --- /dev/null +++ b/internal/client/dcerpc/smb.go @@ -0,0 +1,13 @@ +package dcerpc + +import "github.com/oiweiwei/go-msrpc/smb2" + +const ( + SmbDefaultPort = 445 +) + +type SmbConfig struct { + Port uint16 + FullSecurity bool + ForceDialect smb2.Dialect +} |