Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A possible attack to detect AEAD algorithms #45

Closed
yvbbrjdr opened this issue Feb 13, 2017 · 20 comments
Closed

A possible attack to detect AEAD algorithms #45

yvbbrjdr opened this issue Feb 13, 2017 · 20 comments

Comments

@yvbbrjdr
Copy link

yvbbrjdr commented Feb 13, 2017

About the packet structure implementing AEAD algorithms mentioned in #30 , I have come up with a possible attack to detect it, using a kind of modified replay attack.

Cipher: chacha20-ietf-poly1305

TCP request (after encryption, *ciphertext*)
+--------+----------------+--------------+--------------+---------------+
| NONCE  | PayloadLen_TAG | *PayloadLen* | Payload_TAG  |   *Payload*   |
+--------+----------------+--------------+--------------+---------------+
|  12    |       16       |       2      |     16       |    Variable   |
+--------+----------------+--------------+--------------+---------------+

TCP Chunk (after encryption, *ciphertext*)
+--------------+------------+-----------+----------+
| DATA_LEN_TAG | *DATA_LEN* |  DATA_TAG |  *DATA*  |
+--------------+------------+-----------+----------+
|      16      |     2      |     16    | Variable |
+--------------+------------+-----------+----------+

As you can see from the protocol (idea originating @breakwa11 ) above, the server will detect something wrong only after 30 bytes, when the encrypted PayloadLen is transferred. Before 30 bytes are transferred, the server will simply wait for data to reach 30 bytes, and if the first 30 bytes are authenticated, the server will wait for further data. But if the first 30 bytes aren't authenticated, the server will close the connection immediately.
So here is the attack: when GFW gets a request packet, it can replay the first 30 bytes, and nothing will go wrong. But then, the wall modifies one of the bytes in the first 30 bytes and send it again, the server will close the connection. It is a very obvious pattern. Actually the wall can send the first 29 bytes first and see if the server is waiting; then it can modify the last byte and send it to see if the server closes immediately, or it can send random 29 bytes to the server and send the last 1 random byte to see if the server closes upon receiving the last byte.
Further more, the same pattern appears in TCP Chunks. The wall can replay correct TCP request first, and do the same thing on the first 18 bytes as mentioned in the last paragraph. So that the wall can be sure of the function of the server.
There are loads of more ways to detect AEADs, since fixed header decides same length of one packet, and the server will notice something wrong only after it reads all the bytes needed. Same attack method can also be used to test payload and data, not limited to length.

@riobard
Copy link
Contributor

riobard commented Feb 13, 2017

This is not a weakness of AEAD ciphers, but rather server implementation's behavioral characteristics.

It's trivial for the server to identify such probing attempts. Either add random delay before closing, or keep accepting more bytes till sender disconnects.

@Noisyfox
Copy link

Name an encrypted protocol that won't behave differently when the content is modified then I'll tell you how to solve this issue.

@Mygod
Copy link
Contributor

Mygod commented Feb 13, 2017 via email

@yvbbrjdr
Copy link
Author

yvbbrjdr commented Feb 14, 2017

@wongsyrone

我有个问题,你怎么从其他未知加密协议中区分出用了AEAD的SS的?如果区分不出来,随便发现流量就尝试一番吗?

I think unknown encryption protocols and connections only take up a little proportion of all protocols and connections. Most connections will use known and detectable protocols, such as HTTPS, SSH, IPSec, etc. So I think unknown encryption protocols themselves are patterns. Actually in this case, I think HTTPS is safer to be used to bypass the wall. Just do some tricks on the certification.

@yvbbrjdr
Copy link
Author

yvbbrjdr commented Feb 14, 2017

@Mygod

As I've mentioned before, server should null route the connection instead
of closing it when the incoming packets seem malicious.

Oh, I haven't thought of that. It's a great idea.

@Noisyfox
Copy link

Noisyfox commented Feb 14, 2017

检测到被修改的数据以后保持连接这个做法本身也是特征,一个正常的加密协议不会在明知数据被篡改的情况下依旧保持连接的(因为会占用服务器资源,理应尽早断开,当然如果你想伪装成自己装了个应用层防火墙的话... 那倒是也可以)。如果是避免被检测应该从obfs角度入手,伪装成常见流量。AEAD本身只是防篡改,并不是为了隐藏自己是个加密协议。

@yvbbrjdr
Copy link
Author

