cmd

package
v0.5.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2023 License: GPL-3.0 Imports: 16 Imported by: 5

Documentation

Overview

Package cmd contains functions that can be used to execute external processes. Some OS versions have more advanced featuresets that are avaliable.

Index

Constants

View Source
const LoaderEnabled = true

LoaderEnabled is a compile-time constant that is true if the "DLLToASM" function will modify the provided bytes slice to ASM, otherwise this will be false.

Variables

View Source
var (
	// ErrNotStarted is an error returned by multiple functions when attempting
	// to access a Runnable function that requires the Runnable to be started first.
	ErrNotStarted = xerr.Sub("process has not started", 0x3A)
	// ErrEmptyCommand is an error returned when attempting to start a Runnable
	// that has empty arguments.
	ErrEmptyCommand = xerr.Sub("process arguments are empty", 0x3B)
	// ErrStillRunning is returned when attempting to access the exit code on a
	// Runnable.
	ErrStillRunning = xerr.Sub("process still running", 0x3C)
	// ErrAlreadyStarted is an error returned by the 'Start' or 'Run' functions
	// when attempting to start a Runnable that has already been started via a
	// 'Start' or 'Run' function call.
	ErrAlreadyStarted = xerr.Sub("process already started", 0x3D)
)

Functions

func DLLToASM added in v0.2.0

func DLLToASM(f string, b []byte) []byte

DLLToASM will patch the DLL raw bytes and convert it into shellcode using the SRDi launcher.

SRDi GitHub: https://github.com/monoxgas/sRDI

The first string param is the function name which can be empty if not needed.

The resulting byte slice can be used in an 'Asm' struct to directly load and run the DLL.

func ResumeProcess added in v0.1.0

func ResumeProcess(p uint32) error

ResumeProcess will attempt to resume the process via its PID. This will attempt to resume the process using an OS-dependent syscall.

This will not affect already running processes.

func Split

func Split(v string) []string

Split will attempt to split the specified string based on the escape characters and spaces while attempting to preserve anything that is not a splitting space.

This will automatically detect quotes and backslashes. The return result is a string array that can be used as args.

func SuspendProcess added in v0.1.0

func SuspendProcess(p uint32) error

SuspendProcess will attempt to suspend the process via its PID. This will attempt to suspend the process using an OS-dependent syscall.

This will not affect already suspended processes.

Types

type Assembly added in v0.1.0

type Assembly struct {
	Data []byte

	Timeout time.Duration
	// contains filtered or unexported fields
}

Assembly is a struct that can be used to contain and run shellcode on Windows devices. This struct has many of the functionalities of the standard 'cmd.Program' function.

The 'SetParent*' function will attempt to set the target that runs the shellcode. If none are specified, the shellcode will be injected into the current process.

This struct only works on Windows devices. All calls on non-Windows devices will return 'ErrNoWindows'.

TODO(dij): Add Linux shellcode execution support.

func NewAsm added in v0.1.0

func NewAsm(b []byte) *Assembly

NewAsm creates a new Assembly thread instance that uses the supplied byte array as the Data buffer. Similar to '&Assembly{Data: b}'.

func NewAsmContext added in v0.1.0

func NewAsmContext(x context.Context, b []byte) *Assembly

NewAsmContext creates a new Code thread instance that uses the supplied byte array as the Data buffer.

This function accepts a context that can be used to control the cancellation of the thread.

func (*Assembly) ExitCode added in v0.1.0

func (a *Assembly) ExitCode() (int32, error)

ExitCode returns the Exit Code of the thread. If the thread is still running or has not been started, this function returns an 'ErrNotCompleted' error.

func (*Assembly) Handle added in v0.1.0

func (a *Assembly) Handle() (uintptr, error)

Handle returns the handle of the current running thread. The return is an uintptr that can converted into a Handle.

This function returns an error if the thread was not started. The handle is not expected to be valid after the thread exits or is terminated.

func (*Assembly) Location added in v0.1.0

func (a *Assembly) Location() (uintptr, error)

Location returns the in-memory Location of the current Assembly thread, if running. The return is an uintptr that can converted into a Handle.

