使用C++对物理网卡/虚拟网卡进行识别(包含内外网筛选)
程序员文章站
2022-05-16 12:45:26
简介 在Socket编程的时候,我们需要实时获取我们所需要的IP地址。例如在编写后门的时候,我们可能需要获得有效的外网IP或内网IP;有时候我们可能需要判断我们获取的是否是虚拟机网卡,这时候就需要对每一张网卡上的特征进行识别。以下笔者总结了一些常用的处理方法供大家参考。 参考资料: 1. "提取网卡 ......
简介
在socket编程的时候,我们需要实时获取我们所需要的ip地址。例如在编写后门的时候,我们可能需要获得有效的外网ip或内网ip;有时候我们可能需要判断我们获取的是否是虚拟机网卡,这时候就需要对每一张网卡上的特征进行识别。以下笔者总结了一些常用的处理方法供大家参考。
参考资料:1.
2.
c++代码样例
1. 头文件(包含特征处理函数)
///////////////////////////////////////// // // filename : netinfoproc.h // creator : peterz // date : 2018-6-21 23:50 // comment : 网卡信息筛选 // editor : visual studio 2017 // ///////////////////////////////////////// #pragma once #include <cstdio> #include <cstdlib> #include <iostream> #include <strsafe.h> #include <winsock2.h> #include <iphlpapi.h> #include <cstring> #pragma comment(lib,"iphlpapi.lib") using namespace std; #define reg_error -2 #define no_pci -1 #define is_pci 0 /** * @brief 查看字符串中是否有指定特征串 * @param source 指向源字符串的指针 * @param target 指向目标字符串的指针 */ bool isinstring(lpcstr source, lpcstr target) { if (source == null && target == null) { return false; } const size_t targetlength = strlen(target); const size_t sourcelength = strlen(source); if (sourcelength >= targetlength) { for (int i = 0; i < strlen(source); i++) { if (i + targetlength > sourcelength) { return false; } for (int j = 0; j < targetlength; j++) { if (*(source + i + j) != *(target + j)) { break; } if (j == targetlength - 1) { return true; } } } } return false; } /** * @brief 获取注册表数据 * @param hroot 根键 * @param szsubkey 子键 * @param szvaluename 数据项名 * @param szreginfo 数据 */ bool getreginfo(hkey hroot, lpctstr szsubkey, lpctstr szvaluename, lpstr szreginfo) { hkey hkey; dword dwtype = reg_sz; dword dwlendata = strlen(szreginfo); long lres = regcreatekeyex(hroot, szsubkey, 0, null, reg_option_non_volatile, key_all_access, null, &hkey, null); if (lres != error_success) { if (lres == 5) { printf("please use administrator privilege !\n"); } else { printf("get register info error! error code is "); printf("%ld\n", lres); } regclosekey(hkey); regclosekey(hroot); return false; } regqueryvalueex(hkey, szvaluename, 0, &dwtype, null, &dwlendata); lres = regqueryvalueex(hkey, szvaluename, 0, &dwtype, (lpbyte)szreginfo, &dwlendata); if (lres != error_success) { regclosekey(hkey); regclosekey(hroot); return false; } regclosekey(hkey); regclosekey(hroot); return true; } /** * @brief 验证注册信息是否是pci物理网卡(需要以管理员权限运行程序) * @param pipadapterinfo 指向网卡数据的指针 */ int ispcinetcard(const pip_adapter_info pipadapterinfo) { //通过注册表特征去除非物理网卡 char szregsubkey[255] = "system\\currentcontrolset\\control\\network\\{4d36e972-e325-11ce-bfc1-08002be10318}\\"; char sznetcardreginfo[255] = "\0"; stringcchcat(szregsubkey, sizeof(szregsubkey), pipadapterinfo->adaptername); stringcchcat(szregsubkey, sizeof(szregsubkey), "\\connection"); if (!getreginfo(hkey_local_machine, szregsubkey, "pnpinstanceid", sznetcardreginfo)) { return reg_error; } if (strncmp(sznetcardreginfo, "pci", 3) == 0) return is_pci; else return no_pci; } /** * @brief 验证是否是虚拟网卡 * @param pipadapterinfo 指向网卡数据的指针 */ bool isvirtualnetcard(const pip_adapter_info pipadapterinfo) { //去除有特征名的虚拟网卡 if (isinstring(strlwr(pipadapterinfo->description), "virtual")) return true; //去除有mac的虚拟网卡 vmware if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x05 && pipadapterinfo->address[2] == 0x69) return true; //去除有mac的虚拟网卡 vmware if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x0c && pipadapterinfo->address[2] == 0x29) return true; //去除有mac的虚拟网卡 vmware if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x50 && pipadapterinfo->address[2] == 0x56) return true; //去除有mac的虚拟网卡 vmware if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x1c && pipadapterinfo->address[2] == 0x14) return true; //去除有mac的虚拟网卡 parallels if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x1c && pipadapterinfo->address[2] == 0x42) return true; //去除有mac的虚拟网卡 microsoft virtual pc if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x03 && pipadapterinfo->address[2] == 0xff) return true; //去除有mac的虚拟网卡 virtual iron if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x0f && pipadapterinfo->address[2] == 0x4b) return true; //去除有mac的虚拟网卡 red hat xen , oracle vm , xen source, novell xen if (pipadapterinfo->address[0] == 0x00 && pipadapterinfo->address[1] == 0x16 && pipadapterinfo->address[2] == 0x3e) return true; //去除有mac的虚拟网卡 virtualbox if (pipadapterinfo->address[0] == 0x08 && pipadapterinfo->address[1] == 0x00 && pipadapterinfo->address[2] == 0x27) return true; return false; } /** * @brief 验证是否是0.0.0.0不可用ip * @param pipadapterinfo 指向网卡数据的指针 */ bool isinvalidip(const pip_adapter_info pipadapterinfo) { ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist); do { if (!strcmp(pipaddrstring->ipaddress.string, "0.0.0.0")) { return false; } if ((pipaddrstring = pipaddrstring->next) == null) { return true; } } while (pipaddrstring); return true; } /** * @brief 验证是否是内网ip * @param pipadapterinfo 指向网卡数据的指针 */ bool isintranetip(const pip_adapter_info pipadapterinfo) { ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist); do { if (strncmp(pipaddrstring->ipaddress.string, "10", 2) == 0 || (strncmp(pipaddrstring->ipaddress.string, "172.16", 6) > 0 && strncmp(pipaddrstring->ipaddress.string, "172.31", 6) < 0) || strncmp(pipaddrstring->ipaddress.string, "192.168", 7) == 0) { return true; } if ((pipaddrstring = pipaddrstring->next) == null) { return false; } } while (pipaddrstring); return true; }
2. cpp文件(代码应用演示)
///////////////////////////////////////// // // filename : netcardver.cpp // creator : peterz // date : 2018-6-21 23:50 // comment : 网卡信息筛选 // editor : visual studio 2017 // ///////////////////////////////////////// #include "netinfoproc.h" void output1(pip_adapter_info pipadapterinfo); //结果输出1(正常结果) void output2(pip_adapter_info pipadapterinfo); //结果输出2(删除虚拟网卡的结果) void output3(pip_adapter_info pipadapterinfo); //结果输出3(去除非pci物理网卡) >>需要以管理员权限运行程序<< void output4(pip_adapter_info pipadapterinfo); //结果输出4(筛选内网网卡) //主函数 int main(void) { pip_adapter_info pipadapterinfo = (pip_adapter_info)malloc(sizeof(ip_adapter_info)); unsigned long stsize = sizeof(ip_adapter_info); int nrel = getadaptersinfo(pipadapterinfo, &stsize); if (error_buffer_overflow == nrel/*getadaptersinfo参数传递的内存空间不足*/) { //free(pipadapterinfo); pipadapterinfo = (pip_adapter_info)realloc(pipadapterinfo, stsize); nrel = getadaptersinfo(pipadapterinfo, &stsize); } if (error_success == nrel) { printf(">>>>>>>>> 正常结果 <<<<<<<<<<<\n\n"); output1(pipadapterinfo); printf("\n\n>>>>>>>>> 删除虚拟网卡的结果 <<<<<<<<<\n\n"); output2(pipadapterinfo); printf("\n\n>>>>>>>>> 去除非pci物理网卡的结果 <<<<<<<<<\n\n"); output3(pipadapterinfo); printf("\n\n>>>>>>>>> 筛选内网网卡的结果 <<<<<<<<<\n\n"); output4(pipadapterinfo); } if (pipadapterinfo) { free(pipadapterinfo); } system("pause"); return 0; } //结果输出1(正常结果) void output1(pip_adapter_info pipadapterinfo) { //可能有多网卡,因此通过循环去判断 while (pipadapterinfo) { //输出信息 cout << "网卡名称:" << pipadapterinfo->adaptername << endl; cout << "网卡描述:" << pipadapterinfo->description << endl; cout << "网卡mac地址:" << pipadapterinfo->address; for (uint i = 0; i < pipadapterinfo->addresslength; i++) { if (i == pipadapterinfo->addresslength - 1) { printf("%02x\n", pipadapterinfo->address[i]); } else { printf("%02x-", pipadapterinfo->address[i]); } } cout << "网卡ip地址如下:" << endl; ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist); //可能网卡有多ip,因此通过循环去判断 do { cout << pipaddrstring->ipaddress.string << endl; pipaddrstring = pipaddrstring->next; } while (pipaddrstring); pipadapterinfo = pipadapterinfo->next; cout << "*****************************************************" << endl; } return; } //结果输出2(删除虚拟网卡的结果) void output2(pip_adapter_info pipadapterinfo) { //可能有多网卡,因此通过循环去判断 while (pipadapterinfo) { //去除虚拟网卡ip if (isvirtualnetcard(pipadapterinfo)) { pipadapterinfo = pipadapterinfo->next; continue; } //输出信息 cout << "网卡名称:" << pipadapterinfo->adaptername << endl; cout << "网卡描述:" << pipadapterinfo->description << endl; cout << "网卡mac地址:" << pipadapterinfo->address; for (uint i = 0; i < pipadapterinfo->addresslength; i++) { if (i == pipadapterinfo->addresslength - 1) { printf("%02x\n", pipadapterinfo->address[i]); } else { printf("%02x-", pipadapterinfo->address[i]); } } cout << "网卡ip地址如下:" << endl; ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist); //可能网卡有多ip,因此通过循环去判断 do { cout << pipaddrstring->ipaddress.string << endl; pipaddrstring = pipaddrstring->next; } while (pipaddrstring); pipadapterinfo = pipadapterinfo->next; cout << "*****************************************************" << endl; } return; } //结果输出3(去除非pci物理网卡) void output3(pip_adapter_info pipadapterinfo) { //可能有多网卡,因此通过循环去判断 while (pipadapterinfo) { //去除非pci物理网卡 if (ispcinetcard(pipadapterinfo) != is_pci) { if (ispcinetcard(pipadapterinfo) == reg_error) { printf("1\n"); return; } pipadapterinfo = pipadapterinfo->next; continue; } //输出信息 cout << "网卡名称:" << pipadapterinfo->adaptername << endl; cout << "网卡描述:" << pipadapterinfo->description << endl; cout << "网卡mac地址:" << pipadapterinfo->address; for (uint i = 0; i < pipadapterinfo->addresslength; i++) { if (i == pipadapterinfo->addresslength - 1) { printf("%02x\n", pipadapterinfo->address[i]); } else { printf("%02x-", pipadapterinfo->address[i]); } } cout << "网卡ip地址如下:" << endl; ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist); //可能网卡有多ip,因此通过循环去判断 do { cout << pipaddrstring->ipaddress.string << endl; pipaddrstring = pipaddrstring->next; } while (pipaddrstring); pipadapterinfo = pipadapterinfo->next; cout << "*****************************************************" << endl; } return; } //结果输出4(筛选内网网卡) void output4(pip_adapter_info pipadapterinfo) { //可能有多网卡,因此通过循环去判断 while (pipadapterinfo) { //筛选内网网卡 if (!isintranetip(pipadapterinfo)) { pipadapterinfo = pipadapterinfo->next; continue; } //输出信息 cout << "网卡名称:" << pipadapterinfo->adaptername << endl; cout << "网卡描述:" << pipadapterinfo->description << endl; cout << "网卡mac地址:" << pipadapterinfo->address; for (uint i = 0; i < pipadapterinfo->addresslength; i++) { if (i == pipadapterinfo->addresslength - 1) { printf("%02x\n", pipadapterinfo->address[i]); } else { printf("%02x-", pipadapterinfo->address[i]); } } cout << "网卡ip地址如下:" << endl; ip_addr_string *pipaddrstring = &(pipadapterinfo->ipaddresslist); //可能网卡有多ip,因此通过循环去判断 do { cout << pipaddrstring->ipaddress.string << endl; pipaddrstring = pipaddrstring->next; } while (pipaddrstring); pipadapterinfo = pipadapterinfo->next; cout << "*****************************************************" << endl; } return; }
上一篇: Maya怎么管理模型中的图层?