diff options
Diffstat (limited to 'cmd/tsch.go')
| -rw-r--r-- | cmd/tsch.go | 208 | 
1 files changed, 102 insertions, 106 deletions
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") +			} +		}, +	}  )  |