This function returns an error if the Assembly thread was not started. The handle is not expected to be valid after the thread exits or is terminated.

func (Assembly) Pid added in v0.1.0

func (Assembly) Pid() uint32

Pid returns the process ID of the owning process (the process running the thread.)

This may return zero if the thread has not yet been started.

func (*Assembly) Release added in v0.2.0

func (a *Assembly) Release() error

Release will attempt to release the resources for this Assembly thread, including handles.

After the first call to this function, all other function calls will fail with errors. Repeated calls to this function return nil and are a NOP.

func (*Assembly) Run added in v0.1.0

func (a *Assembly) Run() error

Run will start the Assembly thread and wait until it completes. This function will return the same errors as the 'Start' function if they occur or the 'Wait' function if any errors occur during thread runtime.

Always returns nil on non-Windows devices.

func (*Assembly) Running added in v0.1.0

func (a *Assembly) Running() bool

Running returns true if the current thread is running, false otherwise.

func (Assembly) SetParent added in v0.1.0

func (Assembly) SetParent(_ *filter.Filter)

SetParent will instruct the Assembly thread to choose a parent with the supplied process Filter. If the Filter is nil this will use the current process (default).

This function has no effect if the device is not running Windows.

func (*Assembly) SetSuspended added in v0.1.0

func (a *Assembly) SetSuspended(s bool)

SetSuspended will delay the execution of this thread and will put the thread in a suspended state until it is resumed using a Resume call.

This function has no effect if the device is not running Windows.

func (Assembly) Start added in v0.1.0

func (Assembly) Start() error

Start will attempt to start the Assembly thread and will return any errors that occur while starting the thread.

This function will return 'ErrEmptyCommand' if the 'Data' parameter is empty or the 'ErrAlreadyStarted' error if attempting to start a thread that already has been started previously.

Always returns 'ErrNoWindows' on non-Windows devices.

func (*Assembly) Stop added in v0.1.0

func (a *Assembly) Stop() error

Stop will attempt to terminate the currently running thread.

Always returns nil on non-Windows devices.

func (*Assembly) Wait added in v0.1.0

func (a *Assembly) Wait() error

Wait will block until the thread completes or is terminated by a call to Stop.

This function will return 'ErrNotStarted' if the thread has not been started.

type DLL

type DLL struct {
	Path string

	Timeout time.Duration
	// contains filtered or unexported fields
}

DLL is a struct that can be used to reflectively load a DLL into the memory of a selected process. Similar to the Assembly struct, this struct can only be used on Windows devices and will return 'ErrNoWindows' on non-Windows devices.

The 'SetParent*' function will attempt to set the target that loads the DLL. If none are specified, the DLL will be loaded into the current process.

func NewDLL

func NewDLL(p string) *DLL

NewDLL creates a new DLL instance that uses the supplied string as the DLL file path. Similar to '&DLL{Path: p}'.

func NewDLLContext added in v0.3.4

func NewDLLContext(x context.Context, p string) *DLL

NewDLLContext creates a new DLL instance that uses the supplied string as the DLL file path.

This function accepts a context that can be used to control the cancellation of the thread.

func (*DLL) Done added in v0.2.0

func (d *DLL) Done() <-chan struct{}

Done returns a channel that's closed when this DLL completes

This can be used to monitor a DLL's status using a select statement.

func (*DLL) ExitCode

func (d *DLL) ExitCode() (int32, error)

ExitCode returns the Exit Code of the thread. If the thread is still running or has not been started, this function returns an 'ErrNotCompleted' error.

func (*DLL) Handle

func (d *DLL) Handle() (uintptr, error)

Handle returns the handle of the current running thread. The return is an uintptr that can converted into a Handle.

This function returns an error if the thread was not started. The handle is not expected to be valid after the thread exits or is terminated.

func (DLL) Pid added in v0.1.0

func (DLL) Pid() uint32

Pid returns the process ID of the owning process (the process running the thread.)

This may return zero if the thread has not yet been started.

func (*DLL) Release added in v0.2.0

func (d *DLL) Release() error

Release will attempt to release the resources for this DLL instance, including handles.

