aboutsummaryrefslogtreecommitdiff
path: root/cmd/scmr.go
blob: e142cd7b76fbcd9a00687129e4d6d66dccca7099 (plain)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package cmd

import (
	"errors"
	"fmt"
	"github.com/bryanmcnulty/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"
)

func scmrCmdInit() {
	scmrCmd.PersistentFlags().StringVarP(&executablePath, "executable-path", "e", "", "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.AddCommand(scmrChangeCmd)
	scmrCreateCmdInit()
	scmrCmd.AddCommand(scmrCreateCmd)
	scmrChangeCmdInit()
}

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")
}

func scmrCreateCmdInit() {
	scmrCreateCmd.Flags().BoolVar(&scmrNoDelete, "no-delete", false, "Don't delete service after execution")
}

var (
	// scmr arguments
	scmrName        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

	scmrCmd = &cobra.Command{
		Use:   "scmr",
		Short: "Establish execution via SCMR",
		Args: func(cmd *cobra.Command, args []string) error {
			if len(args) != 1 {
				return errors.New(`command not set. Choose from (change, create)`)
			}
			return nil
		},
		Run: func(cmd *cobra.Command, args []string) {
			if err := cmd.Help(); err != nil {
				panic(err)
			}
		},
	}
	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) {
			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")
			}
			executor := scmrexec.Executor{}
			execCfg := &exec.ExecutionConfig{
				ExecutablePath:  executablePath,
				ExecutableArgs:  executableArgs,
				ExecutionMethod: scmrexec.MethodCreate,

				ExecutionMethodConfig: scmrexec.MethodCreateConfig{
					NoDelete:    scmrNoDelete,
					ServiceName: scmrName,
					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")
			}
			return nil
		},
	}
	scmrChangeCmd = &cobra.Command{
		Use:   "change [target]",
		Short: "Change an existing Windows service to gain execution",
		Args:  scmrArgs,
		Run: func(cmd *cobra.Command, args []string) {
			executor := scmrexec.Executor{}
			execCfg := &exec.ExecutionConfig{
				ExecutablePath:  executablePath,
				ExecutableArgs:  executableArgs,
				ExecutionMethod: scmrexec.MethodModify,

				ExecutionMethodConfig: scmrexec.MethodModifyConfig{
					NoStart:     scmrNoStart,
					ServiceName: scmrName,
				},
			}
			if err := executor.Exec(log.WithContext(ctx), creds, target, execCfg); err != nil {
				log.Fatal().Err(err).Msg("SCMR execution failed")
			}
		},
	}
)