mirror of
https://github.com/BishopFox/sliver.git
synced 2026-11-10 01:41:29 -10:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ed42e4a3d | ||
|
|
ffee881de0 | ||
|
|
339bf15387 | ||
|
|
92c9a50ba7 |
No files matched your search
@@ -23,6 +23,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/assets"
|
||||
@@ -152,10 +153,13 @@ func InstallFromFile(aliasGzFilePath string, autoOverwrite bool, con *console.Sl
|
||||
}
|
||||
|
||||
func installArtifact(aliasGzFilePath string, installPath, artifactPath string, con *console.SliverConsoleClient) error {
|
||||
data, err := util.ReadFileFromTarGz(aliasGzFilePath, artifactPath)
|
||||
data, err := util.ReadFileFromTarGz(aliasGzFilePath, fmt.Sprintf("./%s", strings.TrimPrefix(artifactPath, "/")))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return fmt.Errorf("empty file %s", artifactPath)
|
||||
}
|
||||
localArtifactPath := filepath.Join(installPath, util.ResolvePath(artifactPath))
|
||||
artifactDir := filepath.Dir(localArtifactPath)
|
||||
if _, err := os.Stat(artifactDir); os.IsNotExist(err) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/bishopfox/sliver/client/assets"
|
||||
"github.com/bishopfox/sliver/client/command/help"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
consts "github.com/bishopfox/sliver/client/constants"
|
||||
@@ -97,18 +98,22 @@ func (ec *AliasManifest) getDefaultProcess(targetOS string) (proc string, err er
|
||||
}
|
||||
|
||||
func (a *AliasManifest) getFileForTarget(cmdName string, targetOS string, targetArch string) (string, error) {
|
||||
var filePath string
|
||||
var err error
|
||||
for _, ef := range a.Files {
|
||||
if targetOS == ef.OS && targetArch == ef.Arch {
|
||||
filePath = ef.Path
|
||||
filePath := ""
|
||||
for _, extFile := range a.Files {
|
||||
if targetOS == extFile.OS && targetArch == extFile.Arch {
|
||||
filePath = path.Join(assets.GetAliasesDir(), a.CommandName, extFile.Path)
|
||||
break
|
||||
}
|
||||
}
|
||||
if filePath == "" {
|
||||
err = fmt.Errorf("no alias file found for %s/%s", targetOS, targetArch)
|
||||
err := fmt.Errorf("no alias file found for %s/%s", targetOS, targetArch)
|
||||
return "", err
|
||||
}
|
||||
return filePath, err
|
||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||
err = fmt.Errorf("alias file not found: %s", filePath)
|
||||
return "", err
|
||||
}
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
// AliasesLoadCmd - Locally load a alias into the Sliver shell.
|
||||
@@ -136,23 +141,23 @@ func LoadAlias(manifestPath string, con *console.SliverConsoleClient) (*AliasMan
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
alias, err := ParseAliasManifest(data)
|
||||
aliasManifest, err := ParseAliasManifest(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
alias.RootPath = filepath.Dir(manifestPath)
|
||||
aliasManifest.RootPath = filepath.Dir(manifestPath)
|
||||
// for each alias command, add a new app command
|
||||
|
||||
// do not add if the command already exists
|
||||
if cmdExists(alias.CommandName, con.App) {
|
||||
return nil, fmt.Errorf("'%s' command already exists", alias.CommandName)
|
||||
if cmdExists(aliasManifest.CommandName, con.App) {
|
||||
return nil, fmt.Errorf("'%s' command already exists", aliasManifest.CommandName)
|
||||
}
|
||||
|
||||
helpMsg := fmt.Sprintf("[%s] %s", alias.Name, alias.Help)
|
||||
helpMsg := fmt.Sprintf("[%s] %s", aliasManifest.Name, aliasManifest.Help)
|
||||
addAliasCmd := &grumble.Command{
|
||||
Name: alias.Name,
|
||||
Name: aliasManifest.CommandName,
|
||||
Help: helpMsg,
|
||||
LongHelp: help.FormatHelpTmpl(alias.LongHelp),
|
||||
LongHelp: help.FormatHelpTmpl(aliasManifest.LongHelp),
|
||||
Run: func(extCtx *grumble.Context) error {
|
||||
con.Println()
|
||||
runAliasCommand(extCtx, con)
|
||||
@@ -160,7 +165,7 @@ func LoadAlias(manifestPath string, con *console.SliverConsoleClient) (*AliasMan
|
||||
return nil
|
||||
},
|
||||
Flags: func(f *grumble.Flags) {
|
||||
if alias.IsAssembly {
|
||||
if aliasManifest.IsAssembly {
|
||||
f.String("m", "method", "", "Optional method (a method is required for a .NET DLL)")
|
||||
f.String("c", "class", "", "Optional class name (required for .NET DLL)")
|
||||
f.String("d", "app-domain", "", "AppDomain name to create for .NET assembly. Generated randomly if not set.")
|
||||
@@ -180,14 +185,15 @@ func LoadAlias(manifestPath string, con *console.SliverConsoleClient) (*AliasMan
|
||||
|
||||
// Have to use a global map here, as passing the aliasCmd
|
||||
// either by value or by ref fucks things up
|
||||
loadedAliases[alias.Name] = &loadedAlias{
|
||||
Manifest: alias,
|
||||
loadedAliases[aliasManifest.CommandName] = &loadedAlias{
|
||||
Manifest: aliasManifest,
|
||||
Command: addAliasCmd,
|
||||
}
|
||||
|
||||
return alias, nil
|
||||
return aliasManifest, nil
|
||||
}
|
||||
|
||||
// ParseAliasManifest - Parse an alias manifest
|
||||
func ParseAliasManifest(data []byte) (*AliasManifest, error) {
|
||||
// parse it
|
||||
alias := &AliasManifest{}
|
||||
@@ -233,23 +239,23 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("No alias found for `%s` command\n", ctx.Command.Name)
|
||||
return
|
||||
}
|
||||
alias := loadedAlias.Manifest
|
||||
binPath, err := alias.getFileForTarget(ctx.Command.Name, session.GetOS(), session.GetArch())
|
||||
aliasManifest := loadedAlias.Manifest
|
||||
binPath, err := aliasManifest.getFileForTarget(ctx.Command.Name, session.GetOS(), session.GetArch())
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
con.PrintErrorf("Fail to find alias file: %s\n", err)
|
||||
return
|
||||
}
|
||||
args := ctx.Args.StringList("arguments")
|
||||
var extArgs string
|
||||
if len(alias.DefaultArgs) != 0 && len(args) == 0 {
|
||||
extArgs = alias.DefaultArgs
|
||||
if len(aliasManifest.DefaultArgs) != 0 && len(args) == 0 {
|
||||
extArgs = aliasManifest.DefaultArgs
|
||||
} else {
|
||||
extArgs = strings.Join(args, " ")
|
||||
}
|
||||
entryPoint := alias.Entrypoint
|
||||
entryPoint := aliasManifest.Entrypoint
|
||||
processName := ctx.Flags.String("process")
|
||||
if processName == "" {
|
||||
processName, err = alias.getDefaultProcess(session.GetOS())
|
||||
processName, err = aliasManifest.getDefaultProcess(session.GetOS())
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
@@ -273,7 +279,7 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if alias.IsAssembly {
|
||||
if aliasManifest.IsAssembly {
|
||||
ctrl := make(chan bool)
|
||||
msg := fmt.Sprintf("Executing %s %s ...", ctx.Command.Name, extArgs)
|
||||
con.SpinUntil(msg, ctrl)
|
||||
@@ -299,7 +305,7 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
outFilePath.Write(executeAssemblyResp.GetOutput())
|
||||
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
|
||||
}
|
||||
} else if alias.IsReflective {
|
||||
} else if aliasManifest.IsReflective {
|
||||
ctrl := make(chan bool)
|
||||
msg := fmt.Sprintf("Executing %s %s ...", ctx.Command.Name, extArgs)
|
||||
con.SpinUntil(msg, ctrl)
|
||||
@@ -308,7 +314,7 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
Args: strings.Trim(extArgs, " "),
|
||||
Data: binData,
|
||||
ProcessName: processName,
|
||||
EntryPoint: alias.Entrypoint,
|
||||
EntryPoint: aliasManifest.Entrypoint,
|
||||
Kill: true,
|
||||
})
|
||||
ctrl <- true
|
||||
|
||||
@@ -107,7 +107,11 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
n++
|
||||
}
|
||||
if 0 < n {
|
||||
con.PrintInfof("Loaded %d alias(es) from disk\n", n)
|
||||
if n == 1 {
|
||||
con.PrintInfof("Loaded %d alias from disk\n", n)
|
||||
} else {
|
||||
con.PrintInfof("Loaded %d aliases from disk\n", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Load Extensions
|
||||
|
||||
@@ -98,7 +98,7 @@ func installFromDir(extLocalPath string, con *console.SliverConsoleClient) {
|
||||
|
||||
}
|
||||
|
||||
// Install an extension from a .tar.gz file
|
||||
// InstallFromFilePath - Install an extension from a .tar.gz file
|
||||
func InstallFromFilePath(extLocalPath string, autoOverwrite bool, con *console.SliverConsoleClient) *string {
|
||||
manifestData, err := util.ReadFileFromTarGz(extLocalPath, fmt.Sprintf("./%s", ManifestFileName))
|
||||
if err != nil {
|
||||
|
||||
+16
-11
@@ -98,8 +98,6 @@ const (
|
||||
clientsDirName = "clients"
|
||||
sliversDirName = "slivers"
|
||||
|
||||
encryptKeySize = 16
|
||||
|
||||
// DefaultReconnectInterval - In seconds
|
||||
DefaultReconnectInterval = 60
|
||||
// DefaultMTLSLPort - Default listen port
|
||||
@@ -254,7 +252,7 @@ func GetSliversDir() string {
|
||||
// Sliver Generation Code
|
||||
// -----------------------
|
||||
|
||||
// SliverShellcode - Generates a sliver shellcode using sRDI
|
||||
// SliverShellcode - Generates a sliver shellcode using Donut
|
||||
func SliverShellcode(name string, config *models.ImplantConfig) (string, error) {
|
||||
appDir := assets.GetRootAppDir()
|
||||
goConfig := &gogo.GoConfig{
|
||||
@@ -284,14 +282,16 @@ func SliverShellcode(name string, config *models.ImplantConfig) (string, error)
|
||||
ldflags[0] += " -H=windowsgui"
|
||||
}
|
||||
// Keep those for potential later use
|
||||
gcflags := fmt.Sprintf("")
|
||||
asmflags := fmt.Sprintf("")
|
||||
gcflags := ""
|
||||
asmflags := ""
|
||||
// trimpath is now a separate flag since Go 1.13
|
||||
trimpath := "-trimpath"
|
||||
_, err = gogo.GoBuild(*goConfig, pkgPath, dest, "pie", tags, ldflags, gcflags, asmflags, trimpath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
config.FileName = path.Base(dest)
|
||||
shellcode, err := DonutShellcodeFromFile(dest, config.GOARCH, false, "", "", "")
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -362,11 +362,14 @@ func SliverSharedLibrary(name string, config *models.ImplantConfig) (string, err
|
||||
ldflags[0] += " -H=windowsgui"
|
||||
}
|
||||
// Keep those for potential later use
|
||||
gcflags := fmt.Sprintf("")
|
||||
asmflags := fmt.Sprintf("")
|
||||
gcflags := ""
|
||||
asmflags := ""
|
||||
// trimpath is now a separate flag since Go 1.13
|
||||
trimpath := "-trimpath"
|
||||
_, err = gogo.GoBuild(*goConfig, pkgPath, dest, "c-shared", tags, ldflags, gcflags, asmflags, trimpath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
config.FileName = path.Base(dest)
|
||||
|
||||
err = ImplantBuildSave(name, config, dest)
|
||||
@@ -496,10 +499,12 @@ func renderSliverGoCode(name string, config *models.ImplantConfig, goConfig *gog
|
||||
// Generate wg Keys as needed
|
||||
if config.WGc2Enabled {
|
||||
implantPrivKey, _, err := certs.ImplantGenerateWGKeys(config.WGPeerTunIP)
|
||||
_, serverPubKey, err := certs.GetWGServerKeys()
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to embed implant wg keys: %s", err)
|
||||
return "", err
|
||||
}
|
||||
_, serverPubKey, err := certs.GetWGServerKeys()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to embed implant wg keys: %s", err)
|
||||
}
|
||||
config.WGImplantPrivKey = implantPrivKey
|
||||
config.WGServerPubKey = serverPubKey
|
||||
|
||||
@@ -71,7 +71,7 @@ func getRandomWord(fpath string) (string, error) {
|
||||
}
|
||||
wordsLen := len(words)
|
||||
if wordsLen == 0 {
|
||||
return "", fmt.Errorf("No words found in %s", fpath)
|
||||
return "", fmt.Errorf("no words found in %s", fpath)
|
||||
}
|
||||
word := words[insecureRand.Intn(wordsLen-1)]
|
||||
return strings.TrimSpace(word), nil
|
||||
|
||||
@@ -43,7 +43,7 @@ var (
|
||||
storageLog = log.NamedLogger("generate", "storage")
|
||||
|
||||
// ErrImplantBuildFileNotFound - More descriptive 'key not found' error
|
||||
ErrImplantBuildFileNotFound = errors.New("Implant build file not found")
|
||||
ErrImplantBuildFileNotFound = errors.New("implant build file not found")
|
||||
)
|
||||
|
||||
func getBuildsDir() (string, error) {
|
||||
@@ -75,7 +75,7 @@ func ImplantBuildSave(name string, config *models.ImplantConfig, fPath string) e
|
||||
rootAppDir, _ := filepath.Abs(assets.GetRootAppDir())
|
||||
fPath, _ = filepath.Abs(fPath)
|
||||
if !strings.HasPrefix(fPath, rootAppDir) {
|
||||
return fmt.Errorf("Invalid path '%s' is not a subdirectory of '%s'", fPath, rootAppDir)
|
||||
return fmt.Errorf("invalid path '%s' is not a subdirectory of '%s'", fPath, rootAppDir)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(fPath)
|
||||
|
||||
Reference in new issue
Block a user