Exported AppSketch/MAAT signature-object JSON shows named per-VPN detection rules combining multiple independent vectors: CyberGhost's WireGuard variant is matched by a hex UDP-payload pattern (04000000*), destination port 1337, and ip.proto=17 together (signature cyberghostvpn_wireguard); Windscribe's OpenVPN control channel is matched by two offset-anchored hex byte patterns plus an exact 86-byte payload length (windscribevpn_openvpn_payload); and ExpressVPN is matched independently via a literal JA3 hash (ssl.analysis.ja3), FQDN strings (expressapisv2.com, www.expressvpn.works), and a large enumerated IP list (700+ individual ip.dst entries observed before the 200KB text-extraction cutoff).
"signature_id": 4537, "signature_name": "cyberghostvpn_wireguard", "and_conditions": [ { "or_conditions": [ { "lua_profile_id": 0, "attribute_type": "string", "attribute_name": "udp.payload", "protocol": "udp", "string": { "patterns": [ { "keywords": "04000000*" } ], "expr_type": "simple", "format": "hexbin" } } ], "not_flag": 0 }, { "or_conditions": [ { "lua_profile_id": 0, "attribute_type": "numeric", "attribute_name": "dstport", "port": { "port": "1337" }, "protocol": "common" } ], "not_flag": 0 }
Defense implications
- WireGuard's default handshake type byte (04 00 00 00 for a handshake-initiation-response) plus its common default port choices are treated as an adequate fingerprint on their own — any Lantern transport built on stock WireGuard framing over a predictable port should assume it is trivially matchable without further obfuscation.
- AppSketch stacks JA3 + FQDN + IP-list signatures per app rather than relying on one vector; a defense that only randomizes TLS fingerprint (JA3) while keeping a stable server FQDN or a small static IP pool is still caught by the other two legs of the same rule set.
Related findings
Live TSG session logs from an internal test bed (device 21426003 / XXG-TSG-BJ) show active Deny actions firing against named commercial VPN apps -- Super Unlimited VPN, BetternetVPN, TouchVPN, LetsVPN -- via dated signature patches (e.g. BetternetVPN_Patch01_20240812 through Patch06_20240920, SuperUnlimitedVPN_Patch05 through Patch10 within six weeks), and LetsVPN's block fires on a JA3 TLS fingerprint (LetsVPN_by_ja3) even when the SNI/Host is spoofed to www.bytedance.com.
Beyond the Lantern-specific rules, this batch contains ~40 individually-dated JSON signature files from the same MAAT/AppSketch rule format, each targeting one named VPN/circumvention client by FQDN, destination IP, TLS JA3 hash, or certificate issuer: Signal, Orbot, Cloudflare WARP (including a MASQUE-specific variant combining an app_id classifier with an FQDN condition), ExpressVPN (matched by a literal JA3 hash plus a separate FQDN rule), ProtonVPN/ProtonMail, TurboVPN, QuarkVPN, LetsVPN, BetternetVPN, Browsec, GeckoVPN, HulaVPN, JumpJumpVPN, MouseVPN, NotVPN, SecureVPN, StarkVPNReloaded, SuperUnlimitedVPN, TowerVPN, TrustzoneVPN, USAVPN, VPNIndia/VPNLite/VPNPro/VPNTurkey, FlyVPN, ACE VPN, F1 Rockets VPN, and the Chinese gaming accelerator biubiu加速器. Dates cluster tightly (e.g. many on 2024-08-09, others 2024-09/10/11), indicating an active, continuously-updated per-app signature production pipeline rather than a static list.
A large set of individually-dated per-product signature files shows at least 31 distinct named commercial VPN apps under active, ongoing detection engineering (SecureVPN, LetsVPN, BetternetVPN, SuperUnlimitedVPN, TunnelBear, AtlasVPN, TurboVPN, UrbanVPN, GeckoVPN, VPNUnlimited, BitdefenderVPN, QuarkVPN, FlyVPN, HulaVPN, SurfVPN, BulletVPN, BeePassVPN, SnapVPN, WhitehatVPN, LunaVPN, SuperNetVPN, GitiVPN, CleanerAntivirusVPN, V2VPN/V2Netvpn, 7VPN, and country-branded VPNIndia/VPNCanada/VPNIndonesia/VPNKorea apps), each with multiple detection vectors per app (destination-IP ranges, FQDN, DNS QNAME, TLS cert issuer, JA3, WireGuard-protocol matching, ISAKMP/IKE matching, raw TCP payload); one file shows the resulting policy rule object wired directly to an explicit deny action.
Across dozens of individual signature-rule JSON files in this batch, at least 40 distinct named commercial VPN products carry dedicated detection signatures (by IP src/dst, FQDN, JA3 hash, or protocol-specific payload): BeePassVPN, BetternetVPN (separate isakmp/ja3/WireGuard sub- signatures), BigMamaVPN, BravePrivateVPN, ExpressVPN (JA3 + UDP-payload variants), FlyVPN, hidemevpn (OpenVPN UDP payload), JourneyVPN, JumpjumpVPN, LetsVPN (JA3), Psiphon3 ("psiphon3vpn_serverip"), QuarkVPN, SecureVPN, SuperUnlimitedVPN, TurboVPN, VPNHero, VPNTurkey, and others, each dated/versioned (e.g. "_20240812") indicating an ongoing signature-maintenance pipeline rather than a one-off ruleset.
Dozens of near-identical MAAT/AppSketch-style signature-definition files in this batch each target one named commercial VPN app/service (ProtonVPN, HotSpot VPN, SuperUnlimitedVPN, jumpjumpVPN, BetternetVPN, NotVPN, VPNLite, SymlexVPN, etc.), matched via FQDN suffix, destination IP list, and/or TLS JA3 hash. The same "SuperUnlimitedVPN" signature recurs with new signature_ids/dates roughly monthly (2024-06, -09, -10, -11), showing this is a continuously-maintained, actively-updated VPN-detection pipeline rather than a one-off snapshot.
Leaked per-app JSON signature-rule exports show the detection engine layers multiple independent signals per VPN product: Windscribe VPN is matched via fixed-offset hex-byte keywords inside the OpenVPN UDP handshake payload (offset 73/depth 78 and offset 81/depth 85); "Super Unlimited VPN" (the SuperUnlimitedVPN app) gets three parallel signatures — a JA3 TLS-fingerprint match, an FQDN match, and an OpenVPN c2s-payload-prefix/length match; Hide.me VPN is matched on OpenVPN UDP payload; FastVPN is matched purely by known source/destination IP; and "V2VPN" (Google Play com.v2ray.v2vpn, a V2Ray-based VPN app) has its own dedicated signature — evidencing a deliberately layered (protocol-fingerprint + TLS-fingerprint + FQDN + IP) detection strategy per circumvention product.