yvbbrjdr commented Feb 14, 2017

@Noisyfox @Mygod

检测到被修改的数据以后保持连接这个做法本身也是特征,一个正常的加密协议不会在明知数据被篡改的情况下依旧保持连接的(因为会占用服务器资源,理应尽早断开)。如果是避免被检测应该从obfs角度入手。AEAD本身只是防篡改,并不是为了隐藏自己是个加密协议。

So how to hide from being detected as well as being modified?

@yvbbrjdr yvbbrjdr reopened this Feb 14, 2017
@Noisyfox
Copy link

Noisyfox commented Feb 14, 2017

Either add random delay before closing

That's a possible solution. Or we could follow pattern of the protocol we are pretended to be, like HTTPS.

There may be some more costly ways, such as randomise the packet boundary (eg. the boundary of our chunk is not aligned with the tcp packet boundary) so the gfw won't be able to replay the tcp chunk (but with more delay and use more bandwidth).

@yvbbrjdr
Copy link
Author

I propose using AEAD public key cipher. For connection we generage a new key pair, so the wall will never be able to replay TCP Chunk.

@Noisyfox
Copy link

Then you need to pay extra attention to the packet pattern since you may need some sort of handshake which involves some fixed size packets right after the tcp connection is established.

@yvbbrjdr
Copy link
Author

Use non-fixed-length garbage data. And encrypt it to avoid modification.

@yvbbrjdr
Copy link
Author

I have written a protocol. I can show you later.

@yvbbrjdr
Copy link
Author

yvbbrjdr commented Feb 14, 2017

Anyway, I am going to release my pipesocks protocol here. It does not solve the problem mentioned in this issue. (about modified replay attack)

Header Structure

+-----+-------------------------+-------+-----+--------------------------------+-------+
| MAC | encrypted header length | nonce | MAC | encrypted garbage + public key | nonce |
+-----+-------------------------+-------+-----+--------------------------------+-------+
| 16  |            2            |  24   | 16  |       header length - 82       |  24   |
+-----+-------------------------+-------+-----+--------------------------------+-------+

Both are encrypted by secret key cryptography (XSalsa20). The secret key is password + 0x98 (filled to 32 bytes).
MAC is Poly1305.

Packet Structure

+-----+-------------------------+-------+-----+--------------------+-------+
| MAC | encrypted packet length | nonce | MAC |   encrypted data   | nonce |
+-----+-------------------------+-------+-----+--------------------+-------+
| 16  |            2            |  24   | 16  | packet length - 82 |  24   |
+-----+-------------------------+-------+-----+--------------------+-------+

Packet length is encrypted by secret key cryptography (XSalsa20). The secret key is password + 0x98 (filled to 32 bytes).
Data is encrypted by public key cryptography (XSalsa20).
MAC is Poly1305.

@shinku721
Copy link

Actually I have discussed this kind of attack in #30 .
For defending replay attacks, we have a thread #44 to discuss on it.

I do not think random padding could be a good idea since it must have certain statistical properties.

@yvbbrjdr
Copy link
Author

yvbbrjdr commented Feb 15, 2017 via email

@Mygod
Copy link
Contributor

Mygod commented Feb 15, 2017 via email

@yvbbrjdr
Copy link
Author

We should still use obfs, in my personal sense, give the server a fake HTTPS certification, and open the port on 443.

@yvbbrjdr
Copy link
Author

For normal HTTPS connections, return a fake website.

@shinku721
Copy link

@yvbbrjdr If GFW replays it immediately, we will discover the duplicate in the IV/salt cache.

@Mygod
A pattern of protocol A + An evidence that this is not real protocol A -> Shadowsocks
No pattern of any protocols -> Unknown service, maybe a shadowsocks
In the first case it is causality. In the second case it is probability.
However, of course it is better that we have plenty of plugins to make the diversity and the winner survives. It seems that they do not block unknown services out but do some QoS.

@Mygod
Copy link
Contributor

Mygod commented Feb 20, 2017

@shinku721 Theoretically it's always possible to detect if there is any suspicious payload in the underlying traffic. Our goal is to make it computationally more expensive. For example, active detection is more expensive than passive checking the packets going through. Stateful checks are more expensive than stateless checks. Also I still think ideally plugins should decide/design the behavior when a malicious packet is detected.

See also: steganography and steganalysis.

@Mygod Mygod closed this as completed Feb 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants