Aparecium is a proof-of-concept tool designed to detect TLS camouflage protocols, specifically ShadowTLS v3 and REALITY, by exploiting their handling of TLS 1.3 post-handshake messages.
ShadowTLS v3 and REALITY are TLS 1.3-based camouflage protocols that disguise network traffic as legitimate TLS traffic to evade deep packet inspection (DPI) and active probing. Aparecium identifies these protocols by analyzing discrepancies in post-handshake messages, particularly the NewSessionTicket message, which these protocols fail to mimic correctly.
ShadowTLS v3 uses Pre-Shared Key (PSK) authentication and relays second-pass handshake messages (e.g., ServerHello, EncryptedExtensions, Certificate, CertificateVerify, Finished) from the target server, tainting them with an HMAC(PSK) that adds 4 bytes to their length. After the client sends the ClientFinished message, ShadowTLS stops relaying target server messages and handles encrypted Shadowsocks traffic.
sequenceDiagram
participant Client
participant ShadowTLS
participant Target
Client->>ShadowTLS: ClientHello (Challenge, PSK)
ShadowTLS->>Target: ClientHello
Target->>ShadowTLS: ServerHello, EncryptedExtensions, Certificate, CertificateVerify, Finished
ShadowTLS->>Client: ServerHello, EncryptedExtensions, Certificate, CertificateVerify, Finished (tainted with HMAC(PSK), +4 bytes)
Client->>ShadowTLS: ClientFinished
Client->>ShadowTLS: Shadowsocks (Encrypted)
ShadowTLS->>Client: Shadowsocks (Encrypted)
REALITY operates as a "real" TLS 1.3 server, generating a fake Certificate message and padding responses to match the target server’s message lengths. Like ShadowTLS, it only relays second-pass handshake messages and switches to encrypted TLS AEAD traffic after the ClientFinished message.
sequenceDiagram
participant Client
participant REALITY
participant Target
Client->>REALITY: ClientHello (Challenge, AuthKey)
REALITY->>Target: ClientHello
Target->>REALITY: ServerHello, EncryptedExtensions, Certificate, CertificateVerify, Finished
REALITY->>Client: ServerHello, EncryptedExtensions, Certificate (fake), CertificateVerify, Finished (padded to match original length)
Client->>REALITY: ClientFinished
Client->>REALITY: TLS AEAD (Encrypted)
REALITY->>Client: TLS AEAD (Encrypted)
Aparecium exploits a key vulnerability: both protocols fail to handle post-handshake messages, specifically the NewSessionTicket message, as defined in the TLS 1.3 RFC. In standard TLS 1.3, servers normally (e.g., those using OpenSSL) send one or two NewSessionTicket messages after receiving the ClientFinished message. ShadowTLS and REALITY do not relay or mimic these messages correctly, especially when mimicking OpenSSL-based servers.
NewSessionTicket messages after ClientFinished.sequenceDiagram
participant Client
participant Server
Client->>Server: ClientHello
Server->>Client: ServerHello, EncryptedExtensions, Certificate, CertificateVerify, Finished
Client->>Server: ClientFinished
Server->>Client: NewSessionTicket0 (OpenSSL)
Server->>Client: NewSessionTicket1 (OpenSSL)
NewSessionTicket message before ClientFinished, which ShadowTLS and REALITY relay since it occurs earlier.sequenceDiagram
participant Client
participant Server
Client->>Server: ClientHello
Server->>Client: ServerHello, EncryptedExtensions, Certificate, CertificateVerify, Finished, NewSessionTicket (Go)
Client->>Server: ClientFinished
Since most web servers (e.g., Nginx, Apache) use OpenSSL, ShadowTLS and REALITY fail to mimic their post-handshake behavior, discarding NewSessionTicket messages.
Aparecium detects TLS camouflage protocols in two phases:
ClientHello message and generate its fingerprint using utls.Fingerprinter.ClientHello (with new ClientRandom, SessionID, and KeyShare) to the suspected server.NewSessionTicket messages (typically two equal-length messages for OpenSSL servers).ServerFinished message (fixed at 53 or 69 bytes in TLS 1.3).NewSessionTicket lengths from Phase 1, the server is likely using a TLS camouflage protocol.ServerFinished message is 4 bytes longer (57 or 73 bytes) due to HMAC(PSK) tainting.Some servers, like those operated by Google, do not send NewSessionTicket messages. When ShadowTLS or REALITY mimics these servers, they are immune to this detection method, as described in Phase 1.5.
bash
git clone https://github.com/ban6cat6/aparecium.git
cd apareciumbash
go mod tidybash
$SERVER run -c $PROTOCOL/client.json
$SERVER run -c $PROTOCOL/server.jsonbash
# $protocol can be either "reality" or "shadowtls", default to "reality".
go run ./main.go -victim $protocolProbe the server at 127.0.0.1:10444 using a TLS client, such as curl:
curl -vik --resolve wechat.com:10444:127.0.0.1 https://wechat.com:10444
Alternatively, use this Go code snippet:
package main
import (
"crypto/tls"
"net"
)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:10444")
if err != nil {
panic(err)
}
tlsConn := tls.Client(conn, &tls.Config{
ServerName: "wechat.com",
})
err = tlsConn.Handshake()
if err != nil {
panic(err)
}
}
The TLS handshake should complete without errors.
Send a request through a SOCKS5 proxy to verify detection:
curl -x socks5://127.0.0.1:10080 http://www.example.com
If a TLS camouflage protocol is detected, Aparecium will output:
TLS camouflage connection detected
To resist detection, REALITY servers should mimic OpenSSL-based servers:
1. Delay sending NewSessionTicket messages until after receiving the ClientFinished message.
2. Actively probe the target server to capture NewSessionTicket message lengths.
3. Send fake, padded NewSessionTicket messages matching the target’s lengths.
The HMAC(PSK) tainting in ShadowTLS adds 4 bytes to handshake messages, making it highly detectable. To mitigate:
- Remove or modify the HMAC mechanism to avoid length discrepancies.
- Mimic OpenSSL’s post-handshake behavior by sending fake NewSessionTicket messages after ClientFinished.
ShadowTLS v3 is hereby declared "dead" due to its inherent design flaws. The HMAC(PSK) tainting adds 4 bytes to handshake messages (e.g., ServerFinished, resulting in 57 or 73 bytes instead of the standard 53 or 69 bytes), creating a glaring signature that tools like Aparecium easily detect.
Contributions are welcome! Please submit a pull request or open an issue on the GitHub repository.
This project is licensed under the MIT License.
$ claude mcp add aparecium \
-- python -m otcore.mcp_server <graph>