In an earlier article, I already outlined why it is important to always validate server certificates when using PEAP together with MS-CHAP. This article is going to deal with the mysterious option of Windows called “Connect to these servers” when it comes to hardening your PEAP configuration.
The unlucky name
Actually checking the hostname implies something like “I will connect to this specific server”. But that is not really true.
PEAP has the ability to check the server certificate right before performing the authorization to avoid sending user credentials to a rogue access point. At this state, the computer is connected to the wireless access point which forwards the later authentication to the radius server. However the client is never talking directly to the radius server.
Instead the client checks the common name of the provided certificate for this hostname which might be the hostname of the radius server. But as a radius certificate might have been copied to any other server without any obvious implications, this might not be the case. That’s why a description like Common Name would be a better choice as it would imply what is checked.
The up and downsides of public CAs
Using a public CA puts you into risk that your network is attacked by a third party owning another certificate issued by this CA. If you’d just check the CA, your check would be absolutely useless as an attacker can easily retrieve your radius servers public key and determine the CA. For example iOS devices will display the public key by default on first connect and thus also the issuing CA.
In this example I issued a Let’s Encrypt Certificate for srv0906.admin.local.meis.space. I configured DST Root CA X3 as the only trusted CA. Running the legitimate radius server using this certificate shows, my client is connecting and sending it’s credentials.
Next I was going to play the bad guy using hostapd-wpe. I used my second domain to issue a similar certificate for the awkward looking domain srv0906.admin.local.meis.space.smartnoob.de. At this point the name doesn’t really matter but I will use this in the next paragraph.
As expected my client started to check the CA and sent it’s login credentials as the CA criteria was fulfilled.
Now we know why using public CAs is dangerous and results in serious security implicationson with most clients. But on the other hand we have an easier deployment as public CAs come already pre-installed with Windows. Additionally Windows offers an uncommon option called “Connect to these servers” which most clients like Network Manager, Android or iOS don’t offer.
Checking the common name
The input field offers two modes which aren’t explained in Windows 7. The same option on Windows 10 devices shows the following example:
Obviously you can enter multiple server names separated by semicolons. This way you can validate against multiple redundant servers. The third entry shows that we can use regular expressions as well.
Using server names seems to be perfectly safe on Windows 7 and Windows 10. Chcking for srv0906.admin.local.meis.space results in an error in case of an attack and protects the user credentials. Now it seems we can use public CAs without any doubts.
Using regular expressions might put your networks security into danger and enable an attacker to bypass all your efforts.
As soon as you use at least a single asterisk, Windows will change into regex mode and will check the common name using the given expression.
According to the example I created my own regular expression:
This will ensure, that I can change the radius server inside my server network at any time without reconfiguring the clients. According to the example this should be secure, at least if we rely on the example. However this example is dangerous.
Next I started some evaluation of the regex I’ve written and started to wonder if I had created a serious security hole. Do you remember the domain mentioned above?
It contains the full common name our regular expression is checking for. But I created it as a subdomain for my second domain smartnoob.de. This simulates an attacker who doesn’t have access to your real domain or the private key for the real certificate but can issue a certificate for any other domain he owns. Owning a certificate I started hostapd-wpe again. It resulted into this:
My credentials have been leaked, even if I followed the example and made serious attempts to protect my clients.
Why does it happen?
Evaluation the regular expression on the given common name results in the following match:
Windows doesn’t check if the regular expression matches the common name from first to last character. Instead Windows checks if regular expression finds something within the common name matching the criteria. If true, the authentication process will be started.
It is easy to mitigate the attack. By forcing the regular expression to check for the end of line, we will make it impossible to append a third party domain.
Now we are save from certificates with common names containing a third party domain. However the issue has been caused by a lack of documentation and most admins don’t worry about this. This example has been taken from a production environment and could be exploited in the past.
Microsoft is encouraged to add the missing $ to the example and warn administrators about the issue to prevent this attack. Another option would be to check always for the full common name as there doesn’t seem to be a legit reason for wildcarding the TLD or SLD. However there remains the danger of breaking working setups and the option would loose it’s full regex compatibility. Microsoft has been informed about the issue but did not react withing 90 days.