Consensys / teku

Open-source Ethereum consensus client written in Java
https://consensys.io/teku
Apache License 2.0
684 stars 290 forks source link

Teku replies to malformed RANDOM PACKETS #2648

Closed jrhea closed 4 years ago

jrhea commented 4 years ago

Description

Teku doesn't properly validate RANDOM PACKET before replying with WHOAREYOU. Per the discv5 protocol a RANDOM_PACKET is sent to initiate a handshake and the receiving node replies with WHOAREYOU. The RANDOM_PACKET should have the following layout:

tag -> 32 bytes auth-tag -> 12 bytes (RLP format) random_data -> 44+ bytes

There are two issues

1) Teku will reply to undersized RANDOM PACKETS.

The Discv5 rationale document specifically mentions that the RANDOM PACKET size should be > WHOAREYOU to ensure that an attack using the RANDOM PACKET format will require more bandwidth for the attacker. Teku will reply to RANDOM PACKETS as small as 46 bytes - in other words, the random_data field does not seem to be required in this implementation. 88 bytes + 2 bytes for RLP length prefix should be the minimum acceptable size.

2) Teku does not properly validate the RLP in the auth-tag field.

According to the RLP specification, this field should be prepended with 8c followed by 12 bytes. I opened a related issue in the web3j repo alluding to this problem here.

The following is screenshot showing Teku's reply to a malformed RANDOM PACKET that is undersized AND has invalid RLP encoding:

Invalid RANDOM PACKET: image

Teku's WHOAREYOU response: image

Steps to Reproduce

You can recreate the issue by using this command to send a malformed message to Teku:

> hping3 -d 46 --fast --udp -p [PORT] [IP]

jrhea commented 4 years ago

fyi, it sounds like there needs to be a discv5 spec change to address the issue with implementations responding to undersized RPs. See this discussion:

https://github.com/sigp/lighthouse/issues/1568#issuecomment-683414834

Nashatyrev commented 4 years ago

@jrhea

According to the RLP specification, this field should be prepended with 8c followed by 12 bytes. I opened a related issue in the web3j repo alluding to this problem here.

I believe this should be validated on discovery packet parsing level:

From pure RPL perspective almost any input is legit. I commented here: https://github.com/web3j/web3j/issues/1252#issuecomment-685881038

jrhea commented 4 years ago

I believe this should be validated on discovery packet parsing level:

Agreed - you have to look for 8c at the discovery level because the auth_tag is 12 bytes which is specific to the discovery domain. x8C - x80 = xC = 12

Anyways, i should have been more specific when explaining the issue (the web3j issue is sort of a separate topic).

From pure RPL perspective almost any input is legit. I commented here: web3j/web3j#1252 (comment)

~i'll reply to your comments on the web3j library after i remember why i chose those specific examples~. See my reply to your comment on the RLP issue:

https://github.com/web3j/web3j/issues/1252#issuecomment-685973695