One of the earliest anti-DoS checks done after receiving and deserializing a headers message from a peer is verifying whether the proof-of-work is valid (called in method PeerManagerImpl::ProcessHeadersMessage):
https://github.com/bitcoin/bitcoin/blob/f227e153e80c8c50c30d76e1ac638d7206c7ff61/src/net_processing.cpp#L2752-L2762
The called method PeerManagerImpl::CheckHeadersPoW calls Misbehaving with a score of 100, i.e. leading to an immediate disconnect of the peer:
https://github.com/bitcoin/bitcoin/blob/f227e153e80c8c50c30d76e1ac638d7206c7ff61/src/net_processing.cpp#L2368-L2372
This PR adds a simple test for both the misbehaving log and the resulting disconnect. For creating a block header with invalid proof-of-work, we first create one that is accepted by the node (the difficulty field nBits is copied from the genesis block) and based on that the nonce is modified until we have block header hash prefix that is too high to fulfill even the minimum difficulty.