diff options
author | Bryan McNulty <bryanmcnulty@protonmail.com> | 2025-04-18 04:07:54 -0500 |
---|---|---|
committer | Bryan McNulty <bryanmcnulty@protonmail.com> | 2025-04-18 04:07:54 -0500 |
commit | e16fcfc6ce0bdffdac4a73b5922a792972348a80 (patch) | |
tree | 0c8f01493e18395306eb414d2889847f55894fd2 /cmd | |
parent | 5d2734e51b62f7048dc8be25cca05fb71da4f521 (diff) | |
download | goexec-e16fcfc6ce0bdffdac4a73b5922a792972348a80.tar.gz goexec-e16fcfc6ce0bdffdac4a73b5922a792972348a80.zip |
Some CLI tweaks
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/dcom.go | 89 | ||||
-rw-r--r-- | cmd/root.go | 342 | ||||
-rw-r--r-- | cmd/scmr.go | 15 | ||||
-rw-r--r-- | cmd/tsch.go | 11 | ||||
-rw-r--r-- | cmd/wmi.go | 213 |
5 files changed, 354 insertions, 316 deletions
diff --git a/cmd/dcom.go b/cmd/dcom.go index c671252..f4e4f91 100644 --- a/cmd/dcom.go +++ b/cmd/dcom.go @@ -1,62 +1,63 @@ package cmd import ( - "context" - "github.com/FalconOpsLLC/goexec/pkg/goexec" - dcomexec "github.com/FalconOpsLLC/goexec/pkg/goexec/dcom" - "github.com/oiweiwei/go-msrpc/ssp/gssapi" - "github.com/spf13/cobra" + "context" + "github.com/FalconOpsLLC/goexec/pkg/goexec" + dcomexec "github.com/FalconOpsLLC/goexec/pkg/goexec/dcom" + "github.com/oiweiwei/go-msrpc/ssp/gssapi" + "github.com/spf13/cobra" ) func dcomCmdInit() { - registerRpcFlags(dcomCmd) - dcomMmcCmdInit() - dcomCmd.AddCommand(dcomMmcCmd) + registerRpcFlags(dcomCmd) + dcomMmcCmdInit() + dcomCmd.AddCommand(dcomMmcCmd) } func dcomMmcCmdInit() { - dcomMmcCmd.Flags().StringVarP(&dcomMmc.WorkingDirectory, "directory", "d", `C:\`, "Working directory") - dcomMmcCmd.Flags().StringVar(&dcomMmc.WindowState, "window", "Minimized", "Window state") + dcomMmcCmd.Flags().StringVarP(&dcomMmc.WorkingDirectory, "directory", "d", `C:\`, "Working directory") + dcomMmcCmd.Flags().StringVar(&dcomMmc.WindowState, "window", "Minimized", "Window state") - registerProcessExecutionArgs(dcomMmcCmd) - registerExecutionOutputArgs(dcomMmcCmd) + registerProcessExecutionArgs(dcomMmcCmd) + registerExecutionOutputArgs(dcomMmcCmd) } var ( - dcomMmc dcomexec.DcomMmc - - dcomCmd = &cobra.Command{ - Use: "dcom", - Short: "Establish execution via DCOM", - Args: cobra.NoArgs, - } - - dcomMmcCmd = &cobra.Command{ - Use: "mmc [target]", - Short: "Establish execution via the DCOM MMC20.Application object", - Long: `Description: + dcomMmc dcomexec.DcomMmc + + dcomCmd = &cobra.Command{ + Use: "dcom", + Short: "Execute with Distributed Component Object Model (MS-DCOM)", + GroupID: "module", + Args: cobra.NoArgs, + } + + dcomMmcCmd = &cobra.Command{ + Use: "mmc [target]", + Short: "Execute with the DCOM MMC20.Application object", + Long: `Description: The mmc method uses the exposed MMC20.Application object to call Document.ActiveView.ShellExec, - and ultimately execute system commands. + and ultimately spawn a process on the remote host. References: - https://www.scorpiones.io/articles/lateral-movement-using-dcom-objects - https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/ - https://github.com/fortra/impacket/blob/master/examples/dcomexec.py - https://learn.microsoft.com/en-us/previous-versions/windows/desktop/mmc/view-executeshellcommand + - https://www.scorpiones.io/articles/lateral-movement-using-dcom-objects + - https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/ + - https://github.com/fortra/impacket/blob/master/examples/dcomexec.py + - https://learn.microsoft.com/en-us/previous-versions/windows/desktop/mmc/view-executeshellcommand `, - Args: args( - argsRpcClient("host"), - argsOutput("smb"), - ), - Run: func(cmd *cobra.Command, args []string) { - dcomMmc.Dcom.Client = &rpcClient - dcomMmc.IO = exec - - ctx := log.WithContext(gssapi.NewSecurityContext(context.TODO())) - - if err := goexec.ExecuteCleanMethod(ctx, &dcomMmc, &exec); err != nil { - log.Fatal().Err(err).Msg("Operation failed") - } - }, - } + Args: args( + argsRpcClient("host"), + argsOutput("smb"), + ), + Run: func(cmd *cobra.Command, args []string) { + dcomMmc.Dcom.Client = &rpcClient + dcomMmc.IO = exec + + ctx := log.WithContext(gssapi.NewSecurityContext(context.TODO())) + + if err := goexec.ExecuteCleanMethod(ctx, &dcomMmc, &exec); err != nil { + log.Fatal().Err(err).Msg("Operation failed") + } + }, + } ) diff --git a/cmd/root.go b/cmd/root.go index 300588d..815730e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,167 +1,201 @@ package cmd import ( - "fmt" - "github.com/FalconOpsLLC/goexec/internal/util" - "github.com/FalconOpsLLC/goexec/pkg/goexec" - "github.com/FalconOpsLLC/goexec/pkg/goexec/dce" - "github.com/FalconOpsLLC/goexec/pkg/goexec/smb" - "github.com/RedTeamPentesting/adauth" - "github.com/oiweiwei/go-msrpc/ssp" - "github.com/oiweiwei/go-msrpc/ssp/gssapi" - "github.com/rs/zerolog" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "io" - "os" + "fmt" + "github.com/FalconOpsLLC/goexec/internal/util" + "github.com/FalconOpsLLC/goexec/pkg/goexec" + "github.com/FalconOpsLLC/goexec/pkg/goexec/dce" + "github.com/FalconOpsLLC/goexec/pkg/goexec/smb" + "github.com/RedTeamPentesting/adauth" + "github.com/oiweiwei/go-msrpc/ssp" + "github.com/oiweiwei/go-msrpc/ssp/gssapi" + "github.com/rs/zerolog" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "golang.org/x/term" + "io" + "os" ) var ( - returnCode int - outputMethod string - outputPath string - proxy string - - // === Logging === - logJson bool // Log output in JSON lines - logDebug bool // Output debug log messages - logQuiet bool // Suppress logging output - logOutput string // Log output file - logLevel zerolog.Level = zerolog.InfoLevel - logFile io.WriteCloser = os.Stderr - log zerolog.Logger - // =============== - - rpcClient dce.Client - smbClient smb.Client - - exec = goexec.ExecutionIO{ - Input: new(goexec.ExecutionInput), - Output: new(goexec.ExecutionOutput), - } - - adAuthOpts *adauth.Options - credential *adauth.Credential - target *adauth.Target - - rootCmd = &cobra.Command{ - Use: "goexec", - Short: `Windows remote execution multitool`, - Long: ``, - - PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { - - // Parse logging options - { - if logOutput != "" { - logFile, err = os.OpenFile(logOutput, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return - } - logJson = true - } - if logQuiet { - logLevel = zerolog.ErrorLevel - } else if logDebug { - logLevel = zerolog.DebugLevel - } - if logJson { - log = zerolog.New(logFile).With().Timestamp().Logger() - } else { - log = zerolog.New(zerolog.ConsoleWriter{Out: logFile}).With().Timestamp().Logger() - } - log = log.Level(logLevel) - } - - if proxy != "" { - rpcClient.Proxy = proxy - smbClient.Proxy = proxy - } - - if outputPath != "" { - if outputMethod == "smb" { - if exec.Output.RemotePath == "" { - exec.Output.RemotePath = util.RandomWindowsTempFile() - } - exec.Output.Provider = &smb.OutputFileFetcher{ - Client: &smbClient, - Share: `C$`, - File: exec.Output.RemotePath, - DeleteOutputFile: !exec.Output.NoDelete, - } - } - } - return - }, - - PersistentPostRun: func(cmd *cobra.Command, args []string) { - if err := logFile.Close(); err != nil { - // ... - } - }, - } + flagGroups = map[string]*pflag.FlagSet{} + + returnCode int + outputMethod string + outputPath string + proxy string + + // === Logging === + logJson bool // Log output in JSON lines + logDebug bool // Output debug log messages + logQuiet bool // Suppress logging output + logOutput string // Log output file + logLevel zerolog.Level = zerolog.InfoLevel + logFile io.WriteCloser = os.Stderr + log zerolog.Logger + // =============== + + rpcClient dce.Client + smbClient smb.Client + + exec = goexec.ExecutionIO{ + Input: new(goexec.ExecutionInput), + Output: new(goexec.ExecutionOutput), + } + + adAuthOpts *adauth.Options + credential *adauth.Credential + target *adauth.Target + + rootCmd = &cobra.Command{ + Use: "goexec", + Short: `Windows remote execution multitool`, + Long: ``, + + PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { + + // Parse logging options + { + if logOutput != "" { + logFile, err = os.OpenFile(logOutput, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return + } + logJson = true + } + if logQuiet { + logLevel = zerolog.ErrorLevel + } else if logDebug { + logLevel = zerolog.DebugLevel + } + if logJson { + log = zerolog.New(logFile).With().Timestamp().Logger() + } else { + log = zerolog.New(zerolog.ConsoleWriter{Out: logFile}).With().Timestamp().Logger() + } + log = log.Level(logLevel) + } + + if proxy != "" { + rpcClient.Proxy = proxy + smbClient.Proxy = proxy + } + + if outputPath != "" { + if outputMethod == "smb" { + if exec.Output.RemotePath == "" { + exec.Output.RemotePath = util.RandomWindowsTempFile() + } + exec.Output.Provider = &smb.OutputFileFetcher{ + Client: &smbClient, + Share: `C$`, + File: exec.Output.RemotePath, + DeleteOutputFile: !exec.Output.NoDelete, + } + } + } + return + }, + + PersistentPostRun: func(cmd *cobra.Command, args []string) { + if err := logFile.Close(); err != nil { + // ... + } + }, + } ) +func addFlagSet(fs *pflag.FlagSet) { + flagGroups[fs.Name()] = fs +} + +func moduleFlags(cmd *cobra.Command, module string) (fs *pflag.FlagSet) { + fs, _ = flagGroups[module] + return +} + +// Uses the users terminal size or width of 80 if cannot determine users width +// Based on https://github.com/spf13/cobra/issues/1805#issuecomment-1246192724 +func wrappedFlagUsages(cmd *pflag.FlagSet) string { + fd := int(os.Stdout.Fd()) + width := 80 + + // Get the terminal width and dynamically set + termWidth, _, err := term.GetSize(fd) + if err == nil { + width = termWidth + } + + return cmd.FlagUsagesWrapped(width - 1) +} + func init() { - // Auth init - { - gssapi.AddMechanism(ssp.SPNEGO) - gssapi.AddMechanism(ssp.NTLM) - gssapi.AddMechanism(ssp.KRB5) - } - - // Cobra init - { - cobra.EnableCommandSorting = false - - rootCmd.InitDefaultVersionFlag() - rootCmd.InitDefaultHelpCmd() - - // Logging flags - { - logOpts := pflag.NewFlagSet("Logging", pflag.ExitOnError) - logOpts.BoolVar(&logDebug, "debug", false, "Enable debug logging") - logOpts.BoolVar(&logJson, "json", false, "Write logging output in JSON lines") - logOpts.BoolVar(&logQuiet, "quiet", false, "Disable info logging") - logOpts.StringVarP(&logOutput, "log-file", "O", "", "Write JSON logging output to file") - rootCmd.PersistentFlags().AddFlagSet(logOpts) - } - - // Global networking flags - { - netOpts := pflag.NewFlagSet("Network", pflag.ExitOnError) - netOpts.StringVarP(&proxy, "proxy", "x", "", "Proxy URL") - rootCmd.PersistentFlags().AddFlagSet(netOpts) - } - - // Authentication flags - { - adAuthOpts = &adauth.Options{ - Debug: log.Debug().Msgf, - } - authOpts := pflag.NewFlagSet("Authentication", pflag.ExitOnError) - adAuthOpts.RegisterFlags(authOpts) - rootCmd.PersistentFlags().AddFlagSet(authOpts) - } - - // Modules init - { - dcomCmdInit() - rootCmd.AddCommand(dcomCmd) - wmiCmdInit() - rootCmd.AddCommand(wmiCmd) - scmrCmdInit() - rootCmd.AddCommand(scmrCmd) - tschCmdInit() - rootCmd.AddCommand(tschCmd) - } - } + // Auth init + { + gssapi.AddMechanism(ssp.SPNEGO) + gssapi.AddMechanism(ssp.NTLM) + gssapi.AddMechanism(ssp.KRB5) + } + + // Cobra init + { + cobra.EnableCommandSorting = false + + rootCmd.InitDefaultVersionFlag() + rootCmd.InitDefaultHelpCmd() + + modules := &cobra.Group{ + ID: "module", + Title: "Execution Modules:", + } + rootCmd.AddGroup(modules) + + // Logging flags + { + logOpts := pflag.NewFlagSet("Logging", pflag.ExitOnError) + logOpts.BoolVar(&logDebug, "debug", false, "Enable debug logging") + logOpts.BoolVar(&logJson, "json", false, "Write logging output in JSON lines") + logOpts.BoolVar(&logQuiet, "quiet", false, "Disable info logging") + logOpts.StringVarP(&logOutput, "log-file", "O", "", "Write JSON logging output to file") + rootCmd.PersistentFlags().AddFlagSet(logOpts) + flagGroups["Logging"] = logOpts + } + + // Global networking flags + { + netOpts := pflag.NewFlagSet("Network", pflag.ExitOnError) + netOpts.StringVarP(&proxy, "proxy", "x", "", "Proxy URL") + rootCmd.PersistentFlags().AddFlagSet(netOpts) + } + + // Authentication flags + { + adAuthOpts = &adauth.Options{ + Debug: log.Debug().Msgf, + } + authOpts := pflag.NewFlagSet("Authentication", pflag.ExitOnError) + adAuthOpts.RegisterFlags(authOpts) + rootCmd.PersistentFlags().AddFlagSet(authOpts) + } + + // Modules init + { + dcomCmdInit() + rootCmd.AddCommand(dcomCmd) + wmiCmdInit() + rootCmd.AddCommand(wmiCmd) + scmrCmdInit() + rootCmd.AddCommand(scmrCmd) + tschCmdInit() + rootCmd.AddCommand(tschCmd) + } + } } func Execute() { - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } - os.Exit(returnCode) + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } + os.Exit(returnCode) } diff --git a/cmd/scmr.go b/cmd/scmr.go index 08e23d7..b67b2a6 100644 --- a/cmd/scmr.go +++ b/cmd/scmr.go @@ -64,20 +64,21 @@ var ( scmrDelete scmrexec.ScmrDelete scmrCmd = &cobra.Command{ - Use: "scmr", - Short: "Establish execution via SCMR", - Args: cobra.NoArgs, + Use: "scmr", + Short: "Execute with Service Control Manager Remote (MS-SCMR)", + GroupID: "module", + Args: cobra.NoArgs, } scmrCreateCmd = &cobra.Command{ Use: "create [target]", - Short: "Create & run a new Windows service to gain execution", + Short: "Spawn a remote process by creating & running a Windows service", Long: `Description: - The create method calls RCreateServiceW to create a new Windows service with - the provided executable & arguments as the lpBinaryPathName + The create method calls RCreateServiceW to create a new Windows service on the + remote target with the provided executable & arguments as the lpBinaryPathName References: - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-scmr/6a8ca926-9477-4dd4-b766-692fab07227e + - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-scmr/6a8ca926-9477-4dd4-b766-692fab07227e `, Args: argsRpcClient("cifs"), diff --git a/cmd/tsch.go b/cmd/tsch.go index a647f06..0ed5d9f 100644 --- a/cmd/tsch.go +++ b/cmd/tsch.go @@ -64,9 +64,10 @@ var ( tschTask string tschCmd = &cobra.Command{ - Use: "tsch", - Short: "Establish execution via Windows Task Scheduler (MS-TSCH)", - Args: cobra.NoArgs, + Use: "tsch", + Short: "Execute with Windows Task Scheduler (MS-TSCH)", + GroupID: "module", + Args: cobra.NoArgs, } tschDemandCmd = &cobra.Command{ @@ -78,8 +79,8 @@ var ( additionally call SchRpcRun to forcefully start the task. References: - SchRpcRegisterTask - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/849c131a-64e4-46ef-b015-9d4c599c5167 - SchRpcRun - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/77f2250d-500a-40ee-be18-c82f7079c4f0 + - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/849c131a-64e4-46ef-b015-9d4c599c5167 + - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/77f2250d-500a-40ee-be18-c82f7079c4f0 `, Args: args( argsRpcClient("cifs"), @@ -1,117 +1,118 @@ package cmd import ( - "context" - "encoding/json" - "fmt" - "github.com/FalconOpsLLC/goexec/pkg/goexec" - wmiexec "github.com/FalconOpsLLC/goexec/pkg/goexec/wmi" - "github.com/oiweiwei/go-msrpc/ssp/gssapi" - "github.com/spf13/cobra" + "context" + "encoding/json" + "fmt" + "github.com/FalconOpsLLC/goexec/pkg/goexec" + wmiexec "github.com/FalconOpsLLC/goexec/pkg/goexec/wmi" + "github.com/oiweiwei/go-msrpc/ssp/gssapi" + "github.com/spf13/cobra" ) func wmiCmdInit() { - registerRpcFlags(wmiCmd) + registerRpcFlags(wmiCmd) - wmiCallCmdInit() - wmiCmd.AddCommand(wmiCallCmd) + wmiCallCmdInit() + wmiCmd.AddCommand(wmiCallCmd) - wmiProcCmdInit() - wmiCmd.AddCommand(wmiProcCmd) + wmiProcCmdInit() + wmiCmd.AddCommand(wmiProcCmd) } func wmiCallArgs(_ *cobra.Command, _ []string) error { - return json.Unmarshal([]byte(wmiArguments), &wmiCall.Args) + return json.Unmarshal([]byte(wmiArguments), &wmiCall.Args) } func wmiCallCmdInit() { - wmiCallCmd.Flags().StringVarP(&wmiCall.Resource, "namespace", "n", "//./root/cimv2", "WMI namespace") - wmiCallCmd.Flags().StringVarP(&wmiCall.Class, "class", "C", "", `WMI class to instantiate (i.e. "Win32_Process")`) - wmiCallCmd.Flags().StringVarP(&wmiCall.Method, "method", "m", "", `WMI Method to call (i.e. "Create")`) - wmiCallCmd.Flags().StringVarP(&wmiArguments, "args", "A", "{}", `WMI Method argument(s) in JSON dictionary format (i.e. {"Command":"calc.exe"})`) - - if err := wmiCallCmd.MarkFlagRequired("class"); err != nil { - panic(err) - } - if err := wmiCallCmd.MarkFlagRequired("method"); err != nil { - panic(err) - } + wmiCallCmd.Flags().StringVarP(&wmiCall.Resource, "namespace", "n", "//./root/cimv2", "WMI namespace") + wmiCallCmd.Flags().StringVarP(&wmiCall.Class, "class", "C", "", `WMI class to instantiate (i.e. "Win32_Process")`) + wmiCallCmd.Flags().StringVarP(&wmiCall.Method, "method", "m", "", `WMI Method to call (i.e. "Create")`) + wmiCallCmd.Flags().StringVarP(&wmiArguments, "args", "A", "{}", `WMI Method argument(s) in JSON dictionary format (i.e. {"Command":"calc.exe"})`) + + if err := wmiCallCmd.MarkFlagRequired("class"); err != nil { + panic(err) + } + if err := wmiCallCmd.MarkFlagRequired("method"); err != nil { + panic(err) + } } func wmiProcCmdInit() { - wmiProcCmd.Flags().StringVarP(&wmiProc.Resource, "namespace", "n", "//./root/cimv2", "WMI namespace") - wmiProcCmd.Flags().StringVarP(&wmiProc.WorkingDirectory, "directory", "d", `C:\`, "Working directory") + wmiProcCmd.Flags().StringVarP(&wmiProc.Resource, "namespace", "n", "//./root/cimv2", "WMI namespace") + wmiProcCmd.Flags().StringVarP(&wmiProc.WorkingDirectory, "directory", "d", `C:\`, "Working directory") - registerProcessExecutionArgs(wmiProcCmd) - registerExecutionOutputArgs(wmiProcCmd) + registerProcessExecutionArgs(wmiProcCmd) + registerExecutionOutputArgs(wmiProcCmd) } var ( - wmiCall = wmiexec.WmiCall{} - wmiProc = wmiexec.WmiProc{} - - wmiArguments string - - wmiCmd = &cobra.Command{ - Use: "wmi", - Short: "Establish execution via Windows Management Instrumentation Remote Protocol (MS-WMI)", - Args: cobra.NoArgs, - } - - wmiCallCmd = &cobra.Command{ - Use: "call", - Short: "Execute specified WMI method", - Long: `Description: + wmiCall = wmiexec.WmiCall{} + wmiProc = wmiexec.WmiProc{} + + wmiArguments string + + wmiCmd = &cobra.Command{ + Use: "wmi", + Short: "Execute with Windows Management Instrumentation (MS-WMI)", + GroupID: "module", + Args: cobra.NoArgs, + } + + wmiCallCmd = &cobra.Command{ + Use: "call", + Short: "Execute specified WMI method", + Long: `Description: The call method creates an instance of the specified WMI class (-c), then calls the provided method (-m) with the provided arguments (-A). References: https://learn.microsoft.com/en-us/windows/win32/wmisdk/wmi-classes `, - Args: args(argsRpcClient("host"), wmiCallArgs), - - Run: func(cmd *cobra.Command, args []string) { - var err error - - ctx := gssapi.NewSecurityContext(context.Background()) - - ctx = log.With(). - Str("module", "wmi"). - Str("method", "call"). - Logger(). - WithContext(ctx) - - if err = rpcClient.Connect(ctx); err != nil { - log.Fatal().Err(err).Msg("Connection failed") - } - - defer func() { - closeErr := rpcClient.Close(ctx) - if closeErr != nil { - log.Error().Err(closeErr).Msg("Failed to close connection") - } - }() - - if err = wmiCall.Init(ctx); err != nil { - log.Error().Err(err).Msg("Module initialization failed") - returnCode = 2 - return - } - - out, err := wmiCall.Call(ctx) - if err != nil { - log.Error().Err(err).Msg("Call failed") - returnCode = 4 - return - } - fmt.Println(string(out)) - }, - } - - wmiProcCmd = &cobra.Command{ - Use: "proc", - Short: "Start a Windows process", - Long: `Description: + Args: args(argsRpcClient("host"), wmiCallArgs), + + Run: func(cmd *cobra.Command, args []string) { + var err error + + ctx := gssapi.NewSecurityContext(context.Background()) + + ctx = log.With(). + Str("module", "wmi"). + Str("method", "call"). + Logger(). + WithContext(ctx) + + if err = rpcClient.Connect(ctx); err != nil { + log.Fatal().Err(err).Msg("Connection failed") + } + + defer func() { + closeErr := rpcClient.Close(ctx) + if closeErr != nil { + log.Error().Err(closeErr).Msg("Failed to close connection") + } + }() + + if err = wmiCall.Init(ctx); err != nil { + log.Error().Err(err).Msg("Module initialization failed") + returnCode = 2 + return + } + + out, err := wmiCall.Call(ctx) + if err != nil { + log.Error().Err(err).Msg("Call failed") + returnCode = 4 + return + } + fmt.Println(string(out)) + }, + } + + wmiProcCmd = &cobra.Command{ + Use: "proc", + Short: "Start a Windows process", + Long: `Description: The proc method creates an instance of the Win32_Process WMI class, then calls the Win32_Process.Create method with the provided command (-c), and optional working directory (-d). @@ -119,23 +120,23 @@ References: References: https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/create-method-in-class-win32-process `, - Args: args( - argsOutput("smb"), - argsRpcClient("host"), - ), - - Run: func(cmd *cobra.Command, args []string) { - wmiProc.Client = &rpcClient - wmiProc.IO = exec - - ctx := log.With(). - Str("module", "wmi"). - Str("method", "proc"). - Logger().WithContext(gssapi.NewSecurityContext(context.Background())) - - if err := goexec.ExecuteCleanMethod(ctx, &wmiProc, &exec); err != nil { - log.Fatal().Err(err).Msg("Operation failed") - } - }, - } + Args: args( + argsOutput("smb"), + argsRpcClient("host"), + ), + + Run: func(cmd *cobra.Command, args []string) { + wmiProc.Client = &rpcClient + wmiProc.IO = exec + + ctx := log.With(). + Str("module", "wmi"). + Str("method", "proc"). + Logger().WithContext(gssapi.NewSecurityContext(context.Background())) + + if err := goexec.ExecuteCleanMethod(ctx, &wmiProc, &exec); err != nil { + log.Fatal().Err(err).Msg("Operation failed") + } + }, + } ) |