Skip to content

Commit

Permalink
Merge pull request BishopFox#417 from BishopFox/stage
Browse files Browse the repository at this point in the history
Merge Tunnel Cache PR
  • Loading branch information
moloch-- authored Apr 29, 2021
2 parents 2fe0a61 + 985b213 commit e957b41
Show file tree
Hide file tree
Showing 8 changed files with 363 additions and 227 deletions.
31 changes: 23 additions & 8 deletions client/command/updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,36 +191,51 @@ func updateSavePath(ctx *grumble.Context) (string, error) {
return user.HomeDir, nil
}

func findAssetFor(prefix string, suffix string, assets []version.Asset) *version.Asset {
func hasAnySuffix(assetFileName string, suffixes []string) bool {
for _, suffix := range suffixes {
if strings.HasSuffix(assetFileName, suffix) {
return true
}
}
return false
}

func findAssetFor(prefix string, suffixes []string, assets []version.Asset) *version.Asset {
for _, asset := range assets {
downloadURL, err := url.Parse(asset.BrowserDownloadURL)
if err != nil {
continue
}
assetFileName := filepath.Base(downloadURL.Path)
if strings.HasPrefix(assetFileName, prefix) && strings.HasSuffix(assetFileName, suffix) {
if strings.HasPrefix(assetFileName, prefix) && hasAnySuffix(assetFileName, suffixes) {
return &asset
}
}
return nil
}

func serverAssetForGOOS(assets []version.Asset) *version.Asset {
suffix := fmt.Sprintf("_%s.zip", runtime.GOOS)
suffixes := []string{fmt.Sprintf("_%s.zip", runtime.GOOS), runtime.GOOS}
if runtime.GOOS == "darwin" {
suffix = "_macos.zip"
suffixes = []string{"_macos.zip", "_macos"}
if runtime.GOARCH == "arm64" {
suffixes = []string{"_macos-arm64.zip", "_macos-arm64"}
}
}
prefix := "sliver-server"
return findAssetFor(prefix, suffix, assets)
return findAssetFor(prefix, suffixes, assets)
}

func clientAssetForGOOS(assets []version.Asset) *version.Asset {
suffix := fmt.Sprintf("_%s.zip", runtime.GOOS)
suffixes := []string{fmt.Sprintf("_%s.zip", runtime.GOOS), runtime.GOOS}
if runtime.GOOS == "darwin" {
suffix = "_macos.zip"
suffixes = []string{"_macos.zip", "_macos"}
if runtime.GOARCH == "arm64" {
suffixes = []string{"_macos-arm64.zip", "_macos-arm64"}
}
}
prefix := "sliver-client"
return findAssetFor(prefix, suffix, assets)
return findAssetFor(prefix, suffixes, assets)
}

func updateAvailable(client *http.Client, release *version.Release, saveTo string) {
Expand Down
33 changes: 32 additions & 1 deletion implant/sliver/handlers/tun-handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"fmt"
"io"
"net"
"sync"
"time"

// {{if .Config.Debug}}
Expand Down Expand Up @@ -100,6 +101,11 @@ func tunnelDataHandler(envelope *sliverpb.Envelope, connection *transports.Conne
// {{if .Config.Debug}}
log.Printf("[tunnel] Cache tunnel %d (seq: %d)", tunnel.ID, tunnelData.Sequence)
// {{end}}

//Added a thread lock here because the incrementing of the ReadSequence, adding/deleting things from a shared cache,
//and then making decisions based on the current size of the cache by multiple threads can cause race conditions errors
var l sync.Mutex
l.Lock()
tunnelDataCache[tunnel.ID][tunnelData.Sequence] = tunnelData

// NOTE: The read/write semantics can be a little mind boggling, just remember we're reading
Expand All @@ -119,6 +125,30 @@ func tunnelDataHandler(envelope *sliverpb.Envelope, connection *transports.Conne
tunnel.ReadSequence++ // Increment sequence counter
}

//If cache is building up it probably means a msg was lost and the server is currently hung waiting for it.
//Send a Resend packet to have the msg resent from the cache
if len(cache) > 3 {
data, err := proto.Marshal(&sliverpb.TunnelData{
Sequence: tunnel.WriteSequence, // The tunnel write sequence
Ack: tunnel.ReadSequence,
Resend: true,
TunnelID: tunnel.ID,
Data: []byte{},
})
if err != nil {
// {{if .Config.Debug}}
log.Printf("[shell] Failed to marshal protobuf %s", err)
// {{end}}
} else {
// {{if .Config.Debug}}
log.Printf("[tunnel] Requesting resend of tunnelData seq: %d", tunnel.ReadSequence)
// {{end}}
connection.RequestResend(data)
}
}
//Unlock
l.Unlock()

} else {
// {{if .Config.Debug}}
log.Printf("[tunnel] Received data for nil tunnel %d", tunnelData.TunnelID)
Expand All @@ -137,11 +167,12 @@ func (tw tunnelWriter) Write(data []byte) (int, error) {
n := len(data)
data, err := proto.Marshal(&sliverpb.TunnelData{
Sequence: tw.tun.WriteSequence, // The tunnel write sequence
Ack: tw.tun.ReadSequence,
TunnelID: tw.tun.ID,
Data: data,
})
// {{if .Config.Debug}}
log.Printf("[tunnelWriter] Write %d bytes (write seq: %d)", n, tw.tun.WriteSequence)
log.Printf("[tunnelWriter] Write %d bytes (write seq: %d) ack: %d", n, tw.tun.WriteSequence, tw.tun.ReadSequence)
// {{end}}
tw.tun.WriteSequence++ // Increment write sequence
tw.conn.Send <- &sliverpb.Envelope{
Expand Down
8 changes: 8 additions & 0 deletions implant/sliver/transports/transports.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
"sync"
"time"

"github.com/bishopfox/sliver/protobuf/sliverpb"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"

// {{if .Config.HTTPc2Enabled}}
Expand Down Expand Up @@ -128,6 +129,13 @@ func (c *Connection) RemoveTunnel(ID uint64) {
delete(*c.tunnels, ID)
}

func (c *Connection) RequestResend(data []byte) {
c.Send <- &sliverpb.Envelope{
Type: sliverpb.MsgTunnelData,
Data: data,
}
}

// StartConnectionLoop - Starts the main connection loop
func StartConnectionLoop() *Connection {

Expand Down
23 changes: 17 additions & 6 deletions implant/sliver/transports/udp-dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ const (
)

var (
dnsCharSet = []rune("abcdefghijklmnopqrstuvwxyz0123456789-_")
//Removed "-" because it appears a nonce that ends in "-" is invalid and thus breaks comms
dnsCharSet = []rune("abcdefghijklmnopqrstuvwxyz0123456789_")

replayMutex = &sync.RWMutex{}
replay = &map[string]bool{}
Expand Down Expand Up @@ -117,17 +118,27 @@ func isReplayAttack(ciphertext []byte) bool {
// --------------------------- DNS SESSION SEND ---------------------------

func dnsLookup(domain string) (string, error) {
var err error
var txts []string

// {{if .Config.Debug}}
log.Printf("[dns] lookup -> %s", domain)
// {{end}}
txts, err := net.LookupTXT(domain)
for retry_count := 0; retry_count < 3; retry_count++ {
txts, err = net.LookupTXT(domain)
if err != nil || len(txts) == 0 {
// {{if .Config.Debug}}
log.Printf("[!] failure -> %s", domain)
// {{end}}
} else {
break
}
}
if err != nil || len(txts) == 0 {
// {{if .Config.Debug}}
log.Printf("[!] failure -> %s", domain)
// {{end}}
return "", err
} else {
return strings.Join(txts, ""), nil
}
return strings.Join(txts, ""), nil
}

// Send raw bytes of an arbitrary length to the server
Expand Down
Loading

0 comments on commit e957b41

Please sign in to comment.