mirror of
https://github.com/FalconOpsLLC/goexec
synced 2026-06-06 15:44:27 +00:00
Fixed proxy w/ EPM, fixed TSCH with ncacn_np
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
## Bug Fixes
|
||||
|
||||
- [X] Fix SMB transport for SCMR module - `rpc_s_cannot_support: The requested operation is not supported.`
|
||||
- [ ] Fix proxy - EPM, SMB don't use the proxy dialer
|
||||
- [X] Fix proxy - EPM doesn't use the proxy dialer
|
||||
- [ ] Fix SCMR `change` method so that dependencies field isn't permanently overwritten
|
||||
|
||||
## Lower Priority
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ func registerExecutionFlags(fs *pflag.FlagSet) {
|
||||
func registerExecutionOutputFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVarP(&outputPath, "out", "o", "", `Fetch execution output to file or "-" for standard output`)
|
||||
fs.StringVarP(&outputMethod, "out-method", "m", "smb", "Method to fetch execution output")
|
||||
fs.StringVar(&exec.Output.RemotePath, "out-remote", "", "Location to temporarily store output on remote filesystem")
|
||||
//fs.StringVar(&exec.Output.RemotePath, "out-remote", "", "Location to temporarily store output on remote filesystem")
|
||||
fs.BoolVar(&exec.Output.NoDelete, "no-delete-out", false, "Preserve output file on remote filesystem")
|
||||
}
|
||||
|
||||
|
||||
+67
-64
@@ -1,107 +1,110 @@
|
||||
package dce
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/RedTeamPentesting/adauth/smbauth"
|
||||
"github.com/oiweiwei/go-msrpc/dcerpc"
|
||||
"github.com/oiweiwei/go-msrpc/msrpc/epm/epm/v3"
|
||||
msrpcSMB2 "github.com/oiweiwei/go-msrpc/smb2"
|
||||
"github.com/rs/zerolog"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/RedTeamPentesting/adauth/smbauth"
|
||||
"github.com/oiweiwei/go-msrpc/dcerpc"
|
||||
"github.com/oiweiwei/go-msrpc/msrpc/epm/epm/v3"
|
||||
msrpcSMB2 "github.com/oiweiwei/go-msrpc/smb2"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
Options
|
||||
Options
|
||||
|
||||
conn dcerpc.Conn
|
||||
hostname string
|
||||
conn dcerpc.Conn
|
||||
hostname string
|
||||
}
|
||||
|
||||
func (c *Client) String() string {
|
||||
return ClientName
|
||||
return ClientName
|
||||
}
|
||||
|
||||
func (c *Client) Reconnect(ctx context.Context, opts ...dcerpc.Option) (err error) {
|
||||
c.DcerpcOptions = append(c.DcerpcOptions, opts...)
|
||||
c.DcerpcOptions = append(c.DcerpcOptions, opts...)
|
||||
|
||||
return c.Connect(ctx)
|
||||
return c.Connect(ctx)
|
||||
}
|
||||
|
||||
func (c *Client) Dce() (dce dcerpc.Conn) {
|
||||
return c.conn
|
||||
return c.conn
|
||||
}
|
||||
|
||||
func (c *Client) Logger(ctx context.Context) (log zerolog.Logger) {
|
||||
return zerolog.Ctx(ctx).With().
|
||||
Str("client", c.String()).Logger()
|
||||
return zerolog.Ctx(ctx).With().
|
||||
Str("client", c.String()).Logger()
|
||||
}
|
||||
|
||||
func (c *Client) Connect(ctx context.Context) (err error) {
|
||||
|
||||
log := c.Logger(ctx)
|
||||
ctx = log.WithContext(ctx)
|
||||
log := c.Logger(ctx)
|
||||
ctx = log.WithContext(ctx)
|
||||
|
||||
var do, eo []dcerpc.Option
|
||||
var do, eo []dcerpc.Option
|
||||
|
||||
do = append(do, c.DcerpcOptions...)
|
||||
do = append(do, c.authOptions...)
|
||||
do = append(do, c.DcerpcOptions...)
|
||||
do = append(do, c.authOptions...)
|
||||
|
||||
if c.Smb {
|
||||
c.DcerpcOptions = append(c.DcerpcOptions, dcerpc.WithInsecure())
|
||||
do = append(do, dcerpc.WithSeal())
|
||||
|
||||
var so []msrpcSMB2.DialerOption
|
||||
if c.Smb {
|
||||
var so []msrpcSMB2.DialerOption
|
||||
|
||||
if !c.NoSign {
|
||||
so = append(so, msrpcSMB2.WithSign())
|
||||
}
|
||||
if !c.NoSeal {
|
||||
so = append(so, msrpcSMB2.WithSeal())
|
||||
}
|
||||
if !c.NoSign {
|
||||
so = append(so, msrpcSMB2.WithSign())
|
||||
eo = append(eo, dcerpc.WithSign())
|
||||
}
|
||||
if !c.NoSeal {
|
||||
so = append(so, msrpcSMB2.WithSeal())
|
||||
eo = append(eo, dcerpc.WithSeal())
|
||||
}
|
||||
|
||||
if smbDialer, err := smbauth.Dialer(ctx, c.Credential, c.Target, &smbauth.Options{SMBOptions: so}); err != nil {
|
||||
return fmt.Errorf("parse smb auth: %w", err)
|
||||
if smbDialer, err := smbauth.Dialer(ctx, c.Credential, c.Target, &smbauth.Options{SMBOptions: so}); err != nil {
|
||||
return fmt.Errorf("parse smb auth: %w", err)
|
||||
|
||||
} else {
|
||||
do = append(do, dcerpc.WithSMBDialer(smbDialer))
|
||||
}
|
||||
} else {
|
||||
if !c.NoSign {
|
||||
do = append(do, dcerpc.WithSign())
|
||||
eo = append(eo, dcerpc.WithSign())
|
||||
}
|
||||
if !c.NoSeal {
|
||||
do = append(do, dcerpc.WithSeal(), dcerpc.WithSecurityLevel(dcerpc.AuthLevelPktPrivacy))
|
||||
eo = append(eo, dcerpc.WithSeal(), dcerpc.WithSecurityLevel(dcerpc.AuthLevelPktPrivacy))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
do = append(do, dcerpc.WithSMBDialer(smbDialer))
|
||||
}
|
||||
} else {
|
||||
|
||||
if !c.NoLog {
|
||||
do = append(do, dcerpc.WithLogger(log))
|
||||
eo = append(eo, dcerpc.WithLogger(log))
|
||||
}
|
||||
if !c.NoSign {
|
||||
do = append(do, dcerpc.WithSign())
|
||||
eo = append(eo, dcerpc.WithSign())
|
||||
}
|
||||
if !c.NoSeal {
|
||||
do = append(do, dcerpc.WithSeal())
|
||||
eo = append(eo, dcerpc.WithSeal())
|
||||
}
|
||||
}
|
||||
|
||||
if !c.NoEpm {
|
||||
log.Debug().Msg("Using endpoint mapper")
|
||||
if !c.NoLog {
|
||||
do = append(do, dcerpc.WithLogger(log))
|
||||
eo = append(eo, dcerpc.WithLogger(log))
|
||||
}
|
||||
|
||||
eo = append(eo, c.epmOptions...)
|
||||
eo = append(eo, c.authOptions...)
|
||||
if !c.NoEpm {
|
||||
log.Debug().Msg("Using endpoint mapper")
|
||||
|
||||
do = append(do, epm.EndpointMapper(ctx, c.Host, eo...))
|
||||
}
|
||||
eo = append(eo, c.EpmOptions...)
|
||||
eo = append(eo, c.authOptions...)
|
||||
|
||||
for _, e := range c.stringBindings {
|
||||
do = append(do, dcerpc.WithEndpoint(e.String()))
|
||||
}
|
||||
do = append(do, epm.EndpointMapper(ctx, c.Host, eo...))
|
||||
}
|
||||
|
||||
if c.conn, err = dcerpc.Dial(ctx, c.Host, do...); err != nil {
|
||||
for _, e := range c.stringBindings {
|
||||
do = append(do, dcerpc.WithEndpoint(e.String()))
|
||||
}
|
||||
|
||||
log.Error().Err(err).Msgf("Failed to connect to %s endpoint", c.String())
|
||||
return fmt.Errorf("dial %s: %w", c.String(), err)
|
||||
}
|
||||
if c.conn, err = dcerpc.Dial(ctx, c.Host, do...); err != nil {
|
||||
|
||||
return
|
||||
log.Error().Err(err).Msgf("Failed to connect to %s endpoint", c.String())
|
||||
return fmt.Errorf("dial %s: %w", c.String(), err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) Close(ctx context.Context) (err error) {
|
||||
return c.conn.Close(ctx)
|
||||
return c.conn.Close(ctx)
|
||||
}
|
||||
|
||||
+87
-92
@@ -1,118 +1,113 @@
|
||||
package dce
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/FalconOpsLLC/goexec/pkg/goexec"
|
||||
"github.com/RedTeamPentesting/adauth/dcerpcauth"
|
||||
"github.com/oiweiwei/go-msrpc/dcerpc"
|
||||
"net"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/FalconOpsLLC/goexec/pkg/goexec"
|
||||
"github.com/RedTeamPentesting/adauth/dcerpcauth"
|
||||
"github.com/oiweiwei/go-msrpc/dcerpc"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
goexec.ClientOptions
|
||||
goexec.AuthOptions
|
||||
goexec.ClientOptions
|
||||
goexec.AuthOptions
|
||||
|
||||
// NoSign disables packet signing by omitting dcerpc.WithSign()
|
||||
NoSign bool `json:"no_sign" yaml:"no_sign"`
|
||||
// NoSign disables packet signing by omitting dcerpc.WithSign()
|
||||
NoSign bool `json:"no_sign" yaml:"no_sign"`
|
||||
|
||||
// NoSeal disables packet stub encryption by omitting dcerpc.WithSeal()
|
||||
NoSeal bool `json:"no_seal" yaml:"no_seal"`
|
||||
// NoSeal disables packet stub encryption by omitting dcerpc.WithSeal()
|
||||
NoSeal bool `json:"no_seal" yaml:"no_seal"`
|
||||
|
||||
// NoLog disables logging by omitting dcerpc.WithLogger(...)
|
||||
NoLog bool `json:"no_log" yaml:"no_log"`
|
||||
// NoLog disables logging by omitting dcerpc.WithLogger(...)
|
||||
NoLog bool `json:"no_log" yaml:"no_log"`
|
||||
|
||||
// NoEpm disables DCE endpoint mapper communications
|
||||
NoEpm bool `json:"no_epm" yaml:"no_epm"`
|
||||
// NoEpm disables DCE endpoint mapper communications
|
||||
NoEpm bool `json:"no_epm" yaml:"no_epm"`
|
||||
|
||||
// Endpoint stores the explicit DCE string binding to use
|
||||
Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"`
|
||||
// Endpoint stores the explicit DCE string binding to use
|
||||
Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"`
|
||||
|
||||
// Filter stores the filter for returned endpoints from an endpoint mapper
|
||||
Filter string `json:"filter,omitempty" yaml:"filter,omitempty"`
|
||||
// Filter stores the filter for returned endpoints from an endpoint mapper
|
||||
Filter string `json:"filter,omitempty" yaml:"filter,omitempty"`
|
||||
|
||||
// Smb enables SMB transport for DCE/RPC
|
||||
Smb bool `json:"use_smb" yaml:"use_smb"`
|
||||
// Smb enables SMB transport for DCE/RPC
|
||||
Smb bool `json:"use_smb" yaml:"use_smb"`
|
||||
|
||||
netDialer goexec.Dialer
|
||||
dialer dcerpc.Dialer
|
||||
authOptions []dcerpc.Option
|
||||
DcerpcOptions []dcerpc.Option
|
||||
epmOptions []dcerpc.Option
|
||||
stringBindings []*dcerpc.StringBinding
|
||||
stringBindings []*dcerpc.StringBinding
|
||||
dialer dcerpc.Dialer
|
||||
authOptions []dcerpc.Option
|
||||
DcerpcOptions []dcerpc.Option
|
||||
EpmOptions []dcerpc.Option
|
||||
}
|
||||
|
||||
func (c *Client) Parse(ctx context.Context) (err error) {
|
||||
|
||||
// Reset internals
|
||||
{
|
||||
c.netDialer = nil
|
||||
c.dialer = nil
|
||||
c.stringBindings = []*dcerpc.StringBinding{}
|
||||
c.authOptions = []dcerpc.Option{}
|
||||
c.DcerpcOptions = []dcerpc.Option{}
|
||||
c.epmOptions = []dcerpc.Option{
|
||||
dcerpc.WithSign(), // Require signing for EPM
|
||||
}
|
||||
}
|
||||
// Reset internals
|
||||
{
|
||||
c.dialer = nil
|
||||
c.stringBindings = []*dcerpc.StringBinding{}
|
||||
c.authOptions = []dcerpc.Option{}
|
||||
c.DcerpcOptions = []dcerpc.Option{}
|
||||
c.EpmOptions = []dcerpc.Option{
|
||||
dcerpc.WithSign(), // Require signing for EPM
|
||||
}
|
||||
}
|
||||
|
||||
if !c.NoSeal {
|
||||
// Enable encryption
|
||||
c.DcerpcOptions = append(c.DcerpcOptions, dcerpc.WithSeal(), dcerpc.WithSecurityLevel(dcerpc.AuthLevelPktPrivacy))
|
||||
c.epmOptions = append(c.epmOptions, dcerpc.WithSeal(), dcerpc.WithSecurityLevel(dcerpc.AuthLevelPktPrivacy))
|
||||
}
|
||||
if !c.NoSign {
|
||||
// Enable signing
|
||||
c.DcerpcOptions = append(c.DcerpcOptions, dcerpc.WithSign())
|
||||
//c.epmOptions = append(c.epmOptions, dcerpc.WithSign())
|
||||
}
|
||||
if !c.NoSeal {
|
||||
// Enable encryption
|
||||
c.DcerpcOptions = append(c.DcerpcOptions, dcerpc.WithSeal(), dcerpc.WithSecurityLevel(dcerpc.AuthLevelPktPrivacy))
|
||||
c.EpmOptions = append(c.EpmOptions, dcerpc.WithSeal(), dcerpc.WithSecurityLevel(dcerpc.AuthLevelPktPrivacy))
|
||||
}
|
||||
if !c.NoSign {
|
||||
// Enable signing
|
||||
c.DcerpcOptions = append(c.DcerpcOptions, dcerpc.WithSign())
|
||||
//c.EpmOptions = append(c.EpmOptions, dcerpc.WithSign())
|
||||
}
|
||||
|
||||
// Parse DCERPC endpoint
|
||||
if c.Endpoint != "" {
|
||||
sb, err := dcerpc.ParseStringBinding(c.Endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sb.ProtocolSequence == dcerpc.ProtocolSequenceNamedPipe {
|
||||
c.Smb = true
|
||||
}
|
||||
c.stringBindings = append(c.stringBindings, sb)
|
||||
}
|
||||
// Parse DCERPC endpoint
|
||||
if c.Endpoint != "" {
|
||||
sb, err := dcerpc.ParseStringBinding(c.Endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sb.ProtocolSequence == dcerpc.ProtocolSequenceNamedPipe {
|
||||
c.Smb = true
|
||||
}
|
||||
c.stringBindings = append(c.stringBindings, sb)
|
||||
}
|
||||
|
||||
// Parse EPM filter
|
||||
if c.Filter != "" {
|
||||
sb, err := dcerpc.ParseStringBinding(c.Filter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sb.ProtocolSequence == dcerpc.ProtocolSequenceNamedPipe {
|
||||
c.Smb = true
|
||||
}
|
||||
c.stringBindings = append(c.stringBindings, sb)
|
||||
}
|
||||
// Parse EPM filter
|
||||
if c.Filter != "" {
|
||||
sb, err := dcerpc.ParseStringBinding(c.Filter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sb.ProtocolSequence == dcerpc.ProtocolSequenceNamedPipe {
|
||||
c.Smb = true
|
||||
}
|
||||
c.stringBindings = append(c.stringBindings, sb)
|
||||
}
|
||||
|
||||
if c.Proxy == "" {
|
||||
c.netDialer = &net.Dialer{} // FUTURE: additional dial c
|
||||
if c.Proxy != "" {
|
||||
// Parse proxy URL
|
||||
d, err := goexec.ParseProxyURI(c.Proxy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var ok bool
|
||||
if c.dialer, ok = d.(dcerpc.Dialer); !ok {
|
||||
return fmt.Errorf("cannot cast %T to dcerpc.Dialer", d)
|
||||
}
|
||||
c.DcerpcOptions = append(c.DcerpcOptions, dcerpc.WithDialer(c.dialer))
|
||||
c.EpmOptions = append(c.EpmOptions, dcerpc.WithDialer(c.dialer))
|
||||
}
|
||||
|
||||
} else {
|
||||
// Parse proxy URL
|
||||
d, err := goexec.ParseProxyURI(c.Proxy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var ok bool
|
||||
if c.dialer, ok = d.(dcerpc.Dialer); !ok {
|
||||
return fmt.Errorf("cannot cast %T to dcerpc.Dialer", d)
|
||||
}
|
||||
c.DcerpcOptions = append(c.DcerpcOptions, dcerpc.WithDialer(c.dialer))
|
||||
}
|
||||
// Parse authentication parameters
|
||||
if c.authOptions, err = dcerpcauth.AuthenticationOptions(ctx, c.Credential, c.Target, &dcerpcauth.Options{}); err != nil {
|
||||
return fmt.Errorf("parse auth c: %w", err)
|
||||
}
|
||||
|
||||
// Parse authentication parameters
|
||||
if c.authOptions, err = dcerpcauth.AuthenticationOptions(ctx, c.Credential, c.Target, &dcerpcauth.Options{}); err != nil {
|
||||
return fmt.Errorf("parse auth c: %w", err)
|
||||
}
|
||||
c.Host = c.Target.AddressWithoutPort()
|
||||
|
||||
c.Host = c.Target.AddressWithoutPort()
|
||||
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/FalconOpsLLC/goexec/pkg/goexec"
|
||||
"github.com/FalconOpsLLC/goexec/pkg/goexec/dce"
|
||||
"github.com/oiweiwei/go-msrpc/dcerpc"
|
||||
"github.com/oiweiwei/go-msrpc/msrpc/tsch/itaskschedulerservice/v1"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
@@ -51,7 +52,7 @@ func (m *Tsch) Init(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
// Create ITaskSchedulerService Client
|
||||
m.tsch, err = itaskschedulerservice.NewTaskSchedulerServiceClient(ctx, m.Client.Dce())
|
||||
m.tsch, err = itaskschedulerservice.NewTaskSchedulerServiceClient(ctx, m.Client.Dce(), dcerpc.WithSeal())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user