mirror of
https://github.com/gsmith257-cyber/better-sliver
synced 2026-06-06 15:44:30 +00:00
Remove mingw from docker, cleanup util
This commit is contained in:
+2
-3
@@ -34,7 +34,7 @@ FROM --platform=linux/amd64 base as test
|
||||
RUN apt-get update --fix-missing \
|
||||
&& apt-get -y upgrade \
|
||||
&& apt-get -y install \
|
||||
curl gcc-multilib build-essential mingw-w64 binutils-mingw-w64 g++-mingw-w64
|
||||
curl
|
||||
|
||||
RUN /opt/sliver-server unpack --force
|
||||
|
||||
@@ -56,8 +56,7 @@ RUN apt-get update --fix-missing \
|
||||
postgresql-contrib postgresql-client libpq-dev \
|
||||
curl libapr1 libaprutil1 libsvn1 \
|
||||
libpcap-dev libsqlite3-dev libgmp3-dev \
|
||||
mingw-w64 binutils-mingw-w64 g++-mingw-w64 \
|
||||
nasm gcc-multilib
|
||||
nasm
|
||||
|
||||
### Install MSF for stager generation
|
||||
RUN curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall \
|
||||
|
||||
+4
-9
@@ -160,14 +160,14 @@ echo "curl -L --fail --output $OUTPUT_DIR/linux/amd64/zig https://ziglang.org/do
|
||||
curl -L --fail --output $OUTPUT_DIR/linux/amd64/zig.tar.xz https://ziglang.org/download/$ZIG_VER/zig-linux-x86_64-$ZIG_VER.tar.xz
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/arm64/zig https://ziglang.org/download/$ZIG_VER/zig-linux-aarch64-$ZIG_VER.tar.xz"
|
||||
curl -L --fail --output $OUTPUT_DIR/linux/arm64/zig.tar.xz https://ziglang.org/download/$ZIG_VER/zig-linux-aarch64-$ZIG_VER.tar.xz
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/windows/amd64/zig https://ziglang.org/download/$ZIG_VER/zig-windows-x86_64-$ZIG_VER.zip"
|
||||
curl -L --fail --output $OUTPUT_DIR/windows/amd64/zig.tar.xz https://ziglang.org/download/$ZIG_VER/zig-windows-x86_64-$ZIG_VER.zip
|
||||
# Of course Windows has to be different, because it's awful (zip file instead of a tarball)
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/windows/amd64/zig.zip https://ziglang.org/download/$ZIG_VER/zig-windows-x86_64-$ZIG_VER.zip"
|
||||
curl -L --fail --output $OUTPUT_DIR/windows/amd64/zig.zip https://ziglang.org/download/$ZIG_VER/zig-windows-x86_64-$ZIG_VER.zip
|
||||
|
||||
|
||||
echo "-----------------------------------------------------------------"
|
||||
echo " Garble"
|
||||
echo "-----------------------------------------------------------------"
|
||||
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/amd64/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux"
|
||||
curl -L --fail --output $OUTPUT_DIR/linux/amd64/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/arm64/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux-arm64"
|
||||
@@ -183,28 +183,23 @@ curl -L --fail --output $OUTPUT_DIR/darwin/arm64/garble https://github.com/moloc
|
||||
echo "-----------------------------------------------------------------"
|
||||
echo " Shikata ga nai (ノ ゜Д゜)ノ ︵ 仕方がない"
|
||||
echo "-----------------------------------------------------------------"
|
||||
|
||||
# Linux (amd64)
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/amd64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_linux-amd64.zip"
|
||||
curl -L --fail --output $OUTPUT_DIR/linux/amd64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_linux-amd64.zip
|
||||
|
||||
# Linux (arm64)
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/arm64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_linux-arm64.zip"
|
||||
curl -L --fail --output $OUTPUT_DIR/linux/arm64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_linux-arm64.zip
|
||||
|
||||
# Windows (amd64)
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/windows/amd64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_windows-amd64.zip"
|
||||
curl -L --fail --output $OUTPUT_DIR/windows/amd64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_windows-amd64.zip
|
||||
|
||||
# MacOS (amd64)
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/darwin/amd64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_macos-amd64.zip"
|
||||
curl -L --fail --output $OUTPUT_DIR/darwin/amd64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_macos-amd64.zip
|
||||
|
||||
# MacOS (arm64)
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/darwin/arm64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_macos-arm64.zip"
|
||||
curl -L --fail --output $OUTPUT_DIR/darwin/arm64/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_macos-arm64.zip
|
||||
|
||||
# end
|
||||
# --- Cleanup ---
|
||||
echo -e "clean up: $WORK_DIR"
|
||||
rm -rf $WORK_DIR
|
||||
echo -e "\n[*] All done\n"
|
||||
|
||||
+151
-24
@@ -19,8 +19,10 @@ package assets
|
||||
*/
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"embed"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
@@ -146,21 +148,42 @@ func setupZig(appDir string) error {
|
||||
os.MkdirAll(zigRootPath, 0700)
|
||||
|
||||
// extract xz archive
|
||||
zigXzFSPath := path.Join("fs", runtime.GOOS, runtime.GOARCH, "zig.tar.xz")
|
||||
zigXzBuf, err := assetsFs.ReadFile(zigXzFSPath)
|
||||
if err != nil {
|
||||
setupLog.Errorf("static asset not found: %s", zigXzFSPath)
|
||||
return err
|
||||
if runtime.GOOS != "windows" {
|
||||
// Everything except windows
|
||||
zigXzFSPath := path.Join("fs", runtime.GOOS, runtime.GOARCH, "zig.tar.xz")
|
||||
zigXzBuf, err := assetsFs.ReadFile(zigXzFSPath)
|
||||
if err != nil {
|
||||
setupLog.Errorf("static asset not found: %s", zigXzFSPath)
|
||||
return err
|
||||
}
|
||||
xzReader, err := xz.NewReader(bytes.NewReader(zigXzBuf))
|
||||
if err != nil {
|
||||
setupLog.Errorf("NewReader error %s", err)
|
||||
return err
|
||||
}
|
||||
// Extract tar archive
|
||||
setupLog.Infof("Unpacking zig.tar.xz to %s", zigRootPath)
|
||||
return untarSkipTopLevel(zigRootPath, xzReader)
|
||||
} else {
|
||||
// Windows only, since it's an awful operating system
|
||||
zigZipFSPath := path.Join("fs", runtime.GOOS, runtime.GOARCH, "zig.zip")
|
||||
zigZipBuf, err := assetsFs.ReadFile(zigZipFSPath)
|
||||
if err != nil {
|
||||
setupLog.Errorf("static asset not found: %s", zigZipFSPath)
|
||||
return err
|
||||
}
|
||||
reader, err := zip.NewReader(bytes.NewReader(zigZipBuf), int64(len(zigZipBuf)))
|
||||
if err != nil {
|
||||
setupLog.Errorf("zip.NewReader error %s", err)
|
||||
return err
|
||||
}
|
||||
err = unzipSkipTopLevel(zigRootPath, reader)
|
||||
if err != nil {
|
||||
setupLog.Infof("Failed to unzip file %s -> %s", zigZipFSPath, zigRootPath)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
xzReader, err := xz.NewReader(bytes.NewReader(zigXzBuf))
|
||||
if err != nil {
|
||||
setupLog.Errorf("NewReader error %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Extract tar archive
|
||||
setupLog.Infof("Unpacking zig.tar.xz to %s", zigRootPath)
|
||||
return util.UntarSkipTopLevel(zigRootPath, xzReader)
|
||||
}
|
||||
|
||||
// SetupGo - Unzip Go compiler assets
|
||||
@@ -246,7 +269,7 @@ func setupSGN(appDir string) error {
|
||||
}
|
||||
|
||||
// SetupGoPath - Extracts dependencies to goPathSrc
|
||||
func SetupGoPath(goPathSrc string) error {
|
||||
func SetupGoPath(goPathSrc string, includeDNS bool) error {
|
||||
|
||||
// GOPATH setup
|
||||
if _, err := os.Stat(goPathSrc); os.IsNotExist(err) {
|
||||
@@ -284,15 +307,17 @@ func SetupGoPath(goPathSrc string) error {
|
||||
os.WriteFile(filepath.Join(commonpbDir, "common.pb.go"), commonpbSrc, 0600)
|
||||
|
||||
// DNS PB
|
||||
dnspbSrc, err := protobufs.FS.ReadFile("dnspb/dns.pb.go")
|
||||
if err != nil {
|
||||
setupLog.Info("Static asset not found: dns.pb.go")
|
||||
return err
|
||||
if includeDNS {
|
||||
dnspbSrc, err := protobufs.FS.ReadFile("dnspb/dns.pb.go")
|
||||
if err != nil {
|
||||
setupLog.Info("Static asset not found: dns.pb.go")
|
||||
return err
|
||||
}
|
||||
dnspbSrc = xorPBRawBytes(dnspbSrc)
|
||||
dnspbDir := filepath.Join(goPathSrc, "github.com", "bishopfox", "sliver", "protobuf", "dnspb")
|
||||
os.MkdirAll(dnspbDir, 0700)
|
||||
os.WriteFile(filepath.Join(dnspbDir, "dns.pb.go"), dnspbSrc, 0600)
|
||||
}
|
||||
dnspbSrc = xorPBRawBytes(dnspbSrc)
|
||||
dnspbDir := filepath.Join(goPathSrc, "github.com", "bishopfox", "sliver", "protobuf", "dnspb")
|
||||
os.MkdirAll(dnspbDir, 0700)
|
||||
os.WriteFile(filepath.Join(dnspbDir, "dns.pb.go"), dnspbSrc, 0600)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -318,6 +343,108 @@ func stripSliverpb(src []byte) []byte {
|
||||
return out
|
||||
}
|
||||
|
||||
// UntarSkipTopLevel - Untar a tar file, skipping the top level directory
|
||||
func untarSkipTopLevel(dst string, r io.Reader) error {
|
||||
tr := tar.NewReader(r)
|
||||
topLevel, _ := tr.Next()
|
||||
if topLevel == nil {
|
||||
return fmt.Errorf("no files found in tar")
|
||||
}
|
||||
if topLevel.Typeflag != tar.TypeDir {
|
||||
return fmt.Errorf("expected top level to be a directory, got %v", topLevel.Typeflag)
|
||||
}
|
||||
for {
|
||||
header, err := tr.Next()
|
||||
|
||||
switch {
|
||||
|
||||
// if no more files are found return
|
||||
case err == io.EOF:
|
||||
return nil
|
||||
|
||||
// return any other error
|
||||
case err != nil:
|
||||
return err
|
||||
|
||||
// if the header is nil, just skip it (not sure how this happens)
|
||||
case header == nil:
|
||||
continue
|
||||
}
|
||||
|
||||
// the target location where the dir/file should be created
|
||||
target := filepath.Join(dst, strings.TrimPrefix(header.Name, topLevel.Name))
|
||||
|
||||
// the following switch could also be done using fi.Mode(), not sure if there
|
||||
// a benefit of using one vs. the other.
|
||||
// fi := header.FileInfo()
|
||||
|
||||
// check the file type
|
||||
switch header.Typeflag {
|
||||
|
||||
// if its a dir and it doesn't exist create it
|
||||
case tar.TypeDir:
|
||||
if _, err := os.Stat(target); err != nil {
|
||||
if err := os.MkdirAll(target, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// if it's a file create it
|
||||
case tar.TypeReg:
|
||||
f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy over contents
|
||||
if _, err := io.Copy(f, tr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// manually close here after each file operation; defering would cause each file close
|
||||
// to wait until all operations have completed.
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UnzipSkipTopLevel - Unzip a zip file, skipping the top level directory
|
||||
func unzipSkipTopLevel(dst string, z *zip.Reader) error {
|
||||
topLevel := ""
|
||||
for index, file := range z.File {
|
||||
if index == 0 {
|
||||
topLevel = file.Name
|
||||
continue
|
||||
}
|
||||
rc, err := file.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rc.Close()
|
||||
fPath := filepath.Join(dst, strings.TrimPrefix(file.Name, topLevel))
|
||||
if file.FileInfo().IsDir() {
|
||||
err = os.MkdirAll(fPath, 0700)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err = os.MkdirAll(filepath.Dir(fPath), 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
outFile, err := os.OpenFile(fPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(outFile, rc)
|
||||
outFile.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func xorPBRawBytes(src []byte) []byte {
|
||||
var (
|
||||
fileAst *ast.File
|
||||
@@ -334,7 +461,7 @@ func xorPBRawBytes(src []byte) []byte {
|
||||
}
|
||||
var xorKey [8]byte
|
||||
// generate random xor key
|
||||
if _, err := insecureRand.Read(xorKey[:]); err != nil {
|
||||
if _, err := rand.Read(xorKey[:]); err != nil {
|
||||
// Panic because this is mandatory for the agent to work
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ func SliverSharedLibrary(name string, build *clientpb.ImplantBuild, config *clie
|
||||
|
||||
var cc string
|
||||
var cxx string
|
||||
if runtime.GOOS != config.GOOS {
|
||||
if runtime.GOOS != config.GOOS || runtime.GOARCH != config.GOARCH {
|
||||
buildLog.Debugf("Cross-compiling from %s/%s to %s/%s", runtime.GOOS, runtime.GOARCH, config.GOOS, config.GOARCH)
|
||||
cc, cxx = findCrossCompilers(config.GOOS, config.GOARCH)
|
||||
}
|
||||
@@ -363,8 +363,8 @@ func renderSliverGoCode(name string, build *clientpb.ImplantBuild, config *clien
|
||||
|
||||
// srcDir - ~/.sliver/slivers/<os>/<arch>/<name>/src
|
||||
srcDir := filepath.Join(projectGoPathDir, "src")
|
||||
assets.SetupGoPath(srcDir) // Extract GOPATH dependency files
|
||||
err := util.ChmodR(srcDir, 0600, 0700) // Ensures src code files are writable
|
||||
assets.SetupGoPath(srcDir, config.IncludeDNS) // Extract GOPATH dependency files
|
||||
err := util.ChmodR(srcDir, 0600, 0700) // Ensures src code files are writable
|
||||
if err != nil {
|
||||
buildLog.Errorf("fs perms: %v", err)
|
||||
return "", err
|
||||
|
||||
@@ -20,7 +20,6 @@ package generate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
@@ -114,12 +113,10 @@ func TestSliverExecutableLinux(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSliverSharedLibraryLinux(t *testing.T) {
|
||||
if runtime.GOOS == "linux" {
|
||||
multiLibrary(t, "linux", "amd64", true)
|
||||
multiLibrary(t, "linux", "amd64", false)
|
||||
multiLibrary(t, "linux", "386", true)
|
||||
multiLibrary(t, "linux", "386", false)
|
||||
}
|
||||
multiLibrary(t, "linux", "amd64", true)
|
||||
multiLibrary(t, "linux", "amd64", false)
|
||||
multiLibrary(t, "linux", "386", true)
|
||||
multiLibrary(t, "linux", "386", false)
|
||||
}
|
||||
|
||||
func TestSliverExecutableDarwin(t *testing.T) {
|
||||
|
||||
@@ -21,7 +21,6 @@ package util
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"strings"
|
||||
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -69,71 +68,6 @@ func ByteCountBinary(b int64) string {
|
||||
return fmt.Sprintf("%.1f %ciB", float64(b)/float64(div), "KMGTPE"[exp])
|
||||
}
|
||||
|
||||
// UntarSkipTopLevel - Untar a tar file, skipping the top level directory
|
||||
func UntarSkipTopLevel(dst string, r io.Reader) error {
|
||||
tr := tar.NewReader(r)
|
||||
topLevel, _ := tr.Next()
|
||||
if topLevel == nil {
|
||||
return fmt.Errorf("no files found in tar")
|
||||
}
|
||||
if topLevel.Typeflag != tar.TypeDir {
|
||||
return fmt.Errorf("expected top level to be a directory, got %v", topLevel.Typeflag)
|
||||
}
|
||||
for {
|
||||
header, err := tr.Next()
|
||||
|
||||
switch {
|
||||
|
||||
// if no more files are found return
|
||||
case err == io.EOF:
|
||||
return nil
|
||||
|
||||
// return any other error
|
||||
case err != nil:
|
||||
return err
|
||||
|
||||
// if the header is nil, just skip it (not sure how this happens)
|
||||
case header == nil:
|
||||
continue
|
||||
}
|
||||
|
||||
// the target location where the dir/file should be created
|
||||
target := filepath.Join(dst, strings.TrimPrefix(header.Name, topLevel.Name))
|
||||
|
||||
// the following switch could also be done using fi.Mode(), not sure if there
|
||||
// a benefit of using one vs. the other.
|
||||
// fi := header.FileInfo()
|
||||
|
||||
// check the file type
|
||||
switch header.Typeflag {
|
||||
|
||||
// if its a dir and it doesn't exist create it
|
||||
case tar.TypeDir:
|
||||
if _, err := os.Stat(target); err != nil {
|
||||
if err := os.MkdirAll(target, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// if it's a file create it
|
||||
case tar.TypeReg:
|
||||
f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy over contents
|
||||
if _, err := io.Copy(f, tr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// manually close here after each file operation; defering would cause each file close
|
||||
// to wait until all operations have completed.
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ReadFileFromTarGz - Read a file from a tar.gz file in-memory
|
||||
func ReadFileFromTarGz(tarGzFile string, tarPath string) ([]byte, error) {
|
||||
f, err := os.Open(tarGzFile)
|
||||
|
||||
Reference in New Issue
Block a user