aboutsummaryrefslogtreecommitdiff
path: root/cmd/scmr.go
blob: 150320c819e922628fbf7c0d31c8795696add292 (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
127
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", "s", "", "Name of service to create or modify")
	scmrCmd.PersistentFlags().BoolVar(&scmrNoStart, "no-start", false, "Don't start service after execution")

	scmrCmd.MarkPersistentFlagRequired("executable-path")
	scmrCmd.MarkPersistentFlagRequired("service")

	scmrCmd.AddCommand(scmrChangeCmd)
	scmrChangeCmdInit()
	scmrCmd.AddCommand(scmrCreateCmd)
	scmrCreateCmdInit()
}

func scmrChangeCmdInit() {
	// no unique flags
}

func scmrCreateCmdInit() {
	scmrCreateCmd.Flags().StringVarP(&scmrDisplayName, "display-name", "n", "", "Display name new service")
	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")
			}
		},
	}
)