After the first call to this function, all other function calls will fail with errors. Repeated calls to this function return nil and are a NOP.

func (*DLL) Run

func (d *DLL) Run() error

Run will start the DLL thread and wait until it completes. This function will return the same errors as the 'Start' function if they occur or the 'Wait' function if any errors occur during thread runtime.

Always returns nil on non-Windows devices.

func (*DLL) Running

func (d *DLL) Running() bool

Running returns true if the current thread is running, false otherwise.

func (DLL) SetParent

func (DLL) SetParent(_ *filter.Filter)

SetParent will instruct the DLL to choose a parent with the supplied process Filter. If the Filter is nil this will use the current process (default).

This function has no effect if the device is not running Windows.

func (*DLL) SetSuspended added in v0.1.0

func (d *DLL) SetSuspended(s bool)

SetSuspended will delay the execution of this thread and will put the thread in a suspended state until it is resumed using a Resume call.

This function has no effect if the device is not running Windows.

func (DLL) Start

func (DLL) Start() error

Start will attempt to start the DLL and will return an errors that occur while starting the DLL.

This function will return 'ErrEmptyCommand' if the 'Path' parameter is empty and 'ErrAlreadyStarted' if attempting to start a DLL that already has been started previously.

Always returns 'ErrNoWindows' on non-Windows devices.

func (*DLL) Stop

func (d *DLL) Stop() error

Stop will attempt to terminate the currently running thread.

Always returns nil on non-Windows devices.

func (*DLL) Wait

func (d *DLL) Wait() error

Wait will block until the thread completes or is terminated by a call to Stop.

This function will return 'ErrNotStarted' if the thread has not been started.

type ExitError

type ExitError struct {
	Exit uint32
}

ExitError is a type of error that is returned by the Wait and Run functions when a function returns an error code other than zero.

func (ExitError) Error

func (e ExitError) Error() string

Error fulfills the error interface and returns a formatted string that specifies the Process Exit Code.

type Process

type Process struct {
	Stdout, Stderr io.Writer

	Stdin io.Reader

	Dir       string
	Args, Env []string

	Timeout time.Duration
	// contains filtered or unexported fields
}

Process is a struct that represents an executable command and allows for setting options in order change the operating functions.

func NewProcess

func NewProcess(s ...string) *Process

NewProcess creates a new process instance that uses the supplied string vardict as the command line arguments. Similar to '&Process{Args: s}'.

func NewProcessContext

func NewProcessContext(x context.Context, s ...string) *Process

NewProcessContext creates a new process instance that uses the supplied string vardict as the command line arguments.

This function accepts a context that can be used to control the cancellation of this process.

func (*Process) CombinedOutput

func (p *Process) CombinedOutput() ([]byte, error)

CombinedOutput runs the Process and returns its combined standard output and standard error. Any returned error will usually be of type *ExitError.

func (*Process) ExitCode

func (p *Process) ExitCode() (int32, error)

ExitCode returns the Exit Code of the process.

If the Process is still running or has not been started, this function returns an 'ErrStillRunning' error.

func (*Process) Flags

func (p *Process) Flags() uint32

Flags returns the current set flags value based on the configured options.

func (*Process) Handle

func (p *Process) Handle() (uintptr, error)

Handle returns the handle of the current running Process. The return is an uintptr that can converted into a Handle.

This function returns an error if the Process was not started. The handle is not expected to be valid after the Process exits or is terminated.

This function always returns 'ErrNoWindows' on non-Windows devices.

func (*Process) Output

func (p *Process) Output() ([]byte, error)

Output runs the Process and returns its standard output. Any returned error will usually be of type *ExitError.

func (*Process) Pid

func (p *Process) Pid() uint32

Pid returns the current process PID. This function returns zero if the process has not been started.

func (*Process) Release added in v0.2.0

func (p *Process) Release() error

Release will attempt to release the resources for this Process, including handles.

After the first call to this function, all other function calls will fail with errors. Repeated calls to this function return nil and are a NOP.

func (*Process) Resume added in v0.1.0

func (p *Process) Resume() error

Resume will attempt to resume this process. This will attempt to resume the process using an OS-dependent syscall.

