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 22.214.171.124, 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 (126.96.36.199).
When a device (ex: 10.0.0.2) send a UDP packet to a host (ex: 188.8.131.52 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 (184.108.40.206) so that the destination (220.127.116.11) will reply to 18.104.22.168 instead of 10.0.0.2 which is not a valid public IP address.
When 22.214.171.124 sends back a reply, it gets sent to the router (126.96.36.199) which then looks up the source IP (188.8.131.52) and source port (53) in the NAT table; because 10.0.0.2 originally sent a packet to 184.108.40.206 on port 53 there will be a match and the router will know to replace the destination IP (220.127.116.11) 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
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.