1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
package dce
import (
"context"
"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/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
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) {
dceOpts := append(opts, cfg.DceOptions...)
epmOpts := append(opts, cfg.EpmOptions...)
log := zerolog.Ctx(ctx).With().
Str("client", "DCERPC").Logger()
// Mandatory logging
dceOpts = append(dceOpts, dcerpc.WithLogger(log))
epmOpts = append(epmOpts, dcerpc.WithLogger(log))
ctx = gssapi.NewSecurityContext(ctx)
ao, err := dcerpcauth.AuthenticationOptions(ctx, creds, 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()))
}
if !cfg.NoEpm {
dceOpts = append(dceOpts,
epm.EndpointMapper(ctx, target.AddressWithoutPort(), append(epmOpts, ao...)...))
}
return dcerpc.Dial(ctx, target.AddressWithoutPort(), append(dceOpts, ao...)...)
}
|