This will not affect already running processes.

func (*Process) Run

func (p *Process) Run() error

Run will start the process and wait until it completes.

This function will return the same errors as the 'Start' function if they occur or the 'Wait' function if any errors occur during Process runtime.

func (*Process) Running

func (p *Process) Running() bool

Running returns true if the current Process is running, false otherwise.

func (*Process) SetDetached

func (p *Process) SetDetached(d bool)

SetDetached will detach or detach the console of the newly spawned process from the parent. This function has no effect on non-console commands. Setting this to true disables SetNewConsole.

This function has no effect if the device is not running Windows.

func (*Process) SetFlags

func (p *Process) SetFlags(f uint32)

SetFlags will set the startup Flag values used for Windows programs. This function overrides many of the 'Set*' functions.

func (*Process) SetFullscreen

func (p *Process) SetFullscreen(f bool)

SetFullscreen will set the window fullscreen state of the newly spawned process. This function has no effect on commands that do not generate windows.

This function has no effect if the device is not running Windows.

func (*Process) SetGID

func (p *Process) SetGID(g int32)

SetGID will set the process GID at runtime. This function takes the numerical GID value. Use '-1' to disable this setting. The GID value is validated at runtime.

This function has no effect on Windows devices.

func (*Process) SetInheritEnv

func (p *Process) SetInheritEnv(i bool)

SetInheritEnv will change the behavior of the Environment variable inheritance on startup. If true (the default), the current Environment variables will be filled in, even if 'Env' is not empty.

If set to false, the current Environment variables will not be added into the Process's starting Environment.

func (*Process) SetLogin added in v0.3.0

func (p *Process) SetLogin(u, d, pw string)

SetLogin will set the User credentials that this Process will run under.

WARNING: This may cause issues when running with a parent process.

Currently only supported on Windows devices.

func (*Process) SetNewConsole

func (p *Process) SetNewConsole(c bool)

SetNewConsole will allocate a new console for the newly spawned process. This console output will be independent of the parent process.

This function has no effect if the device is not running Windows.

func (*Process) SetNoWindow

func (p *Process) SetNoWindow(h bool)

SetNoWindow will hide or show the window of the newly spawned process.

This function has no effect on commands that do not generate windows or if the device is not running Windows.

func (*Process) SetParent

func (p *Process) SetParent(f *filter.Filter)

SetParent will instruct the Process to choose a parent with the supplied process Filter. If the Filter is nil this will use the current process (default). Setting the Parent process will automatically set 'SetNewConsole' to true

This function has no effect if the device is not running Windows.

func (*Process) SetSuspended

func (p *Process) SetSuspended(s bool)

SetSuspended will delay the execution of this Process and will put the process in a suspended state until it is resumed using a Resume call.

This function has no effect if the device is not running Windows.

func (*Process) SetToken added in v0.2.0

func (p *Process) SetToken(t uintptr)

SetToken will set the User or Process Token handle that this Process will run under.

WARNING: This may cause issues when running with a parent process.

This function has no effect on commands that do not generate windows or if the device is not running Windows.

func (*Process) SetUID

func (p *Process) SetUID(u int32)

SetUID will set the process UID at runtime. This function takes the numerical UID value. Use '-1' to disable this setting. The UID value is validated at runtime.

This function has no effect on Windows devices.

func (*Process) SetWindowDisplay

func (p *Process) SetWindowDisplay(m int)

SetWindowDisplay will set the window display mode of the newly spawned process. This function has no effect on commands that do not generate windows.

See the 'SW_*' values in winuser.h or the Golang windows package documentation for more details.

This function has no effect if the device is not running Windows.

func (*Process) SetWindowPosition

func (p *Process) SetWindowPosition(x, y uint32)

SetWindowPosition will set the window position of the newly spawned process. This function has no effect on commands that do not generate windows.

This function has no effect if the device is not running Windows.

func (*Process) SetWindowSize

func (p *Process) SetWindowSize(w, h uint32)

SetWindowSize will set the window display size of the newly spawned process. This function has no effect on commands that do not generate windows.

This function has no effect if the device is not running Windows.

func (*Process) SetWindowTitle

