Several weaknesses were discovered in the V2Ray recently, which could be used to identify V2Ray clients or servers that run VMess, TLS or HTTP protocol. Below is our summary and understanding on these weaknesses.
In general, these weaknesses fall into three categories:
Authentication Credential is a HMAC associated with the
user ID and a
Command is encrypted using
AES-128-CFB(iv, key), where the
iv is the md5 hash value of the
UTC timestamp, and
key is the preshared one associated with
The following table shows the structure of
Command after decryption:
|Response Auth V
Encryption IV and the
Encryption Key are used to decrypt
Margin P and
Random Value are used as a padding scheme.
Margin P specifies the length of the
Random Value to be between 0 and 15 bytes.
serving as a MAC,
should be the FNV1a hash of all plaintext in
VMess authenticates each request in two steps,
Authentication Credential and
Unfortunately both of them can be circumvented.
the VMess server validates whether the timestamp in
Authentication Credential is expired.
The expiration time is 120 seconds at maximum and 60 seconds on average
(see here and here for implementation details).
That is to say,
an attacker can record and replay a legitimate
Authentication Credential within around 60 seconds to bypass this authentication.
aes-cfb used to encrypt the
Command does not provide any authentication,
a MAC-then-Encrypt mechanism is used.
As pointed out by @p4gefau1t,
VMess fell into the same pitfall as Shadowsocks OTA mode did (See the English summary on the weakness of Shadowsocks OTA mode here).
since the length of the
Random Value varies,
the server will not be able to know where the
Checksum F (MAC) is located,
unless it blindly trusts the value in
Margin P without any authentication (see here for implementation details).
In other words,
only after reading P+4 bytes,
V2Ray will be able to validate whether the decrypted content is legal.
If not legal,
the V2Ray server will close the connection.
VMess server indeed has a replay defense mechanism.
In particular, the server records the (
Encryption Key) of each request,
regardless of the validity of the requests;
and close the connection immediately when the (
Encryption Key) is seen before.
Depending on her needs, an attacker can:
Encryption IV or
Encryption Key) first time and more times.
Exploiting these weaknesses, many replay-based probes are creatively crafted to identify the VMess server. We introduce them below in separate sections.
The malicious probe is a replay of the legitimate request, with many bytes changed as follows:
|Malicious Incomplete Command
Malicious Incomplete Command includes:
|Response Auth V
In total, the attacker makes 16 connections to the server. In each connection, the attacker:
Encryption Key and the 4-bit
Margin P changed to a value different from the ones in other connections;
If the Ms recorded among 16 connections happen to be a list of non-repeated integers with the delta of max and min is 15, then it is very likely that the server runs VMess protocol.
The explanations of the attack are as follows:
the attacker replays an
Auth Info sent by the legitimate client in around 60 seconds.
the attacker uses a different value of the
Encryption Key in each connection.
the attacker carefully chooses the last byte of the
Encryption Key to alter.
This is because this byte happens to be within the same 16-byte cipher block as the
Margin P. (Note that,
the bit error propagation of
AES-128-CFB works as follows:
changing a bit in cipher block Ci, will change 1) the specific corresponding bit in plaintext block Pi; 2) as well as the Random bit errors in all subsequent blocks.)
Margin P in 16 connections.
Checksum before closing the connection due to checksum error.
the M measured here is actually
N-byte address + P-byte padding + 4-byte checksum.
Margin P from M because the
Paddings is the only field with varied length. (The length of the
Address is a fixed value,
because the address type is not changed.)
After the patches to defeat the probes above, @nametoolong found two more types of replay-based probes that can still detect the VMess servers. Both of them are related to how the server closes the connection. Below, we introduce the first of them, and we leave the explanations of the second attack as an exercise to reader.
@nametoolong described the probes and the behaviors of the server as follows:
Let M1 be the first 54 bytes of a valid session.
Let M2=M1. Tamper with M2 (i.e. alter the 49th byte of M2).
Replay M1. Connection is closed immediately.
Replay M2. Connection is not closed.
Replay M2 again. Connection is closed immediately.
The byte 48 (counting from 0) that got changed is the last byte of the
In this attack,
the attacker intentionally triggers the replay defense,
and expects the inconsistent behaviors of the servers when seeing the same (
Encryption Key) for the first time and for more times. The detailed explanations are as follows:
Encryption Key) in M1 is the same as the one in the legitimate connection,
the server will detect this replay attack and thus close the connection immediately.
it will bypass the replay defense.
The server thus waits for more bytes to come,
rather than close the connection.
Encryption Key) before,
the server will close the connection immediately.
The V2Ray has actually been patched so that it will close the connections after reading a random number of bytes within a certain range, or after waiting for a random amount of time within a certain range. However, this attack is possible because of the inconsistent usage of the draining methods when different types of errors happen.
@nametoolong thus suggested:
Drain the connection on all types of errors.
It still needs to be considered whether draining the connection itself is a attack vector.
Although we do not know whether the GFW uses active probing against VMess protocol, the attacks proposed above are feasible to the GFW. For example, it is observed that the GFW is capable of sending replay-based probes with no delay or arbitrarily long delay. We will investigate whether the GFW uses active probing against VMess protocol in the following work. At the same time, it will save us a lot of time if users can report which V2Ray servers were blocked when using what settings.
It may be a good idea to use a replay defense mechanism for the
auth info that is based on both
expiration time and
On one hand,
V2Ray uses a replay defense mechanism based on expiration time.
It will thus consider a replay sent within the expiration time as valid.
On the other hand,
Shadowsocks-libev uses a replay defense mechanism based on nonce.
But it requires the servers to remember these nonces forever until the key is changed.
This seems to be complicated to implement as it should even still remember the nonce after a reboot of the software.
a replay defense mechanism based on both
expiration time and
nonce may be a good choice.
Frolov et al. found that various popular circumvention tools, including obfs4, Shadowsocks Outline, Psiphon’s OSSH and Lantern’s Lampshade, can be identified using the TCP flags and timing information when the servers close the connections. Frolov et al. thus suggested that servers should “forever read” on errors, so that the probers will be the first to close the connection. This way, it not only reduces the information leaked by server’s timeout value, but also lets the server close the connection with FIN/ACK consistently (see Fig. 1 here for more details).
On May 30, 2020, @p4gefau1t reported V2Ray clients would send TLS ClientHello messages with very unique fingerprints. Such unique fingerprints not only gave a censor the opportunity to identify the V2Ray clients and servers, but also allowed a censor to accurately block the TLS traffic by V2Ray without much collateral damage.
@p4gefau1t further identified that these unique fingerprints were partially caused by the use of a hardcoded ciphersuite.
this rarely seen ciphersuite would be used,
AllowInsecureCiphers flag was its default value
V2Ray developer @xiaokangwang mitigated this weakness by using the default settings of go-tls library since
(see patches #2510, #2512, #2518).
@tomac4t summarized a form, comparing the ClientHello fingerprints before and after the patches using tlsfingerprint.io.
the fingerprints seem to be still quite unique.
To our best knowledge, as early as November, 2019, @klzgrad had already investigated the fingerprints of V2Ray v4.21.3 as well as many other TLS-based circumvention tools. The result shows most of them have rarely seen TLS ClientHello fingerprints.
Since the parrot is dead since 2013,
instead of reviving the parrot,
using a real HTTP engine may be a more promising solution here.
Many circumvention tools have been using the idea of
application fronting, which include forwardproxy,
naiveproxy and trojan.
All credit goes to the authors of the corresponding works.
We want to thank @studentmain and @p4gefau1t for helping us understand their proposed replay attacks, and for sharing their inspiring thoughts on the future works. We are also grateful to David Fifield and @studentmain for offering detailed feedback on a draft of this summary.
We will investigate whether the GFW uses active probing against VMess protocol in the following work. At the same time, it will save us a lot of time if you, as a user, can report which circumvention services were blocked when using what settings. We encourage you to share your comments publicly or privately. Our private contact information can be found at the footer of GFW Report.