3

I'm using Windows 8.1 which doesn't have a tool (with a GUI) to manage wifi network profiles. So I'm writing one which will help me. I did some googling and found Managed Wifi API, and with the help of a tutorial I managed to put this code together:

foreach (WlanClient.WlanInterface wlanIface in client.Interfaces)
{
    foreach (Wlan.WlanProfileInfo profileInfo in wlanIface.GetProfiles())
    {
        string profileName = profileInfo.profileName;
        ListViewItem item = new ListViewItem(profileName);

        string profileXML = wlanIface.GetProfileXml(profileInfo.profileName);
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(profileXML);
        var NSManager = new XmlNamespaceManager(doc.NameTable);
        NSManager.AddNamespace("d", "http://www.microsoft.com/networking/WLAN/profile/v1");
        XmlNode node = doc.DocumentElement.SelectSingleNode("//d:WLANProfile/d:MSM/d:security/d:authEncryption/d:authentication", NSManager);

        item.SubItems.Add(node.InnerText);
        Profiles.Items.Add(item);
    }
}

Getting the list of saved network profiles and printing them on a ListView. I have two problems. One is how to get the full profile information using Managed Wifi API? Because the only thing I can get is the profile name. There is no documentation in the site.

The second problem is, since I can't get the full network information using the API, I used the API to print the profile info in XML format and then parse the XML and read it. An example XML:

<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
    <name>MEDO PUB</name>
    <SSIDConfig>
        <SSID>
            <hex>4D45444F20505542</hex>
            <name>MEDO PUB</name>
        </SSID>
    </SSIDConfig>
    <connectionType>ESS</connectionType>
    <connectionMode>manual</connectionMode>
    <MSM>
        <security>
            <authEncryption>
                <authentication>WPA2PSK</authentication>
                <encryption>AES</encryption>
                <useOneX>false</useOneX>
            </authEncryption>
            <sharedKey>
                <keyType>passPhrase</keyType>
                <protected>true</protected>
                <keyMaterial>someReallyLongStringLike500+chars</keyMaterial>
            </sharedKey>
        </security>
    </MSM>
</WLANProfile>

I need to get the wifi password but I think it is encrypted. How can I get the actual password or decode the encrypted password?


Update: I found two links: Exposing the WiFi Password Secrets and [C++] Dump wireless passwords but I'm not sure if they work, or rather how to implement them in C#.

akinuri
  • 10,690
  • 10
  • 65
  • 102
  • Forget about breaking the passwords. You can recursively add xml using code like on the following webpage : http://stackoverflow.com/questions/1596163/traverse-a-xml-using-recursive-function – jdweng Jun 28 '15 at 04:39
  • @jdweng I'm not sure what you mean. I'm not trying to read the XML values. I want to decrypt the crypted or "hashed" XML value which is the wifi password. – akinuri Jun 28 '15 at 23:49
  • It is a password and is designed not to be decrypted. – jdweng Jun 29 '15 at 02:28
  • @jdweng 3rd party applications can decrypt the passwords, e.g. [WinFi](http://main.kerkia.com/Products/WinFi/Download.aspx), or access it somehow. – akinuri Jun 29 '15 at 03:38
  • 1
    [Possible duplicate](http://stackoverflow.com/questions/10765860/decrypt-wep-wlan-profile-key-using-cryptunprotectdata) Also, "Windows 8.1 which doesn't have a tool to manage wifi network profiles" -- this statement is incorrect. You can do this with cmd tool netsh. Open up a cmd window as admin and type: `netsh wlan show profiles`, then to get the password from it: `netsh wlan show profile " key=clear` – alexcalibur Jul 01 '15 at 20:58
  • @alexcalibur Yea, normally I use the command line to do this. I meant a tool other than `netsh`, like with a GUI, e.g. like in Windows 7. Sorry if I wasn't being clear. And I'll check the questions you linked. I also want to do it without using Managed Wifi API. – akinuri Jul 02 '15 at 05:43

1 Answers1

7

As I mentioned in a comment, you can do this with

netsh wlan show profiles

then

netsh wlan show profile "<a profile from the last step>" key=clear

If you still want to do this in code, read on:

The managed WiFi API you are using doesn't have this function, but you can add it easily.

Modify the WlanProfileFlags enum in Interop.cs to this:

[Flags]
public enum WlanProfileFlags
{
    /// <remarks>
    /// The only option available on Windows XP SP2.
    /// </remarks>
    AllUser = 0,
    GroupPolicy = 1,
    User = 2,
    GetPlaintextKey = 4
}

Add this function to the WlanApi.cs file, probably near the GetProfileXml function (for organization's sake).

/// <summary>
/// Gets the profile's XML specification. Key is unencrypted.
/// </summary>
/// <param name="profileName">The name of the profile.</param>
/// <returns>The XML document.</returns>
public string GetProfileXmlUnencrypted(string profileName)
{
    IntPtr profileXmlPtr;
    Wlan.WlanProfileFlags flags = Wlan.WlanProfileFlags.GetPlaintextKey;
    Wlan.WlanAccess access;
    Wlan.ThrowIfError(
        Wlan.WlanGetProfile(client.clientHandle, info.interfaceGuid, profileName, IntPtr.Zero, out profileXmlPtr, out flags, out access));
    try
    {
        return Marshal.PtrToStringUni(profileXmlPtr);
    }
    finally
    {
        Wlan.WlanFreeMemory(profileXmlPtr);
    }
}

You can call this function to get the unencrypted key.

I haven't tested this but it should work. Let me know if you have any questions.

alexcalibur
  • 384
  • 1
  • 7
  • The code sample you provided is working fine. I have a question tho. How do you know about this? I tried to find documentation and tutorials about Managed Wifi API, but couldn't find any. Does it come from experience or is there some sort of source? I might need further help on this tool I'm building, so I'd like to know. – akinuri Jul 02 '15 at 05:54
  • I work with the native WiFi API all the time, so I just looked at what the managed one was doing and added the functionality that was missing. Here is the link to the relevant native function, [WlanGetProfile](https://msdn.microsoft.com/en-us/library/windows/desktop/ms706738(v=vs.85).aspx). Note that the fourth argument, pdwFlags, has a value WLAN_PROFILE_GET_PLAINTEXT_KEY. This corresponds to the 4 I added. – alexcalibur Jul 02 '15 at 06:10
  • Whoops, I meant the 6th argument. – alexcalibur Jul 02 '15 at 06:18
  • Since I have seen a lot of questions about this Managed WiFi API and it seems popular, I have just decided to clone it to github [here](https://github.com/jorgebv/windows-wifi-api). Right know it's just a carbon copy of the one on Codeplex, but if there is anything else you have trouble with, feel free to open an issue there and I will help out. – alexcalibur Jul 02 '15 at 07:01
  • I'm glad you did that, because I think I'll improve my tool, and definitely gonna need help :) – akinuri Jul 02 '15 at 07:36
  • @alexcalibur this works, thanks. two questions: 1) how can I list only the saved wlans identical to the result of `netsh wlan show profile`? 2) how can I access profile data directly with only given Profile/SSID name? I know, I could loop through all interfaces and all profiles - and if the name matches I have my desired profile. Is there a more direct way? Thanks – SUSiS Jan 09 '23 at 14:41