Compare commits

...
Author SHA1 Message Date
moloch-- b3429f5f88 Fix err nil deref 2023-11-18 13:31:47 -07:00
moloch-- 04d8d2aac7 Add missing builder permissions 2023-11-18 12:39:34 -07:00
moloch-- b71759f3b2 Add basic methods 2023-11-18 12:33:06 -07:00
moloch-- 13c68a7f50 Implement method checks 2023-11-18 12:27:39 -07:00
moloch-- 1f894f50ff Add permissions to operator config 2023-11-18 12:14:33 -07:00
moloch-- 33ea66de58 Add production 'slim' Docker stage 2023-11-18 10:19:14 -07:00
moloch-- 9a432f583d Add missing libs to docker test 2023-11-18 10:09:32 -07:00
moloch-- cbcd948c83 Add comments to Dockerfile 2023-11-18 09:24:21 -07:00
Joe 2ada8bf8ed Merge pull request #1465 from BishopFox/vendor/ssh
Update ssh and garble
2023-11-18 08:16:16 -08:00
moloch-- 02a4657d14 Additional tweaks to dockerfile 2023-11-18 08:53:46 -07:00
Joe b7cef9a07c Merge branch 'master' into vendor/ssh 2023-11-18 07:06:53 -08:00
moloch-- 49606ba753 Update ssh and garble 2023-11-18 07:49:03 -07:00
Joe 116431a049 Merge pull request #1421 from BishopFox/upload-dir
Adding the ability to upload directories
2023-11-17 10:03:09 -08:00
70 changed files with 329 additions and 134 deletions

No files matched your search