func (p *Process) SetWindowTitle(s string)

SetWindowTitle will set the title of the new spawned window to the specified string. This function has no effect on commands that do not generate windows. Setting the value to an empty string will unset this setting.

This function has no effect if the device is not running Windows.

func (*Process) Start

func (p *Process) Start() error

Start will attempt to start the Process and will return an errors that occur while starting the Process.

This function will return 'ErrEmptyCommand' if the 'Args' parameter is empty and 'ErrAlreadyStarted' if attempting to start a Process that already has been started previously.

func (*Process) StderrPipe

func (p *Process) StderrPipe() (io.ReadCloser, error)

StderrPipe returns a pipe that will be connected to the Process's standard error when the Processes starts.

The pipe will be closed after the Process exits, so most callers need not close the pipe themselves. It is thus incorrect to call Wait before all reads from the pipe have completed. For the same reason, it is incorrect to use Run when using StderrPipe.

See the stdlib StdoutPipe example for idiomatic usage.

func (*Process) StdinPipe

func (p *Process) StdinPipe() (io.WriteCloser, error)

StdinPipe returns a pipe that will be connected to the Process's standard input when the Process starts. The pipe will be closed automatically after the Processes starts. A caller need only call Close to force the pipe to close sooner.

func (*Process) StdoutPipe

func (p *Process) StdoutPipe() (io.ReadCloser, error)

StdoutPipe returns a pipe that will be connected to the Process's standard output when the Processes starts.

The pipe will be closed after the Process exits, so most callers need not close the pipe themselves. It is thus incorrect to call Wait before all reads from the pipe have completed. For the same reason, it is incorrect to use Run when using StderrPipe.

See the stdlib StdoutPipe example for idiomatic usage.

func (*Process) Stop

func (p *Process) Stop() error

Stop will attempt to terminate the currently running Process instance.

Stopping a Process may prevent the ability to read the Stdout/Stderr and any proper exit codes.

func (*Process) Suspend added in v0.1.0

func (p *Process) Suspend() error

Suspend will attempt to suspend this process. This will attempt to suspend the process using an OS-dependent syscall.

This will not affect already suspended processes.

func (*Process) Wait

func (p *Process) Wait() error

Wait will block until the Process completes or is terminated by a call to Stop.

This will start the process if not already started.

type ProcessInfo added in v0.2.2

type ProcessInfo struct {
	Name, User string
	PID, PPID  uint32
	// contains filtered or unexported fields
}

ProcessInfo is a struct that holds simple process related data for extraction This struct is returned via a call to 'Processes'.

This struct also supports binary Marshaling/UnMarshaling.

func Processes added in v0.2.2

func Processes() ([]ProcessInfo, error)

Processes attempts to gather the current running Processes and returns them as a slice of ProcessInfo structs, otherwise any errors are returned.

func (ProcessInfo) MarshalStream added in v0.2.2

func (p ProcessInfo) MarshalStream(w data.Writer) error

MarshalStream transforms this struct into a binary format and writes to the supplied data.Writer.

func (*ProcessInfo) UnmarshalStream added in v0.2.2

func (p *ProcessInfo) UnmarshalStream(r data.Reader) error

UnmarshalStream transforms this struct from a binary format that is read from the supplied data.Reader.

type Runnable

type Runnable interface {
	Run() error
	Pid() uint32
	Wait() error
	Stop() error
	Start() error
	Running() bool
	Release() error
	Handle() (uintptr, error)
	ExitCode() (int32, error)
	SetParent(*filter.Filter)
}

Runnable is an interface that helps support the type of structs that can be used for execution, such as Assembly, DLL and Process, which share the same methods as this interface.

type Zombie added in v0.1.0

type Zombie struct {
	Data []byte

	Process
	// contains filtered or unexported fields
}

Zombie is a struct that represents an Assembly backed process. This is similar to 'execute-assembly' and will launch a suspended process to be injected into.

The 'Path' or 'Data' arguments can be used to specify a DLL path or shellcode to be ran by the zombie. The 'Data' argument takes precedence over 'Path'. At least one of them must be supplied or an 'ErrEmptyCommand' error will be returned on any calls to 'Start'.

