【问题标题】:How to detect the original MAC address after it has been spoofed?被欺骗后如何检测原始MAC地址?
【发布时间】:2012-03-21 17:16:11
【问题描述】:

我们正在使用以下代码来检索 windows pc 的活动 MAC 地址。

private static string macId()
{
    return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
}

private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
{
    string result = "";
    System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
    System.Management.ManagementObjectCollection moc = mc.GetInstances();
    foreach (System.Management.ManagementObject mo in moc)
    {
        if (mo[wmiMustBeTrue].ToString() == "True")
        {
            //Only get the first one
            if (result == "")
            {
                try
                {
                    result = mo[wmiProperty].ToString();
                    break;
                }
                catch
                {
                }
            }
        }
    }
    return result;
}
//Return a hardware identifier
private static string identifier(string wmiClass, string wmiProperty)
{
    string result = "";
    System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
    System.Management.ManagementObjectCollection moc = mc.GetInstances();
    foreach (System.Management.ManagementObject mo in moc)
    {
        //Only get the first one
        if (result == "")
        {
            try
            {
                result = mo[wmiProperty].ToString();
                break;
            }
            catch
            {
            }
        }
    }
    return result;
}

检索 MAC 地址可以正常工作。问题是当 MAC 地址被欺骗时,它会返回欺骗的 MAC 地址。我们想以某种方式检索在工厂分配的唯一的原始 MAC 地址。有什么办法吗?

【问题讨论】:

  • 欺骗 MAC 的全部目的是让计算机(及其上的软件)相信它是正确的 MAC。
  • @Joe,是的。我最初的问题是“真的有任何方法可以唯一地识别任何计算机”吗?我得到了一些建议,即 MAC 地址可以用作唯一标识符。这就引出了这个问题。
  • 这里有一些其他想法:stackoverflow.com/questions/671876/…
  • 你最坏的情况是什么?为什么担心 MAC 地址被更改的可能性?
  • 如果有人想尝试构建一个可行的解决方案,应该可以使用 IOCTL_NDIS_QUERY_GLOBAL_STATS 和 OID_FDDI_LONG_PERMANENT_ADDR 检索硬件 MAC。

标签: c# windows networking uniqueidentifier spoofing


【解决方案1】:

我想提供一个替代方案。我不知道它是否真的回答了“一种唯一识别任何计算机的方法”。
但是,此方法查询 System.Management 中的 Win32_BIOS 类并返回一个具有很高唯一性的字符串。 (等待被拒绝!!)

/// <summary>
/// BIOS IDentifier
/// </summary>
/// <returns></returns>
public static string BIOS_ID()
{
    return    GetFirstIdentifier("Win32_BIOS", "Manufacturer")
            + GetFirstIdentifier("Win32_BIOS", "SMBIOSBIOSVersion")
            + GetFirstIdentifier("Win32_BIOS", "IdentificationCode")
            + GetFirstIdentifier("Win32_BIOS", "SerialNumber")
            + GetFirstIdentifier("Win32_BIOS", "ReleaseDate")
            + GetFirstIdentifier("Win32_BIOS", "Version");
}

/// <summary>
/// ManagementClass used to read the first specific properties
/// </summary>
/// <param name="wmiClass">Object Class to query</param>
/// <param name="wmiProperty">Property to get info</param>
/// <returns></returns>
private static string GetFirstIdentifier(string wmiClass, string wmiProperty)
{
    string result = string.Empty;
    ManagementClass mc = new System.Management.ManagementClass(wmiClass);
    ManagementObjectCollection moc = mc.GetInstances();
    foreach (ManagementObject mo in moc)
    {
        //Only get the first one
        if (string.IsNullOrEmpty(result))
        {
            try
            {
                if (mo[wmiProperty] != null) result = mo[wmiProperty].ToString();
                break;
            }
            catch
            {
            }
        }
    }
    return result.Trim();
}

