Get client Mac address

Recently, there is a need to obtain the MAC address of the client as the basis for whitelist verification. Use. net, B/S architecture. Baidu first found some ways to get the MAC address,

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Net;
using System.Configuration;
using System.Web;
using System.Security.Cryptography;
using System.Data;
using System.Web.UI.WebControls;
using System.Management;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;

namespace Qianxun.Common
{
    public class MacAddress
    {
        #region obtain mac Some methods of address
        #region 1 adopt IPConfig Command read MAC Address (optional)
        /// <summary>
        /// According to interception ipconfig /all Get the network card from the output stream of the command Mac
        /// </summary>
        /// <returns></returns>
        public static List<string> GetMacByIPConfig()
        {
            List<string> macs = new List<string>();
            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo("ipconfig", "/all");
                startInfo.UseShellExecute = false;
                startInfo.RedirectStandardInput = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError = true;
                startInfo.CreateNoWindow = true;
                Process p = Process.Start(startInfo);
                // Intercept output stream
                StreamReader reader = p.StandardOutput;
                string line = reader.ReadLine();

                while (!reader.EndOfStream)
                {
                    if (!string.IsNullOrEmpty(line))
                    {
                        line = line.Trim();

                        if (line.StartsWith("Physical Address") || line.StartsWith("Physical address"))
                        {
                            macs.Add(line.Substring(line.IndexOf(":") + 1, line.Length - line.IndexOf(":") - 1));
                            break;
                        }
                    }

                    line = reader.ReadLine();
                }

                // Wait for the program to finish executing and exit the process
                p.WaitForExit();
                p.Close();
                reader.Close();
            }
            catch (Exception ex) { 
            
            }
            return macs;
        }
        #endregion

        #region 2 adopt WMI read MAC address
        /// <summary>
        /// adopt WMI Read the network card in the system information MAC
        /// The method depends on WMI System service, which will not be closed generally; However, if the system service is missing or there is a problem, this method cannot be obtained MAC Address.
        /// </summary>
        /// <returns></returns>
        public static List<string> GetMacByWMI()
        {
            List<string> macs = new List<string>();
            try
            {
                string mac = "";
                ManagementClass mc = new ManagementClass(" Win32_NetworkAdapterConfiguration ");
                ManagementObjectCollection moc = mc.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    if ((bool)mo[" IPEnabled "])
                    {
                        mac = mo[" MacAddress "].ToString();
                        macs.Add(mac);
                    }
                }
                moc = null;
                mc = null;
            }
            catch(Exception ex)
            {
            }

            return macs;
        }
        #endregion

        #region 3 adopt NetworkInterface read MAC Address: 1) if the current network card is disabled (the hardware is in the hard off state), the address of the network card cannot be obtained MAC Address, (you can test by disabling the network card). 2) If multiple network cards are currently enabled, the first returned address is the information of the recently enabled network connection
        // Returns an object that describes the network interface on the local computer(Network interfaces are also called network adapters). 
        public static NetworkInterface[] NetCardInfo()
        {
            return NetworkInterface.GetAllNetworkInterfaces();
        }

        /// <summary>
        /// adopt NetworkInterface Read network card Mac
        /// </summary>
        /// <returns></returns>
        public static List<string> GetMacByNetworkInterface()
        {
            List<string> macs = new List<string>();
            try
            {
                NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
                foreach (NetworkInterface ni in interfaces)
                {
                    macs.Add(ni.GetPhysicalAddress().ToString());
                }
            }
            catch (Exception ex)
            { 
            
            }
            return macs;
        }
        #endregion
        #region 4 adopt SendARP read MAC address
        /// <summary>
        /// adopt SendARP Get network card Mac
        /// This method fails when the network is disabled or not connected to the network (e.g. no network cable is plugged in)
        /// </summary>
        /// <param name="remoteIP"></param>
        /// <returns></returns>
        public static string GetMacBySendARP(string remoteIP)
        {
            StringBuilder macAddress = new StringBuilder();

            try
            {
                Int32 remote = inet_addr(remoteIP);

                Int64 macInfo = new Int64();
                Int32 length = 6;
                SendARP(remote, 0, ref macInfo, ref length);

                string temp = Convert.ToString(macInfo, 16).PadLeft(12, '0').ToUpper();

                int x = 12;
                for (int i = 0; i < 6; i++)
                {
                    if (i == 5)
                    {
                        macAddress.Append(temp.Substring(x - 2, 2));
                    }
                    else
                    {
                        macAddress.Append(temp.Substring(x - 2, 2) + " - ");
                    }
                    x -= 2;
                }

                return macAddress.ToString();
            }
            catch
            {
                return macAddress.ToString();
            }
        }

        [DllImport(" Iphlpapi.dll ")]
        private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);
        [DllImport(" Ws2_32.dll ")]
        private static extern Int32 inet_addr(string ip);
        #endregion

        #region 5 Read from registry MAC address
        //Regular users can read the registry key Windows Genuine Advantage Get the physical network card address.
        //1)If the registry key is modified, it cannot be obtained MAC address
        //HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Genuine Advantage
        #endregion
        #endregion
    }
}

