I initially thought NBitcoin was a wrapper for Bitcoin Core JSON RPC and that Bitcoin Core was the only way to communicate with the bitcoin network. But now that I've discovered it's not, I'm curious to know how both communicate with the bitcoin network under the hood?
Bitcoin has a network protocol that all nodes use to communicate with each other. So long as a software can speak that protocol, it can join the network. Since Bitcoin Core is open source, the protocol details are freely available for anyone to see and implement themselves elsewhere. The protocol details are also described on bitcoin.org.