This struct shares many of the same methods as the 'Process' struct. The 'SetParent' function will affect the parent of the spawned process.

func NewZombie added in v0.1.0

func NewZombie(b []byte, s ...string) *Zombie

NewZombie creates a Zombie struct that can be used to spawn a sacrificial process specified in the args vardict that will execute the shellcode in the byte array.

func NewZombieContext added in v0.1.0

func NewZombieContext(x context.Context, b []byte, s ...string) *Zombie

NewZombieContext creates a Zombie struct that can be used to spawn a sacrificial process specified in the args vardict that will execute the shellcode in the byte array.

This function allows for specification of a Context for cancellation.

func (*Zombie) ExitCode added in v0.1.0

func (z *Zombie) ExitCode() (int32, error)

ExitCode returns the Exit Code of the Zombie thread. If the Zombie is still running or has not been started, this function returns an 'ErrStillRunning' error.

func (*Zombie) Handle added in v0.1.0

func (z *Zombie) Handle() (uintptr, error)

Handle returns the handle of the current running Zombie. The return is an uintptr that can converted into a Handle.

This function returns an error if the Zombie was not started. The handle is not expected to be valid after the Process exits or is terminated.

This function always returns 'ErrNoWindows' on non-Windows devices.

func (*Zombie) Location added in v0.1.0

func (z *Zombie) Location() (uintptr, error)

Location returns the in-memory Location of the current Zombie thread, if running. The return is an uintptr that can converted into a Handle.

This function returns an error if the Zombie thread was not started. The handle is not expected to be valid after the thread exits or is terminated.

func (*Zombie) Release added in v0.5.0

func (z *Zombie) Release() error

Release will attempt to release the resources for this Zombie, including handles.

After the first call to this function, all other function calls will fail with errors. Repeated calls to this function return nil and are a NOP.

func (*Zombie) Resume added in v0.1.0

func (z *Zombie) Resume() error

Resume will attempt to resume this process. This will attempt to resume the process using an OS-dependent syscall.

This will not affect already running processes.

func (*Zombie) Run added in v0.1.0

func (z *Zombie) Run() error

Run will start the Zombie and wait until it completes. This function will return the same errors as the 'Start' function if they occur or the 'Wait' function if any errors occur during Process runtime.

func (*Zombie) Running added in v0.1.0

func (z *Zombie) Running() bool

Running returns true if the current Zombie is running, false otherwise.

func (*Zombie) SetSuspended added in v0.1.0

func (z *Zombie) SetSuspended(s bool)

SetSuspended will delay the execution of this thread and will put the thread in a suspended state until it is resumed using a Resume call.

This function has no effect if the device is not running Windows.

func (Zombie) Start added in v0.1.0

func (Zombie) Start() error

Start will attempt to start the Zombie and will return an errors that occur while starting the Process.

This function will return 'ErrEmptyCommand' if the 'Args', the 'Data' or the 'Path; parameters are empty and 'ErrAlreadyStarted' if attempting to start a Zombie that already has been started previously.

Always returns 'ErrNoWindows' on non-Windows devices.

func (*Zombie) Stop added in v0.1.0

func (z *Zombie) Stop() error

Stop will attempt to terminate the currently running Zombie instance. Stopping a Zombie may prevent the ability to read the Stdout/Stderr and any proper exit codes.

func (*Zombie) Suspend added in v0.1.0

func (z *Zombie) Suspend() error

Suspend will attempt to suspend this process. This will attempt to suspend the process using an OS-dependent syscall.

This will not affect already suspended processes.

func (*Zombie) Wait added in v0.1.0

func (z *Zombie) Wait() error

Wait will block until the Zombie completes or is terminated by a call to Stop. This will start the process if not already started.

Directories

Path Synopsis
Package filter is a separate container for the 'Filter' struct that can be used to target a specific process or one that matches an attribute set.
Package filter is a separate container for the 'Filter' struct that can be used to target a specific process or one that matches an attribute set.
Package script contains Script engines in separate packages to prevent loading if not needed/included.
Package script contains Script engines in separate packages to prevent loading if not needed/included.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL