Skip to content

Transport Encryption

Joe edited this page Sep 21, 2021 · 53 revisions

This document describes the way Sliver implants secure communication back to the C2 server. NOTE: This does not apply when mTLS or WireGuard are used.

Versions 1.5.0+

The following keys are embedded in each implant at compile time, the server also stores these values in its database in addition to the SHA256 hash of the implant's public key:

  1. ECC Public Key of Server
  2. ECC Client Public Key
  3. ECC Client Private Key
  4. TOTP Shared Secret (server-wide shared secret)

Key Exchange

  1. Implant generates 256-bit symmetric "session key"
  2. Implant generates:
  • Current TOTP code using SHA256, Unix UTC, 8 numeric code
  • SHA256 hash of its own ECC public key
  • Uses Nacl Box (Curve25519, XSalsa20 and Poly1305) to encrypt session key with server's public ECC key
  1. Implant sends [ TOTP Code | Hash of Public Key | Nacl Box Ciphertext ] to server
  2. Server verifies TOTP Code
  3. Server looks up sender public key using hash of public key in database
  4. Decrypts Nacl with sender public key + server private key
  5. Server generates a session ID, encrypts it with the session key using ChaCha20Poly1305, and sends it back
  6. All messages are encrypted with the session key using ChaCha20Poly1305 and associated with via the session ID
  7. Each side stores a SHA2-256 hash of each message's ciphertext to detect replayed messages.

Known Limitations

There are some known limitations, if you spot any or have ideas on improvements please file a ticket or contact us.

  1. Perfect Forward Secrecy: We do get some forward secrecy, since only the public key encrypted version of the session key is sent over the wire; therefore recovery of the hardcoded implant keys from the binary should not result in recovery of the session key. Only when the server's private key is compromised is forward secrecy broken. However, it my be desirable to do a full DH-exchange to protected against recovery of the server certificates too.

Versions <= 1.4.21

Transport Encryption for HTTP(S) / DNS

When the implant cannot directly route TCP traffic back to the C2 server or redirector the implant may, when configured to do so, connect back to the C2 server over HTTP, HTTPS, or DNS. In an operational environment it may not be posssible to establish a trusted HTTPS connect back to the server and HTTP/DNS do not implement any tranport encryption so Sliver "brings it's own crypto" to all of these protocols including HTTPS. This allows us to establish secure connections even if the only way out of the network is over a HTTPS interception proxy.

The following keys are embedded in each implant at compile time:

  1. ECC Public Key of Server CA
  2. ECC Client Public Key (used for mTLS)
  3. ECC Client Private Key (used for mTLS)

In this context "client" refers to the implant. The CA public key (#1) is shared among all implants generated by a given server. The client certificate pair (#2, and #3) are unqiue per-binary.

Key Exchange

  1. Implant requests a public RSA key from the server in the "clear"
  2. Server responds with a public RSA key in the "clear" (X.509 2048-bit)
  3. Implant verifies RSA public key is signed by the trusted authority embedded at compile-time
  4. Implant generates AES session key, encrypts it with the public RSA key, and sends it to the server
  5. Server generates a session ID, encrypts it with the session key using AES-GCM-256, and sends it back
  6. All messages are encrypted with the session key using AES-GCM-256 and associated with via the session ID
  7. Each side stores a SHA2-256 hash of each message's ciphertext to detect replayed messages.

Note: "Clear" data may still be encoded/obfuscated but is considered public. Session IDs are also considered public parameters. It's up to the protocol specific tansports to handle any data encoding/obfuscation. Session keys are only stored in memory

[implant] ---[ Do you have an RSA Key? ]-----> [server]
[implant] <--[ Here is my RSA Key ]----------- [server]
[implant] ---[ RSA encrypted AES key ]-------> [server]
[implant] <--[ AES encrypted session ID ]----- [server]

[implant] <--[ AES encrypted session data ]--> [server]

Security Goals

The security goals of this key exchange/setup are:

  • Robust data secrecy, integrity, and authenticity
  • Protection against MitM attacks
  • Protection against replay attacks
  • Protection against bit-flipping, padding oracle, etc. attacks

Known Limitations

The key exchange should provide a reasonable amount of security, however when possible we still recommend using mTLS or WireGuard. There are some known limitations in this scheme that we plan to address in the future, if you spot any or have ideas on improvements please file a ticket or contact us.

  1. No implant-to-server authentication: One of the nice properties of mutual TLS is that the implant authenticates itself to the server in addition to the server authenticating itself to the implant. In this model the implant never proves to the server it was generated by this server. Since the implant does have ECC keys known to the server in the future we plan to have the implant sign some type of nonce or timestamp during the key exchange.
  2. Session Initialization Replays: While there is replay protection against any messages sent between the server and the implant the initial message that establishes the session can be replayed against the server, but should only result in another (un-associated) session getting created.
  3. Perfect Forward Secrecy: We do get some forward secrecy, since only the public key encrypted version of the session key is sent over the wire; therefore recovery of the hardcoded implant keys from the binary should not result in recovery of the session key. Only when the server's private key is compromised is forward secrecy broken. However, it my be desirable to do a full DH-exchange to protected against recovery of the server certificates too.

Clone this wiki locally