Giter Club home page Giter Club logo

Comments (5)

moloch-- avatar moloch-- commented on June 5, 2024

I think the real bug is in the detection of case sensitive vs. case insensitive encoding, the implant should* be able to detect this manipulation and fallback to base32 but doesn't.

from sliver.

miszr avatar miszr commented on June 5, 2024

There are multiple issues here:

First Issue

An example of a message which failes to decode is the initial TOTP message, which is always base32 encoded.

func (s *SliverDNSClient) otpMsg() (string, error) {
otpMsg := &dnspb.DNSMessage{
Type: dnspb.DNSMessageType_TOTP,
ID: uint32(0), // Take advantage of the variable length encoding
}
data, err := proto.Marshal(otpMsg)
if err != nil {
return "", err
}
msg, _ := s.base32.Encode(data)
return string(msg), nil
}

The problem is that the DNS-0x20 encoding will alter the case of the subdata, which then fails decoding in the base32 encoder, as there are characters which are uppercase.

const base32Alphabet = "ab1c2d3e4f5g6h7j8k9m0npqrtuvwxyz"
var sliverBase32 = base32.NewEncoding(base32Alphabet).WithPadding(base32.NoPadding)
// Encode - Base32 Encode
func (e Base32) Encode(data []byte) ([]byte, error) {
return []byte(sliverBase32.EncodeToString(data)), nil
}
// Decode - Base32 Decode
func (e Base32) Decode(data []byte) ([]byte, error) {
return sliverBase32.DecodeString(string(data))
}

Possible Solution

A solution to this is doing strings.ToLower on the input data.

return sliverBase32.DecodeString(strings.ToLower(string(data)))

This however is partially problematic(programming wise) as, it transfers the responsibility from server/c2/dns.go to the base32 encoder.

Second Issue

Sometimes, a base32 encoded value mangled by DNS-0x20(for example) is interpreted as a base58 encoded value. I have seen you mention this issue here: #1354 (comment)

This can become a problem for example here:

sliver/server/c2/dns.go

Lines 382 to 394 in c8a7948

msg, checksum, err := s.decodeSubdata(subdomain)
if err != nil {
dnsLog.Errorf("[dns] error decoding subdata: %v", err)
return s.nameErrorResp(req)
}
// TOTP Handler can be called without dns session ID
if msg.Type == dnspb.DNSMessageType_TOTP {
return s.handleHello(domain, msg, req)
}
// All other handlers require a valid dns session ID
_, ok := s.sessions.Load(msg.ID & sessionIDBitMask)

When the data gets interpreted as base58 and produces semi-valid protobuf data, the decodeSubdata functions returns a message and no error. This becomes a problem on line 394 as we use the ID field, which is incorrectly interpreted.

This issue will produce a log warning:

dnsLog.Warnf("[dns] session not found for id %v (%v)", msg.ID, msg.ID&sessionIDBitMask)

Possible Solution

A possible solution could be that if we attempt to decode the subdata using the current method and we are unable to find a valid session id we could attempt to decode the lowercase value of the subdata.

The solution would look something like this:

	dnsLog.Debugf("[dns] processing req for subdomain = %s", subdomain)
	msg, checksum, err := s.decodeSubdata(subdomain)
	if err != nil {
		dnsLog.Errorf("[dns] error decoding subdata: %v", err)
		return s.nameErrorResp(req)
	}

	// TOTP Handler can be called without dns session ID
	if msg.Type == dnspb.DNSMessageType_TOTP {
		return s.handleHello(domain, msg, req)
	}

	// All other handlers require a valid dns session ID
	_, ok := s.sessions.Load(msg.ID & sessionIDBitMask)
	if !ok {
		subdomain = strings.ToLower(subdomain)

		dnsLog.Debugf("[dns] reprocessing req for subdomain = %s", subdomain)
		msg, checksum, err = s.decodeSubdata(subdomain)
		if err != nil {
			dnsLog.Errorf("[dns] error decoding subdata: %v", err)
			return s.nameErrorResp(req)
		}
		_, ok := s.sessions.Load(msg.ID & sessionIDBitMask)
		if !ok {
			dnsLog.Warnf("[dns] session not found for id %v (%v)", msg.ID, msg.ID&sessionIDBitMask)
			return s.nameErrorResp(req)
		}
	}

This is a bit of a hacky solution, but should work.

Better Solution

Would be nice to be able to determine whether the resolver manipulates the DNS queries using for example DNS-0x20 encoding.

from sliver.

moloch-- avatar moloch-- commented on June 5, 2024

We've removed TOTP in v1.6, it would be good to address all these issues in that branch. Perhaps we should just use a single bit to indicate the Base32 vs. Base58 instead of trying to detect it.

from sliver.

miszr avatar miszr commented on June 5, 2024

Sorry, but I do not understand. The code I referenced in the previous comment is from the master branch and not to the 1.5.x/master branch.

Is there a more updated version of v1.6?

from sliver.

moloch-- avatar moloch-- commented on June 5, 2024

Oh yes, you're right. We did remove the TOTP auth, but the message is still called TOTP.

from sliver.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.