diff options
Diffstat (limited to 'internal/client/dce/dce.go')
-rw-r--r-- | internal/client/dce/dce.go | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/internal/client/dce/dce.go b/internal/client/dce/dce.go index 1ddec65..f58123b 100644 --- a/internal/client/dce/dce.go +++ b/internal/client/dce/dce.go @@ -2,30 +2,29 @@ package dce import ( "context" + "errors" "fmt" "github.com/RedTeamPentesting/adauth" "github.com/RedTeamPentesting/adauth/dcerpcauth" "github.com/oiweiwei/go-msrpc/dcerpc" + "github.com/oiweiwei/go-msrpc/midl/uuid" "github.com/oiweiwei/go-msrpc/msrpc/epm/epm/v3" "github.com/oiweiwei/go-msrpc/ssp/gssapi" "github.com/rs/zerolog" ) -var ( - NP = "ncacn_np" - TCP = "ncacn_ip_tcp" - HTTP = "ncacn_http" -) - type ConnectionMethodDCEConfig struct { - NoEpm bool // NoEpm disables EPM - EpmAuto bool // EpmAuto will find any suitable endpoint, without any filter - Endpoint *dcerpc.StringBinding // Endpoint is the endpoint passed to dcerpc.WithEndpoint. ignored if EpmAuto is false + NoEpm bool // NoEpm disables EPM + EpmAuto bool // EpmAuto will find any suitable endpoint, without any filter + Insecure bool + NoSign bool + Endpoint *dcerpc.StringBinding // Endpoint is the explicit endpoint passed to dcerpc.WithEndpoint for use without EPM + EpmFilter *dcerpc.StringBinding // EpmFilter is the rough filter used to pick an EPM endpoint DceOptions []dcerpc.Option // DceOptions are the options passed to dcerpc.Dial EpmOptions []dcerpc.Option // EpmOptions are the options passed to epm.EndpointMapper } -func (cfg *ConnectionMethodDCEConfig) GetDce(ctx context.Context, creds *adauth.Credential, target *adauth.Target, opts ...dcerpc.Option) (cc dcerpc.Conn, err error) { +func (cfg *ConnectionMethodDCEConfig) GetDce(ctx context.Context, cred *adauth.Credential, target *adauth.Target, endpoint, object string, opts ...dcerpc.Option) (cc dcerpc.Conn, err error) { dceOpts := append(opts, cfg.DceOptions...) epmOpts := append(opts, cfg.EpmOptions...) @@ -37,17 +36,41 @@ func (cfg *ConnectionMethodDCEConfig) GetDce(ctx context.Context, creds *adauth. epmOpts = append(epmOpts, dcerpc.WithLogger(log)) ctx = gssapi.NewSecurityContext(ctx) - ao, err := dcerpcauth.AuthenticationOptions(ctx, creds, target, &dcerpcauth.Options{}) + auth, err := dcerpcauth.AuthenticationOptions(ctx, cred, target, &dcerpcauth.Options{}) if err != nil { log.Error().Err(err).Msg("Failed to parse authentication options") return nil, fmt.Errorf("parse auth options: %w", err) } - if cfg.Endpoint != nil && !cfg.EpmAuto { - dceOpts = append(dceOpts, dcerpc.WithEndpoint(cfg.Endpoint.String())) + addr := target.AddressWithoutPort() + log = log.With().Str("address", addr).Logger() + + if object != "" { + if id, err := uuid.Parse(object); err != nil { + log.Error().Err(err).Msg("Failed to parse input object UUID") + } else { + dceOpts = append(dceOpts, dcerpc.WithObjectUUID(id)) + } } - if !cfg.NoEpm { - dceOpts = append(dceOpts, - epm.EndpointMapper(ctx, target.AddressWithoutPort(), append(epmOpts, ao...)...)) + if cfg.Endpoint != nil { + dceOpts = append(dceOpts, dcerpc.WithEndpoint(cfg.Endpoint.String())) + log.Debug().Str("binding", cfg.Endpoint.String()).Msg("Using endpoint") + + } else if !cfg.NoEpm { + dceOpts = append(dceOpts, epm.EndpointMapper(ctx, addr, append(epmOpts, auth...)...)) + log.Debug().Msg("Using endpoint mapper") + + if cfg.EpmFilter != nil { + dceOpts = append(dceOpts, dcerpc.WithEndpoint(cfg.EpmFilter.String())) + log.Debug().Str("filter", cfg.EpmFilter.String()).Msg("Using endpoint filter") + } + } else if endpoint != "" { + dceOpts = append(dceOpts, dcerpc.WithEndpoint(endpoint)) + log.Debug().Str("endpoint", endpoint).Msg("Using default endpoint") + + } else { + log.Err(err).Msg("Invalid DCE connection options") + return nil, errors.New("get DCE: invalid connection options") } - return dcerpc.Dial(ctx, target.AddressWithoutPort(), append(dceOpts, ao...)...) + + return dcerpc.Dial(ctx, target.AddressWithoutPort(), append(dceOpts, auth...)...) } |