+82 -24
View File
@@ -1,3 +1,12 @@
#
# For production:
# docker build --target production -t sliver .
# docker run -it --rm -v $HOME/.sliver:/home/sliver/.sliver sliver
#
# For unit testing:
# docker build --target test .
#
# STAGE: base
## Compiles Sliver for use
FROM --platform=linux/amd64 golang:1.21.4 as base
@@ -22,25 +31,10 @@ RUN cp -vv sliver-server /opt/sliver-server
## Use `--target test` in the docker build command to run this stage
FROM --platform=linux/amd64 base as test
### Install testing packages
RUN apt-get update --fix-missing && apt-get -y install \
libxml2 libxml2-dev libxslt-dev locate curl \
libreadline6-dev libcurl4-openssl-dev git-core \
libssl-dev libyaml-dev openssl autoconf libtool \
ncurses-dev bison curl xsel postgresql \
postgresql-contrib postgresql-client libpq-dev \
libapr1 libaprutil1 libsvn1 \
libpcap-dev libsqlite3-dev libgmp3-dev \
mingw-w64 binutils-mingw-w64 g++-mingw-w64 \
nasm gcc-multilib
### Install MSF for testing
RUN curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall \
&& chmod 755 msfinstall \
&& ./msfinstall
RUN mkdir -p ~/.msf4/ \
&& touch ~/.msf4/initial_setup_complete \
&& su -l sliver -c 'mkdir -p ~/.msf4/ && touch ~/.msf4/initial_setup_complete'
RUN apt-get update --fix-missing \
&& apt-get -y upgrade \
&& apt-get -y install \
curl gcc-multilib build-essential mingw-w64 binutils-mingw-w64 g++-mingw-w64
RUN /opt/sliver-server unpack --force
@@ -51,17 +45,81 @@ RUN /go/src/github.com/bishopfox/sliver/go-tests.sh
## Final dockerized form of Sliver
FROM --platform=linux/amd64 debian:bookworm-slim as production
### Install production packages
RUN apt-get update --fix-missing \
&& apt-get -y upgrade \
&& apt-get -y install \
libxml2 libxml2-dev libxslt-dev locate gnupg \
libreadline6-dev libcurl4-openssl-dev git-core \
libssl-dev libyaml-dev openssl autoconf libtool \
ncurses-dev bison curl xsel postgresql \
postgresql-contrib postgresql-client libpq-dev \
curl libapr1 libaprutil1 libsvn1 \
libpcap-dev libsqlite3-dev libgmp3-dev \
mingw-w64 binutils-mingw-w64 g++-mingw-w64 \
nasm gcc-multilib
### Install MSF for stager generation
RUN curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall \
&& chmod 755 msfinstall \
&& ./msfinstall \
&& mkdir -p ~/.msf4/ \
&& touch ~/.msf4/initial_setup_complete
### Cleanup unneeded packages
RUN apt-get remove -y curl gnupg \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
### Add sliver user
RUN groupadd -g 999 sliver \
&& useradd -r -u 999 -g sliver sliver \
&& mkdir -p /home/sliver/ \
&& chown -R sliver:sliver /home/sliver \
&& su -l sliver -c 'mkdir -p ~/.msf4/ && touch ~/.msf4/initial_setup_complete'
### Copy compiled binary
COPY --from=base /opt/sliver-server /opt/sliver-server
### Add sliver user
RUN groupadd -g 999 sliver && useradd -r -u 999 -g sliver sliver
RUN mkdir -p /home/sliver/ && chown -R sliver:sliver /home/sliver
### Unpack Sliver:
USER sliver
RUN /opt/sliver-server unpack --force
WORKDIR /home/sliver/
VOLUME [ "/home/sliver/.sliver" ]
ENTRYPOINT [ "/opt/sliver-server" ]
# STAGE: production-slim (about 1Gb smaller)
### Slim production image, i.e. without MSF and assoicated libraries
### Still include GCC and MinGW for cross-platform generation
FROM --platform=linux/amd64 debian:bookworm-slim as production-slim
### Install production packages
RUN apt-get update --fix-missing \
&& apt-get -y upgrade \
&& apt-get -y install \
build-essential mingw-w64 binutils-mingw-w64 g++-mingw-w64 gcc-multilib
### Cleanup unneeded packages
RUN apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
### Add sliver user
RUN groupadd -g 999 sliver \
&& useradd -r -u 999 -g sliver sliver \
&& mkdir -p /home/sliver/ \
&& chown -R sliver:sliver /home/sliver
### Copy compiled binary
COPY --from=base /opt/sliver-server /opt/sliver-server
### Unpack Sliver:
USER sliver
RUN /opt/sliver-server unpack --force
USER sliver
WORKDIR /home/sliver/
VOLUME [ "/home/sliver/.sliver" ]
ENTRYPOINT [ "/opt/sliver-server" ]
+1 -1
View File
@@ -21,7 +21,7 @@ set -e
# Creates the static go asset archives
GO_VER="1.21.4"
GARBLE_VER="1.21.4a"
GARBLE_VER="1.21.4b"
SGN_VER="0.0.3"
BLOAT_FILES="AUTHORS CONTRIBUTORS PATENTS VERSION favicon.ico robots.txt SECURITY.md CONTRIBUTING.md LICENSE README.md ./doc ./test ./api ./misc"
+1 -1
View File
@@ -45,7 +45,7 @@ require (
github.com/things-go/go-socks5 v0.0.3
github.com/xlab/treeprint v1.2.0
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e
golang.org/x/crypto v0.14.0
golang.org/x/crypto v0.15.0
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
golang.org/x/net v0.17.0
golang.org/x/sys v0.14.0
+2
View File
@@ -448,6 +448,8 @@ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
+1 -1
View File
@@ -272,7 +272,7 @@ func listenAndServeTLS(srv *http.Server, certPEMBlock, keyPEMBlock []byte) error
}
config := &tls.Config{}
if srv.TLSConfig != nil {
*config = *srv.TLSConfig
config = srv.TLSConfig
}
if certs.TLSKeyLogger != nil {
config.KeyLogWriter = certs.TLSKeyLogger
+5 -4
View File
@@ -44,10 +44,11 @@ const (
forceFlagStr = "force"
// Operator flags
nameFlagStr = "name"
lhostFlagStr = "lhost"
lportFlagStr = "lport"
saveFlagStr = "save"
nameFlagStr = "name"
lhostFlagStr = "lhost"
lportFlagStr = "lport"
saveFlagStr = "save"
permissionsFlagStr = "permissions"
// Cert flags
caTypeFlagStr = "type"
+4 -4
View File
@@ -71,10 +71,10 @@ var daemonCmd = &cobra.Command{
},
}
func StartPersistentJobs(listenerJobs *[]clientpb.ListenerJob) error {
if len(*listenerJobs) > 0 {
func StartPersistentJobs(listenerJobs []*clientpb.ListenerJob) error {
if len(listenerJobs) > 0 {
// StartPersistentJobs - Start persistent jobs
for _, j := range *listenerJobs {
for _, j := range listenerJobs {
listenerJob, err := db.ListenerByJobID(j.JobID)
if err != nil {
return err
@@ -117,7 +117,7 @@ func StartPersistentJobs(listenerJobs *[]clientpb.ListenerJob) error {
}
j.JobID = uint32(id)
}
db.UpdateHTTPC2Listener(&j)
db.UpdateHTTPC2Listener(j)
}
}
+20 -11
View File
@@ -33,54 +33,63 @@ var operatorCmd = &cobra.Command{
Short: "Generate operator configuration files",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
name, err := cmd.Flags().GetString(nameFlagStr)
if err != nil {
fmt.Printf("Failed to parse --%s flag %s", nameFlagStr, err)
os.Exit(1)
return
}
if name == "" {
fmt.Printf("Must specify --%s", nameFlagStr)
os.Exit(1)
return
}
lhost, err := cmd.Flags().GetString(lhostFlagStr)
if err != nil {
fmt.Printf("Failed to parse --%s flag %s", lhostFlagStr, err)
os.Exit(1)
return
}
if lhost == "" {
fmt.Printf("Must specify --%s", lhostFlagStr)
os.Exit(1)
return
}
lport, err := cmd.Flags().GetUint16(lportFlagStr)
if err != nil {
fmt.Printf("Failed to parse --%s flag %s", lportFlagStr, err)
os.Exit(1)
return
}
save, err := cmd.Flags().GetString(saveFlagStr)
if err != nil {
fmt.Printf("Failed to parse --%s flag %s", saveFlagStr, err)
os.Exit(1)
return
}
if save == "" {
save, _ = os.Getwd()
}
permissions, err := cmd.Flags().GetStringSlice(permissionsFlagStr)
if err != nil {
fmt.Printf("Failed to parse --%s flag %s", permissionsFlagStr, err)
return
}
if len(permissions) == 0 {
fmt.Printf("Must specify --%s", permissionsFlagStr)
return
}
certs.SetupCAs()
configJSON, err := console.NewOperatorConfig(name, lhost, lport)
configJSON, err := console.NewOperatorConfig(name, lhost, lport, permissions)
if err != nil {
fmt.Printf("Failed: %s\n", err)
os.Exit(1)
return
}
saveTo, _ := filepath.Abs(save)
fi, err := os.Stat(saveTo)
if !os.IsNotExist(err) && !fi.IsDir() {
fmt.Printf("File already exists: %s\n", err)
os.Exit(1)
return
}
if !os.IsNotExist(err) && fi.IsDir() {
filename := fmt.Sprintf("%s_%s.cfg", filepath.Base(name), filepath.Base(lhost))
@@ -89,7 +98,7 @@ var operatorCmd = &cobra.Command{
err = os.WriteFile(saveTo, configJSON, 0600)
if err != nil {
fmt.Printf("Write failed: %s (%s)\n", saveTo, err)
os.Exit(1)
return
}
},
}
+20 -4
View File
@@ -24,7 +24,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
@@ -86,13 +85,14 @@ func newOperatorCmd(cmd *cobra.Command, _ []string) {
lhost, _ := cmd.Flags().GetString("lhost")
lport, _ := cmd.Flags().GetUint16("lport")
save, _ := cmd.Flags().GetString("save")
permissions, _ := cmd.Flags().GetStringSlice("permissions")
if save == "" {
save, _ = os.Getwd()
}
fmt.Printf(Info + "Generating new client certificate, please wait ... \n")
configJSON, err := NewOperatorConfig(name, lhost, lport)
configJSON, err := NewOperatorConfig(name, lhost, lport, permissions)
if err != nil {
fmt.Printf(Warn+"%s\n", err)
return
@@ -108,7 +108,7 @@ func newOperatorCmd(cmd *cobra.Command, _ []string) {
filename := fmt.Sprintf("%s_%s.cfg", filepath.Base(name), filepath.Base(lhost))
saveTo = filepath.Join(saveTo, filename)
}
err = ioutil.WriteFile(saveTo, configJSON, 0o600)
err = os.WriteFile(saveTo, configJSON, 0o600)
if err != nil {
fmt.Printf(Warn+"Failed to write config to: %s (%s) \n", saveTo, err)
return
@@ -117,7 +117,7 @@ func newOperatorCmd(cmd *cobra.Command, _ []string) {
}
// NewOperatorConfig - Generate a new player/client/operator configuration
func NewOperatorConfig(operatorName string, lhost string, lport uint16) ([]byte, error) {
func NewOperatorConfig(operatorName string, lhost string, lport uint16, permissions []string) ([]byte, error) {
if !namePattern.MatchString(operatorName) {
return nil, errors.New("invalid operator name (alphanumerics only)")
}
@@ -127,6 +127,9 @@ func NewOperatorConfig(operatorName string, lhost string, lport uint16) ([]byte,
if lhost == "" {
return nil, errors.New("invalid lhost")
}
if len(permissions) == 0 {
return nil, errors.New("must specify at least one permission")
}
rawToken := models.GenerateOperatorToken()
digest := sha256.Sum256([]byte(rawToken))
@@ -134,6 +137,19 @@ func NewOperatorConfig(operatorName string, lhost string, lport uint16) ([]byte,
Name: operatorName,
Token: hex.EncodeToString(digest[:]),
}
for _, permission := range permissions {
switch permission {
case "all":
dbOperator.PermissionAll = true
break
case "builder":
dbOperator.PermissionBuilder = true
case "crackstation":
dbOperator.PermissionCrackstation = true
default:
return nil, fmt.Errorf("invalid permission: %s", permission)
}
}
err := db.Session().Save(dbOperator).Error
if err != nil {
return nil, err
+1 -1
View File
@@ -12,7 +12,7 @@ import (
func TestRootOnlyVerifyCertificate(t *testing.T) {
certs.SetupCAs()
data, err := NewOperatorConfig("zerocool", "localhost", uint16(1337))
data, err := NewOperatorConfig("zerocool", "localhost", uint16(1337), []string{"all"})
if err != nil {
t.Fatalf("failed to generate test player profile %s", err)
}
+22 -1
View File
@@ -85,7 +85,7 @@ func serverOnlyCmds() (commands []*cobra.Command) {
newOperator := &cobra.Command{
Use: consts.NewOperatorStr,
Short: "Create a new operator config file",
Long: help.GetHelpFor([]string{consts.NewOperatorStr}),
Long: newOperatorLongHelp,
Run: newOperatorCmd,
GroupID: consts.MultiplayerHelpGroup,
}
@@ -94,6 +94,7 @@ func serverOnlyCmds() (commands []*cobra.Command) {
f.Uint16P("lport", "p", 31337, "listen port")
f.StringP("save", "s", "", "directory/file in which to save config")
f.StringP("name", "n", "", "operator name")
f.StringSliceP("permissions", "P", []string{}, "grant permissions to the operator profile (all, builder, crackstation)")
})
command.FlagComps(newOperator, func(comp *carapace.ActionMap) {
(*comp)["save"] = carapace.ActionDirectories()
@@ -115,3 +116,23 @@ func serverOnlyCmds() (commands []*cobra.Command) {
return
}
const newOperatorLongHelp = `
Create a new operator config file, operator configuration files allow
remote machines to connect to the Sliver server. They are most commonly
used for allowing remote operators to connect in "Multiplayer Mode."
To generate a profile for a remote operator, you need to specify the
the "all" permission to grant the profile access to all gRPC APIs:
new-operator --name <operator name> --lhost <sliver server> --permissions all
Operator profiles can also be used to allow remote machines to connect to
the Sliver server for other purposes, such as a "Remote Builder" or a
"Crackstation."
You can restrict profiles' permissions by using the --permissions flag, for
example, to create a profile that can only be used as a "Remote Builder":
new-operator --name <operator name> --lhost <sliver server> --permissions builder
`
+1 -1
View File
@@ -31,11 +31,11 @@ type ImplantConnection struct {
ID string
Send chan *sliverpb.Envelope
RespMutex *sync.RWMutex
LastMessageMutex *sync.RWMutex
Resp map[int64]chan *sliverpb.Envelope
Transport string
RemoteAddress string
LastMessage time.Time
LastMessageMutex *sync.RWMutex
Cleanup func()
}
+4 -4
View File
@@ -525,15 +525,15 @@ func ListenerByJobID(JobID uint32) (*clientpb.ListenerJob, error) {
return listenerJob.ToProtobuf(), err
}
func ListenerJobs() (*[]clientpb.ListenerJob, error) {
func ListenerJobs() ([]*clientpb.ListenerJob, error) {
listenerJobs := []models.ListenerJob{}
err := Session().Where(&models.ListenerJob{}).Find(&listenerJobs).Error
pbListenerJobs := []clientpb.ListenerJob{}
pbListenerJobs := []*clientpb.ListenerJob{}
for _, listenerJob := range listenerJobs {
pbListenerJobs = append(pbListenerJobs, *listenerJob.ToProtobuf())
pbListenerJobs = append(pbListenerJobs, listenerJob.ToProtobuf())
}
return &pbListenerJobs, err
return pbListenerJobs, err
}
func DeleteListener(JobID uint32) error {
+8 -5
View File
@@ -28,12 +28,15 @@ import (
"gorm.io/gorm"
)
// Operator - Colletions of content to serve from HTTP(S)
// Operator - Collections of content to serve from HTTP(S)
type Operator struct {
ID uuid.UUID `gorm:"primaryKey;->;<-:create;type:uuid;"`
CreatedAt time.Time `gorm:"->;<-:create;"`
Name string
Token string `gorm:"uniqueIndex"`
ID uuid.UUID `gorm:"primaryKey;->;<-:create;type:uuid;"`
CreatedAt time.Time `gorm:"->;<-:create;"`
Name string
Token string `gorm:"uniqueIndex"` // NOTE: This is the SHA256 of the token
PermissionAll bool `gorm:"default:false"` // Access all gRPC APIs
PermissionBuilder bool `gorm:"default:false"` // Access Builder gRPC APIs
PermissionCrackstation bool `gorm:"default:false"` // Access Crackstation gRPC APIs
}
// BeforeCreate - GORM hook
+1 -1
View File
@@ -283,7 +283,7 @@ func PortInUse(newPort uint32) error {
return err
}
var port uint32
for _, job := range *listenerJobs {
for _, job := range listenerJobs {
listener, err := db.ListenerByJobID(job.JobID)
if err != nil {
return err
+79 -6
View File
@@ -29,6 +29,7 @@ import (
"github.com/bishopfox/sliver/server/configs"
"github.com/bishopfox/sliver/server/core"
"github.com/bishopfox/sliver/server/db"
"github.com/bishopfox/sliver/server/db/models"
"github.com/bishopfox/sliver/server/log"
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
@@ -64,6 +65,7 @@ func initMiddleware(remoteAuth bool) []grpc.ServerOption {
return []grpc.ServerOption{
grpc.ChainUnaryInterceptor(
grpc_auth.UnaryServerInterceptor(tokenAuthFunc),
permissionsUnaryServerInterceptor(),
auditLogUnaryServerInterceptor(),
grpc_tags.UnaryServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
grpc_logrus.UnaryServerInterceptor(logrusEntry, logrusOpts...),
@@ -71,6 +73,7 @@ func initMiddleware(remoteAuth bool) []grpc.ServerOption {
),
grpc.ChainStreamInterceptor(
grpc_auth.StreamServerInterceptor(tokenAuthFunc),
permissionsStreamServerInterceptor(),
grpc_tags.StreamServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
grpc_logrus.StreamServerInterceptor(logrusEntry, logrusOpts...),
grpc_logrus.PayloadStreamServerInterceptor(logrusEntry, deciderStream),
@@ -123,23 +126,93 @@ func tokenAuthFunc(ctx context.Context) (context.Context, error) {
digest := sha256.Sum256([]byte(rawToken))
token := hex.EncodeToString(digest[:])
newCtx := context.WithValue(ctx, Transport, "mtls")
if name, ok := tokenCache.Load(token); ok {
if op, ok := tokenCache.Load(token); ok {
mtlsLog.Debugf("Token in cache!")
newCtx = context.WithValue(newCtx, Operator, name.(string))
newCtx = context.WithValue(newCtx, Operator, op.(*models.Operator))
return newCtx, nil
}
operator, err := db.OperatorByToken(token)
if err != nil || operator == nil {
mtlsLog.Errorf("Authentication failure: %s", err)
mtlsLog.Errorf("Authentication failure: %v", err)
return nil, status.Error(codes.Unauthenticated, "Authentication failure")
}
mtlsLog.Debugf("Valid user token for %s", operator.Name)
tokenCache.Store(token, operator.Name)
mtlsLog.Debugf("Valid token for %s", operator.Name)
tokenCache.Store(token, operator)
newCtx = context.WithValue(newCtx, Operator, operator.Name)
newCtx = context.WithValue(newCtx, Operator, operator)
return newCtx, nil
}
var (
// Builder - Allowed methods
builderMethods = map[string]bool{
"/rpcpb.SliverRPC/GetVersion": true,
"/rpcpb.SliverRPC/GenerateExternalGetBuildConfig": true,
"/rpcpb.SliverRPC/GenerateExternalSaveBuild": true,
"/rpcpb.SliverRPC/BuilderRegister": true,
"/rpcpb.SliverRPC/BuilderTrigger": true,
"/rpcpb.SliverRPC/Builders": true,
}
// Crackstation - Allowed methods
crackstationMethods = map[string]bool{
"/rpcpb.SliverRPC/GetVersion": true,
"/rpcpb.SliverRPC/CrackstationRegister": true,
"/rpcpb.SliverRPC/CrackstationTrigger": true,
"/rpcpb.SliverRPC/CrackstationBenchmark": true,
"/rpcpb.SliverRPC/Crackstations": true,
"/rpcpb.SliverRPC/CrackTaskByID": true,
"/rpcpb.SliverRPC/CrackTaskUpdate": true,
"/rpcpb.SliverRPC/CrackFilesList": true,
"/rpcpb.SliverRPC/CrackFileCreate": true,
"/rpcpb.SliverRPC/CrackFileChunkUpload": true,
"/rpcpb.SliverRPC/CrackFileChunkDownload": true,
"/rpcpb.SliverRPC/CrackFileComplete": true,
"/rpcpb.SliverRPC/CrackFileDelete": true,
}
)
func permissionsUnaryServerInterceptor() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) {
operator := ctx.Value(Operator).(*models.Operator)
if operator.PermissionAll {
return handler(ctx, req)
}
if operator.PermissionBuilder {
if ok, _ := builderMethods[info.FullMethod]; ok {
return handler(ctx, req)
}
}
if operator.PermissionCrackstation {
if ok, _ := crackstationMethods[info.FullMethod]; ok {
return handler(ctx, req)
}
}
mtlsLog.Warnf("Permission denied for %s attempting to access %s", operator.Name, info.FullMethod)
return nil, status.Error(codes.PermissionDenied, "Permission denied")
}
}
func permissionsStreamServerInterceptor() grpc.StreamServerInterceptor {
return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
operator := ss.Context().Value(Operator).(*models.Operator)
if operator.PermissionAll {
return handler(srv, ss)
}
if operator.PermissionBuilder {
if ok, _ := builderMethods[info.FullMethod]; ok {
return handler(srv, ss)
}
}
if operator.PermissionCrackstation {
if ok, _ := crackstationMethods[info.FullMethod]; ok {
return handler(srv, ss)
}
}
mtlsLog.Warnf("Permission denied for %s attempting to access %s", operator.Name, info.FullMethod)
return status.Error(codes.PermissionDenied, "Permission denied")
}
}
func deciderUnary(_ context.Context, _ string, _ interface{}) bool {
return serverConfig.Logs.GRPCUnaryPayloads
}
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.12
// +build go1.12
package acme
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
package argon2
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !amd64 || purego || !gc
// +build !amd64 purego !gc
package argon2
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.7 && amd64 && gc && !purego
// +build go1.7,amd64,gc,!purego
package blake2b
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.7 && amd64 && gc && !purego
// +build go1.7,amd64,gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !go1.7 && amd64 && gc && !purego
// +build !go1.7,amd64,gc,!purego
package blake2b
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !amd64 || purego || !gc
// +build !amd64 purego !gc
package blake2b
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.9
// +build go1.9
package blake2b
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build 386 && gc && !purego
// +build 386,gc,!purego
package blake2s
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build 386 && gc && !purego
// +build 386,gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
package blake2s
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (!amd64 && !386) || !gc || purego
// +build !amd64,!386 !gc purego
package blake2s
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.9
// +build go1.9
package blake2s
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
package chacha20
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (!arm64 && !s390x && !ppc64le) || !gc || purego
// +build !arm64,!s390x,!ppc64le !gc purego
package chacha20
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
package chacha20
-1
View File
@@ -20,7 +20,6 @@
// due to the calling conventions and initialization of constants.
//go:build gc && !purego
// +build gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
package chacha20
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
#include "go_asm.h"
#include "textflag.h"
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
package chacha20poly1305
+22 -3
View File
@@ -5,7 +5,6 @@
// This file was originally from https://golang.org/cl/24717 by Vlad Krasnov of CloudFlare.
//go:build gc && !purego
// +build gc,!purego
#include "textflag.h"
// General register allocation
@@ -184,11 +183,31 @@ GLOBL ·andMask<>(SB), (NOPTR+RODATA), $240
#define shiftD1Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xd2; BYTE $0x04 // PALIGNR $4, X10, X10
#define shiftD2Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x04 // PALIGNR $4, X11, X11
#define shiftD3Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x04 // PALIGNR $4, X15, X15
// Some macros
// ROL rotates the uint32s in register R left by N bits, using temporary T.
#define ROL(N, R, T) \
MOVO R, T; PSLLL $(N), T; PSRLL $(32-(N)), R; PXOR T, R
// ROL16 rotates the uint32s in register R left by 16, using temporary T if needed.
#ifdef GOAMD64_v2
#define ROL16(R, T) PSHUFB ·rol16<>(SB), R
#else
#define ROL16(R, T) ROL(16, R, T)
#endif
// ROL8 rotates the uint32s in register R left by 8, using temporary T if needed.
#ifdef GOAMD64_v2
#define ROL8(R, T) PSHUFB ·rol8<>(SB), R
#else
#define ROL8(R, T) ROL(8, R, T)
#endif
#define chachaQR(A, B, C, D, T) \
PADDD B, A; PXOR A, D; PSHUFB ·rol16<>(SB), D \
PADDD B, A; PXOR A, D; ROL16(D, T) \
PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $12, T; PSRLL $20, B; PXOR T, B \
PADDD B, A; PXOR A, D; PSHUFB ·rol8<>(SB), D \
PADDD B, A; PXOR A, D; ROL8(D, T) \
PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $7, T; PSRLL $25, B; PXOR T, B
#define chachaQR_AVX2(A, B, C, D, T) \
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !amd64 || !gc || purego
// +build !amd64 !gc purego
package chacha20poly1305
-1
View File
@@ -1,7 +1,6 @@
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
package field
-1
View File
@@ -1,7 +1,6 @@
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
#include "textflag.h"
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !amd64 || !gc || purego
// +build !amd64 !gc purego
package field
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build arm64 && gc && !purego
// +build arm64,gc,!purego
package field
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build arm64 && gc && !purego
// +build arm64,gc,!purego
#include "textflag.h"
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !arm64 || !gc || purego
// +build !arm64 !gc purego
package field
+3 -1
View File
@@ -56,7 +56,9 @@ func (f *hkdf) Read(p []byte) (int, error) {
// Fill the rest of the buffer
for len(p) > 0 {
f.expander.Reset()
if f.counter > 1 {
f.expander.Reset()
}
f.expander.Write(f.prev)
f.expander.Write(f.info)
f.expander.Write([]byte{f.counter})
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !purego
// +build !purego
// Package alias implements memory aliasing tests.
package alias
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build purego
// +build purego
// Package alias implements memory aliasing tests.
package alias
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !go1.13
// +build !go1.13
package poly1305
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.13
// +build go1.13
package poly1305
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (!amd64 && !ppc64le && !s390x) || !gc || purego
// +build !amd64,!ppc64le,!s390x !gc purego
package poly1305
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
package poly1305
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
package poly1305
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
package poly1305
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gc && !purego
// +build gc,!purego
#include "textflag.h"
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && !purego && gc
// +build amd64,!purego,gc
package salsa
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && !purego && gc
// +build amd64,!purego,gc
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !amd64 || purego || !gc
// +build !amd64 purego !gc
package salsa
+9 -4
View File
@@ -141,9 +141,14 @@ const (
agentAddSmartcardKeyConstrained = 26
// 3.7 Key constraint identifiers
agentConstrainLifetime = 1
agentConstrainConfirm = 2
agentConstrainExtension = 3
agentConstrainLifetime = 1
agentConstrainConfirm = 2
// Constraint extension identifier up to version 2 of the protocol. A
// backward incompatible change will be required if we want to add support
// for SSH_AGENT_CONSTRAIN_MAXSIGN which uses the same ID.
agentConstrainExtensionV00 = 3
// Constraint extension identifier in version 3 and later of the protocol.
agentConstrainExtension = 255
)
// maxAgentResponseBytes is the maximum agent reply size that is accepted. This
@@ -205,7 +210,7 @@ type constrainLifetimeAgentMsg struct {
}
type constrainExtensionAgentMsg struct {
ExtensionName string `sshtype:"3"`
ExtensionName string `sshtype:"255|3"`
ExtensionDetails []byte
// Rest is a field used for parsing, not part of message
+1 -1
View File
@@ -208,7 +208,7 @@ func parseConstraints(constraints []byte) (lifetimeSecs uint32, confirmBeforeUse
case agentConstrainConfirm:
confirmBeforeUse = true
constraints = constraints[1:]
case agentConstrainExtension:
case agentConstrainExtension, agentConstrainExtensionV00:
var msg constrainExtensionAgentMsg
if err = ssh.Unmarshal(constraints, &msg); err != nil {
return 0, false, nil, err
-3
View File
@@ -10,7 +10,6 @@ import (
"fmt"
"io"
"math"
"strings"
"sync"
_ "crypto/sha1"
@@ -140,8 +139,6 @@ var supportedPubKeyAuthAlgos = []string{
KeyAlgoDSA,
}
var supportedPubKeyAuthAlgosList = strings.Join(supportedPubKeyAuthAlgos, ",")
// unexpectedMessageError results when the SSH message that we received didn't
// match what we wanted.
func unexpectedMessageError(expected, got uint8) error {
+7
View File
@@ -11,6 +11,7 @@ import (
"io"
"log"
"net"
"strings"
"sync"
)
@@ -50,6 +51,10 @@ type handshakeTransport struct {
// connection.
hostKeys []Signer
// publicKeyAuthAlgorithms is non-empty if we are the server. In that case,
// it contains the supported client public key authentication algorithms.
publicKeyAuthAlgorithms []string
// hostKeyAlgorithms is non-empty if we are the client. In that case,
// we accept these key types from the server as host key.
hostKeyAlgorithms []string
@@ -141,6 +146,7 @@ func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byt
func newServerTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ServerConfig) *handshakeTransport {
t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)
t.hostKeys = config.hostKeys
t.publicKeyAuthAlgorithms = config.PublicKeyAuthAlgorithms
go t.readLoop()
go t.kexLoop()
return t
@@ -649,6 +655,7 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
// message with the server-sig-algs extension if the client supports it. See
// RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9.
if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
supportedPubKeyAuthAlgosList := strings.Join(t.publicKeyAuthAlgorithms, ",")
extInfo := &extInfoMsg{
NumExtensions: 2,
Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)+4+16+4+1),
+15 -4
View File
@@ -1232,16 +1232,27 @@ func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{},
return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err)
}
var result interface{}
switch block.Type {
case "RSA PRIVATE KEY":
return x509.ParsePKCS1PrivateKey(buf)
result, err = x509.ParsePKCS1PrivateKey(buf)
case "EC PRIVATE KEY":
return x509.ParseECPrivateKey(buf)
result, err = x509.ParseECPrivateKey(buf)
case "DSA PRIVATE KEY":
return ParseDSAPrivateKey(buf)
result, err = ParseDSAPrivateKey(buf)
default:
return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
err = fmt.Errorf("ssh: unsupported key type %q", block.Type)
}
// Because of deficiencies in the format, DecryptPEMBlock does not always
// detect an incorrect password. In these cases decrypted DER bytes is
// random noise. If the parsing of the key returns an asn1.StructuralError
// we return x509.IncorrectPasswordError.
if _, ok := err.(asn1.StructuralError); ok {
return nil, x509.IncorrectPasswordError
}
return result, err
}
// ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as
+18 -2
View File
@@ -64,6 +64,13 @@ type ServerConfig struct {
// Config contains configuration shared between client and server.
Config
// PublicKeyAuthAlgorithms specifies the supported client public key
// authentication algorithms. Note that this should not include certificate
// types since those use the underlying algorithm. This list is sent to the
// client if it supports the server-sig-algs extension. Order is irrelevant.
// If unspecified then a default set of algorithms is used.
PublicKeyAuthAlgorithms []string
hostKeys []Signer
// NoClientAuth is true if clients are allowed to connect without
@@ -201,6 +208,15 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
if fullConf.MaxAuthTries == 0 {
fullConf.MaxAuthTries = 6
}
if len(fullConf.PublicKeyAuthAlgorithms) == 0 {
fullConf.PublicKeyAuthAlgorithms = supportedPubKeyAuthAlgos
} else {
for _, algo := range fullConf.PublicKeyAuthAlgorithms {
if !contains(supportedPubKeyAuthAlgos, algo) {
return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo)
}
}
}
// Check if the config contains any unsupported key exchanges
for _, kex := range fullConf.KeyExchanges {
if _, ok := serverForbiddenKexAlgos[kex]; ok {
@@ -524,7 +540,7 @@ userAuthLoop:
return nil, parseError(msgUserAuthRequest)
}
algo := string(algoBytes)
if !contains(supportedPubKeyAuthAlgos, underlyingAlgo(algo)) {
if !contains(config.PublicKeyAuthAlgorithms, underlyingAlgo(algo)) {
authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo)
break
}
@@ -591,7 +607,7 @@ userAuthLoop:
// algorithm name that corresponds to algo with
// sig.Format. This is usually the same, but
// for certs, the names differ.
if !contains(supportedPubKeyAuthAlgos, sig.Format) {
if !contains(config.PublicKeyAuthAlgorithms, sig.Format) {
authErr = fmt.Errorf("ssh: algorithm %q not accepted", sig.Format)
break
}
+2 -2
View File
@@ -736,8 +736,8 @@ go4.org/mem
# go4.org/netipx v0.0.0-20230824141953-6213f710f925
## explicit; go 1.18
go4.org/netipx
# golang.org/x/crypto v0.14.0
## explicit; go 1.17
# golang.org/x/crypto v0.15.0
## explicit; go 1.18
golang.org/x/crypto/acme
golang.org/x/crypto/acme/autocert
golang.org/x/crypto/argon2