diff options
author | Bryan McNulty <bryanmcnulty@protonmail.com> | 2025-04-18 04:07:54 -0500 |
---|---|---|
committer | Bryan McNulty <bryanmcnulty@protonmail.com> | 2025-04-18 04:07:54 -0500 |
commit | e16fcfc6ce0bdffdac4a73b5922a792972348a80 (patch) | |
tree | 0c8f01493e18395306eb414d2889847f55894fd2 /pkg | |
parent | 5d2734e51b62f7048dc8be25cca05fb71da4f521 (diff) | |
download | goexec-e16fcfc6ce0bdffdac4a73b5922a792972348a80.tar.gz goexec-e16fcfc6ce0bdffdac4a73b5922a792972348a80.zip |
Some CLI tweaks
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/goexec/dcom/mmc.go | 68 | ||||
-rw-r--r-- | pkg/goexec/dcom/module.go | 211 |
2 files changed, 145 insertions, 134 deletions
diff --git a/pkg/goexec/dcom/mmc.go b/pkg/goexec/dcom/mmc.go index ecb3a74..993d1bb 100644 --- a/pkg/goexec/dcom/mmc.go +++ b/pkg/goexec/dcom/mmc.go @@ -1,51 +1,51 @@ package dcomexec import ( - "context" - "fmt" - "github.com/FalconOpsLLC/goexec/pkg/goexec" - "github.com/rs/zerolog" + "context" + "fmt" + "github.com/FalconOpsLLC/goexec/pkg/goexec" + "github.com/rs/zerolog" ) const ( - MethodMmc = "MMC" // MMC20.Application::Document.ActiveView.ExecuteShellCommand + MethodMmc = "MMC" // MMC20.Application::Document.ActiveView.ExecuteShellCommand ) type DcomMmc struct { - Dcom + Dcom - IO goexec.ExecutionIO + IO goexec.ExecutionIO - WorkingDirectory string - WindowState string + WorkingDirectory string + WindowState string } // Execute will perform command execution via the MMC20.Application DCOM object. func (m *DcomMmc) Execute(ctx context.Context, execIO *goexec.ExecutionIO) (err error) { - log := zerolog.Ctx(ctx).With(). - Str("module", ModuleName). - Str("method", MethodMmc). - Logger() - - method := "Document.ActiveView.ExecuteShellCommand" - - cmdline := execIO.CommandLine() - proc := cmdline[0] - args := cmdline[1] - - // Arguments must be passed in reverse order - if _, err := callComMethod(ctx, - m.dispatchClient, - method, - stringToVariant(m.WindowState), - stringToVariant(args), - stringToVariant(m.WorkingDirectory), - stringToVariant(proc)); err != nil { - - log.Error().Err(err).Msg("Failed to call method") - return fmt.Errorf("call %q: %w", method, err) - } - log.Info().Msg("Method call successful") - return + log := zerolog.Ctx(ctx).With(). + Str("module", ModuleName). + Str("method", MethodMmc). + Logger() + + method := "Document.ActiveView.ExecuteShellCommand" + + cmdline := execIO.CommandLine() + proc := cmdline[0] + args := cmdline[1] + + // Arguments must be passed in reverse order + if _, err := callComMethod(ctx, + m.dispatchClient, + method, + stringToVariant(m.WindowState), + stringToVariant(args), + stringToVariant(m.WorkingDirectory), + stringToVariant(proc)); err != nil { + + log.Error().Err(err).Msg("Failed to call method") + return fmt.Errorf("call %q: %w", method, err) + } + log.Info().Msg("Method call successful") + return } diff --git a/pkg/goexec/dcom/module.go b/pkg/goexec/dcom/module.go index 71e4f6e..40804c3 100644 --- a/pkg/goexec/dcom/module.go +++ b/pkg/goexec/dcom/module.go @@ -1,120 +1,131 @@ package dcomexec import ( - "context" - "errors" - "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/dcom" - "github.com/oiweiwei/go-msrpc/msrpc/dcom/iremotescmactivator/v0" - "github.com/oiweiwei/go-msrpc/msrpc/dcom/oaut/idispatch/v0" - "github.com/rs/zerolog" + "context" + "errors" + "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/midl/uuid" + "github.com/oiweiwei/go-msrpc/msrpc/dcom" + "github.com/oiweiwei/go-msrpc/msrpc/dcom/iremotescmactivator/v0" + "github.com/oiweiwei/go-msrpc/msrpc/dcom/oaut/idispatch/v0" + "github.com/oiweiwei/go-msrpc/msrpc/dtyp" + "github.com/rs/zerolog" ) const ( - ModuleName = "DCOM" + ModuleName = "DCOM" ) type Dcom struct { - goexec.Cleaner + goexec.Cleaner - Client *dce.Client + Client *dce.Client + ClassID string - dispatchClient idispatch.DispatchClient + dispatchClient idispatch.DispatchClient } func (m *Dcom) Connect(ctx context.Context) (err error) { - if err = m.Client.Connect(ctx); err == nil { - m.AddCleaner(m.Client.Close) - } - return + if err = m.Client.Connect(ctx); err == nil { + m.AddCleaner(m.Client.Close) + } + return } func (m *Dcom) Init(ctx context.Context) (err error) { - log := zerolog.Ctx(ctx).With(). - Str("module", ModuleName).Logger() - - if m.Client == nil || m.Client.Dce() == nil { - return errors.New("DCE connection not initialized") - } - - opts := []dcerpc.Option{ - dcerpc.WithSign(), - } - - inst := &dcom.InstantiationInfoData{ - ClassID: &MmcClsid, - IID: []*dcom.IID{IDispatchIID}, - ClientCOMVersion: ComVersion, - } - ac := &dcom.ActivationContextInfoData{} - loc := &dcom.LocationInfoData{} - scm := &dcom.SCMRequestInfoData{ - RemoteRequest: &dcom.CustomRemoteRequestSCMInfo{ - RequestedProtocolSequences: []uint16{7}, - }, - } - - ap := &dcom.ActivationProperties{ - DestinationContext: 2, - Properties: []dcom.ActivationProperty{inst, ac, loc, scm}, - } - - apin, err := ap.ActivationPropertiesIn() - if err != nil { - return err - } - - act, err := iremotescmactivator.NewRemoteSCMActivatorClient(ctx, m.Client.Dce()) - if err != nil { - return err - } - - cr, err := act.RemoteCreateInstance(ctx, &iremotescmactivator.RemoteCreateInstanceRequest{ - ORPCThis: &dcom.ORPCThis{ - Version: ComVersion, - Flags: 1, - CID: &RandCid, - }, - ActPropertiesIn: apin, - }) - if err != nil { - return err - } - log.Info().Msg("RemoteCreateInstance succeeded") - - apout := new(dcom.ActivationProperties) - if err = apout.Parse(cr.ActPropertiesOut); err != nil { - return err - } - si := apout.SCMReplyInfoData() - pi := apout.PropertiesOutInfo() - - if si == nil { - return fmt.Errorf("remote create instance response: SCMReplyInfoData is nil") - } - - if pi == nil { - return fmt.Errorf("remote create instance response: PropertiesOutInfo is nil") - } - - opts = append(opts, si.RemoteReply.OXIDBindings.EndpointsByProtocol("ncacn_ip_tcp")...) - - err = m.Client.Reconnect(ctx, opts...) - if err != nil { - return err - } - log.Info().Msg("created new DCERPC dialer") - - m.dispatchClient, err = idispatch.NewDispatchClient(ctx, m.Client.Dce(), dcom.WithIPID(pi.InterfaceData[0].IPID())) - if err != nil { - return err - } - log.Info().Msg("created IDispatch Client") - - return + log := zerolog.Ctx(ctx).With(). + Str("module", ModuleName).Logger() + + if m.Client == nil || m.Client.Dce() == nil { + return errors.New("DCE connection not initialized") + } + + m.ClassID = "49B2791A-B1AE-4C90-9B8E-E860BA07F889" + //m.ClassID = "9BA05972-F6A8-11CF-A442-00A0C90A8F39" + class := dcom.ClassID(*dtyp.GUIDFromUUID(uuid.MustParse(m.ClassID))) + + if class.GUID() == nil { + return fmt.Errorf("invalid class ID: %s", m.ClassID) + } + + opts := []dcerpc.Option{ + dcerpc.WithSign(), + } + + inst := &dcom.InstantiationInfoData{ + ClassID: &class, + IID: []*dcom.IID{IDispatchIID}, + ClientCOMVersion: ComVersion, + } + ac := &dcom.ActivationContextInfoData{} + loc := &dcom.LocationInfoData{} + scm := &dcom.SCMRequestInfoData{ + RemoteRequest: &dcom.CustomRemoteRequestSCMInfo{ + RequestedProtocolSequences: []uint16{7}, + }, + } + + ap := &dcom.ActivationProperties{ + DestinationContext: 2, + Properties: []dcom.ActivationProperty{inst, ac, loc, scm}, + } + + apin, err := ap.ActivationPropertiesIn() + if err != nil { + return err + } + + act, err := iremotescmactivator.NewRemoteSCMActivatorClient(ctx, m.Client.Dce()) + if err != nil { + return err + } + + cr, err := act.RemoteCreateInstance(ctx, &iremotescmactivator.RemoteCreateInstanceRequest{ + ORPCThis: &dcom.ORPCThis{ + Version: ComVersion, + Flags: 1, + CID: &RandCid, + }, + ActPropertiesIn: apin, + }) + if err != nil { + return err + } + log.Info().Msg("RemoteCreateInstance succeeded") + + apout := new(dcom.ActivationProperties) + if err = apout.Parse(cr.ActPropertiesOut); err != nil { + return err + } + si := apout.SCMReplyInfoData() + pi := apout.PropertiesOutInfo() + + if si == nil { + return fmt.Errorf("remote create instance response: SCMReplyInfoData is nil") + } + + if pi == nil { + return fmt.Errorf("remote create instance response: PropertiesOutInfo is nil") + } + + opts = append(opts, si.RemoteReply.OXIDBindings.EndpointsByProtocol("ncacn_ip_tcp")...) + + err = m.Client.Reconnect(ctx, opts...) + if err != nil { + return err + } + log.Info().Msg("created new DCERPC dialer") + + m.dispatchClient, err = idispatch.NewDispatchClient(ctx, m.Client.Dce(), dcom.WithIPID(pi.InterfaceData[0].IPID())) + if err != nil { + return err + } + log.Info().Msg("created IDispatch Client") + + return } |