Zero Amplification

ZeroAccess is a peer-to-peer botnet (bots which can accept incoming connections act as servers and those that cannot act as workers). The p2p protocol is built on top of UDP and has a fairly significant size difference between the main request and response size, which is ideal for both reflection and amplification. Each bot send a 16-byte peer request via UDP to every supernode in its active list with the purpose of learning about new peers and files, if the supernode is online it responds with a UDP packet containing a 16-byte header, 16 peers and a list of available files. Each peer entry is 8 bytes and a file entry is 140 bytes (currently there are 2 files, so that brings the response to a total size of 424 bytes (almost 27 times larger than the request).

Using a server which allows source address spoofing, we can send a peer request packet to each supernode with the source IP spoofed to the IP of the system we wish to attack, resulting in each supernode “replying” with a 424 byte packet to the victim’s IP address. Assuming we have a sever that can output at 1gb/s, the target will receive up to 26.5 gb/s worth of packets from various supernodes (though it will vary depending on how busy the supernodes are and their throughput).

Unfortunately, there’s nowhere near as many supernodes as there are bots, due to something called NAT (Network Address Translation).

NAT

The idea behind NAT is to allow multiple computer to share the same public IP address (I’ll give a brief and oversimplified explanation of how this works). Above is an example of a very simple network consisting of 3 computers connected to a router. All of the computers access the internet using the public IP address 123.123.123.123, but on a network level none of them are aware of this. What actually happens is each device is assigned its own private IP address (10.0.0.x), and it’s the router which holds the public IP address (123.123.123.123). When a device (ex: 10.0.0.2) send a UDP packet to a host (ex: 8.8.8.8 on port 53), the packet is sent to the router (10.0.0.1) which stores some information in the NAT table (most importantly the source and destination IP + port), then replaces the source IP (10.0.0.2) with the public IP (123.123.123.123) so that the destination (8.8.8.8) will reply to 123.123.123.123 instead of 10.0.0.2 which is not a valid public IP address. When 8.8.8.8 sends back a reply, it gets sent to the router (123.123.123.123) which then looks up the source IP (8.8.8.8) and source port (53) in the NAT table; because 10.0.0.2 originally sent a packet to 8.8.8.8 on port 53 there will be a match and the router will know to replace the destination IP (123.123.123.123) with the original source IP (10.0.0.2) and forward it to said device. Assuming port forwarding is not enabled, when the router receives and incoming packet which does not match an entry in the NAT table (i.e. none of the devices have recently sent a packet to that IP and port) it is dropped; this is why devices behind NAT can communicate using connectionless protocols such as UDP, but cannot act as a UDP server. It’s also important to note that NAT entries do not last forever, most routers will remove an entry after a period of about two minutes where no packets have been sent between the source and destination.

Theoretical Way to leverage worker bots during the attack

Even though worker bots can’t act as supernodes because they’re behind NAT, they still operate using the same code as that of the supernodes—That is, they bind a specific UDP port which they will send and received requests from. Due to this, when a supernode receives a peer request from a bot behind NAT, it can reply with a peer request and the worker bot will send a response (because they are running the same code supernodes do). Obviously because we’re spoofing peer requests from the victims IP address, in order for the packets to punch through the worker bot’s NAT we need the bot to have recently sent a packet to the victim, we also need to know the source and destination port (as the NAT router will still drop the packets if the source and destination ports don’t match the ones in the NAT table). If we go back to what I said earlier, the workers are running the supernode code (which binds a single port for all requests and responses), so all UDP packets are set from the same source port (we can acquire every worker bot’s source port by running our own supernode and letting them connect to us). Now all we need is to get the worker to send a packet to the victim on a port of our choosing, giving us everything we need to punch through NAT). So how exactly do we get the worker bot to connect to an arbitrary IP address? With the peer list of course. Theoretically we could add the victims IP and any port of our choosing to the peer list, resulting in all worker bots attempting to send peer requests to it (opening up NAT to replies from that IP and port combination). Once we know a peer request has been sent to the victim we can spoof a peer request back resulting in the worker bot sending the 424 byte response (All supernodes are contacted in order of newest to oldest every 40 minutes, so once our supernode receives a peer request from a worker bot, we know it has already sent one to the victim). All that’s left to do now is start flooding the worker bots with spoofed peer requests from the victims IP and port which we put in the peer list. Conclusion The laws when it comes to DDoSing something (even with full permission from the victim) are incredibly grey and made even more so by the fact we’d be using other people’s computer to relay the attack. As it happens I’m quite picky when it comes to food, making prison likely a less than enjoyable experience, so here’s a graph of what this attack may look like if I were to do it.

While I was reverse engineering ZeroAccess in order to write a monitoring system, I had an idea which would allow me to use ZeroAccess C&C infrastructure to reflect and amplify a UDP based DDoS attack, which I’d found to be beautifully ironic. After further analysis, I discovered it may even be possible to use non worker bots (which connect from behind NAT) to participate in the attack.