aboutsummaryrefslogtreecommitdiff
path: root/cmd/scmr.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/scmr.go')
-rw-r--r--cmd/scmr.go106
1 files changed, 75 insertions, 31 deletions
diff --git a/cmd/scmr.go b/cmd/scmr.go
index f2f0d51..7772fc4 100644
--- a/cmd/scmr.go
+++ b/cmd/scmr.go
@@ -1,8 +1,8 @@
package cmd
import (
- "fmt"
"github.com/FalconOpsLLC/goexec/internal/exec"
+ "github.com/FalconOpsLLC/goexec/internal/util"
"github.com/FalconOpsLLC/goexec/internal/windows"
"github.com/RedTeamPentesting/adauth"
"github.com/spf13/cobra"
@@ -14,11 +14,11 @@ func scmrCmdInit() {
registerRpcFlags(scmrCmd)
scmrCmd.PersistentFlags().StringVarP(&executablePath, "executable-path", "f", "", "Full path to remote Windows executable")
scmrCmd.PersistentFlags().StringVarP(&executableArgs, "args", "a", "", "Arguments to pass to executable")
- scmrCmd.PersistentFlags().StringVarP(&scmrName, "service-name", "s", "", "Name of service to create or modify")
-
- scmrCmd.MarkPersistentFlagRequired("executable-path")
- scmrCmd.MarkPersistentFlagRequired("service-name")
+ scmrCmd.PersistentFlags().StringVarP(&scmrServiceName, "service-name", "s", "", "Name of service to create or modify")
+ if err := scmrCmd.MarkPersistentFlagRequired("executable-path"); err != nil {
+ panic(err)
+ }
scmrCmd.AddCommand(scmrChangeCmd)
scmrCreateCmdInit()
scmrCmd.AddCommand(scmrCreateCmd)
@@ -28,30 +28,24 @@ func scmrCmdInit() {
func scmrChangeCmdInit() {
scmrChangeCmd.Flags().StringVarP(&scmrDisplayName, "display-name", "n", "", "Display name of service to create")
scmrChangeCmd.Flags().BoolVar(&scmrNoStart, "no-start", false, "Don't start service")
+ scmrChangeCmd.Flags().StringVarP(&scmrServiceName, "service-name", "s", "", "Name of service to modify")
+ if err := scmrChangeCmd.MarkFlagRequired("service-name"); err != nil {
+ panic(err)
+ }
}
func scmrCreateCmdInit() {
+ scmrCreateCmd.Flags().StringVarP(&scmrServiceName, "service-name", "s", "", "Name of service to create")
scmrCreateCmd.Flags().BoolVar(&scmrNoDelete, "no-delete", false, "Don't delete service after execution")
}
var (
// scmr arguments
- scmrName string
+ scmrServiceName string
scmrDisplayName string
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
@@ -63,16 +57,29 @@ var (
scmrCreateCmd = &cobra.Command{
Use: "create [target]",
Short: "Create & run a new Windows service to gain execution",
- Args: scmrArgs,
- RunE: func(cmd *cobra.Command, args []string) (err error) {
+ Args: needsRpcTarget("cifs"),
+ Run: func(cmd *cobra.Command, args []string) {
+
+ if scmrServiceName == "" {
+ log.Warn().Msg("No service name was specified, using random string")
+ scmrServiceName = util.RandomString()
+ }
if scmrNoDelete {
log.Warn().Msg("Service will not be deleted after execution")
}
if scmrDisplayName == "" {
- scmrDisplayName = scmrName
- log.Warn().Msg("No display name specified, using service name as display name")
+ log.Debug().Msg("No display name specified, using service name as display name")
+ scmrDisplayName = scmrServiceName
}
+
executor := scmrexec.Module{}
+ cleanCfg := &exec.CleanupConfig{
+ CleanupMethod: scmrexec.CleanupMethodDelete,
+ }
+ connCfg := &exec.ConnectionConfig{
+ ConnectionMethod: exec.ConnectionMethodDCE,
+ ConnectionMethodConfig: dceConfig,
+ }
execCfg := &exec.ExecutionConfig{
ExecutablePath: executablePath,
ExecutableArgs: executableArgs,
@@ -80,36 +87,73 @@ var (
ExecutionMethodConfig: scmrexec.MethodCreateConfig{
NoDelete: scmrNoDelete,
- ServiceName: scmrName,
+ ServiceName: util.RandomStringIfBlank(scmrServiceName),
DisplayName: scmrDisplayName,
ServiceType: windows.SERVICE_WIN32_OWN_PROCESS,
StartType: windows.SERVICE_DEMAND_START,
},
}
- if err := executor.Exec(log.WithContext(ctx), creds, target, execCfg); err != nil {
- log.Fatal().Err(err).Msg("SCMR execution failed")
+ ctx = log.With().
+ Str("module", "scmr").
+ Str("method", "create").
+ Logger().WithContext(ctx)
+
+ if err := executor.Connect(ctx, creds, target, connCfg); err != nil {
+ log.Fatal().Err(err).Msg("Connection failed")
+ }
+ if !scmrNoDelete {
+ defer func() {
+ if err := executor.Cleanup(ctx, cleanCfg); err != nil {
+ log.Error().Err(err).Msg("Cleanup failed")
+ }
+ }()
+ }
+ if err := executor.Exec(ctx, execCfg); err != nil {
+ log.Error().Err(err).Msg("Execution failed")
}
- return nil
},
}
scmrChangeCmd = &cobra.Command{
Use: "change [target]",
Short: "Change an existing Windows service to gain execution",
- Args: scmrArgs,
+ Args: needsRpcTarget("cifs"),
Run: func(cmd *cobra.Command, args []string) {
+
executor := scmrexec.Module{}
+ cleanCfg := &exec.CleanupConfig{
+ CleanupMethod: scmrexec.CleanupMethodRevert,
+ }
+ connCfg := &exec.ConnectionConfig{
+ ConnectionMethod: exec.ConnectionMethodDCE,
+ ConnectionMethodConfig: dceConfig,
+ }
execCfg := &exec.ExecutionConfig{
ExecutablePath: executablePath,
ExecutableArgs: executableArgs,
- ExecutionMethod: scmrexec.MethodModify,
+ ExecutionMethod: scmrexec.MethodChange,
- ExecutionMethodConfig: scmrexec.MethodModifyConfig{
+ ExecutionMethodConfig: scmrexec.MethodChangeConfig{
NoStart: scmrNoStart,
- ServiceName: scmrName,
+ ServiceName: scmrServiceName,
},
}
- if err := executor.Exec(log.WithContext(ctx), creds, target, execCfg); err != nil {
- log.Fatal().Err(err).Msg("SCMR execution failed")
+ log = log.With().
+ Str("module", "scmr").
+ Str("method", "change").
+ Logger()
+
+ if err := executor.Connect(log.WithContext(ctx), creds, target, connCfg); err != nil {
+ log.Fatal().Err(err).Msg("Connection failed")
+ }
+ if !scmrNoDelete {
+ defer func() {
+ if err := executor.Cleanup(log.WithContext(ctx), cleanCfg); err != nil {
+ log.Error().Err(err).Msg("Cleanup failed")
+ }
+ }()
+ }
+ if err := executor.Exec(log.WithContext(ctx), execCfg); err != nil {
+ log.Error().Err(err).Msg("Execution failed")
}
},
}