【讨论】:

  • 感谢您的替代方案,尽管我已经想到了。无论如何,我感谢任何合理的建议。没有什么可否认的。 :)
  • 这些参数可以在系统格式或全新的 Windows 安装上更改吗?
  • 我会说不,因为它们与 BIOS 中的数据相关联。但我没有测试过。
  • 唯一的问题是我们发现许多计算机的 BIOS 只是填充了默认字符串,通常甚至没有输入序列号。对于较小的无风扇盒子尤其如此,它们几乎不会在 BIOS 中填写任何细节。
  • 这是我的 PC BIOS 中的一个示例。 [系统] 制造商 = 由 O.E.M. 填写产品 = 由 O.E.M. 填充版本 = 由 OEM 填写SerialNum = 由 O.E.M. 填写
【解决方案2】:

可以有两种选择。

  1. 您可以使用之前提供的代码 sn-p 获取 MAC 地址,并检查该 MAC 地址是否属于任何 NIC(网络接口卡)。如果它不属于一个,那么这个MAC地址显然是被欺骗的。这是使用 MAC 地址定位 NIC 的代码

    using System.Net.Sockets;
    using System.Net;
    using System.Net.NetworkInformation;
    
    string localNicMac = "00:00:00:11:22:33".Replace(":", "-"); // Parse doesn't like colons
    
    var mac = PhysicalAddress.Parse(localNicMac);
    var localNic =
    NetworkInterface.GetAllNetworkInterfaces()
        .Where(nic => nic.GetPhysicalAddress().Equals(mac)) // Must use .Equals, not ==
        .SingleOrDefault();
    if (localNic == null)
    {
        throw new ArgumentException("Local NIC with the specified MAC could not be found.");
    }
    
    var ips =
        localNic.GetIPProperties().UnicastAddresses
        .Select(x => x.Address);
    
  2. 直接获取网卡地址。

    a. NWIF = dotnetClass "System.Net.NetworkInformation.NetworkInterface"  
    b. the_Mac_array = NWIF.GetAllNetworkInterfaces() -- this is an array of all the Networks  
    c. the_PhysicalAddress_Array = #()  
    d. for net in the_Mac_array where (net.NetworkInterfaceType.toString()) == "Ethernet" do append   the_PhysicalAddress_Array ((net.GetPhysicalAddress()).toString())  
    e. print the_PhysicalAddress_Array
    

((我在这里找到了http://snipplr.com/view/23006/))

【讨论】:

  • @Guvante,不,它没有。它将向您显示欺骗的 MAC 地址属于相应的 NIC。事实上,到目前为止,我使用的每一个代码都会检索当前的 MAC 地址,而不是工厂分配的原始 MAC 地址。
  • 你的答案没有用但是你是唯一一个试图给出这个问题的实际答案的人..所以我决定给你赏金.. :)
  • 我很抱歉。我应该提到我自己没有测试过代码。但是如果 MAC 被欺骗,我认为操作系统不会将它与 NIC 链接。操作系统中必须运行某种方法,将欺骗的 MAC 链接到 NIC,该 NIC 必须将原始 MAC 存储在某处。试图找到可能太复杂了。这是一篇关于 MAC 地址欺骗检测的精彩论文。 net-security.org/article.php?id=364 但我不确定它是否有助于检测系统中的欺骗 MAC 地址。 @拉赫曼。非常感谢。赏金非常感谢。 :)
  • @HUNKY_Monkey:可能有一种方法可以通过使用非标准 API 找到它,但至少每个 NIC 制造商都会改变,并且可能会改变每个 NIC 类型。
【解决方案3】:

不久前我不得不写一些类似的东西,因为我使用了一些硬件参数来“激活”我的软件。

看看DeviceIoControlOID_802_3_PERMANENT_ADDRESS。 它有很多互操作代码(我处理它的类大约是 200 行),但它让我得到了保证的硬件代码。

一些代码 sn-ps 让你开始,

private const uint IOCTL_NDIS_QUERY_GLOBAL_STATS = 0x170002;

