When you connect to a Wi-Fi network and choose to save the credentials, they can be later fetched not only by Windows but by anyone who knows where and how to look for them.
When you connect to a Wifi network and choose to save the credentials, they can be later fetched not only by Windows but by anyone who knows where and how to look for them. We developed a small utility named GetWifiData for the purpose of displaying any stored Wifi data. We will maintain this tool and publish updates in a dedicated web site.
Purpose of the article
In the past (Windows XP), credentials were stored in the Registry, however since Windows 7, the credentials are stored in separate XML files. The Native Wi-fi also provides a centralised way to access the credentials, while Windows Cryptography provides the necessities to decrypt the encryption keys back. Several articles were published about Wifi credentials but some of them are outdated which is why I wrote this article and created the utility to display all stored Wifi credentials.
How Wifi Credentials are stored
When you connect to a Wifi network and choose to save the credentials, they can be later fetched not only by Windows but by anyone who knows where and how to look for them.
The location is different among different versions of Windows.
On Windows XP that place would be under the following Registry location:
Under each interface you can find separate files per each stored network.
Windows Native Wifi
The more recent Windows “Native Wifi” provides a better way to access the Wi-Fi credentials as it is the front end of any API call to automatically configure component configures, to connect or disconnect from / to a Wi-Fi network. Further, Windows Native Wifi can store profiles on the networks it interacts with in the form of XML documents.
The source code of this article uses a simple method to fetch each element from these XML files and to generate a report of all stored Wifi credentials.
As you can see in the photo above, the file holds the credentials of a Wifi network named Villa_Carriagehouse from a great B&B hotel in Indinapolis. We stayed there several months ago (great hotel, by the way) so the credentials are stored in my PC and can be fetched, as you can see.
Windows uses the WLAN_profile Schema to define each WLAN's profile using the following XML elements:
- SSID - Both plain text and HEX versions can be found and contain the SSID of a wireless LAN.
- name - The 'name' element is the SSID in the form of plan text.
- authentication - The 'authentication' element specifies the authentication method to be used.
- encryption - The 'encryption' element specifies the type of data encryption to be used.
- keyMaterial - The 'keyMaterial' element contains a network key or passphrase. If the protected element has a value of TRUE, then this key material is encrypted; otherwise, the key material is unencrypted. Encrypted key material is expressed in hexadecimal form.
How Wi-Fi credentials can be decrypted
When the Wi-Fi credentials are encrypted, they can be decrypted using Windows Cryptography. Microsoft cryptographic technologies include CryptoAPI, Cryptographic Service Providers (CSP), CryptoAPI Tools, CAPICOM, WinTrust, issuing and managing certificates, and developing customizable public key infrastructures.
First, we need to locate an element named keyMaterial and isolate it into a string variable (strKey).
Given strKey is a CString variable holding an encrypted Wi-Fi credential key (pass code), the following code block uses CryptUnprotectedData to decrypt it back.
As a result, strKey will hold now the decrypted password for the given Wi-Fi network.
Now, all we need to do is to go over each Wi-Fi / Network interface and per each interface go over each XML profile and fetch the Wi-Fi credentials of that profile, all into one report on screen and in a file.
To do so, here are some helper functions we use at Secured Globe, Inc.
Logging using WriteStatus()
We use logging for several purposes and in most cases we want to see anything important that happens, on a Console window (even with UI based applications) as well as in a text file (the 'log') which can be used later.
void WriteStatus(LPCTSTR lpText, ...)
FILE *fp; CTime Today = CTime::GetCurrentTime();
_wfopen_s(&fp, utilsLogFilename, L"a");
fwprintf(fp, L"%s", sLine);
Basically, instead of using printf (or wprintf) you just call WriteStatus with the same arguments.
The output of the GetWifiData program is generated using this function.
Ensuring Administration privileges
Such program requires Administrator privileges. That can be achieved first by forcing the user to elevate.
Go to the project's properties. Then go to Linker -> Manifest File -> UAC Execution Level, and set the value to
In addition, there is a way to detect the execution level during runtime. We use the following function:
DWORD dwSize = 0;
HANDLE hToken = NULL;
BOOL bReturn = FALSE;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
if (GetTokenInformation(hToken, TokenElevation, &tokenInformation,
bReturn = (BOOL)tokenInformation.TokenIsElevated;
Then you can warn the user in case the program isn't running "As Administrator" which isn't really needed given the project's settings described herein, but for the purpose of describing the IsElevated() function, I placed the following line in our source code:
Hide Copy Code
if (!IsElevated()) WriteStatus(L"[!] Running without administrative rights\n");
Displaying output using a fancy Console window
For the purpose of showing the program's output during runtime, without having to wait for the log file, we use the following functions and functionalities:
To get the Desktop measures for the purpose of resizing the console to fit the maximum size possible (larger size = more data to be displayed), we use the following function: