Compare commits

...
Author SHA1 Message Date
rkervella 25795b3ceb Switch fd 2022-01-14 15:43:47 -08:00
rkervella aa272c2e14 Use pipes for IPC 2022-01-14 15:41:32 -08:00
rkervella 3be52dde2f Add back exports 2022-01-12 09:12:44 -08:00
rkervella 8b18bf571a Install dependencies for bundles too 2022-01-11 14:25:44 -08:00
Joe 10429b7314 Merge pull request #560 from hypnoticpattern/dev-hp
Fixed bug in ls command and added timestamp to SessionClosed
2022-01-05 22:24:35 -06:00
hypnoticpattern dfb6d2e1bb Fixed bug with 'ls' command 2022-01-05 16:54:19 -08:00
hypnoticpattern de3f2c827d Added timestamp to the SessionClosed event 2022-01-05 14:11:28 -08:00
moloch-- bf892e9c4b Fix ext id when loading into implant 2022-01-01 09:29:33 -06:00
moloch-- cb7f2b1aea Added download msg 2021-12-31 10:50:40 -06:00
moloch-- 44f16bb6a3 Improved ux 2021-12-31 10:21:41 -06:00
moloch-- 51af17906c Remove coff loader from go assets script 2021-12-31 10:17:47 -06:00
moloch-- 4ba374cee6 Fix extraction path in install from file 2021-12-31 10:12:04 -06:00
moloch-- 55c1145b2d Fix plaintext len calculation 2021-12-30 19:28:27 -06:00
rkervella 336fc4ffea Avoid attempting to load empty library 2021-12-30 13:52:22 -08:00
rkervella 581395e9a4 Fix extension filepath 2021-12-30 13:51:57 -08:00
moloch-- 16ce440014 Fix help cmd 2021-12-30 14:33:23 -06:00
moloch-- 2bf87bff98 Merge branch 'alias-ext' into stage 2021-12-30 11:49:41 -06:00
moloch-- 65788c1003 Fix armory update cmd exists 2021-12-30 11:44:54 -06:00
17 changed files with 103 additions and 84 deletions

No files matched your search

-39
View File
@@ -19,9 +19,7 @@ package assets
*/
import (
"embed"
"fmt"
"io/fs"
"io/ioutil"
"log"
"os"
@@ -32,11 +30,6 @@ import (
ver "github.com/bishopfox/sliver/client/version"
)
var (
//go:embed fs/*
clientAssetsFs embed.FS
)
const (
// SliverClientDirName - Directory storing all of the client configs/logs
SliverClientDirName = ".sliver-client"
@@ -86,41 +79,9 @@ This is free software, and you are welcome to redistribute it
under certain conditions; type 'licenses' for details.`)
fmt.Printf("\n\nUnpacking assets ...\n")
}
err := setupDefaultExtensions(appDir)
if err != nil {
fmt.Println(err)
log.Fatal(err)
}
saveAssetVersion(appDir)
}
if _, err := os.Stat(filepath.Join(appDir, settingsFileName)); os.IsNotExist(err) {
SaveSettings(nil)
}
}
func setupDefaultExtensions(appDir string) error {
localExtDir := GetExtensionsDir()
rootEmbedPath := "fs/extensions"
return fs.WalkDir(clientAssetsFs, rootEmbedPath, func(embedPath string, embedDir fs.DirEntry, err error) error {
if err != nil {
return err
}
localPath := strings.TrimPrefix(embedPath, rootEmbedPath)
if embedDir.IsDir() {
err := os.MkdirAll(filepath.Join(localExtDir, localPath), 0o700)
if err != nil {
return err
}
} else {
data, err := fs.ReadFile(clientAssetsFs, embedPath)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(localExtDir, localPath), data, 0o600)
if err != nil {
return err
}
}
return nil
})
}
+1 -1
View File
@@ -32,7 +32,7 @@ func AliasesCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if 0 < len(loadedAliases) {
PrintAliases(con)
} else {
con.PrintInfof("No aliases loaded\n")
con.PrintInfof("No aliases installed, use the 'armory' command to automatically install some\n")
}
}
+14 -6
View File
@@ -20,7 +20,6 @@ package armory
import (
"errors"
"fmt"
"io/ioutil"
"net/url"
"os"
@@ -64,7 +63,7 @@ func ArmoryInstallCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
func installBundle(bundle *ArmoryBundle, clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) {
for _, pkgName := range bundle.Packages {
err := installExtensionPackageByName(pkgName, clientConfig, con)
err := installPackageByName(pkgName, clientConfig, con)
if err != nil {
con.PrintErrorf("Failed to install '%s': %s", pkgName, err)
}
@@ -114,6 +113,8 @@ func installAliasPackageByName(name string, clientConfig ArmoryHTTPConfig, con *
return err
}
con.PrintInfof("Downloading alias ...")
var sig *minisign.Signature
var tarGz []byte
if pkgParser, ok := pkgParsers[repoURL.Hostname()]; ok {
@@ -144,6 +145,8 @@ func installAliasPackageByName(name string, clientConfig ArmoryHTTPConfig, con *
}
tmpFile.Close()
con.Printf(console.Clearln + "\r") // Clear the line
installPath := alias.InstallFromFile(tmpFile.Name(), true, con)
if installPath == nil {
return errors.New("failed to install alias")
@@ -228,6 +231,8 @@ func installExtensionPackageByName(name string, clientConfig ArmoryHTTPConfig, c
return err
}
con.PrintInfof("Downloading extension ...")
var sig *minisign.Signature
var tarGz []byte
if pkgParser, ok := pkgParsers[repoURL.Hostname()]; ok {
@@ -256,7 +261,12 @@ func installExtensionPackageByName(name string, clientConfig ArmoryHTTPConfig, c
if err != nil {
return err
}
tmpFile.Close()
err = tmpFile.Sync()
if err != nil {
return err
}
con.Printf(console.Clearln + "\r") // Clear download message
installPath := extensions.InstallFromFilePath(tmpFile.Name(), true, con)
if installPath == nil {
@@ -266,10 +276,8 @@ func installExtensionPackageByName(name string, clientConfig ArmoryHTTPConfig, c
if err != nil {
return err
}
// do not add if the command already exists
if extensions.CmdExists(extCmd.Name, con.App) {
return fmt.Errorf("%s command already exists", extCmd.Name)
con.App.Commands().Remove(extCmd.Name)
}
extensions.ExtensionRegisterCommand(extCmd, con)
return nil
+1 -1
View File
@@ -56,7 +56,7 @@ The structure is the following one:
- `files`: a list of object pointing to the extensions files to load for each architectures and operating systems
- `init`: the initialization function name (if relevant, can be omitted)
- `arguments`: an optional list of objects (for DLLs), but mandatory for BOFs
- `dependsOn`: the name of an extension required by the current extension (won't load if the dependency is not loaded)
- `depends_on`: the name of an extension required by the current extension (won't load if the dependency is not loaded)
The `type` of an argument can be one of the following:
+5 -1
View File
@@ -34,7 +34,11 @@ import (
// ExtensionsCmd - List information about installed extensions
func ExtensionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
PrintExtensions(con)
if 0 < len(getInstalledManifests()) {
PrintExtensions(con)
} else {
con.PrintInfof("No extensions installed, use the 'armory' command to automatically install some\n")
}
}
// PrintExtensions - Print a list of loaded extensions
+8 -2
View File
@@ -151,14 +151,20 @@ func InstallFromFilePath(extLocalPath string, autoOverwrite bool, con *console.S
}
func installArtifact(extGzFilePath string, installPath string, artifactPath string, con *console.SliverConsoleClient) error {
data, err := util.ReadFileFromTarGz(extGzFilePath, artifactPath)
data, err := util.ReadFileFromTarGz(extGzFilePath, "."+artifactPath)
if err != nil {
return err
}
if len(data) == 0 {
return fmt.Errorf("archive path '%s' is empty", "."+artifactPath)
}
localArtifactPath := filepath.Join(installPath, util.ResolvePath(artifactPath))
artifactDir := filepath.Dir(localArtifactPath)
if _, err := os.Stat(artifactDir); os.IsNotExist(err) {
os.MkdirAll(artifactDir, 0o700)
err := os.MkdirAll(artifactDir, 0o700)
if err != nil {
return err
}
}
err = ioutil.WriteFile(localArtifactPath, data, 0o600)
if err != nil {
+8 -7
View File
@@ -82,7 +82,7 @@ func (e *ExtensionManifest) getFileForTarget(cmdName string, targetOS string, ta
filePath := ""
for _, extFile := range e.Files {
if targetOS == extFile.OS && targetArch == extFile.Arch {
filePath = path.Join(assets.GetExtensionsDir(), cmdName, extFile.Path)
filePath = path.Join(assets.GetExtensionsDir(), e.CommandName, extFile.Path)
break
}
}
@@ -105,12 +105,12 @@ func ExtensionLoadCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
return
}
// do not add if the command already exists
if CmdExists(extCmd.Name, con.App) {
con.PrintErrorf("%s command already exists\n", extCmd.Name)
if CmdExists(extCmd.CommandName, con.App) {
con.PrintErrorf("%s command already exists\n", extCmd.CommandName)
return
}
ExtensionRegisterCommand(extCmd, con)
con.PrintInfof("Added %s command: %s\n", extCmd.Name, extCmd.Help)
con.PrintInfof("Added %s command: %s\n", extCmd.CommandName, extCmd.Help)
}
// ParseExtensions - Parse extension files
@@ -280,7 +280,7 @@ func loadExtension(ctx *grumble.Context, session *clientpb.Session, con *console
func registerExtension(con *console.SliverConsoleClient, ext *ExtensionManifest, binData []byte, session *clientpb.Session, ctx *grumble.Context) error {
registerResp, err := con.Rpc.RegisterExtension(context.Background(), &sliverpb.RegisterExtensionReq{
Name: ext.Name,
Name: ext.CommandName,
Data: binData,
OS: session.OS,
Init: ext.Init,
@@ -298,7 +298,7 @@ func registerExtension(con *console.SliverConsoleClient, ext *ExtensionManifest,
func loadDep(session *clientpb.Session, con *console.SliverConsoleClient, ctx *grumble.Context, depName string) error {
depExt, f := loadedExtensions[depName]
if f {
depBinPath, err := depExt.getFileForTarget(depExt.Name, session.OS, session.Arch)
depBinPath, err := depExt.getFileForTarget(depExt.CommandName, session.OS, session.Arch)
if err != nil {
return err
}
@@ -370,7 +370,7 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
// Regular DLL
extArgs := strings.Join(ctx.Args.StringList("arguments"), " ")
extensionArgs = []byte(extArgs)
extName = ext.Name
extName = ext.CommandName
entryPoint = ext.Entrypoint
}
ctrl := make(chan bool)
@@ -399,6 +399,7 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
outFilePath.Write(callExtension.Output)
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
}
con.Println()
}
}
+4
View File
@@ -81,6 +81,10 @@ func LsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
// Then we have a filter on the end of the path
remotePath = baseDir
filter = potentialFilter
} else {
if !strings.HasSuffix(remotePath, "/") {
remotePath = remotePath + "/"
}
}
}
}
+2 -1
View File
@@ -46,7 +46,7 @@ func printHelp(con *console.SliverConsoleClient) {
for _, c := range con.App.Commands().All() {
key := c.HelpGroup
targetOS := ""
session, beacon := con.ActiveTarget.GetInteractive()
session, beacon := con.ActiveTarget.Get()
if session != nil {
targetOS = session.OS
} else if beacon != nil {
@@ -97,6 +97,7 @@ func printHelp(con *console.SliverConsoleClient) {
con.Println()
printHeadline(con.App.Config(), headline, con)
con.Printf("%s\n", columnize.Format(output, config))
con.Println()
}
}
}
+3 -2
View File
@@ -208,8 +208,9 @@ func (con *SliverConsoleClient) EventLoop() {
case consts.SessionClosedEvent:
session := event.Session
con.PrintEventErrorf("Lost session #%d %s - %s (%s) - %s/%s",
session.ID, session.Name, session.RemoteAddress, session.Hostname, session.OS, session.Arch)
currentTime := time.Now().Format(time.RFC1123)
con.PrintEventErrorf("Lost session #%d %s - %s (%s) - %s/%s - %v",
session.ID, session.Name, session.RemoteAddress, session.Hostname, session.OS, session.Arch, currentTime)
activeSession := con.ActiveTarget.GetSession()
if activeSession != nil && activeSession.ID == session.ID {
con.ActiveTarget.Set(nil, nil)
-7
View File
@@ -21,7 +21,6 @@
GO_VER="1.17.5"
GARBLE_VER="1.17.5"
COFF_LOADER_VER="1.0.7"
GO_ARCH_1="amd64"
GO_ARCH_2="arm64"
@@ -145,12 +144,6 @@ curl -L --output $OUTPUT_DIR/windows/$GO_ARCH_1/garble.exe https://github.com/mo
curl -L --output $OUTPUT_DIR/darwin/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_macos-$GO_ARCH_1
curl -L --output $OUTPUT_DIR/darwin/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_macos-$GO_ARCH_2
echo "-----------------------------------------------------------------"
echo " COFF Loader"
echo "-----------------------------------------------------------------"
curl -L --output $CLIENT_OUTPUT_DIR/extensions/coff-loader/windows/COFFLoader.x64.dll https://github.com/lesnuages/COFFLoader/releases/download/v$COFF_LOADER_VER/COFFLoader.x64.dll
curl -L --output $CLIENT_OUTPUT_DIR/extensions/coff-loader/windows/COFFLoader.x86.dll https://github.com/lesnuages/COFFLoader/releases/download/v$COFF_LOADER_VER/COFFLoader.x86.dll
# end
echo -e "clean up: $WORK_DIR"
rm -rf $WORK_DIR
+2 -1
View File
@@ -104,11 +104,12 @@ func Encrypt(key [chacha20poly1305.KeySize]byte, plaintext []byte) ([]byte, erro
if err != nil {
return nil, err
}
plaintext = bytes.NewBuffer(GzipBuf(plaintext)).Bytes()
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(plaintext)+aead.Overhead())
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
return aead.Seal(nonce, nonce, GzipBuf(plaintext), nil), nil
return aead.Seal(nonce, nonce, plaintext, nil), nil
}
// Decrypt - Decrypt using chacha20poly1305
+12 -1
View File
@@ -18,7 +18,13 @@ package extension
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import "errors"
import (
"errors"
// {{if .Config.Debug}}
"log"
// {{end}}
)
var extensions map[string]Extension
@@ -45,6 +51,11 @@ func Run(extID string, funcName string, arguments []byte, callback func([]byte))
if ext, found := extensions[extID]; found {
return ext.Call(funcName, arguments, callback)
}
// {{if .Config.Debug}}
for id, ext := range extensions {
log.Printf("Extension '%s' (%s)", id, ext.GetArch())
}
//{{end}}
return errors.New("{{if .Config.Debug}} extension not found{{end}}")
}
+35 -12
View File
@@ -20,7 +20,10 @@ package extension
import (
"bytes"
"io/ioutil"
"os"
"runtime"
"syscall"
"unsafe"
// {{if .Config.Debug}}
@@ -39,10 +42,12 @@ type DarwinExtension struct {
}
type extensionArguments struct {
inDataSize uintptr
inDataBuff uintptr
outDataSize uintptr
outDataBuff uintptr
inDataSize uintptr
inDataBuff uintptr
pipeIn int
pipeOut int
// outDataSize uintptr
// outDataBuff uintptr
}
func NewDarwinExtension(data []byte, id string, arch string, init string) *DarwinExtension {
@@ -98,7 +103,16 @@ func (d *DarwinExtension) Call(export string, arguments []byte, onFinish func([]
// {{if .Config.Debug}}
log.Printf("Calling %s, arg size: %d\n", export, extArgs.inDataSize)
// {{end}}
_, err := d.module.Call(export, uintptr(unsafe.Pointer(&extArgs)))
pipe := make([]int, 2)
err := syscall.Pipe(pipe)
if err != nil {
return err
}
defer syscall.Close(pipe[0])
defer syscall.Close(pipe[1])
extArgs.pipeIn = pipe[0] // read
extArgs.pipeOut = pipe[1] // write
_, err = d.module.Call(export, uintptr(unsafe.Pointer(&extArgs)))
if err != nil {
return err
}
@@ -106,14 +120,23 @@ func (d *DarwinExtension) Call(export string, arguments []byte, onFinish func([]
log.Printf("%s done!\n", export)
// {{end}}
outData := new(bytes.Buffer)
outDataSize := int(extArgs.outDataSize)
// {{if .Config.Debug}}
log.Printf("Out data size: %d\n", outDataSize)
// {{end}}
for i := 0; i < outDataSize; i++ {
b := (*byte)(unsafe.Pointer(uintptr(i) + extArgs.outDataBuff))
outData.WriteByte(*b)
outFile := os.NewFile(uintptr(extArgs.pipeIn), "pipe")
if outFile == nil {
return syscall.EINVAL
}
data, err := ioutil.ReadAll(outFile)
if err != nil {
return err
}
outData.Write(data)
// outDataSize := int(extArgs.outDataSize)
// // {{if .Config.Debug}}
// log.Printf("Out data size: %d\n", outDataSize)
// // {{end}}
// for i := 0; i < outDataSize; i++ {
// b := (*byte)(unsafe.Pointer(uintptr(i) + extArgs.outDataBuff))
// outData.WriteByte(*b)
// }
// We currently don't have a way to trigger a callback
// in the loaded code for Darwin.
if outData.Len() > 0 {
@@ -65,6 +65,9 @@ func (w *WindowsExtension) GetArch() string {
func (w *WindowsExtension) Load() error {
var err error
if len(w.data) == 0 {
return errors.New("{{if .Config.Debug}} extension data is empty {{end}}")
}
w.module, err = memmod.LoadLibrary(w.data)
if err != nil {
return err
+2 -2
View File
@@ -169,12 +169,12 @@ func DllInstall() { main() }
// DllRegisterServer - is used when executing the Sliver implant with regsvr32.exe (i.e. regsvr32.exe /s sliver.dll)
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682162(v=vs.85).aspx
// export DllRegisterServer
//export DllRegisterServer
func DllRegisterServer() { main() }
// DllUnregisterServer - is used when executing the Sliver implant with regsvr32.exe (i.e. regsvr32.exe /s /u sliver.dll)
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms691457(v=vs.85).aspx
// export DllUnregisterServer
//export DllUnregisterServer
func DllUnregisterServer() { main() }
// {{end}}
+3 -1
View File
@@ -24,6 +24,7 @@ package cryptography
*/
import (
"bytes"
"crypto/ed25519"
"crypto/rand"
"crypto/sha256"
@@ -145,11 +146,12 @@ func Encrypt(key [chacha20poly1305.KeySize]byte, plaintext []byte) ([]byte, erro
if err != nil {
return nil, err
}
plaintext = bytes.NewBuffer(util.GzipBuf(plaintext)).Bytes()
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(plaintext)+aead.Overhead())
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
return aead.Seal(nonce, nonce, util.GzipBuf(plaintext), nil), nil
return aead.Seal(nonce, nonce, plaintext, nil), nil
}
// Decrypt - Decrypt using chacha20poly1305