Trojan Wire Format

TLS Handshake

  • The client performs a normal TLS handshake first.
  • If the handshake fails, the server closes the connection like a regular HTTPS server.
  • Some implementations also return an nginx-like response to plain HTTP probes.

Initial Request

After TLS is established, the first application data packet is:

+-----------------------+---------+----------------+---------+----------+
| hex(SHA224(password)) |  CRLF   | Trojan Request |  CRLF   | Payload  |
+-----------------------+---------+----------------+---------+----------+
|          56           | 0x0D0A  |    Variable    | 0x0D0A  | Variable |
+-----------------------+---------+----------------+---------+----------+

Trojan Request

Trojan Request uses a SOCKS5-like format:

+-----+------+----------+----------+
| CMD | ATYP | DST.ADDR | DST.PORT |
+-----+------+----------+----------+
|  1  |  1   | Variable |    2     |
+-----+------+----------+----------+
  • CMD values: 0x01 CONNECT, 0x03 UDP ASSOCIATE.
  • ATYP values: 0x01 IPv4, 0x03 DOMAINNAME, 0x04 IPv6.
  • DST.ADDR is the destination address, DST.PORT is network byte order.
  • SOCKS5 field details: https://tools.ietf.org/html/rfc1928

UDP Associate Framing

When CMD is UDP ASSOCIATE, each UDP datagram is framed in the TLS stream as:

+------+----------+----------+--------+---------+----------+
| ATYP | DST.ADDR | DST.PORT | Length |  CRLF   | Payload  |
+------+----------+----------+--------+---------+----------+
|  1   | Variable |    2     |   2    | 0x0D0A  | Variable |
+------+----------+----------+--------+---------+----------+
  • Length is the payload size in network byte order.
  • Payload is the raw UDP datagram.

Notes

  • The first TLS record can include payload immediately after the request, reducing packet count and length patterns.
  • Clients often expose a local SOCKS5 proxy and translate local SOCKS5 requests into Trojan requests.