diff options
-rw-r--r-- | TODO.md | 7 | ||||
-rw-r--r-- | cmd/scmr.go | 39 | ||||
-rw-r--r-- | cmd/tsch.go | 9 | ||||
-rw-r--r-- | internal/client/dcerpc/client.go (renamed from pkg/client/dcerpc/client.go) | 0 | ||||
-rw-r--r-- | internal/client/dcerpc/dcerpc.go (renamed from pkg/client/dcerpc/dcerpc.go) | 0 | ||||
-rw-r--r-- | internal/client/dcerpc/smb.go (renamed from pkg/client/dcerpc/smb.go) | 0 | ||||
-rw-r--r-- | internal/exec/exec.go (renamed from pkg/exec/exec.go) | 0 | ||||
-rw-r--r-- | internal/exec/scmr/exec.go (renamed from pkg/exec/scmr/exec.go) | 8 | ||||
-rw-r--r-- | internal/exec/scmr/module.go (renamed from pkg/exec/scmr/module.go) | 2 | ||||
-rw-r--r-- | internal/exec/scmr/scmr.go (renamed from pkg/exec/scmr/scmr.go) | 4 | ||||
-rw-r--r-- | internal/exec/tsch/exec.go (renamed from pkg/exec/tsch/exec.go) | 6 | ||||
-rw-r--r-- | internal/exec/tsch/module.go (renamed from pkg/exec/tsch/module.go) | 10 | ||||
-rw-r--r-- | internal/exec/tsch/tsch.go (renamed from pkg/exec/tsch/tsch.go) | 0 | ||||
-rw-r--r-- | internal/windows/const.go (renamed from pkg/windows/const.go) | 0 |
14 files changed, 45 insertions, 40 deletions
@@ -1,5 +1,8 @@ # TODO +## High Priority +- [ ] Add dcom module + +## Lower Priority - [ ] Add command to tsch - update task if it already exists. See https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/849c131a-64e4-46ef-b015-9d4c599c5167 (`flags` argument) -- [ ] Add delete command to scmr - should look similar to `tsch delete` -- [ ] Add ATSvc module. See https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/920fb461-5cb5-41cc-b0fc-d9449d9976b8 +- [ ] Add delete command to scmr - should look similar to `tsch delete`
\ No newline at end of file diff --git a/cmd/scmr.go b/cmd/scmr.go index 8105ff6..8d453a5 100644 --- a/cmd/scmr.go +++ b/cmd/scmr.go @@ -1,12 +1,14 @@ package cmd import ( + "fmt" + "github.com/FalconOpsLLC/goexec/internal/exec" + scmrexec2 "github.com/FalconOpsLLC/goexec/internal/exec/scmr" + "github.com/FalconOpsLLC/goexec/internal/windows" "github.com/RedTeamPentesting/adauth" "github.com/spf13/cobra" - "github.com/FalconOpsLLC/goexec/pkg/exec" - scmrexec "github.com/FalconOpsLLC/goexec/pkg/exec/scmr" - "github.com/FalconOpsLLC/goexec/pkg/windows" + scmrexec "github.com/FalconOpsLLC/goexec/internal/exec/scmr" ) func scmrCmdInit() { @@ -17,11 +19,10 @@ func scmrCmdInit() { scmrCmd.MarkPersistentFlagRequired("executable-path") scmrCmd.MarkPersistentFlagRequired("service-name") - scmrChangeCmdInit() scmrCmd.AddCommand(scmrChangeCmd) - scmrCreateCmdInit() scmrCmd.AddCommand(scmrCreateCmd) + scmrChangeCmdInit() } func scmrChangeCmdInit() { @@ -40,17 +41,29 @@ var ( scmrNoDelete bool scmrNoStart bool + scmrArgs = func(cmd *cobra.Command, args []string) (err error) { + if len(args) != 1 { + return fmt.Errorf("expected exactly 1 positional argument, got %d", len(args)) + } + if creds, target, err = authOpts.WithTarget(ctx, "cifs", args[0]); err != nil { + return fmt.Errorf("failed to parse target: %w", err) + } + log.Debug().Str("target", args[0]).Msg("Resolved target") + return nil + } + creds *adauth.Credential target *adauth.Target scmrCmd = &cobra.Command{ Use: "scmr", Short: "Establish execution via SCMR", + Args: cobra.NoArgs, } scmrCreateCmd = &cobra.Command{ Use: "create [target]", Short: "Create & run a new Windows service to gain execution", - Args: needsTarget, + Args: scmrArgs, RunE: func(cmd *cobra.Command, args []string) (err error) { if scmrNoDelete { log.Warn().Msg("Service will not be deleted after execution") @@ -59,13 +72,13 @@ var ( scmrDisplayName = scmrName log.Warn().Msg("No display name specified, using service name as display name") } - module := scmrexec.Module{} + executor := scmrexec.Module{} execCfg := &exec.ExecutionConfig{ ExecutablePath: executablePath, ExecutableArgs: executableArgs, - ExecutionMethod: scmrexec.MethodCreate, + ExecutionMethod: scmrexec2.MethodCreate, - ExecutionMethodConfig: scmrexec.MethodCreateConfig{ + ExecutionMethodConfig: scmrexec2.MethodCreateConfig{ NoDelete: scmrNoDelete, ServiceName: scmrName, DisplayName: scmrDisplayName, @@ -73,7 +86,7 @@ var ( StartType: windows.SERVICE_DEMAND_START, }, } - if err := module.Exec(log.WithContext(ctx), creds, target, execCfg); err != nil { + if err := executor.Exec(log.WithContext(ctx), creds, target, execCfg); err != nil { log.Fatal().Err(err).Msg("SCMR execution failed") } return nil @@ -82,15 +95,15 @@ var ( scmrChangeCmd = &cobra.Command{ Use: "change [target]", Short: "Change an existing Windows service to gain execution", - Args: needsTarget, + Args: scmrArgs, Run: func(cmd *cobra.Command, args []string) { executor := scmrexec.Module{} execCfg := &exec.ExecutionConfig{ ExecutablePath: executablePath, ExecutableArgs: executableArgs, - ExecutionMethod: scmrexec.MethodModify, + ExecutionMethod: scmrexec2.MethodModify, - ExecutionMethodConfig: scmrexec.MethodModifyConfig{ + ExecutionMethodConfig: scmrexec2.MethodModifyConfig{ NoStart: scmrNoStart, ServiceName: scmrName, }, diff --git a/cmd/tsch.go b/cmd/tsch.go index 6be81b8..05c55cf 100644 --- a/cmd/tsch.go +++ b/cmd/tsch.go @@ -1,9 +1,8 @@ package cmd import ( - "fmt" - "github.com/FalconOpsLLC/goexec/pkg/exec" - tschexec "github.com/FalconOpsLLC/goexec/pkg/exec/tsch" + "github.com/FalconOpsLLC/goexec/internal/exec" + "github.com/FalconOpsLLC/goexec/internal/exec/tsch" "github.com/spf13/cobra" "time" ) @@ -60,9 +59,7 @@ var ( tschCmd = &cobra.Command{ Use: "tsch", Short: "Establish execution via TSCH (ITaskSchedulerService)", - Args: func(cmd *cobra.Command, args []string) error { - return fmt.Errorf("command not set. Choose from (delete, register, demand)") - }, + Args: cobra.NoArgs, } tschRegisterCmd = &cobra.Command{ Use: "register [target]", diff --git a/pkg/client/dcerpc/client.go b/internal/client/dcerpc/client.go index d9d8d71..d9d8d71 100644 --- a/pkg/client/dcerpc/client.go +++ b/internal/client/dcerpc/client.go diff --git a/pkg/client/dcerpc/dcerpc.go b/internal/client/dcerpc/dcerpc.go index 5c9a734..5c9a734 100644 --- a/pkg/client/dcerpc/dcerpc.go +++ b/internal/client/dcerpc/dcerpc.go diff --git a/pkg/client/dcerpc/smb.go b/internal/client/dcerpc/smb.go index cab82eb..cab82eb 100644 --- a/pkg/client/dcerpc/smb.go +++ b/internal/client/dcerpc/smb.go diff --git a/pkg/exec/exec.go b/internal/exec/exec.go index 16fa543..16fa543 100644 --- a/pkg/exec/exec.go +++ b/internal/exec/exec.go diff --git a/pkg/exec/scmr/exec.go b/internal/exec/scmr/exec.go index ab4cfdd..41c5d8a 100644 --- a/pkg/exec/scmr/exec.go +++ b/internal/exec/scmr/exec.go @@ -4,9 +4,9 @@ import ( "context" "errors" "fmt" - "github.com/FalconOpsLLC/goexec/pkg/client/dcerpc" - "github.com/FalconOpsLLC/goexec/pkg/exec" - "github.com/FalconOpsLLC/goexec/pkg/windows" + dcerpc2 "github.com/FalconOpsLLC/goexec/internal/client/dcerpc" + "github.com/FalconOpsLLC/goexec/internal/exec" + "github.com/FalconOpsLLC/goexec/internal/windows" "github.com/RedTeamPentesting/adauth" "github.com/rs/zerolog" ) @@ -31,7 +31,7 @@ func (mod *Module) createClients(ctx context.Context) (cleanup func(cCtx context } } cleanup(ctx) - mod.dce = dcerpc.NewDCEClient(ctx, false, &dcerpc.SmbConfig{Port: 445}) + mod.dce = dcerpc2.NewDCEClient(ctx, false, &dcerpc2.SmbConfig{Port: 445}) cleanup = func(context.Context) {} if err = mod.dce.Connect(ctx, mod.creds, mod.target); err != nil { diff --git a/pkg/exec/scmr/module.go b/internal/exec/scmr/module.go index fd57bc7..95977b8 100644 --- a/pkg/exec/scmr/module.go +++ b/internal/exec/scmr/module.go @@ -1,7 +1,7 @@ package scmrexec import ( - "github.com/FalconOpsLLC/goexec/pkg/client/dcerpc" + "github.com/FalconOpsLLC/goexec/internal/client/dcerpc" "github.com/RedTeamPentesting/adauth" "github.com/oiweiwei/go-msrpc/msrpc/scmr/svcctl/v2" "github.com/rs/zerolog" diff --git a/pkg/exec/scmr/scmr.go b/internal/exec/scmr/scmr.go index e9ef53f..3a6ae08 100644 --- a/pkg/exec/scmr/scmr.go +++ b/internal/exec/scmr/scmr.go @@ -4,9 +4,9 @@ import ( "context" "errors" "fmt" + "github.com/FalconOpsLLC/goexec/internal/exec" "github.com/FalconOpsLLC/goexec/internal/util" - "github.com/FalconOpsLLC/goexec/pkg/exec" - "github.com/FalconOpsLLC/goexec/pkg/windows" + "github.com/FalconOpsLLC/goexec/internal/windows" "github.com/oiweiwei/go-msrpc/msrpc/scmr/svcctl/v2" ) diff --git a/pkg/exec/tsch/exec.go b/internal/exec/tsch/exec.go index 868f9ea..51f157c 100644 --- a/pkg/exec/tsch/exec.go +++ b/internal/exec/tsch/exec.go @@ -5,9 +5,9 @@ import ( "encoding/xml" "errors" "fmt" + dcerpc2 "github.com/FalconOpsLLC/goexec/internal/client/dcerpc" + "github.com/FalconOpsLLC/goexec/internal/exec" "github.com/FalconOpsLLC/goexec/internal/util" - dce "github.com/FalconOpsLLC/goexec/pkg/client/dcerpc" - "github.com/FalconOpsLLC/goexec/pkg/exec" "github.com/RedTeamPentesting/adauth" "github.com/oiweiwei/go-msrpc/dcerpc" "github.com/oiweiwei/go-msrpc/msrpc/tsch/itaskschedulerservice/v1" @@ -37,7 +37,7 @@ func xmlDuration(dur time.Duration) string { // Connect to the target & initialize DCE & TSCH clients func (mod *Module) Connect(ctx context.Context, creds *adauth.Credential, target *adauth.Target) (err error) { if mod.dce == nil { - mod.dce = dce.NewDCEClient(ctx, false, &dce.SmbConfig{}) + mod.dce = dcerpc2.NewDCEClient(ctx, false, &dcerpc2.SmbConfig{}) if err = mod.dce.Connect(ctx, creds, target); err != nil { return fmt.Errorf("DCE connect: %w", err) } else if mod.tsch, err = itaskschedulerservice.NewTaskSchedulerServiceClient(ctx, mod.dce.DCE(), dcerpc.WithSecurityLevel(dcerpc.AuthLevelPktPrivacy)); err != nil { diff --git a/pkg/exec/tsch/module.go b/internal/exec/tsch/module.go index 077951b..dbd9ade 100644 --- a/pkg/exec/tsch/module.go +++ b/internal/exec/tsch/module.go @@ -1,21 +1,13 @@ package tschexec import ( - "context" - "github.com/FalconOpsLLC/goexec/pkg/client/dcerpc" + "github.com/FalconOpsLLC/goexec/internal/client/dcerpc" "github.com/RedTeamPentesting/adauth" "github.com/oiweiwei/go-msrpc/msrpc/tsch/itaskschedulerservice/v1" "github.com/rs/zerolog" "time" ) -type Step struct { - Name string // Name of the step - Status string // Status indicates whether the task succeeded, failed, etc. - Call func(context.Context, *Module, ...any) (interface{}, error) // Call will invoke the procedure - Match func(context.Context, *Module, ...any) (bool, error) // Match will make an assertion to determine whether the step was successful -} - type Module struct { creds *adauth.Credential target *adauth.Target diff --git a/pkg/exec/tsch/tsch.go b/internal/exec/tsch/tsch.go index bc3ed0b..bc3ed0b 100644 --- a/pkg/exec/tsch/tsch.go +++ b/internal/exec/tsch/tsch.go diff --git a/pkg/windows/const.go b/internal/windows/const.go index 4c4fbe6..4c4fbe6 100644 --- a/pkg/windows/const.go +++ b/internal/windows/const.go |