Getting Wi-Fi profile information
Asked Answered
D

1

5

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#.

Dutra answered 27/6, 2015 at 23:24 Comment(6)
Forget about breaking the passwords. You can recursively add xml using code like on the following webpage : #1596663Maidstone
@Maidstone 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.Dutra
It is a password and is designed not to be decrypted.Maidstone
@Maidstone 3rd party applications can decrypt the passwords, e.g. WinFi, or access it somehow.Dutra
Possible duplicate 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 "<a profile from the last step> key=clearMesomorphic
@Mesomorphic 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.Dutra
M
8

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.

Mesomorphic answered 1/7, 2015 at 21:31 Comment(6)
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.Dutra
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. Note that the fourth argument, pdwFlags, has a value WLAN_PROFILE_GET_PLAINTEXT_KEY. This corresponds to the 4 I added.Mesomorphic
Whoops, I meant the 6th argument.Mesomorphic
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. 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.Mesomorphic
I'm glad you did that, because I think I'll improve my tool, and definitely gonna need help :)Dutra
@Mesomorphic 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? ThanksJulide

© 2022 - 2024 — McMap. All rights reserved.