Don’t leak my WiFi key!
damiel · Follow
2 min read · Jul 4, 2023
Prevent unexpected disclosure of WPA credentials on Windows
A recent post on Günter Born’s blog (German version with comments, English
version) discussed the fact that you can display the WPA pre shared key of a
WLAN network stored in Windows in clear text using a command line like the
following (replace my-ssid with the SSID of the desired WLAN):
netsh wlan show profiles my-ssid key=clear
The facts in the article itself were rather unsurprising to me, as this works exactly
how you would expect it to work:
1. A user with administrative priviledges may view the WPA keys of all stored
WLAN profiles.
2. An unpriviledged user may view the WPA keys of the WLAN profiles created
by himself/herself.
Still, this caught my interest, as there are also ways to store WLAN profiles in
Windows without a logged in user. Two of them immediately came to my mind:
1. Manually connect to the wireless network from the lock screen before logging
on.
2. Automatically create the WLAN profile through a provisioning package
applied during the OOBE of a Windows installation (that’s done through the
Image Configuration Designer / ICD or “Set up school PC” apps).
To my big surprise, for both of these cases I was able to view the WPA key in clear
text with a standard (non-administrative) user. Ooops, didn’t expect that! What is
going on here?
The relevant security information seems to be stored in the registry, structured
by network interface and profile at the HKLM:
\Software\Microsoft\WlanSvc\Interfaces\*\Profiles\*\MetaData keys. There are two
values All User Profile Security Descriptor and CreatorSid that store a security
descriptor and a binary representation of the creator’s security identifier.
Looking at these values I noticed the SD is always the same in my test cases, so I
left this alone. The SID is set to the following value:
• S-1–5–18 (SYSTEM user) for profiles created on the lock screen
• S-1–1–0 (World/Everyone) for profiles created by OOBE applied provisioning
packages
• the user’s SID for profiles created by a logged on user
Based on these observations, I decided to fix this by changing all WLAN profiles
with CreatorSid values of S-1–5–18 or S-1–1–0 to the SID of an unused local
administrator. I came up with the following PowerShell script:
# create binary SID representation of the target user
$targetUserName = "localuser"
$targetSIDString = (New-Object System.Security.Principal.NTAccount($targetUserName)).T
$targetSID = [System.Security.Principal.SecurityIdentifier]::new($targetSIDString)
$targetBinarySID = [byte[]]::new($targetSID.BinaryLength)
$targetSID.GetBinaryForm($targetBinarySID, 0)
# enumerate the binary SIDs of the creators of all WLAN profiles
$creatorSIDs = Get-ItemProperty -Path "HKLM:\Software\Microsoft\WlanSvc\Interfaces\*\P
foreach ($creatorSID in $creatorSIDs) {
# convert the binary SID representation to text
$creatorSIDString = (New-Object -TypeName System.Security.Principal.SecurityIdenti
# OOBE provisioning package profiles have Everyone as the creator, lock screen pro
if (($creatorSIDString -eq "S-1-1-0") -or ($creatorSIDString -eq "S-1-5-18")) {
# change the creator to the target user
Set-ItemProperty -Path $creatorSID.PSPath -Name "CreatorSid" -Value $targetBin
}
}
I run this script as part of my home grown MDM, it works as intended for me. Of
course, I can’t guarantee what it will do to your systems.