mirror of
https://github.com/BishopFox/sliver.git
synced 2026-11-08 01:38:17 -10:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16b54c8f5b | ||
|
|
8317678143 | ||
|
|
d3a6e82214 | ||
|
|
4f899c97f0 | ||
|
|
1a388c6e1e |
No files matched your search
@@ -169,5 +169,5 @@ func Commands(con *console.SliverClient) []*cobra.Command {
|
||||
(*comp)["compress"] = carapace.ActionValues([]string{"zlib", "gzip", "deflate9", "none"}...).Tag("compression formats")
|
||||
})
|
||||
|
||||
return []*cobra.Command{jobsCmd, mtlsCmd, wgCmd, httpCmd, httpsCmd, stageCmd}
|
||||
return []*cobra.Command{jobsCmd, mtlsCmd, wgCmd, dnsCmd, httpCmd, httpsCmd, stageCmd}
|
||||
}
|
||||
@@ -162,6 +162,60 @@ func DNSStartSession(parent string, opts *DNSOptions) (*SliverDNSClient, error)
|
||||
return client, nil
|
||||
}
|
||||
|
||||
type DNSBase32Encoder struct{}
|
||||
|
||||
const alpha = "abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
// Encode - Base32 Encode
|
||||
func (e DNSBase32Encoder) Encode(data []byte) ([]byte, error) {
|
||||
encodedData, err := encoders.Base32.Encode(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
index := insecureRand.Intn(len(alpha))
|
||||
if index&1 == 1 {
|
||||
index = index - 1
|
||||
}
|
||||
prefix := alpha[index]
|
||||
return append([]byte{prefix}, encodedData...), nil
|
||||
}
|
||||
|
||||
// Decode - Base32 Decode
|
||||
func (e DNSBase32Encoder) Decode(data []byte) ([]byte, error) {
|
||||
if len(data) < 1 {
|
||||
return nil, errors.New("invalid data")
|
||||
}
|
||||
return encoders.Base32.Decode(data[1:])
|
||||
}
|
||||
|
||||
type DNSBase58Encoder struct{}
|
||||
|
||||
// Encode - Base58 Encode
|
||||
func (e DNSBase58Encoder) Encode(data []byte) ([]byte, error) {
|
||||
encodedData, err := encoders.Base58.Encode(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
index := insecureRand.Intn(len(alpha))
|
||||
if index&1 != 1 {
|
||||
index = index + 1
|
||||
if len(alpha) <= index {
|
||||
index = index - 2
|
||||
}
|
||||
}
|
||||
prefix := alpha[index]
|
||||
return append([]byte{prefix}, encodedData...), nil
|
||||
}
|
||||
|
||||
// Decode - Base58 Decode
|
||||
func (e DNSBase58Encoder) Decode(data []byte) ([]byte, error) {
|
||||
if len(data) < 1 {
|
||||
return nil, errors.New("invalid data")
|
||||
}
|
||||
return encoders.Base58.Decode(data[1:])
|
||||
}
|
||||
|
||||
// NewDNSClient - Initialize a new DNS client, generally you should use DNSStartSession
|
||||
// instead of this function, this is exported mostly for unit testing
|
||||
func NewDNSClient(parent string, opts *DNSOptions) *SliverDNSClient {
|
||||
@@ -179,9 +233,10 @@ func NewDNSClient(parent string, opts *DNSOptions) *SliverDNSClient {
|
||||
closed: true,
|
||||
|
||||
WorkersPerResolver: opts.WorkersPerResolver,
|
||||
subdataSpace: 254 - len(parent) - (1 + (254-len(parent))/64),
|
||||
base32: encoders.Base32Encoder{},
|
||||
base58: encoders.Base58Encoder{},
|
||||
// parent domain data encoder
|
||||
subdataSpace: 254 - len(parent) - (1 + (254-len(parent))/64) - 1,
|
||||
base32: DNSBase32Encoder{},
|
||||
base58: DNSBase58Encoder{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,8 +265,8 @@ type SliverDNSClient struct {
|
||||
workerPool []*DNSWorker
|
||||
WorkersPerResolver int
|
||||
|
||||
base32 encoders.Base32Encoder
|
||||
base58 encoders.Base58Encoder
|
||||
base32 DNSBase32Encoder
|
||||
base58 DNSBase58Encoder
|
||||
|
||||
enableCaseSensitiveEncoder bool
|
||||
}
|
||||
@@ -460,8 +515,8 @@ func (s *SliverDNSClient) ReadEnvelope() (*pb.Envelope, error) {
|
||||
log.Printf("[dns] read envelope ...")
|
||||
// {{end}}
|
||||
|
||||
resolver, meta := s.randomResolver()
|
||||
pollMsg, err := s.pollMsg(meta)
|
||||
resolver, _ := s.randomResolver()
|
||||
pollMsg, err := s.pollMsg()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -536,7 +591,7 @@ func (s *SliverDNSClient) ReadEnvelope() (*pb.Envelope, error) {
|
||||
log.Printf("[dns] clear msg domain: %v", domain)
|
||||
// {{end}}
|
||||
|
||||
respData, _, err = resolver.A(domain)
|
||||
_, _, err = resolver.A(domain)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("[dns] clear msg error: %s", err)
|
||||
@@ -740,13 +795,13 @@ func (s *SliverDNSClient) SplitBuffer(msg *dnspb.DNSMessage, encoder encoders.En
|
||||
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
|
||||
// Sometimes adding a byte will result in +2 chars so we -2 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))
|
||||
// len(encoded), (s.subdataSpace - 2), stop, len(data))
|
||||
// {{end}}
|
||||
for len(encoded) < (s.subdataSpace-1) && stop < len(data) {
|
||||
for len(encoded) < (s.subdataSpace-2) && stop < len(data) {
|
||||
stop++
|
||||
// {{if .Config.Debug}}
|
||||
// log.Printf("[dns] shave data [%d:%d] of %d", start, stop, len(data))
|
||||
@@ -889,7 +944,7 @@ func (s *SliverDNSClient) joinSubdataToParent(subdata string) (string, error) {
|
||||
return domain, nil
|
||||
}
|
||||
|
||||
func (s *SliverDNSClient) pollMsg(meta *ResolverMetadata) (string, error) {
|
||||
func (s *SliverDNSClient) pollMsg() (string, error) {
|
||||
nonceBuf := make([]byte, 8)
|
||||
rand.Read(nonceBuf)
|
||||
pollMsg, _ := proto.Marshal(&dnspb.DNSMessage{
|
||||
|
||||
@@ -75,28 +75,28 @@ func TestSplitBufferBase58(t *testing.T) {
|
||||
t.Logf("Testing with client1")
|
||||
client1 := NewDNSClient(parent1, opts)
|
||||
testData := randomData(2048)
|
||||
clientSplitBuffer(t, client1, encoders.Base58{}, testData)
|
||||
clientSplitBuffer(t, client1, DNSBase58Encoder{}, testData)
|
||||
|
||||
t.Logf("Testing with client2")
|
||||
client2 := NewDNSClient(parent2, opts)
|
||||
testData2 := randomData(2048)
|
||||
clientSplitBuffer(t, client2, encoders.Base58{}, testData2)
|
||||
clientSplitBuffer(t, client2, DNSBase58Encoder{}, testData2)
|
||||
|
||||
t.Logf("Testing with client3")
|
||||
client3 := NewDNSClient(parent3, opts)
|
||||
testData3 := randomData(2048)
|
||||
clientSplitBuffer(t, client3, encoders.Base58{}, testData3)
|
||||
clientSplitBuffer(t, client3, DNSBase58Encoder{}, testData3)
|
||||
|
||||
t.Logf("Testing with client max")
|
||||
clientMax := NewDNSClient(parentMax, opts)
|
||||
testDataMax := randomData(2048)
|
||||
clientSplitBuffer(t, clientMax, encoders.Base58{}, testDataMax)
|
||||
clientSplitBuffer(t, clientMax, DNSBase58Encoder{}, testDataMax)
|
||||
|
||||
t.Logf("Testing all clients with randomly sized data")
|
||||
for _, client := range []*SliverDNSClient{client1, client2, client3} {
|
||||
for count := 0; count < 10; count++ {
|
||||
testData := randomDataRandomSize(2 * 1024 * 1024)
|
||||
clientSplitBuffer(t, client, encoders.Base58{}, testData)
|
||||
clientSplitBuffer(t, client, DNSBase58Encoder{}, testData)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,28 +106,28 @@ func TestSplitBufferBase32(t *testing.T) {
|
||||
t.Logf("Testing with client1")
|
||||
client1 := NewDNSClient(parent1, opts)
|
||||
testData := randomData(2048)
|
||||
clientSplitBuffer(t, client1, encoders.Base32{}, testData)
|
||||
clientSplitBuffer(t, client1, DNSBase32Encoder{}, testData)
|
||||
|
||||
t.Logf("Testing with client2")
|
||||
client2 := NewDNSClient(parent2, opts)
|
||||
testData2 := randomData(2048)
|
||||
clientSplitBuffer(t, client2, encoders.Base32{}, testData2)
|
||||
clientSplitBuffer(t, client2, DNSBase32Encoder{}, testData2)
|
||||
|
||||
t.Logf("Testing with client3")
|
||||
client3 := NewDNSClient(parent3, opts)
|
||||
testData3 := randomData(2048)
|
||||
clientSplitBuffer(t, client3, encoders.Base32{}, testData3)
|
||||
clientSplitBuffer(t, client3, DNSBase32Encoder{}, testData3)
|
||||
|
||||
t.Logf("Testing with client max")
|
||||
clientMax := NewDNSClient(parentMax, opts)
|
||||
testDataMax := randomData(2048)
|
||||
clientSplitBuffer(t, clientMax, encoders.Base32{}, testDataMax)
|
||||
clientSplitBuffer(t, clientMax, DNSBase32Encoder{}, testDataMax)
|
||||
|
||||
t.Logf("Testing all clients with randomly sized data")
|
||||
for _, client := range []*SliverDNSClient{client1, client2, client3} {
|
||||
for count := 0; count < 10; count++ {
|
||||
testData := randomDataRandomSize(2 * 1024 * 1024)
|
||||
clientSplitBuffer(t, client, encoders.Base32{}, testData)
|
||||
clientSplitBuffer(t, client, DNSBase32Encoder{}, testData)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,41 +186,41 @@ func TestSubdataSpace(t *testing.T) {
|
||||
|
||||
// 1.example.com. (14 chars parent, 240 chars subdata)
|
||||
// Grand Total: 254 chars
|
||||
// parent | subdata with '.' | subdata without '.'
|
||||
// 254 - 15 - [64 - 64 - 64 - 47] = 63 + 63 + 63 + 46 (235)
|
||||
// parent | subdata with '.' | subdata without '.'
|
||||
// 254 - 15 - [64 - 64 - 64 - 47] - 1 = 63 + 63 + 63 + 46 (234)
|
||||
// expected value is thus 235 (max chars without '.'), rounded down if applicable
|
||||
client1 := NewDNSClient(parent1, opts)
|
||||
if client1.subdataSpace != 235 {
|
||||
if client1.subdataSpace != 234 {
|
||||
t.Fatalf("Unexpected subdata space for parent %s: %d", parent1, client1.subdataSpace)
|
||||
}
|
||||
|
||||
// .something-longer.example.com. (30 chars parent, 224 chars subdata)
|
||||
// Grand Total: 254 chars
|
||||
// parent | subdata with '.' | subdata without '.'
|
||||
// 254 - 30 - [64 - 64 - 64 - 32] = 63 + 63 + 63 + 31 (220)
|
||||
// parent | subdata with '.' | subdata without '.'
|
||||
// 254 - 30 - [64 - 64 - 64 - 32] - 1 = 63 + 63 + 63 + 31 (219)
|
||||
// expected value is thus 235 (max chars without '.'), rounded down if applicable
|
||||
client2 := NewDNSClient(parent2, opts)
|
||||
if client2.subdataSpace != 220 {
|
||||
if client2.subdataSpace != 219 {
|
||||
t.Fatalf("Unexpected subdata space for parent %s: %d", parent2, client2.subdataSpace)
|
||||
}
|
||||
|
||||
// .something-even-longer.example.computer. (40 chars parent, 214 chars subdata)
|
||||
// Grand Total: 254 chars
|
||||
// parent | subdata with '.' | subdata without '.'
|
||||
// 254 - 40 - [64 - 64 - 64 - 22] = 63 + 63 + 63 + 21 (210)
|
||||
// parent | subdata with '.' | subdata without '.'
|
||||
// 254 - 40 - [64 - 64 - 64 - 22] - 1 = 63 + 63 + 63 + 21 (209)
|
||||
// expected value is thus 235 (max chars without '.'), rounded down if applicable
|
||||
client3 := NewDNSClient(parent3, opts)
|
||||
if client3.subdataSpace != 210 {
|
||||
if client3.subdataSpace != 209 {
|
||||
t.Fatalf("Unexpected subdata space for parent %s: %d", parent3, client3.subdataSpace)
|
||||
}
|
||||
|
||||
// "maxParent" (154 chars parent, 100 chars subdata)
|
||||
// Grand Total: 254 chars
|
||||
// parent | subdata with '.' | subdata without '.'
|
||||
// 254 - 154 - [64 - 36] = 63 + 35 (98)
|
||||
// parent | subdata with '.' | subdata without '.'
|
||||
// 254 - 154 - [64 - 36] - 1 = 63 + 35 (97)
|
||||
// expected value is thus 98 (max chars without '.'), rounded down if applicable
|
||||
clientMax := NewDNSClient(parentMax, opts)
|
||||
if clientMax.subdataSpace != 98 {
|
||||
if clientMax.subdataSpace != 97 {
|
||||
t.Fatalf("Unexpected subdata space for parent %s: %d", parentMax, clientMax.subdataSpace)
|
||||
}
|
||||
}
|
||||
|
||||
+39
-37
@@ -19,12 +19,12 @@ package c2
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
We've put a little effort to making the server at least not super easily fingerprintable,
|
||||
We've put a little effort to making the server at least not super easily finger printable,
|
||||
though I'm guessing it's also still not super hard to do. The server must receive a valid
|
||||
TOTP code before we start returning any non-error records. All requests must be formatted
|
||||
as valid protobuf and contain a 24-bit "dns session ID" (16777216 possible values), and a
|
||||
8 bit "message ID." The server only responds to non-TOTP queries with valid dns session IDs
|
||||
16,777,216 can probably be bruteforced but it'll at least be slow.
|
||||
16,777,216 can probably be brute-forced but it'll at least be slow.
|
||||
|
||||
DNS command and control outline:
|
||||
1. Implant sends TOTP encoded message to DNS server, server checks validity
|
||||
@@ -45,7 +45,6 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
consts "github.com/bishopfox/sliver/client/constants"
|
||||
"github.com/bishopfox/sliver/protobuf/dnspb"
|
||||
@@ -87,7 +86,6 @@ func StartDNSListener(bindIface string, lport uint16, domains []string, canaries
|
||||
messages: &sync.Map{}, // In progress message streams
|
||||
TTL: 0,
|
||||
MaxTXTLength: defaultMaxTXTLength,
|
||||
EnforceOTP: enforceOTP,
|
||||
}
|
||||
dnsLog.Infof("Starting DNS listener for %v (canaries: %v) ...", domains, canaries)
|
||||
dns.HandleFunc(".", func(writer dns.ResponseWriter, req *dns.Msg) {
|
||||
@@ -317,7 +315,6 @@ type SliverDNSServer struct {
|
||||
messages *sync.Map
|
||||
TTL uint32
|
||||
MaxTXTLength int
|
||||
EnforceOTP bool
|
||||
}
|
||||
|
||||
// Shutdown - Shutdown the DNS server
|
||||
@@ -387,7 +384,7 @@ func (s *SliverDNSServer) handleC2(domain string, req *dns.Msg) *dns.Msg {
|
||||
|
||||
// TOTP Handler can be called without dns session ID
|
||||
if msg.Type == dnspb.DNSMessageType_TOTP {
|
||||
return s.handleHello(domain, msg, req)
|
||||
return s.handleHello(msg, req)
|
||||
}
|
||||
|
||||
// All other handlers require a valid dns session ID
|
||||
@@ -402,15 +399,15 @@ func (s *SliverDNSServer) handleC2(domain string, req *dns.Msg) *dns.Msg {
|
||||
case dnspb.DNSMessageType_NOP:
|
||||
return s.handleNOP(domain, msg, checksum, req)
|
||||
case dnspb.DNSMessageType_INIT:
|
||||
return s.handleDNSSessionInit(domain, msg, checksum, req)
|
||||
return s.handleDNSSessionInit(msg, req)
|
||||
case dnspb.DNSMessageType_POLL:
|
||||
return s.handlePoll(domain, msg, checksum, req)
|
||||
return s.handlePoll(msg, req)
|
||||
case dnspb.DNSMessageType_DATA_FROM_IMPLANT:
|
||||
return s.handleDataFromImplant(domain, msg, checksum, req)
|
||||
return s.handleDataFromImplant(msg, checksum, req)
|
||||
case dnspb.DNSMessageType_DATA_TO_IMPLANT:
|
||||
return s.handleDataToImplant(domain, msg, checksum, req)
|
||||
return s.handleDataToImplant(msg, req)
|
||||
case dnspb.DNSMessageType_CLEAR:
|
||||
return s.handleClear(domain, msg, checksum, req)
|
||||
return s.handleClear(msg, checksum, req)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -420,31 +417,36 @@ func (s *SliverDNSServer) handleC2(domain string, req *dns.Msg) *dns.Msg {
|
||||
// of the plaintext data (that would be very bad).
|
||||
func (s *SliverDNSServer) decodeSubdata(subdomain string) (*dnspb.DNSMessage, uint32, error) {
|
||||
subdata := strings.Join(strings.Split(subdomain, "."), "")
|
||||
dnsLog.Debugf("subdata = %s", subdata)
|
||||
encoders := s.determineLikelyEncoders(subdata)
|
||||
for _, encoder := range encoders {
|
||||
data, err := encoder.Decode([]byte(subdata))
|
||||
if err == nil {
|
||||
msg := &dnspb.DNSMessage{}
|
||||
err = proto.Unmarshal(data, msg)
|
||||
if err == nil {
|
||||
return msg, crc32.ChecksumIEEE(data), nil
|
||||
}
|
||||
}
|
||||
dnsLog.Debugf("failed to decode subdata with %#v (%s)", encoder, err)
|
||||
if len(subdata) < 2 {
|
||||
return nil, 0, ErrInvalidMsg
|
||||
}
|
||||
dnsLog.Debugf("subdata = %s", subdata)
|
||||
encoder := determineEncoder(subdata[0])
|
||||
data, err := encoder.Decode([]byte(subdata[1:]))
|
||||
if err == nil {
|
||||
msg := &dnspb.DNSMessage{}
|
||||
err = proto.Unmarshal(data, msg)
|
||||
if err == nil {
|
||||
return msg, crc32.ChecksumIEEE(data), nil
|
||||
}
|
||||
}
|
||||
dnsLog.Debugf("failed to decode subdata with %#v (%s)", encoder, err)
|
||||
|
||||
return nil, 0, ErrInvalidMsg
|
||||
}
|
||||
|
||||
// Returns the most likely -> least likely encoders, if decoding fails fallback to
|
||||
// the next encoder until we run out of options.
|
||||
func (s *SliverDNSServer) determineLikelyEncoders(subdata string) []encoders.Encoder {
|
||||
for _, char := range subdata {
|
||||
if unicode.IsUpper(char) {
|
||||
return []encoders.Encoder{encoders.Base58{}, encoders.Base32{}}
|
||||
}
|
||||
func determineEncoder(firstChar byte) encoders.Encoder {
|
||||
index := strings.Index("abcdefghijklmnopqrstuvwxyz", strings.ToLower(string(firstChar)))
|
||||
if index == -1 {
|
||||
return encoders.Base32{}
|
||||
}
|
||||
return []encoders.Encoder{encoders.Base32{}, encoders.Base58{}}
|
||||
// if the index is odd, use base58, otherwise use base32
|
||||
if index&1 == 1 {
|
||||
return encoders.Base58{}
|
||||
}
|
||||
return encoders.Base32{}
|
||||
}
|
||||
|
||||
func (s *SliverDNSServer) nameErrorResp(req *dns.Msg) *dns.Msg {
|
||||
@@ -464,7 +466,7 @@ func (s *SliverDNSServer) refusedErrorResp(req *dns.Msg) *dns.Msg {
|
||||
// ---------------------------
|
||||
// DNS Message Handlers
|
||||
// ---------------------------
|
||||
func (s *SliverDNSServer) handleHello(domain string, msg *dnspb.DNSMessage, req *dns.Msg) *dns.Msg {
|
||||
func (s *SliverDNSServer) handleHello(msg *dnspb.DNSMessage, req *dns.Msg) *dns.Msg {
|
||||
dnsLog.Debugf("[dns] totp request: %v", msg)
|
||||
|
||||
dnsSessionID := dnsSessionID()
|
||||
@@ -498,7 +500,7 @@ func (s *SliverDNSServer) handleHello(domain string, msg *dnspb.DNSMessage, req
|
||||
return resp
|
||||
}
|
||||
|
||||
func (s *SliverDNSServer) handleDNSSessionInit(domain string, msg *dnspb.DNSMessage, checksum uint32, req *dns.Msg) *dns.Msg {
|
||||
func (s *SliverDNSServer) handleDNSSessionInit(msg *dnspb.DNSMessage, req *dns.Msg) *dns.Msg {
|
||||
dnsLog.Debugf("[session init] with dns session id %d", msg.ID&sessionIDBitMask)
|
||||
loadSession, _ := s.sessions.Load(msg.ID & sessionIDBitMask)
|
||||
dnsSession := loadSession.(*DNSSession)
|
||||
@@ -591,7 +593,7 @@ func (s *SliverDNSServer) handleDNSSessionInit(domain string, msg *dnspb.DNSMess
|
||||
return resp
|
||||
}
|
||||
|
||||
func (s *SliverDNSServer) handlePoll(domain string, msg *dnspb.DNSMessage, checksum uint32, req *dns.Msg) *dns.Msg {
|
||||
func (s *SliverDNSServer) handlePoll(msg *dnspb.DNSMessage, req *dns.Msg) *dns.Msg {
|
||||
dnsLog.Debugf("[poll] with dns session id %d", msg.ID&sessionIDBitMask)
|
||||
loadSession, _ := s.sessions.Load(msg.ID & sessionIDBitMask)
|
||||
dnsSession := loadSession.(*DNSSession)
|
||||
@@ -621,7 +623,7 @@ func (s *SliverDNSServer) handlePoll(domain string, msg *dnspb.DNSMessage, check
|
||||
}
|
||||
}
|
||||
|
||||
respData := []byte{}
|
||||
var respData []byte
|
||||
dnsLog.Debugf("[poll] manifest %d (%d bytes)", msgID, msgLen)
|
||||
respData, _ = proto.Marshal(&dnspb.DNSMessage{
|
||||
Type: dnspb.DNSMessageType_MANIFEST,
|
||||
@@ -672,7 +674,7 @@ func (s *SliverDNSServer) handlePoll(domain string, msg *dnspb.DNSMessage, check
|
||||
return resp
|
||||
}
|
||||
|
||||
func (s *SliverDNSServer) handleDataFromImplant(domain string, msg *dnspb.DNSMessage, checksum uint32, req *dns.Msg) *dns.Msg {
|
||||
func (s *SliverDNSServer) handleDataFromImplant(msg *dnspb.DNSMessage, checksum uint32, req *dns.Msg) *dns.Msg {
|
||||
dnsLog.Debugf("[from implant] dns session id %d", msg.ID&sessionIDBitMask)
|
||||
loadSession, _ := s.sessions.Load(msg.ID & sessionIDBitMask)
|
||||
dnsSession := loadSession.(*DNSSession)
|
||||
@@ -702,7 +704,7 @@ func (s *SliverDNSServer) handleDataFromImplant(domain string, msg *dnspb.DNSMes
|
||||
return resp
|
||||
}
|
||||
|
||||
func (s *SliverDNSServer) handleDataToImplant(domain string, msg *dnspb.DNSMessage, checksum uint32, req *dns.Msg) *dns.Msg {
|
||||
func (s *SliverDNSServer) handleDataToImplant(msg *dnspb.DNSMessage, req *dns.Msg) *dns.Msg {
|
||||
dnsLog.Debugf("[to implant] dns session id %d", msg.ID&sessionIDBitMask)
|
||||
loadSession, _ := s.sessions.Load(msg.ID & sessionIDBitMask)
|
||||
dnsSession := loadSession.(*DNSSession)
|
||||
@@ -761,7 +763,7 @@ func (s *SliverDNSServer) handleDataToImplant(domain string, msg *dnspb.DNSMessa
|
||||
return resp
|
||||
}
|
||||
|
||||
func (s *SliverDNSServer) handleClear(domain string, msg *dnspb.DNSMessage, checksum uint32, req *dns.Msg) *dns.Msg {
|
||||
func (s *SliverDNSServer) handleClear(msg *dnspb.DNSMessage, checksum uint32, req *dns.Msg) *dns.Msg {
|
||||
dnsLog.Debugf("[clear] dns session id %d", msg.ID&sessionIDBitMask)
|
||||
loadSession, _ := s.sessions.Load(msg.ID & sessionIDBitMask)
|
||||
dnsSession := loadSession.(*DNSSession)
|
||||
@@ -802,7 +804,7 @@ func (s *SliverDNSServer) handleClear(domain string, msg *dnspb.DNSMessage, chec
|
||||
return resp
|
||||
}
|
||||
|
||||
func (s *SliverDNSServer) handleNOP(domain string, msg *dnspb.DNSMessage, checksum uint32, req *dns.Msg) *dns.Msg {
|
||||
func (s *SliverDNSServer) handleNOP(_ string, _ *dnspb.DNSMessage, checksum uint32, req *dns.Msg) *dns.Msg {
|
||||
dnsLog.Debugf("[nop] request checksum: %d", checksum)
|
||||
resp := new(dns.Msg)
|
||||
resp.SetReply(req)
|
||||
|
||||
+76
-10
@@ -103,7 +103,7 @@ func TestPendingEnvelopes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func reassemble(t *testing.T, parent string, size int, encoder encoders.Encoder) {
|
||||
func reassemble(t *testing.T, _ string, size int, encoder encoders.Encoder) {
|
||||
client := dnsclient.NewDNSClient(example1, opts)
|
||||
dnsMsgs, original := randomDNSMsgs(t, example1, size, encoder, client)
|
||||
dnsSession := DNSSession{
|
||||
@@ -162,14 +162,80 @@ func TestIsC2Domain(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetermineLikelyEncoders(t *testing.T) {
|
||||
listener := StartDNSListener("", uint16(9999), c2Domains, false, true)
|
||||
sample := randomDataRandomSize(2048)
|
||||
encodedSample, _ := encoders.Base58{}.Encode(sample)
|
||||
b58Sample := string(encodedSample)
|
||||
likelyEncoders := listener.determineLikelyEncoders(b58Sample)
|
||||
_, err := likelyEncoders[0].Decode([]byte(b58Sample))
|
||||
if err != nil {
|
||||
t.Error("DetermineLikelyEncoders failed to decode sample")
|
||||
func TestDetermineEncoder1(t *testing.T) {
|
||||
encoder := determineEncoder("a"[0])
|
||||
|
||||
// check which encoder type the encoder is
|
||||
if encoder == nil {
|
||||
t.Fatal("Expected encoder to not be nil")
|
||||
}
|
||||
|
||||
// check if the encoder is the correct type
|
||||
if _, ok := encoder.(encoders.Base32); !ok {
|
||||
t.Fatalf("Expected encoder to be of type Base32 got %T", encoder)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetermineEncoder2(t *testing.T) {
|
||||
encoder := determineEncoder("b"[0])
|
||||
|
||||
// check which encoder type the encoder is
|
||||
if encoder == nil {
|
||||
t.Fatal("Expected encoder to not be nil")
|
||||
}
|
||||
|
||||
// check if the encoder is the correct type
|
||||
if _, ok := encoder.(encoders.Base58); !ok {
|
||||
t.Fatalf("Expected encoder to be of type Base58 got %T", encoder)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetermineEncoder3(t *testing.T) {
|
||||
encoder := determineEncoder("1"[0])
|
||||
|
||||
// check which encoder type the encoder is
|
||||
if encoder == nil {
|
||||
t.Fatal("Expected encoder to not be nil")
|
||||
}
|
||||
|
||||
// check if the encoder is the correct type
|
||||
if _, ok := encoder.(encoders.Base32); !ok {
|
||||
t.Fatalf("Expected encoder to be of type Base32 got %T", encoder)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetermineEncoder4(t *testing.T) {
|
||||
alpha := "abcdefghijklmnopqrstuvwxyz"
|
||||
for i := 0; i < 100; i++ {
|
||||
index := insecureRand.Intn(len(alpha))
|
||||
if index&1 == 1 {
|
||||
index = index - 1
|
||||
}
|
||||
encoder := determineEncoder(alpha[index])
|
||||
|
||||
// check if the encoder is the correct type
|
||||
if _, ok := encoder.(encoders.Base32); !ok {
|
||||
t.Fatalf("Expected encoder to be of type Base32 got %T", encoder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetermineEncoder5(t *testing.T) {
|
||||
alpha := "abcdefghijklmnopqrstuvwxyz"
|
||||
for i := 0; i < 100; i++ {
|
||||
index := insecureRand.Intn(len(alpha))
|
||||
if index&1 != 1 {
|
||||
index = index + 1
|
||||
if len(alpha) <= index {
|
||||
index = index - 2
|
||||
}
|
||||
}
|
||||
|
||||
encoder := determineEncoder(alpha[index])
|
||||
|
||||
// check if the encoder is the correct type
|
||||
if _, ok := encoder.(encoders.Base58); !ok {
|
||||
t.Fatalf("Expected encoder to be of type Base58 got %T", encoder)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -525,7 +525,6 @@ func (s *SliverHTTPC2) mainHandler(resp http.ResponseWriter, req *http.Request)
|
||||
// redirect to default page
|
||||
httpLog.Debugf("No pattern matches for request uri")
|
||||
s.defaultHandler(resp, req)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *SliverHTTPC2) startSessionHandler(resp http.ResponseWriter, req *http.Request) {
|
||||
|
||||
+9
-10
@@ -29,7 +29,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/bishopfox/sliver/client/constants"
|
||||
consts "github.com/bishopfox/sliver/client/constants"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/server/certs"
|
||||
@@ -52,9 +51,9 @@ func StartMTLSListenerJob(mtlsListener *clientpb.MTLSListenerReq) (*core.Job, er
|
||||
|
||||
job := &core.Job{
|
||||
ID: core.NextJobID(),
|
||||
Name: constants.MtlsStr,
|
||||
Name: consts.MtlsStr,
|
||||
Description: fmt.Sprintf("mutual tls listener %s", bind),
|
||||
Protocol: constants.TCPListenerStr,
|
||||
Protocol: consts.TCPListenerStr,
|
||||
Port: uint16(mtlsListener.Port),
|
||||
JobCtrl: make(chan bool),
|
||||
}
|
||||
@@ -79,9 +78,9 @@ func StartWGListenerJob(wgListener *clientpb.WGListenerReq) (*core.Job, error) {
|
||||
|
||||
job := &core.Job{
|
||||
ID: core.NextJobID(),
|
||||
Name: constants.WGStr,
|
||||
Name: consts.WGStr,
|
||||
Description: fmt.Sprintf("wg listener port: %d", wgListener.Port),
|
||||
Protocol: constants.UDPListenerStr,
|
||||
Protocol: consts.UDPListenerStr,
|
||||
Port: uint16(wgListener.Port),
|
||||
JobCtrl: make(chan bool),
|
||||
}
|
||||
@@ -132,9 +131,9 @@ func StartDNSListenerJob(dnsListener *clientpb.DNSListenerReq) (*core.Job, error
|
||||
description := fmt.Sprintf("%s (canaries %v)", strings.Join(dnsListener.Domains, " "), dnsListener.Canaries)
|
||||
job := &core.Job{
|
||||
ID: core.NextJobID(),
|
||||
Name: constants.DnsStr,
|
||||
Name: consts.DnsStr,
|
||||
Description: description,
|
||||
Protocol: constants.UDPListenerStr,
|
||||
Protocol: consts.UDPListenerStr,
|
||||
Port: uint16(dnsListener.Port),
|
||||
JobCtrl: make(chan bool),
|
||||
Domains: dnsListener.Domains,
|
||||
@@ -175,16 +174,16 @@ func StartHTTPListenerJob(req *clientpb.HTTPListenerReq) (*core.Job, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := constants.HttpStr
|
||||
name := consts.HttpStr
|
||||
if req.Secure {
|
||||
name = constants.HttpsStr
|
||||
name = consts.HttpsStr
|
||||
}
|
||||
|
||||
job := &core.Job{
|
||||
ID: core.NextJobID(),
|
||||
Name: name,
|
||||
Description: fmt.Sprintf("%s for domain %s", name, req.Domain),
|
||||
Protocol: constants.TCPListenerStr,
|
||||
Protocol: consts.TCPListenerStr,
|
||||
Port: uint16(req.Port),
|
||||
JobCtrl: make(chan bool),
|
||||
Domains: []string{req.Domain},
|
||||
|
||||
+1
-1
@@ -195,7 +195,7 @@ func socketReadEnvelope(connection net.Conn) (*sliverpb.Envelope, error) {
|
||||
}
|
||||
|
||||
// getServerTLSConfig - Generate the TLS configuration, we do now allow the end user
|
||||
// to specify any TLS paramters, we choose sensible defaults instead
|
||||
// to specify any TLS parameters, we choose sensible defaults instead
|
||||
func getServerTLSConfig(host string) *tls.Config {
|
||||
|
||||
mtlsCACert, _, err := certs.GetCertificateAuthority(certs.MtlsImplantCA)
|
||||
|
||||
@@ -18,6 +18,7 @@ package encoders
|
||||
|
||||
import (
|
||||
"encoding/base32"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Base32 Encoder
|
||||
@@ -35,5 +36,5 @@ func (e Base32) Encode(data []byte) ([]byte, error) {
|
||||
|
||||
// Decode - Base32 Decode
|
||||
func (e Base32) Decode(data []byte) ([]byte, error) {
|
||||
return sliverBase32.DecodeString(string(data))
|
||||
return sliverBase32.DecodeString(strings.ToLower(string(data)))
|
||||
}
|
||||
Reference in new issue
Block a user