aboutsummaryrefslogtreecommitdiff
path: root/cmd/args.go
blob: ca61c227a4aba0f9e066e3a0e89706d5f350149a (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
128
129
130
131
132
133
134
135
136
137
138
139
package cmd

import (
	"context"
	"errors"
	"fmt"
	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
	"os"
)

func registerRpcFlags(cmd *cobra.Command) {
	rpcFlags := pflag.NewFlagSet("RPC", pflag.ExitOnError)

	rpcFlags.BoolVar(&rpcClient.NoEpm, "no-epm", false, "Do not use EPM to automatically detect endpoints")
	//rpcFlags.BoolVar(&rpcClient.Options.EpmAuto, "epm-auto", false, "Automatically detect endpoints instead of using the module defaults")
	rpcFlags.BoolVar(&rpcClient.NoSign, "no-sign", false, "Disable signing on DCE messages")
	rpcFlags.BoolVar(&rpcClient.NoSeal, "no-seal", false, "Disable packet stub encryption on DCE messages")
	rpcFlags.StringVar(&rpcClient.Filter, "epm-filter", "", "String binding to filter endpoints returned by EPM")
	rpcFlags.StringVar(&rpcClient.Endpoint, "endpoint", "", "Explicit RPC endpoint definition")

	cmd.PersistentFlags().AddFlagSet(rpcFlags)

	cmd.MarkFlagsMutuallyExclusive("endpoint", "epm-filter")
	cmd.MarkFlagsMutuallyExclusive("no-epm", "epm-filter")
}

func registerProcessExecutionArgs(cmd *cobra.Command) {
	group := pflag.NewFlagSet("Execution", pflag.ExitOnError)

	group.StringVarP(&exec.Input.Arguments, "args", "a", "", "Command line arguments")
	group.StringVarP(&exec.Input.Command, "command", "c", "", "Windows process command line (executable & arguments)")
	group.StringVarP(&exec.Input.Executable, "executable", "e", "", "Windows executable to invoke")

	cmd.PersistentFlags().AddFlagSet(group)

	cmd.MarkFlagsOneRequired("executable", "command")
	cmd.MarkFlagsMutuallyExclusive("executable", "command")
}

func registerExecutionOutputArgs(cmd *cobra.Command) {
	group := pflag.NewFlagSet("Output", pflag.ExitOnError)

	group.StringVarP(&outputPath, "output", "o", "", `Fetch execution output to file or "-" for standard output`)
	group.StringVarP(&outputMethod, "output-method", "m", "smb", "Method to fetch execution output")
	group.StringVar(&exec.Output.RemotePath, "remote-output", "", "Location to temporarily store output on remote filesystem")
	group.BoolVar(&exec.Output.NoDelete, "no-delete-output", false, "Preserve output file on remote filesystem")

	cmd.PersistentFlags().AddFlagSet(group)
}

func args(reqs ...func(*cobra.Command, []string) error) (fn func(*cobra.Command, []string) error) {

	return func(cmd *cobra.Command, args []string) (err error) {

		for _, req := range reqs {
			if err = req(cmd, args); err != nil {
				return
			}
		}
		return
	}
}

func argsTarget(proto string) func(cmd *cobra.Command, args []string) error {

	return func(cmd *cobra.Command, args []string) (err error) {

		if len(args) != 1 {
			return errors.New("command require exactly one positional argument: [target]")
		}

		if credential, target, err = authOpts.WithTarget(context.TODO(), proto, args[0]); err != nil {
			return fmt.Errorf("failed to parse target: %w", err)
		}

		if credential == nil {
			return errors.New("no credentials supplied")
		}
		if target == nil {
			return errors.New("no target supplied")
		}
		return
	}
}

func argsSmbClient() func(cmd *cobra.Command, args []string) error {
	return args(
		argsTarget("cifs"),

		func(_ *cobra.Command, _ []string) error {

			smbClient.Credential = credential
			smbClient.Target = target
			smbClient.Proxy = proxy

			return smbClient.Parse(context.TODO())
		},
	)
}

func argsRpcClient(proto string) func(cmd *cobra.Command, args []string) error {
	return args(
		argsTarget(proto),

		func(cmd *cobra.Command, args []string) (err error) {

			rpcClient.Target = target
			rpcClient.Credential = credential
			rpcClient.Proxy = proxy

			return rpcClient.Parse(context.TODO())
		},
	)
}

func argsOutput(methods ...string) func(cmd *cobra.Command, args []string) error {

	var as []func(*cobra.Command, []string) error

	for _, method := range methods {
		if method == "smb" {
			as = append(as, argsSmbClient())
		}
	}

	return args(append(as, func(*cobra.Command, []string) (err error) {

		if outputPath != "" {
			if outputPath == "-" {
				exec.Output.Writer = os.Stdout

			} else if exec.Output.Writer, err = os.OpenFile(outputPath, os.O_WRONLY|os.O_CREATE, 0644); err != nil {
				log.Fatal().Err(err).Msg("Failed to open output file")
			}
		}
		return
	})...)
}