During the test, I suddenly found that the MAC addresses obtained by multiple clients are the same. I was surprised to obtain the MAC address of the server, and the server language obtains the MAC of the server. Then I need to obtain the client Mac, and I should use the client language. The first thing I think of is js (because I have encountered the problem of client ip and server ip, I can think of it clearly here). Baidu made a circle. The MAC address needs ActiveX script support,

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ie Browser get client Mac address</title>
</head>

<body>

    <object classid="CLSID:76A64158-CB41-11D1-8B02-00600806D9B6" id="locator" style="display: none; visibility: hidden"></object>
    <object classid="CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223" id="foo" style="display: none; visibility: hidden"></object>
    <form name="myForm">
        <br />
        MAC Address:<input type="text" name="macAddress">
    </form>
</body>
</html>

<script language="javascript">
    var sMacAddr = "";
    var sIPAddr = "";
    var sDNSName = "";
    var service = locator.ConnectServer();
    service.Security_.ImpersonationLevel = 3;
    service.InstancesOfAsync(foo, 'Win32_NetworkAdapterConfiguration');
</script>
<script for="foo" event="OnObjectReady(objObject,objAsyncContext)" language="JScript">
    if (objObject.IPEnabled != null && objObject.IPEnabled != "undefined" && objObject.IPEnabled == true) {
        if (objObject.IPEnabled && objObject.IPAddress(0) != null && objObject.IPAddress(0) != "undefined")
            sIPAddr = objObject.IPAddress(0);
        if (objObject.MACAddress != null && objObject.MACAddress != "undefined")
            sMacAddr = objObject.MACAddress;
        if (objObject.DNSHostName != null && objObject.DNSHostName != "undefined")
            sDNSName = objObject.DNSHostName;
    }
</script>

<script for="foo" event="OnCompleted(hResult,pErrorObject, pAsyncContext)" language="JScript">
    myForm.macAddress.value = sMacAddr;
</script>

<script>
    //Determine whether the browser supports ActiveX control
    //if (window.ActiveXObject) {
    //support-adopt ActiveXObject Create a new instance of XMLHttpRequest object
    var WshShell = new ActiveXObject("WScript.Shell");
    //}
    //else {
    //    $("#tips").html(" please use ie and add the domain name of the system to the trusted site, and open the relevant permissions of ActiveX plug-ins and scripts in the internet option - trusted site ");
    //}
</script>

This thing only supports ie, but the client system is not compatible with ie. if it needs to be adjusted and the workload is huge, it can only make other browsers such as chorme compatible with ActiveX.

1. First, find the chorme for ActiveX extension. After trying several versions, I still can't get the mac address. I don't know whether there is a problem with my usage or whether this method has failed. (chorme has been upgraded to the latest version 96.0.4664.45 (official version) (64 bit)).

2. After that, I found the IE Tab extension, but it seems that only an ie kernel is embedded in chorme, so the system is also incompatible.

3. Then I found the oil monkey and thought about writing a script to get the mac address and store it in a TXT text on Disk c, and then the system can read the txt file. However, the oil monkey wrote an alert ('hello world ') It didn't take effect. I don't know whether the use method was wrong or whether the relevant mechanism prevented this meaningless interruption. I think of another problem. If the back-end saves the file, it is actually saved to the server, and the back-end needs the client to upload the file. The client script doesn't have permission to operate the file and save it directly to TXT (it's a bit of a Trojan horse, but it doesn't involve this technology). So the scheme is put on hold for the time being.

4. Another plug-in PluginOK was found, but it was a paid plug-in. The principle should be that js called c + + to obtain computer physical information, and then integrated into the system through two-way communication. I felt that I was overqualified and didn't have so much budget, so I put it on hold and didn't measure it. This pain point made an enterprise.

The fundamental contradiction of the extraction problem: the mac address only supports ie acquisition, and the system is not compatible with ie, so it can only be divided into two steps. 1.ie obtains mac. 2. Log in to the system using chorme. A connection needs to be generated between 1 and 2 to pass the data obtained by 1 to 2. Considering the logic of last wechat code scanning login, the pre login mechanism is used, which is associated with the security order mechanism of blizzard Xu thought:

1. The login page creates a pre login record, stores it in the database, obtains the id, and splices it into a security order login url on the page

2. The user uses the url spliced in the previous step of ie login to obtain the mac address and store it in the corresponding database record according to the input parameter id (the user's ie needs to be configured first: 1.ie browser internet options - Security - trusted sites add the system domain name to the trusted sites 2. Also open the relevant permissions of ActiveX controls and plug-ins at the local customization level just now)

3. Return to the original login page and enter the account and password to log in. After normal logic login, match the mac address white list with the pre login id (mac address can be obtained from the database)

The curve saves the country, the safety order adds some interactive effects, and the detailed operation instructions are added everywhere, which can barely meet the requirements

Added by jeancharles on Wed, 01 Dec 2021 05:48:53 +0200