Portfolio Blog Code Repository Contact

Trojan, Shadowsocks, and the Art of Automatic Disguise Selection

Two More Faces of the Chameleon

In our last post, we covered XTLS-REALITY (the "perfect impersonator") and VMess (the "binary chameleon"). Today, we complete the Chameleon Engine's transport lineup with two protocols that take radically different philosophical approaches to evasion and then tie everything together with BPP's automatic protocol selection.


Trojan: Hiding in Plain Sight

The Philosophy

Trojan-GFW took a contrarian approach to anti-censorship: instead of making traffic look random or exotic, make it look boring. Specifically, make it look like ordinary HTTPS traffic from a normal web server.

The key difference from REALITY: where REALITY borrows another site's certificate, Trojan wraps its data inside standard TLS Application Data records with its own certificate. The authentication mechanism is an HMAC-SHA224 hash of a pre-shared password.

BPP's Trojan Implementation

When BPP operates in Trojan mode, the wire format is precisely:

[56 bytes: hex-encoded HMAC-SHA224 hash]
[2 bytes: CRLF (\r\n)]
[1 byte: command]
[address + port]
[2 bytes: CRLF]
[payload]

The 56-byte hex HMAC hash serves as both authentication and identification. On the server side, PeekConn checks for this exact pattern: 56 hex characters followed by \r\n. If the hash matches the server's expected value, the connection is authenticated. If not, the server drops the connection silently no error messages that could help a probe identify it as a Trojan server.

Entropy Profile: Trojan

Trojan traffic averages 7.48 bits/byte the lowest entropy of all BPP transports. This is because the TLS Application Data framing, the HMAC header, and the structured command/address fields all contribute non-random bytes. The result? Traffic that sits right at the bottom of the legitimate TLS range (7.3 7.8), making it virtually identical to a regular HTTPS session transferring web content.


Shadowsocks: The OG that Still Has Teeth

History

Shadowsocks deserves special respect. Created in 2012 by a Chinese developer known as @clowwindy, it was one of the first protocols specifically designed to evade the Great Firewall. The developer was eventually forced to delete the repository by Chinese authorities but the code was already forked and alive across the world. The open-source community carried it forward.

The Design: No Fingerprint at All

Shadowsocks takes the opposite approach from Trojan. Where Trojan says "look like normal HTTPS," Shadowsocks says "look like nothing in particular." There are no magic bytes, no protocol headers, no recognizable structure. Just a random salt followed by AEAD-encrypted data.

[32 bytes: random salt]
[AEAD-encrypted payload]

That's it. No headers, no version fields, no identifiers. To a DPI, it's just a stream of high-entropy bytes.

The Double-Edged Sword of Pure Randomness

Here's the twist that taught the security community a hard lesson: perfectly random traffic is itself suspicious.

Real internet traffic is never perfectly random. Web pages have HTML structure. Images have headers. Even encrypted TLS traffic has record type markers and length fields. A stream with entropy at exactly ~8.0 bits/byte (the theoretical maximum) screams "I'm encrypted data with no protocol structure" and that's exactly what the Great Firewall learned to detect in 2020.

The GFW began analyzing the statistical distribution of the first 50 bytes of connections. Shadowsocks, with its salt + encrypted payload, produces near-perfect randomness. The very feature that was supposed to make it undetectable became its fingerprint.

How BPP Handles This

BPP's Shadowsocks transport produces traffic with entropy at 7.97 bits/byte consistent with real Shadowsocks AEAD implementations. But this transport is intentionally placed last in the fallback chain. When maximum stealth is needed, REALITY or Trojan (with their lower, TLS-like entropy profiles) are preferred. Shadowsocks serves as the final fallback when protocol-specific transports are being blocked.


Smart Selection: Letting the Protocol Choose Itself

The Problem

A user in Iran doesn't face the same censorship infrastructure as a user in China, who doesn't face the same as someone in Russia. Expecting end users to understand the nuances of XTLS-REALITY vs. VMess vs. Trojan is unrealistic and dangerous a wrong choice could mean detection.

The Solution: Automatic Protocol Selection with Intelligent Fallback

Phase 1: Ranked Attempt

  1. XTLS-REALITY Perfect TLS 1.3 mimicry, active probe resistant
  2. uTLS Browser fingerprint matching, JA3-resistant
  3. VMess Binary protocol, no fixed signatures
  4. Trojan TLS Application Data embedding
  5. Shadowsocks No protocol structure, last resort

Phase 2: Timeout Detection

Each transport gets a configurable timeout (default: 3 seconds). If the connection doesn't complete within the timeout, the client assumes that transport is being blocked and moves to the next one.

Phase 3: Transparent Fallback

The switch happens silently. No error messages, no user interaction. From the user's perspective, the connection just takes a few extra seconds. Behind the scenes, BPP might have tried two or three transports before finding one that works.

Real-World Test

We simulated a network where TLS traffic to non-whitelisted IPs is blocked (this is an actual configuration used by some Iranian ISPs):

  • ✗ Attempt 1: XTLS-REALITY → timeout after 3s (TLS blocked)
  • ✗ Attempt 2: uTLS → timeout after 3s (also TLS-based, also blocked)
  • ✗ Attempt 3: Trojan → timeout after 3s (TLS-based, also blocked)
  • ✓ Attempt 4: VMess → success (binary protocol, not recognized as TLS)
  • Total connection time: ~9.4 seconds

The user waited less than 10 seconds. No configuration change. No technical knowledge required. BPP found a way through automatically.


The Fallback Philosophy

Here's the deeper insight: BPP doesn't try to be the perfect disguise. It tries to be an adaptive one.

No single transport will work everywhere forever. The Great Firewall will learn new detection methods. ISPs will deploy new heuristics. What will survive is the ability to switch disguises faster than the adversary can learn to detect them.

Five transports today. Plugin architecture planned for tomorrow. The Chameleon Engine is designed to grow.

Sources

  1. Trojan-GFW. "An unidentifiable mechanism that helps you bypass GFW." trojan-gfw.github.io
  2. The Shadowsocks Project. "Shadowsocks: A secure SOCKS5 proxy." shadowsocks.org
  3. GFW Report. "How China Detects and Blocks Fully Encrypted Traffic." gfw.report (2023)
  4. V2Ray Community. "Project V: Platform for building proxies." v2fly.org
  5. Wang, Z. et al. "Seeing through Network-Protocol Obfuscation." ACM CCS, 2015.
  6. XTLS Community. "Xray-core, XTLS & REALITY." github.com/XTLS/Xray-core
  7. Alice, Bob, Carol, and Dave. "How the Great Firewall of China Detects and Blocks Fully Encrypted Traffic." USENIX Security 2023.

Amine Boutouil

Security Architect · Technical Polymath

boutouil.me →