Compare commits

...
1 Commits
6 changed files with 1172 additions and 1070 deletions

No files matched your search

+3 -1
View File
@@ -25,12 +25,14 @@ func Commands(con *console.SliverClient) []*cobra.Command {
}
flags.Bind("", false, executeCmd, func(f *pflag.FlagSet) {
f.BoolP("token", "T", false, "execute command with current token (Windows only)")
f.BoolP("output", "o", false, "capture command output")
f.BoolP("output", "o", true, "capture command output")
f.BoolP("save", "s", false, "save output to a file")
f.BoolP("loot", "X", false, "save output as loot")
f.BoolP("ignore-stderr", "S", false, "don't print STDERR output")
f.StringP("stdout", "O", "", "remote path to redirect STDOUT to")
f.StringP("stderr", "E", "", "remote path to redirect STDERR to")
f.Bool("env-inheritance", true, "inherit environment variables from the current process")
f.StringArray("env", nil, "set an environment variable for the child process (key=value)")
f.StringP("name", "n", "", "name to assign loot (optional)")
f.Uint32P("ppid", "P", 0, "parent process id (optional, Windows only)")
f.BoolP("hidden", "H", false, "hide the window of the spawned process (Windows only)")
+35 -7
View File
@@ -49,6 +49,13 @@ func ExecuteCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
saveLoot, _ := cmd.Flags().GetBool("loot")
saveOutput, _ := cmd.Flags().GetBool("save")
ppid, _ := cmd.Flags().GetUint32("ppid")
envInheritance, _ := cmd.Flags().GetBool("env-inheritance")
envPairs, _ := cmd.Flags().GetStringArray("env")
envVars, err := parseEnvPairs(envPairs)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
hostName := getHostname(session, beacon)
// If the user wants to loot or save the output, we have to capture it regardless of if they specified -o
@@ -59,15 +66,19 @@ func ExecuteCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
}
var exec *sliverpb.Execute
var err error
ctrl := make(chan bool)
con.PrintInfof("Execute: %s [%s]\n", cmdPath, strings.Join(args, " "))
con.SpinUntil(fmt.Sprintf("Executing %s %s ...", cmdPath, strings.Join(args, " ")), ctrl)
if token || hidden || ppid != 0 {
if (session != nil && session.OS != "windows") || (beacon != nil && beacon.OS != "windows") {
con.PrintErrorf("The token, hide window, and ppid options are not valid on %s\n", session.OS)
return
}
if envInheritance || len(envVars) > 0 {
con.PrintErrorf("The env and env-inheritance options are not supported with token, hidden, or ppid\n")
return
}
exec, err = con.Rpc.ExecuteWindows(context.Background(), &sliverpb.ExecuteWindowsReq{
Request: con.ActiveTarget.Request(cmd),
Path: cmdPath,
@@ -81,12 +92,14 @@ func ExecuteCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
})
} else {
exec, err = con.Rpc.Execute(context.Background(), &sliverpb.ExecuteReq{
Request: con.ActiveTarget.Request(cmd),
Path: cmdPath,
Args: args,
Output: captureOutput,
Stderr: stderr,
Stdout: stdout,
Request: con.ActiveTarget.Request(cmd),
Path: cmdPath,
Args: args,
Output: captureOutput,
Stderr: stderr,
Stdout: stdout,
EnvInheritance: envInheritance,
Env: envVars,
})
}
ctrl <- true
@@ -179,6 +192,21 @@ func getHostname(session *clientpb.Session, beacon *clientpb.Beacon) string {
return ""
}
func parseEnvPairs(envPairs []string) (map[string]string, error) {
if len(envPairs) == 0 {
return nil, nil
}
envVars := make(map[string]string, len(envPairs))
for _, pair := range envPairs {
parts := strings.SplitN(pair, "=", 2)
if len(parts) != 2 || parts[0] == "" {
return nil, fmt.Errorf("invalid --env value %q, expected key=value", pair)
}
envVars[parts[0]] = parts[1]
}
return envVars, nil
}
func determineCommandName(command string) string {
commandName := strings.ReplaceAll(command, "\\", "/")
+17
View File
@@ -68,6 +68,7 @@ var (
consts.RunAsStr: runAsHelp,
consts.ImpersonateStr: impersonateHelp,
consts.RevToSelfStr: revToSelfHelp,
consts.ExecuteStr: executeHelp,
consts.ExecuteAssemblyStr: executeAssemblyHelp,
consts.ExecuteShellcodeStr: executeShellcodeHelp,
consts.MigrateStr: migrateHelp,
@@ -124,6 +125,22 @@ var (
consts.C2ProfileStr + sep + consts.C2GenerateStr: c2GenerateHelp,
}
executeHelp = `[[.Bold]]Command:[[.Normal]] execute <path to executable> [options] -- [args...]
[[.Bold]]About:[[.Normal]] Execute a program on the remote system with optional arguments, note the subprocess
arguments are be separated from the sliver 'execute' arguments with '--'
[[.Bold]]Example:[[.Normal]]
execute /bin/bash --env FOO=1 -- -c env
[*] Execute: /bin/bash [-c env]
[*] Output:
FOO=1
PWD=/Users/moloch/git/sliver
SHLVL=1
_=/usr/bin/env
`
jobsHelp = `[[.Bold]]Command:[[.Normal]] jobs <options>
[[.Bold]]About:[[.Normal]] Manage jobs/listeners.`
+25
View File
@@ -27,10 +27,12 @@ import (
"fmt"
"io"
"io/fs"
"maps"
"os"
"os/exec"
"path/filepath"
"regexp"
"sort"
"strings"
"time"
"unicode/utf8"
@@ -1146,6 +1148,29 @@ func executeHandler(data []byte, resp RPCResponse) {
return
}
cmd := exec.Command(exePath, execReq.Args...)
if execReq.EnvInheritance || len(execReq.Env) > 0 {
envVars := make(map[string]string)
if execReq.EnvInheritance {
for _, entry := range os.Environ() {
parts := strings.SplitN(entry, "=", 2)
if len(parts) == 2 {
envVars[parts[0]] = parts[1]
} else if len(parts) == 1 {
envVars[parts[0]] = ""
}
}
}
maps.Copy(envVars, execReq.Env)
keys := make([]string, 0, len(envVars))
for key := range envVars {
keys = append(keys, key)
}
sort.Strings(keys)
cmd.Env = make([]string, 0, len(envVars))
for _, key := range keys {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, envVars[key]))
}
}
if execReq.Output {
stdOutBuff := new(bytes.Buffer)
File diff suppressed because it is too large. Load diff
+3
View File
@@ -515,6 +515,9 @@ message ExecuteReq {
bool Output = 3;
string Stdout = 4;
string Stderr = 5;
bool EnvInheritance = 6;
map<string, string> Env = 7;
uint32 PPid = 10;
commonpb.Request Request = 9;