shadow-tls

repository·master·Indexed 25 days ago

https://github.com/ihciah/shadow-tls

A TLS camouflage proxy designed to expose real TLS handshakes to firewalls using existing trusted certificates. It makes proxy traffic indistinguishable from legitimate HTTPS traffic to deep packet inspection (DPI). The project includes implementations of ShadowTLS V1, V2, and V3 protocols, offering varying levels of defense against active detection and traffic analysis. It can be deployed via prebuilt binaries or Docker Compose.

Tokens
8.1K
Snippets
8
Records
46
Agent score
83%

What's inside shadow-tls

  1. Overview of Shadow TLS

    master
    Shadow TLS is a TLS camouflage proxy designed to expose a real TLS handshake to firewalls. Unlike Trojan, it does not require you to sign your own certificates; instead, it allows you to use existing trusted certificates (e.g., from large companies or institutions). This ensures that when a browser accesses the domain directly, it shows valid, trusted content, making the traffic appear legitimate to deep packet inspection (DPI).
  2. Understand ShadowTLS V3 Protocol Design

    master
    ShadowTLS V3 is designed to defend against traffic feature detection, active probing, and traffic hijacking. Unlike V2, V3 aims to be resilient against middleman hijacking by implementing a robust authentication and data encapsulation mechanism that does not require hacking or implementing the TLS protocol from scratch. It acts as a TCP stream proxy.
  3. Understand ShadowTLS V2 Protocol Design

    master

    ShadowTLS V2 is a more complex protocol designed to defend against active probing and traffic analysis. It supports TLS 1.3 and makes post-handshake traffic difficult to distinguish from real web traffic.

    Capabilities:

    • Defends against active probing: If an attacker uses a browser to access the server, the server relays the traffic to the TLS handshake server, making it behave like a real web server.
    • Defends against traffic analysis: All data is encapsulated within TLS Application Data.
    • Supports TLS 1.3.

    Mechanism:

    • Uses an 8-byte HMAC inserted at the beginning of the first Application Data packet to identify the client.
    • The HMAC is calculated based on all data sent by the server (acting as a challenge).
  4. Understand ShadowTLS V1 Protocol Design

    master

    ShadowTLS V1 is a simple protocol designed to make traffic appear as a legitimate TLS handshake using a trusted certificate from a third-party domain.

    Capabilities:

    • Defends against traffic feature-based blocking (looks like normal TLS rather than random data).
    • Defends against SNI-based blocking by using legitimate, trusted domains.

    Limitations:

    • Cannot defend against active probing.
    • Post-handshake traffic is easily distinguishable because it uses TLS without HTTP, which is a rare pattern.
    • Only supports TLS 1.2 because the server must monitor the handshake to detect completion.
  5. Understand ShadowTLS V3 Handshake and Security

    master

    The V3 protocol handshake is designed to defend against traffic signature detection, active probing, and traffic hijacking.

    Key Handshake Mechanics:

    • Custom SessionID: The client constructs a 32-byte SessionID. The first 28 bytes are random, and the last 4 bytes are an HMAC signature of the ClientHello frame (excluding the 5-byte TLS header). The HMAC is created using a password.
    • Server Authentication: The server authenticates the ClientHello. If authentication fails, the server acts as a standard TCP relay to the handshake server. If it succeeds, the server hijacks the stream.
    • ServerRandom: The server logs the ServerRandom from the ServerHello and uses it to initialize an HMAC instance for data encapsulation.
    • Switching Mechanism: The client uses a ReadWrapper to detect specific HMAC prefixes in the ApplicationData to determine if the server is legitimate or if the connection has been hijacked.
  6. Understand ShadowTLS V2 Protocol

    master

    ShadowTLS V2 is a more advanced protocol designed to defend against active detection and traffic analysis. It supports TLS 1.3 and ensures that traffic after the handshake is hard to distinguish from real web traffic.

    Key Features:

    • Active Detection Defense: If an attacker accesses the server with a browser, the server behaves like a real web server by relaying traffic to the trusted TLS handshaking backend.
    • Traffic Obfuscation: All data is packed within TLS application data.
    • Authentication Mechanism: Uses an 8-byte HMAC inserted at the front of the first application data packet to identify legitimate clients.
    • TLS Support: Supports TLS 1.3 and other versions.
  7. Understand ShadowTLS V1 Protocol

    master

    ShadowTLS V1 is a simple protocol designed to expose valid TLS handshaking to a man-in-the-middle (MITM) using trusted certificates from external domains. It defends against SNI-based blocking and basic traffic characteristic blocking, provided the attacker does not perform active detection or post-handshake traffic analysis.

    Limitations:

    • Cannot defend against active detection.
    • Post-handshake traffic is easily distinguishable from normal HTTP/TLS traffic because it uses the application data protocol without modification.
    • Only supports TLS 1.2 (required to sense when the handshake finishes).
  8. Implement ShadowTLS V2 Server

    master

    A V2 server relays data between the client and two backends (a TLS handshaking server and a real server) using an HMAC-based switch instead of handshake monitoring.

    Workflow:

    1. Accept connections.
    2. Relay traffic between the client and the TLS handshaking server. The server uses all data sent by the server to calculate an HMAC.
    3. Monitor incoming application data packets from the client. If a packet contains a valid 8-byte HMAC at its front, the server switches the traffic to the real server.
    4. If no valid HMAC is detected, the traffic continues to be relayed to the TLS handshaking server. This allows standard web browsers to access the HTTP service on the handshaking server without detection.
  9. Implement ShadowTLS V3 Client

    master

    The client performs the TLS handshake, handles the switch to encapsulated data, and manages encapsulation/decapsulation. It requires a TLS Client integrated with a ReadWrapper and a WriteWrapper over the TCPStream.

    Stage 1: TLS Handshake

    1. ClientHello: Construct a custom SessionID (32 bytes: 28 random bytes + 4 bytes HMAC signature of the ClientHello frame excluding the 5-byte TLS header). Use a one-time HMAC instance created with the PreSharedKey.
    2. ReadWrapper:
      • Extract ServerRandom from the ServerHello and create HMAC_ServerRandom.
      • For ApplicationData frames: Check if the first 4 bytes match the HMAC of the content (excluding the 4-byte HMAC).
        • If it matches: The frame is a handshake residue. Rewrite the content using XOR SHA256(PreSharedKey + ServerRandom) and strip the 4-byte HMAC.
        • If it does NOT match: The connection is likely hijacked. After the handshake, send a random-length 'decoy' HTTP request and then close the connection.

    Stage 2: Data Forwarding (Post-Handshake)

    This stage does not depend on the TLS library. Use HMAC_ServerRandomC (for client-to-server) and HMAC_ServerRandomS (for server-to-client).

    1. Reading (Server to Client): Parse ApplicationData and verify the 4-byte HMAC using HMAC_ServerRandomS or HMAC_ServerRandom:
      • HMAC_ServerRandom matches: It is handshake residue; ignore it.
      • HMAC_ServerRandomS matches: This is the encapsulated data. Disable the HMAC_ServerRandom branch and forward the content (without the HMAC) to the user.
      • Neither matches: Treat as Alert bad_record_mac and handle error.
    2. Writing (Client to Server): Wrap data in ApplicationData and prepend a 4-byte HMAC calculated via HMAC_ServerRandomC.
  10. Deploy Shadow TLS Server using Docker Compose

    master

    To deploy the Shadow TLS server, create a docker-compose.yml file with the following configuration. This setup assumes you are also running a Shadowsocks server (e.g., shadowsocks-libev) on the same host.

    Ensure the SERVER environment variable in the shadow-tls service points to the local address and port of your Shadowsocks instance, and the TLS variable points to a legitimate domain (e.g., cloud.tencent.com:443) to mimic real TLS traffic.

    version: '2.4'
    services:
      shadowsocks:
        image: shadowsocks/shadowsocks-libev
        container_name: shadowsocks-raw
        restart: always
        network_mode: "host"
        environment:
          - SERVER_PORT=24000
          - SERVER_ADDR=127.0.0.1
          - METHOD=chacha20-ietf-poly1305
          - PASSWORD=EXAMPLE_PASSWORD_CHANGE_IT
      shadow-tls:
        image: ghcr.io/ihciah/shadow-tls:latest
        restart: always
        network_mode: "host"
        environment:
          - MODE=server
          - LISTEN=0.0.0.0:8443
          - SERVER=127.0.0.1:24000
          - TLS=cloud.tencent.com:443
          - PASSWORD=CHANGE_IT_123321
  11. Implement ShadowTLS V3 Server

    master

    The server forwards the TLS handshake, detects the switch to encapsulated data, and manages encapsulation/decapsulation without relying on a TLS library.

    Stage 1: Handshake Forwarding

    1. ClientHello: Inspect the SessionID.
      • If authentication fails: Treat as active probing and switch to direct TCP forwarding (or SNI-based routing if implementing multi-SNI).
      • If authentication succeeds: Forward the frame and proceed.
    2. ServerHello: Extract ServerRandom from the response.
    3. Bidirectional Forwarding (with Handshake Server):
      • Create HMAC_ServerRandomC and HMAC_ServerRandom.
      • Client $\rightarrow$ Handshake Server: Forward directly until a frame is encountered where the first 4 bytes match the HMAC_ServerRandomC signature. At this point, stop bidirectional forwarding (ensuring in-flight frames are completed).
      • Handshake Server $\rightarrow$ Client: Modify ApplicationData frames by applying XOR SHA256(PreSharedKey + ServerRandom) and prepending a 4-byte HMAC calculated by HMAC_ServerRandom.

    Stage 2: Data Forwarding (with Data Server)

    1. Create HMAC_ServerRandomS.
    2. Client $\rightarrow$ Data Server: Parse ApplicationData and verify the 4-byte HMAC using HMAC_ServerRandomC. If verification fails, handle as Alert bad_record_mac. After verification, update the HMAC_ServerRandomC instance with the 4-byte HMAC value itself to prevent cutting/pasting attacks.
    3. Data Server $\rightarrow$ Client: Encapsulate data in ApplicationData with a 4-byte HMAC calculated via HMAC_ServerRandomS. Update the HMAC_ServerRandomS instance with the 4-byte HMAC value.
  12. Implement ShadowTLS V3 Client Logic

    master

    A V3 client must wrap the network stream with a TLS Client and a ReadWrapper (on the read side) and a WriteWrapper (on the write side). The process occurs in two stages:

    Stage 1: TLS Handshake

    1. Construct SessionID: Sign a custom 32-byte SessionID from the TLS library.
    2. ReadWrapper Logic:
      • Extract ServerRandom from ServerHello and create HMAC_ServerRandom.
      • If the first 4 bytes of an ApplicationData frame match HMAC_ServerRandom(frame content), the server is verified. Rewrite the content using XOR SHA256(PreSharedKey + ServerRandom) and remove the 4-byte HMAC.
      • If it does not match, mark the connection as hijacked and send a 'muddled request' (random length HTTP request) after the handshake.

    Stage 2: Data Forwarding

    1. Initialize HMACs: Create HMAC_ServerRandomC and HMAC_ServerRandomS.
    2. Read Side: Parse ApplicationData and verify the 4-byte HMAC:
      • If HMAC_ServerRandom matches: It is residual handshake data; ignore it.
      • If HMAC_ServerRandomS matches: The switchover is complete; forward the data (without HMAC) to the user.
      • If neither matches: Handle as Alert bad_record_mac.
    3. Write Side: When writing to the connection, add the ApplicationData header and the HMAC calculated by HMAC_ServerRandomC.