[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool DeviceIoControl(
        SafeFileHandle hDevice,
        uint dwIoControlCode,
        ref int InBuffer,
        int nInBufferSize,
        byte[] OutBuffer,
        int nOutBufferSize,
        out int pBytesReturned,
        IntPtr lpOverlapped);

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern SafeFileHandle CreateFile(
    string lpFileName,
    EFileAccess dwDesiredAccess,
    EFileShare dwShareMode,
    IntPtr lpSecurityAttributes,
    ECreationDisposition dwCreationDisposition,
    EFileAttributes dwFlagsAndAttributes,
    IntPtr hTemplateFile);

[Flags]
internal enum EFileAccess : uint
{
    Delete = 0x10000,
    ReadControl = 0x20000,
    WriteDAC = 0x40000,
    WriteOwner = 0x80000,
    Synchronize = 0x100000,

    StandardRightsRequired = 0xF0000,
    StandardRightsRead = ReadControl,
    StandardRightsWrite = ReadControl,
    StandardRightsExecute = ReadControl,
    StandardRightsAll = 0x1F0000,
    SpecificRightsAll = 0xFFFF,

    AccessSystemSecurity = 0x1000000,       // AccessSystemAcl access type

    MaximumAllowed = 0x2000000,         // MaximumAllowed access type

    GenericRead = 0x80000000,
    GenericWrite = 0x40000000,
    GenericExecute = 0x20000000,
    GenericAll = 0x10000000
}

// Open a file handle to the interface
using (SafeFileHandle handle = FileInterop.CreateFile(deviceName,
    FileInterop.EFileAccess.GenericRead | FileInterop.EFileAccess.GenericWrite,
    0, IntPtr.Zero, FileInterop.ECreationDisposition.OpenExisting,
    0, IntPtr.Zero))
{
    int bytesReturned;
    // Set the OID to query the permanent address
    // http://msdn.microsoft.com/en-us/library/windows/hardware/ff569074(v=vs.85).aspx
    int OID_802_3_PERMANENT_ADDRESS = 0x01010101;

    // Array to capture the mac address
    var address = new byte[6];
    if (DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS,
        ref OID_802_3_PERMANENT_ADDRESS, sizeof(uint),
        address, 6, out bytesReturned, IntPtr.Zero))
    {
        // Attempt to parse the MAC address into a string
        // any exceptions will be passed onto the caller
        return BitConverter.ToString(address, 0, 6);
    }
}

【讨论】:

  • 这看起来很有希望。谢谢 :) 我会测试并告诉你。
  • @SajibMahmood 如果您遇到困难,请告诉我。在我的软件中,它在超过 250 种不同的计算机硬件上运行了超过 150,000 台机器。它总是捕获mac地址。不幸的是,使用 WMI 不会获得这样的成功率。
  • @SajibMahmood 是的,Windows XP 32 位,到 Windows 7 64 位已经过测试。
  • 那可能是我的错。出于某种原因,我仍然没有发现这个成功。但是,由于其他事情,我不能给它太多时间。让我再尝试一次。感谢您的合作。
  • 没有EFileShareECreationDispositionEFileAttributes 吗?
【解决方案4】:

好吧,我不会把所有的钱都押在 NetworkInterface 类列出 NetworkInterface 的顺序上。 我的主板有 2 个适配器,每次重启时顺序似乎都会切换。

所以这里有一个对我有用的建议(顺便说一句:学分可能要归功于另一个很棒的 stackoverflow 贡献者,ty):

    public static string GetMACAddress()
    {
        NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
        //for each j you can get the MAC 
        PhysicalAddress address = nics[0].GetPhysicalAddress();
        byte[] bytes = address.GetAddressBytes();

        string macAddress = "";

        for (int i = 0; i < bytes.Length; i++)
        {
            // Format the physical address in hexadecimal. 
            macAddress += bytes[i].ToString("X2");
            // Insert a hyphen after each byte, unless we are at the end of the address. 
            if (i != bytes.Length - 1)
            {
                macAddress += "-";
            }
        }

        return macAddress;
    }

【讨论】:

    猜你喜欢
    • 2017-11-21
    • 1970-01-01
    • 2019-02-24
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 2013-04-22
    相关资源
    最近更新 更多