Skip to content

Commit

Permalink
Random cleanups and improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
moloch-- committed Sep 9, 2022
1 parent d411d24 commit 3cc7be8
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 40 deletions.
4 changes: 2 additions & 2 deletions server/certs/acme.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ package certs

import (
"os"
"path"
"path/filepath"

"github.com/bishopfox/sliver/server/log"
"golang.org/x/crypto/acme/autocert"
Expand All @@ -37,7 +37,7 @@ var (

// GetACMEDir - Dir to store ACME certs
func GetACMEDir() string {
acmePath := path.Join(getCertDir(), ACMEDirName)
acmePath := filepath.Join(getCertDir(), ACMEDirName)
if _, err := os.Stat(acmePath); os.IsNotExist(err) {
acmeLog.Infof("[mkdir] %s", acmePath)
os.MkdirAll(acmePath, 0700)
Expand Down
16 changes: 8 additions & 8 deletions server/certs/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"

"github.com/bishopfox/sliver/server/assets"
)
Expand All @@ -44,7 +44,7 @@ func SetupCAs() {

func getCertDir() string {
rootDir := assets.GetRootAppDir()
certDir := path.Join(rootDir, "certs")
certDir := filepath.Join(rootDir, "certs")
if _, err := os.Stat(certDir); os.IsNotExist(err) {
err := os.MkdirAll(certDir, 0700)
if err != nil {
Expand All @@ -57,7 +57,7 @@ func getCertDir() string {
// GenerateCertificateAuthority - Creates a new CA cert for a given type
func GenerateCertificateAuthority(caType string, commonName string) (*x509.Certificate, *ecdsa.PrivateKey) {
storageDir := getCertDir()
certFilePath := path.Join(storageDir, fmt.Sprintf("%s-ca-cert.pem", caType))
certFilePath := filepath.Join(storageDir, fmt.Sprintf("%s-ca-cert.pem", caType))
if _, err := os.Stat(certFilePath); os.IsNotExist(err) {
certsLog.Infof("Generating certificate authority for '%s'", caType)
cert, key := GenerateECCCertificate(caType, commonName, true, false)
Expand Down Expand Up @@ -104,9 +104,9 @@ func GetCertificateAuthority(caType string) (*x509.Certificate, *ecdsa.PrivateKe

// GetCertificateAuthorityPEM - Get PEM encoded CA cert/key
func GetCertificateAuthorityPEM(caType string) ([]byte, []byte, error) {
caType = path.Base(caType)
caCertPath := path.Join(getCertDir(), fmt.Sprintf("%s-ca-cert.pem", caType))
caKeyPath := path.Join(getCertDir(), fmt.Sprintf("%s-ca-key.pem", caType))
caType = filepath.Base(caType)
caCertPath := filepath.Join(getCertDir(), fmt.Sprintf("%s-ca-cert.pem", caType))
caKeyPath := filepath.Join(getCertDir(), fmt.Sprintf("%s-ca-key.pem", caType))

certPEM, err := ioutil.ReadFile(caCertPath)
if err != nil {
Expand Down Expand Up @@ -134,8 +134,8 @@ func SaveCertificateAuthority(caType string, cert []byte, key []byte) {

// CAs get written to the filesystem since we control the names and makes them
// easier to move around/backup
certFilePath := path.Join(storageDir, fmt.Sprintf("%s-ca-cert.pem", caType))
keyFilePath := path.Join(storageDir, fmt.Sprintf("%s-ca-key.pem", caType))
certFilePath := filepath.Join(storageDir, fmt.Sprintf("%s-ca-cert.pem", caType))
keyFilePath := filepath.Join(storageDir, fmt.Sprintf("%s-ca-key.pem", caType))

err := ioutil.WriteFile(certFilePath, cert, 0600)
if err != nil {
Expand Down
20 changes: 10 additions & 10 deletions server/codenames/codenames.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"fmt"
insecureRand "math/rand"
"os"
"path"
"path/filepath"
"strings"

"github.com/bishopfox/sliver/server/assets"
Expand All @@ -39,11 +39,11 @@ var (
})
)

// readlines - Read lines of a text file into a slice
func readlines(fpath string) ([]string, error) {
file, err := os.Open(fpath)
// readLines - Read lines of a text file into a slice
func readLines(txtFilePath string) ([]string, error) {
file, err := os.Open(txtFilePath)
if err != nil {
codenameLog.Errorf("Error opening %s: %v", fpath, err)
codenameLog.Errorf("Error opening %s: %v", txtFilePath, err)
return nil, err
}
defer file.Close()
Expand All @@ -63,26 +63,26 @@ func readlines(fpath string) ([]string, error) {
}

// getRandomWord - Get a random word from a file, not cryptographically secure
func getRandomWord(fpath string) (string, error) {
func getRandomWord(txtFilePath string) (string, error) {
appDir := assets.GetRootAppDir()
words, err := readlines(path.Join(appDir, fpath))
words, err := readLines(filepath.Join(appDir, txtFilePath))
if err != nil {
return "", err
}
wordsLen := len(words)
if wordsLen == 0 {
return "", fmt.Errorf("no words found in %s", fpath)
return "", fmt.Errorf("no words found in %s", txtFilePath)
}
word := words[insecureRand.Intn(wordsLen-1)]
return strings.TrimSpace(word), nil
}

// getRandomAdjective - Get a random noun, not cryptographically secure
// RandomAdjective - Get a random noun, not cryptographically secure
func RandomAdjective() (string, error) {
return getRandomWord("adjectives.txt")
}

// getRandomNoun - Get a random noun, not cryptographically secure
// RandomNoun - Get a random noun, not cryptographically secure
func RandomNoun() (string, error) {
return getRandomWord("nouns.txt")
}
Expand Down
35 changes: 26 additions & 9 deletions server/configs/http-c2.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import (

const (
httpC2ConfigFileName = "http-c2.json"
chromeBaseVer = 97
DefaultChromeBaseVer = 100
DefaultMacOSVer = "10_15_7"
)

// HTTPC2Config - Parent config file struct for implant/server
Expand Down Expand Up @@ -69,7 +70,7 @@ func (h *HTTPC2Config) generateChromeUserAgent(goos string, goarch string) strin
case "arm64":
fallthrough // https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/core/frame/navigator_id.cc;l=76
case "amd64":
return fmt.Sprintf("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36", h.ChromeVer())
return fmt.Sprintf("Mozilla/5.0 (Macintosh; Intel Mac OS X %s) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36", h.MacOSVer(), h.ChromeVer())
}

}
Expand All @@ -83,7 +84,19 @@ func (h *HTTPC2Config) generateChromeUserAgent(goos string, goarch string) strin

// ChromeVer - Generate a random Chrome user-agent
func (h *HTTPC2Config) ChromeVer() string {
return fmt.Sprintf("%d.0.%d.%d", chromeBaseVer+insecureRand.Intn(3), 1000+insecureRand.Intn(8999), insecureRand.Intn(999))
chromeVer := h.ImplantConfig.ChromeBaseVersion
if chromeVer == 0 {
chromeVer = DefaultChromeBaseVer
}
return fmt.Sprintf("%d.0.%d.%d", chromeVer+insecureRand.Intn(3), 1000+insecureRand.Intn(8999), insecureRand.Intn(999))
}

func (h *HTTPC2Config) MacOSVer() string {
macosVer := h.ImplantConfig.MacOSVersion
if macosVer == "" {
macosVer = DefaultMacOSVer
}
return macosVer
}

// RandomImplantConfig - Randomly generate a config
Expand Down Expand Up @@ -126,7 +139,9 @@ type NameValueProbability struct {
// .png = stop
// .woff = sliver shellcode
type HTTPC2ImplantConfig struct {
UserAgent string `json:"user_agent"`
UserAgent string `json:"user_agent"`
ChromeBaseVersion int `json:"chrome_base_version"`
MacOSVersion string `json:"macos_version"`

URLParameters []NameValueProbability `json:"url_parameters"`
Headers []NameValueProbability `json:"headers"`
Expand Down Expand Up @@ -222,11 +237,13 @@ var (
},
},
ImplantConfig: &HTTPC2ImplantConfig{
UserAgent: "", // Blank string is rendered as randomized platform user-agent
MaxFiles: 8,
MinFiles: 2,
MaxPaths: 8,
MinPaths: 2,
UserAgent: "", // Blank string is rendered as randomized platform user-agent
ChromeBaseVersion: DefaultChromeBaseVer,
MacOSVersion: DefaultMacOSVer,
MaxFiles: 8,
MinFiles: 2,
MaxPaths: 8,
MinPaths: 2,

StagerFileExt: ".woff",

Expand Down
2 changes: 1 addition & 1 deletion server/core/socks.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
)

var (
// TunSocksTunnels - Interating with duplex SocksTunnels
// TunSocksTunnels - Interacting with duplex SocksTunnels
SocksTunnels = tcpTunnel{
tunnels: map[uint64]*TcpTunnel{},
mutex: &sync.Mutex{},
Expand Down
8 changes: 4 additions & 4 deletions server/core/tunnels.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
)

var (
// Tunnels - Interating with duplex tunnels
// Tunnels - Interacting with duplex tunnels
Tunnels = tunnels{
tunnels: map[uint64]*Tunnel{},
mutex: &sync.Mutex{},
Expand Down Expand Up @@ -125,10 +125,10 @@ func (t *tunnels) Create(sessionID string) *Tunnel {
// will close it once there is no data for at least delayBeforeClose delay since last message
// This is _necessary_ since we processing messages asynchronously
// and if tunnelCloseHandler routine will fire before tunnelDataHandler routine we will lose some data
// (this is what happends for socks and portfwd)
// (this is what happens for socks and portfwd)
// There is no another way around it, if we want to stick to async processing as we do now.
// All additional changes requires changes on implants(like sequencing for close messages),
// and as there is a goal to keep compatability we don't do that at the moment.
// and as there is a goal to keep compatibility we don't do that at the moment.
// So there is trade off - more stability or more speed. Or rewriting implant logic.
// At the moment, i see it affects only `shell` command and locking it for 10 seconds on exit. Not a big deal.
func (t *tunnels) ScheduleClose(tunnelID uint64) {
Expand All @@ -153,7 +153,7 @@ func (t *tunnels) ScheduleClose(tunnelID uint64) {
}

// Close - closing tunnel
// It's prefered to use ScheduleClose function if you don't 100% sure there is no more data to receive
// It's preferred to use ScheduleClose function if you don't 100% sure there is no more data to receive
func (t *tunnels) Close(tunnelID uint64) error {
t.mutex.Lock()
defer t.mutex.Unlock()
Expand Down
12 changes: 6 additions & 6 deletions server/handlers/sessions.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func tunnelDataHandler(implantConn *core.ImplantConnection, data []byte) *sliver
tunnelData := &sliverpb.TunnelData{}
proto.Unmarshal(data, tunnelData)

sessionHandlerLog.Debugf("[DATA] Sequence on tunel %d, %d, data: %s", tunnelData.TunnelID, tunnelData.Sequence, tunnelData.Data)
sessionHandlerLog.Debugf("[DATA] Sequence on tunnel %d, %d, data: %s", tunnelData.TunnelID, tunnelData.Sequence, tunnelData.Data)

tunnel := core.Tunnels.Get(tunnelData.TunnelID)
if tunnel != nil {
Expand All @@ -137,7 +137,7 @@ func tunnelCloseHandler(implantConn *core.ImplantConnection, data []byte) *slive

tunnelData := &sliverpb.TunnelData{}
proto.Unmarshal(data, tunnelData)
sessionHandlerLog.Debugf("[CLOSE] Sequence on tunel %d, %d, data: %s", tunnelData.TunnelID, tunnelData.Sequence, tunnelData.Data)
sessionHandlerLog.Debugf("[CLOSE] Sequence on tunnel %d, %d, data: %s", tunnelData.TunnelID, tunnelData.Sequence, tunnelData.Data)
if !tunnelData.Closed {
return nil
}
Expand Down Expand Up @@ -181,10 +181,10 @@ func socksDataHandler(implantConn *core.ImplantConnection, data []byte) *sliverp
// return nil
//}
sessionHandlerLog.Debugf("socksDataHandler:", len(socksData.Data), socksData.Data)
SocksTunne := core.SocksTunnels.Get(socksData.TunnelID)
if SocksTunne != nil {
if session.ID == SocksTunne.SessionID {
SocksTunne.FromImplant <- socksData
socksTunnel := core.SocksTunnels.Get(socksData.TunnelID)
if socksTunnel != nil {
if session.ID == socksTunnel.SessionID {
socksTunnel.FromImplant <- socksData
} else {
sessionHandlerLog.Warnf("Warning: Session %s attempted to send data on tunnel it did not own", session.ID)
}
Expand Down
18 changes: 18 additions & 0 deletions server/sgn/sgn.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
package sgn

/*
Sliver Implant Framework
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import (
"bytes"
"errors"
Expand Down

0 comments on commit 3cc7be8

Please sign in to comment.