aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorBryan McNulty <bryanmcnulty@protonmail.com>2025-04-17 03:22:59 -0500
committerBryan McNulty <bryanmcnulty@protonmail.com>2025-04-17 03:22:59 -0500
commitfc2ed14f92dd82268ca94d3d08c3760aba534d3f (patch)
treef17c5ccb01dfbf2764bfa938ee4570a9fa1b38d3 /cmd
parent22e4fc56cca0a8c466bf09a6f529573063ce5cb6 (diff)
downloadgoexec-fc2ed14f92dd82268ca94d3d08c3760aba534d3f.tar.gz
goexec-fc2ed14f92dd82268ca94d3d08c3760aba534d3f.zip
Slim down cobra Run function (WMI & TSCH)
Diffstat (limited to 'cmd')
-rw-r--r--cmd/root.go184
-rw-r--r--cmd/tsch.go208
-rw-r--r--cmd/wmi.go224
3 files changed, 297 insertions, 319 deletions
diff --git a/cmd/root.go b/cmd/root.go
index 0f8a17a..3d696aa 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -1,112 +1,112 @@
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"
- "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"
+ "os"
)
var (
- debug bool
- logJson bool
- returnCode int
- outputMethod string
- outputPath string
- proxy string
-
- log zerolog.Logger
-
- rpcClient dce.Client
- smbClient smb.Client
-
- exec = goexec.ExecutionIO{
- Input: new(goexec.ExecutionInput),
- Output: new(goexec.ExecutionOutput),
- }
-
- authOpts *adauth.Options
- credential *adauth.Credential
- target *adauth.Target
-
- rootCmd = &cobra.Command{
- Use: "goexec",
- Short: `Windows remote execution multitool`,
- Long: `TODO`,
-
- PersistentPreRun: func(cmd *cobra.Command, args []string) {
-
- if logJson {
- log = zerolog.New(os.Stderr)
- } else {
- log = zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr})
- }
-
- log = log.Level(zerolog.InfoLevel).With().Timestamp().Logger()
- if debug {
- log = log.Level(zerolog.DebugLevel)
- }
-
- 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: true, // TEMP
- }
- }
- },
- }
+ debug bool
+ logJson bool
+ returnCode int
+ outputMethod string
+ outputPath string
+ proxy string
+
+ log zerolog.Logger
+
+ rpcClient dce.Client
+ smbClient smb.Client
+
+ exec = goexec.ExecutionIO{
+ Input: new(goexec.ExecutionInput),
+ Output: new(goexec.ExecutionOutput),
+ }
+
+ authOpts *adauth.Options
+ credential *adauth.Credential
+ target *adauth.Target
+
+ rootCmd = &cobra.Command{
+ Use: "goexec",
+ Short: `Windows remote execution multitool`,
+ Long: `TODO`,
+
+ PersistentPreRun: func(cmd *cobra.Command, args []string) {
+
+ if logJson {
+ log = zerolog.New(os.Stderr)
+ } else {
+ log = zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr})
+ }
+
+ log = log.Level(zerolog.InfoLevel).With().Timestamp().Logger()
+ if debug {
+ log = log.Level(zerolog.DebugLevel)
+ }
+
+ 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, // TEMP
+ }
+ }
+ },
+ }
)
func init() {
- // Cobra init
- {
- cobra.EnableCommandSorting = false
+ // Cobra init
+ {
+ cobra.EnableCommandSorting = false
- rootCmd.InitDefaultVersionFlag()
- rootCmd.InitDefaultHelpCmd()
- rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "Enable debug logging")
- rootCmd.PersistentFlags().BoolVar(&logJson, "log-json", false, "Log in JSON format")
+ rootCmd.InitDefaultVersionFlag()
+ rootCmd.InitDefaultHelpCmd()
+ rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "Enable debug logging")
+ rootCmd.PersistentFlags().BoolVar(&logJson, "log-json", false, "Log in JSON format")
- dcomCmdInit()
- rootCmd.AddCommand(dcomCmd)
+ dcomCmdInit()
+ rootCmd.AddCommand(dcomCmd)
- wmiCmdInit()
- rootCmd.AddCommand(wmiCmd)
+ wmiCmdInit()
+ rootCmd.AddCommand(wmiCmd)
- scmrCmdInit()
- rootCmd.AddCommand(scmrCmd)
+ scmrCmdInit()
+ rootCmd.AddCommand(scmrCmd)
- tschCmdInit()
- rootCmd.AddCommand(tschCmd)
- }
+ tschCmdInit()
+ rootCmd.AddCommand(tschCmd)
+ }
- // Auth init
- {
- gssapi.AddMechanism(ssp.SPNEGO)
- gssapi.AddMechanism(ssp.NTLM)
- gssapi.AddMechanism(ssp.KRB5)
+ // Auth init
+ {
+ gssapi.AddMechanism(ssp.SPNEGO)
+ gssapi.AddMechanism(ssp.NTLM)
+ gssapi.AddMechanism(ssp.KRB5)
- authOpts = &adauth.Options{Debug: log.Debug().Msgf}
- authOpts.RegisterFlags(rootCmd.PersistentFlags())
- }
+ authOpts = &adauth.Options{Debug: log.Debug().Msgf}
+ authOpts.RegisterFlags(rootCmd.PersistentFlags())
+ }
}
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/tsch.go b/cmd/tsch.go
index 9192b0a..328adcd 100644
--- a/cmd/tsch.go
+++ b/cmd/tsch.go
@@ -1,87 +1,87 @@
package cmd
import (
- "context"
- "github.com/FalconOpsLLC/goexec/internal/util"
- "github.com/FalconOpsLLC/goexec/pkg/goexec"
- tschexec "github.com/FalconOpsLLC/goexec/pkg/goexec/tsch"
- "github.com/oiweiwei/go-msrpc/ssp/gssapi"
- "github.com/spf13/cobra"
- "time"
+ "context"
+ "github.com/FalconOpsLLC/goexec/internal/util"
+ "github.com/FalconOpsLLC/goexec/pkg/goexec"
+ tschexec "github.com/FalconOpsLLC/goexec/pkg/goexec/tsch"
+ "github.com/oiweiwei/go-msrpc/ssp/gssapi"
+ "github.com/spf13/cobra"
+ "time"
)
func tschCmdInit() {
- registerRpcFlags(tschCmd)
+ registerRpcFlags(tschCmd)
- tschDemandCmdInit()
- tschCmd.AddCommand(tschDemandCmd)
+ tschDemandCmdInit()
+ tschCmd.AddCommand(tschDemandCmd)
- tschCreateCmdInit()
- tschCmd.AddCommand(tschCreateCmd)
+ tschCreateCmdInit()
+ tschCmd.AddCommand(tschCreateCmd)
}
func argsTschTaskIdentifiers(name, path string) error {
- switch {
- case path != "":
- return tschexec.ValidateTaskPath(path)
- case name != "":
- return tschexec.ValidateTaskName(name)
- default:
- }
- return nil
+ switch {
+ case path != "":
+ return tschexec.ValidateTaskPath(path)
+ case name != "":
+ return tschexec.ValidateTaskName(name)
+ default:
+ }
+ return nil
}
func argsTschDemand(_ *cobra.Command, _ []string) error {
- return argsTschTaskIdentifiers(tschDemand.TaskName, tschDemand.TaskPath)
+ return argsTschTaskIdentifiers(tschDemand.TaskName, tschDemand.TaskPath)
}
func argsTschCreate(_ *cobra.Command, _ []string) error {
- return argsTschTaskIdentifiers(tschCreate.TaskName, tschCreate.TaskPath)
+ return argsTschTaskIdentifiers(tschCreate.TaskName, tschCreate.TaskPath)
}
func tschDemandCmdInit() {
- tschDemandCmd.Flags().StringVarP(&tschDemand.TaskName, "name", "t", "", "Name of task to register")
- tschDemandCmd.Flags().StringVarP(&tschDemand.TaskPath, "path", "P", "", "Path of task to register")
- tschDemandCmd.Flags().Uint32Var(&tschDemand.SessionId, "session", 0, "Hijack existing session given the session ID")
- tschDemandCmd.Flags().BoolVar(&tschDemand.NoDelete, "no-delete", false, "Don't delete task after execution")
- tschDemandCmd.Flags().StringVar(&tschDemand.UserSid, "sid", "S-1-5-18", "User SID to impersonate")
+ tschDemandCmd.Flags().StringVarP(&tschDemand.TaskName, "name", "t", "", "Name of task to register")
+ tschDemandCmd.Flags().StringVarP(&tschDemand.TaskPath, "path", "P", "", "Path of task to register")
+ tschDemandCmd.Flags().Uint32Var(&tschDemand.SessionId, "session", 0, "Hijack existing session given the session ID")
+ tschDemandCmd.Flags().BoolVar(&tschDemand.NoDelete, "no-delete", false, "Don't delete task after execution")
+ tschDemandCmd.Flags().StringVar(&tschDemand.UserSid, "sid", "S-1-5-18", "User SID to impersonate")
- registerProcessExecutionArgs(tschDemandCmd)
- registerExecutionOutputArgs(tschDemandCmd)
+ registerProcessExecutionArgs(tschDemandCmd)
+ registerExecutionOutputArgs(tschDemandCmd)
- tschDemandCmd.MarkFlagsMutuallyExclusive("name", "path")
+ tschDemandCmd.MarkFlagsMutuallyExclusive("name", "path")
}
func tschCreateCmdInit() {
- tschCreateCmd.Flags().StringVarP(&tschCreate.TaskName, "name", "t", "", "Name of task to register")
- tschCreateCmd.Flags().StringVarP(&tschCreate.TaskPath, "path", "P", "", "Path of task to register")
- tschCreateCmd.Flags().DurationVar(&tschCreate.StopDelay, "delay-stop", 5*time.Second, "Delay between task execution and termination. This will not stop the process spawned by the task")
- tschCreateCmd.Flags().DurationVar(&tschCreate.StartDelay, "start-delay", 5*time.Second, "Delay between task registration and execution")
- tschCreateCmd.Flags().DurationVar(&tschCreate.DeleteDelay, "delete-delay", 0*time.Second, "Delay between task termination and deletion")
- tschCreateCmd.Flags().BoolVar(&tschCreate.NoDelete, "no-delete", false, "Don't delete task after execution")
- tschCreateCmd.Flags().BoolVar(&tschCreate.CallDelete, "call-delete", false, "Directly call SchRpcDelete to delete task")
- tschCreateCmd.Flags().StringVar(&tschCreate.UserSid, "sid", "S-1-5-18", "User SID to impersonate")
-
- registerProcessExecutionArgs(tschCreateCmd)
- registerExecutionOutputArgs(tschCreateCmd)
-
- tschCreateCmd.MarkFlagsMutuallyExclusive("name", "path")
+ tschCreateCmd.Flags().StringVarP(&tschCreate.TaskName, "name", "t", "", "Name of task to register")
+ tschCreateCmd.Flags().StringVarP(&tschCreate.TaskPath, "path", "P", "", "Path of task to register")
+ tschCreateCmd.Flags().DurationVar(&tschCreate.StopDelay, "delay-stop", 5*time.Second, "Delay between task execution and termination. This will not stop the process spawned by the task")
+ tschCreateCmd.Flags().DurationVar(&tschCreate.StartDelay, "start-delay", 5*time.Second, "Delay between task registration and execution")
+ tschCreateCmd.Flags().DurationVar(&tschCreate.DeleteDelay, "delete-delay", 0*time.Second, "Delay between task termination and deletion")
+ tschCreateCmd.Flags().BoolVar(&tschCreate.NoDelete, "no-delete", false, "Don't delete task after execution")
+ tschCreateCmd.Flags().BoolVar(&tschCreate.CallDelete, "call-delete", false, "Directly call SchRpcDelete to delete task")
+ tschCreateCmd.Flags().StringVar(&tschCreate.UserSid, "sid", "S-1-5-18", "User SID to impersonate")
+
+ registerProcessExecutionArgs(tschCreateCmd)
+ registerExecutionOutputArgs(tschCreateCmd)
+
+ tschCreateCmd.MarkFlagsMutuallyExclusive("name", "path")
}
var (
- tschDemand tschexec.TschDemand
- tschCreate tschexec.TschCreate
-
- tschCmd = &cobra.Command{
- Use: "tsch",
- Short: "Establish execution via Windows Task Scheduler (MS-TSCH)",
- Args: cobra.NoArgs,
- }
-
- tschDemandCmd = &cobra.Command{
- Use: "demand [target]",
- Short: "Register a remote scheduled task and demand immediate start",
- Long: `Description:
+ tschDemand tschexec.TschDemand
+ tschCreate tschexec.TschCreate
+
+ tschCmd = &cobra.Command{
+ Use: "tsch",
+ Short: "Establish execution via Windows Task Scheduler (MS-TSCH)",
+ Args: cobra.NoArgs,
+ }
+
+ tschDemandCmd = &cobra.Command{
+ Use: "demand [target]",
+ Short: "Register a remote scheduled task and demand immediate start",
+ Long: `Description:
Similar to the create method, the demand method will call SchRpcRegisterTask,
But rather than setting a defined time when the task will start, it will
additionally call SchRpcRun to forcefully start the task.
@@ -90,33 +90,31 @@ 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
`,
- Args: args(
- argsRpcClient("cifs"),
- argsOutput("smb"),
- argsTschDemand,
- ),
-
- Run: func(cmd *cobra.Command, args []string) {
- var err error
-
- tschDemand.Client = &rpcClient
- tschDemand.IO = exec
-
- if tschDemand.TaskName == "" && tschDemand.TaskPath == "" {
- tschDemand.TaskPath = `\` + util.RandomString()
- }
-
- ctx := log.WithContext(gssapi.NewSecurityContext(context.TODO()))
-
- if err = goexec.ExecuteCleanMethod(ctx, &tschDemand, &exec); err != nil {
- log.Fatal().Err(err).Msg("Operation failed")
- }
- },
- }
- tschCreateCmd = &cobra.Command{
- Use: "create [target]",
- Short: "Create a remote scheduled task with an automatic start time",
- Long: `Description:
+ Args: args(
+ argsRpcClient("cifs"),
+ argsOutput("smb"),
+ argsTschDemand,
+ ),
+
+ Run: func(cmd *cobra.Command, args []string) {
+ tschDemand.Client = &rpcClient
+ tschDemand.IO = exec
+
+ if tschDemand.TaskName == "" && tschDemand.TaskPath == "" {
+ tschDemand.TaskPath = `\` + util.RandomString()
+ }
+
+ ctx := log.WithContext(gssapi.NewSecurityContext(context.TODO()))
+
+ if err := goexec.ExecuteCleanMethod(ctx, &tschDemand, &exec); err != nil {
+ log.Fatal().Err(err).Msg("Operation failed")
+ }
+ },
+ }
+ tschCreateCmd = &cobra.Command{
+ Use: "create [target]",
+ Short: "Create a remote scheduled task with an automatic start time",
+ Long: `Description:
The create method calls SchRpcRegisterTask to register a scheduled task
with an automatic start time.This method avoids directly calling SchRpcRun,
and can even avoid calling SchRpcDelete by populating the DeleteExpiredTaskAfter
@@ -128,27 +126,25 @@ References:
SchRpcDelete - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/360bb9b1-dd2a-4b36-83ee-21f12cb97cff
DeleteExpiredTaskAfter - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/6bfde6fe-440e-4ddd-b4d6-c8fc0bc06fae
`,
- Args: args(
- argsRpcClient("cifs"),
- argsOutput("smb"),
- argsTschCreate,
- ),
-
- Run: func(cmd *cobra.Command, args []string) {
- var err error
-
- tschCreate.Tsch.Client = &rpcClient
- tschCreate.IO = exec
-
- if tschCreate.TaskName == "" && tschDemand.TaskPath == "" {
- tschCreate.TaskPath = `\` + util.RandomString()
- }
-
- ctx := log.WithContext(gssapi.NewSecurityContext(context.TODO()))
-
- if err = goexec.ExecuteCleanMethod(ctx, &tschCreate, &exec); err != nil {
- log.Fatal().Err(err).Msg("Operation failed")
- }
- },
- }
+ Args: args(
+ argsRpcClient("cifs"),
+ argsOutput("smb"),
+ argsTschCreate,
+ ),
+
+ Run: func(cmd *cobra.Command, args []string) {
+ tschCreate.Tsch.Client = &rpcClient
+ tschCreate.IO = exec
+
+ if tschCreate.TaskName == "" && tschDemand.TaskPath == "" {
+ tschCreate.TaskPath = `\` + util.RandomString()
+ }
+
+ ctx := log.WithContext(gssapi.NewSecurityContext(context.TODO()))
+
+ if err := goexec.ExecuteCleanMethod(ctx, &tschCreate, &exec); err != nil {
+ log.Fatal().Err(err).Msg("Operation failed")
+ }
+ },
+ }
)
diff --git a/cmd/wmi.go b/cmd/wmi.go
index a9563a8..6fde395 100644
--- a/cmd/wmi.go
+++ b/cmd/wmi.go
@@ -1,119 +1,117 @@
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"
- "io"
- "os"
+ "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. {"CommandLine":"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. {"CommandLine":"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{}
+ wmiCall = wmiexec.WmiCall{}
+ wmiProc = wmiexec.WmiProc{}
- wmiArguments string
+ wmiArguments string
- wmiCmd = &cobra.Command{
- Use: "wmi",
- Short: "Establish execution via wmi",
- Args: cobra.NoArgs,
- }
+ wmiCmd = &cobra.Command{
+ Use: "wmi",
+ Short: "Establish execution via wmi",
+ Args: cobra.NoArgs,
+ }
- wmiCallCmd = &cobra.Command{
- Use: "call",
- Short: "Execute specified WMI method",
- Long: `Description:
+ 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).
@@ -121,39 +119,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) {
- var err error
-
- wmiProc.Client = &rpcClient
- wmiProc.IO = exec
-
- ctx := log.WithContext(gssapi.NewSecurityContext(context.TODO()))
-
- var writer io.WriteCloser
-
- if outputPath == "-" {
- writer = os.Stdout
-
- } else if outputPath != "" {
-
- if writer, err = os.OpenFile(outputPath, os.O_WRONLY|os.O_CREATE, 0644); err != nil {
- log.Fatal().Err(err).Msg("Failed to open output file")
- }
- defer writer.Close()
- }
-
- if err = goexec.ExecuteCleanMethod(ctx, &wmiProc, &exec); err != nil {
- log.Fatal().Err(err).Msg("Operation failed")
- }
-
- if outputPath != "" {
- if err = wmiProc.IO.GetOutput(ctx); err != nil {
- log.Error().Err(err).Msg("Failed to get process execution output")
- returnCode = 4
- }
- }
- },
- }
+ 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.TODO()))
+
+ if err := goexec.ExecuteCleanMethod(ctx, &wmiProc, &exec); err != nil {
+ log.Fatal().Err(err).Msg("Operation failed")
+ }
+ },
+ }
)