设为首页收藏本站
查看: 747|回复: 0

[翻译]规避技术: 网络

[复制链接]
  • TA的每日心情
    开心
    2022-1-9 18:41
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2021-9-12 16:50:25 | 显示全部楼层 |阅读模式
    备注
    原文地址:https://evasions.checkpoint.com/techniques/network.html
    原文标题:Evasions: Network
    更新日期:2021年5月27日
    此文后期:根据自身所学进行内容扩充
    因自身技术有限,只能尽自身所能翻译国外技术文章,供大家学习,若有不当或可完善的地方,希望可以指出,用于共同完善这篇文章。


    目录
    • 所使用的网络检测方法
    • 1. 具体的网络属性
    • 1.1. 检查MAC地址是否是特定的
    • 1.2. 检查适配器名称是否是特定的
    • 1.3. 检查网络共享的提供者的名称是否是特定的
    • 2. 检查网络是否属于安全范围
    • 3. 基于NetValidateName结果的反伪装技术
    • 4. 基于Cuckoo ResultServer连接的反伪装技术
    • 识别标志:
    • 反制措施
    • 归功于

    网络检测方法
    这一组的规避技术与网络有着某种联系。要么使用与网络有关的功能,要么检查网络参数--如果它们与通常的主机操作系统不同,那么虚拟环境很可能被检测到。
    1. 具体的网络属性
    不同虚拟环境的供应商为他们的产品硬编码了一些值(MAC地址)和名称(网络适配器)--由于这一事实,这种环境可以通过检查适当对象的属性来检测。
    1.1. 检查MAC地址是否是特定的
    使用的函数:
    • GetAdaptersAddresses(AF_UNSPEC, ...)
    • GetAdaptersInfo

    代码样本(函数GetAdaptersAddresses):
    1. int pafish_check_mac_vendor(char * mac_vendor) {
    2.     unsigned long alist_size = 0, ret;
    3.     ret = GetAdaptersAddresses(AF_UNSPEC, 0, 0, 0, &alist_size);

    4.     if (ret == ERROR_BUFFER_OVERFLOW) {
    5.         IP_ADAPTER_ADDRESSES* palist = (IP_ADAPTER_ADDRESSES*)LocalAlloc(LMEM_ZEROINIT,alist_size);
    6.         void * palist_free = palist;

    7.         if (palist) {
    8.             GetAdaptersAddresses(AF_UNSPEC, 0, 0, palist, &alist_size);
    9.             char mac[6]={0};
    10.             while (palist){
    11.                 if (palist->PhysicalAddressLength == 0x6) {
    12.                     memcpy(mac, palist->PhysicalAddress, 0x6);
    13.                     if (!memcmp(mac_vendor, mac, 3)) {  /* First 3 bytes are the same */
    14.                         LocalFree(palist_free);
    15.                         return TRUE;
    16.                     }
    17.                 }
    18.                 palist = palist->Next;
    19.             }
    20.             LocalFree(palist_free);
    21.         }
    22.     }

    23.     return FALSE;
    24. }
    复制代码

    此代码样本的作者:pafish项目
    代码样本(函数etAdaptersInfo):
    1. BOOL check_mac_addr(TCHAR* szMac)
    2. {
    3.     BOOL bResult = FALSE;
    4.     PIP_ADAPTER_INFO pAdapterInfo;
    5.     ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
    6.     pAdapterInfo = (PIP_ADAPTER_INFO) MALLOC(sizeof(IP_ADAPTER_INFO));

    7.     if (pAdapterInfo == NULL)
    8.     {
    9.         _tprintf(_T("Error allocating memory needed to call GetAdaptersinfo.\n"));
    10.         return -1;
    11.     }

    12.     // Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable
    13.     if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
    14.     {
    15.         FREE(pAdapterInfo);
    16.         pAdapterInfo = (PIP_ADAPTER_INFO) MALLOC(ulOutBufLen);
    17.         if (pAdapterInfo == NULL) {
    18.             printf("Error allocating memory needed to call GetAdaptersinfo\n");
    19.             return 1;
    20.         }
    21.     }

    22.     // Now, we can call GetAdaptersInfo
    23.     if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_SUCCESS)
    24.     {
    25.         // Convert the given mac address to an array of multibyte chars so we can compare.
    26.         CHAR szMacMultiBytes [4];
    27.         for (int i = 0; i < 4; i++) {
    28.             szMacMultiBytes[i] = (CHAR)szMac[i];
    29.         }
    30.         while(pAdapterInfo)
    31.         {
    32.             if (pAdapterInfo->AddressLength == 6 && !memcmp(szMacMultiBytes, pAdapterInfo->Address, 3))
    33.             {
    34.                 bResult = TRUE;
    35.                 break;
    36.             }
    37.             pAdapterInfo = pAdapterInfo->Next;
    38.         }
    39.     }

    40.     return bResult;
    41. }
    复制代码

    此代码样本的作者:al-khaser项目
    检测表:
    检查MAC地址是否从以下值开始:
    检测
    MAC地址的开头是
    字节数
    Parallels
    00:1C:42
    \x00\x1C\x42
    VirtualBox
    08:00:27
    \x08\x00\x27
    VMware
    00:05:69
    \x00\x05\x69
    00:0C:29
    \x00\x0C\x29
    00:1C:14
    \x00\x1C\x14
    00:50:56
    \x00\x50\x56
    Xen
    00:16:E3
    \x00\x16\xE3

    1.2. 检查适配器名称是否是特定的
    使用的函数:
    • GetAdaptersAddresses(AF_UNSPEC, ...)
    • GetAdaptersInfo

    代码样本(函数GetAdaptersAddresses):
    1. int pafish_check_adapter_name(char * name) {
    2.     unsigned long alist_size = 0, ret;
    3.     wchar_t aux[1024];

    4.     mbstowcs(aux, name, sizeof(aux)-sizeof(aux[0]));
    5.     ret = GetAdaptersAddresses(AF_UNSPEC, 0, 0, 0, &alist_size);

    6.     if (ret == ERROR_BUFFER_OVERFLOW) {
    7.         IP_ADAPTER_ADDRESSES *palist = (IP_ADAPTER_ADDRESSES *)LocalAlloc(LMEM_ZEROINIT, alist_size);
    8.         void * palist_free = palist;
    9.         if (palist) {
    10.             if (GetAdaptersAddresses(AF_UNSPEC, 0, 0, palist, &alist_size) == ERROR_SUCCESS) {
    11.                 while (palist) {
    12.                     if (wcsstr(palist->Description, aux)) {
    13.                         LocalFree(palist_free);
    14.                         return TRUE;
    15.                     }
    16.                     palist = palist->Next;
    17.                 }
    18.             }
    19.             LocalFree(palist_free);
    20.         }
    21.     }

    22.     return FALSE;
    23. }
    复制代码

    此代码样本的作者:pafish项目
    代码样本(函数GetAdaptersInfo):
    1. BOOL check_adapter_name(TCHAR* szName)
    2. {
    3.     BOOL bResult = FALSE;
    4.     PIP_ADAPTER_INFO pAdapterInfo;
    5.     ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
    6.     pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(sizeof(IP_ADAPTER_INFO));

    7.     if (pAdapterInfo == NULL)
    8.     {
    9.         _tprintf(_T("Error allocating memory needed to call GetAdaptersinfo.\n"));
    10.         return -1;
    11.     }

    12.     // Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable
    13.     if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
    14.     {
    15.         FREE(pAdapterInfo);
    16.         pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(ulOutBufLen);
    17.         if (pAdapterInfo == NULL) {
    18.             printf("Error allocating memory needed to call GetAdaptersinfo\n");
    19.             return 1;
    20.         }
    21.     }

    22.     if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_SUCCESS)
    23.     {
    24.         while (pAdapterInfo)
    25.         {
    26.             if (StrCmpI(ascii_to_wide_str(pAdapterInfo->Description), szName) == 0)
    27.             {
    28.                 bResult = TRUE;
    29.                 break;
    30.             }
    31.             pAdapterInfo = pAdapterInfo->Next;
    32.         }
    33.     }

    34.     return bResult;
    35. }
    复制代码

    此代码样本的作者:al-khaser项目
    检测表:
    检查适配器的名称为:
    检测
    名称
    VMware
    Vmware

    1.3. 检查网络共享的提供者的名称是否是特定的
    使用的函数(见关于本地函数的注释):
    • WNetGetProviderName(WNNC_NET_RDR2SAMPLE, ...)

    代码样本:
    1. int vbox_network_share() {
    2.     unsigned long pnsize = 0x1000;
    3.     char provider[pnsize];

    4.     int retv = WNetGetProviderName(WNNC_NET_RDR2SAMPLE, provider, &pnsize);
    5.     if (retv == NO_ERROR) {
    6.         if (lstrcmpi(provider, "VirtualBox Shared Folders") == 0)
    7.             return TRUE;
    8.         else
    9.             return FALSE;
    10.     }

    11.     return FALSE;
    12. }
    复制代码

    此代码样本的作者:pafish项目
    检测表:
    检查网络共享的提供者名称如下:
    检测
    名称
    VirtualBox
    VirtualBox Shared Folders

    2. 检查网络是否属于安全范围
    恶意软件向https[:]//www.maxmind.com/geoip/v2.1/city/me 发出请求,这通常需要某种认证或API密钥。为了绕过这一要求,恶意软件通过将HTTP Referrer设置为https[:]//www.maxmind.com/en/locate-my-ip-address,将User-Agent设置为Mozilla/5.0(兼容;MSIE 10.0;Windows NT 6.1;Trident/6.0),使请求看起来像是来自该网站本身。这个技巧允许样本检索它所运行的机器的IP地址信息。

    响应以JSON格式返回,包含国家、城市的信息,最重要的是,与IP地址相关的组织。如果在响应中发现一些 "坏 "字符串,恶意软件就知道它是在某种安全边界/组织内启动的。
    实例

    恶意软件样本中的“包含恶意的字符串”(固定大小写):
    1. Amazon
    2. anonymous
    3. BitDefender
    4. BlackOakComputers
    5. Blue Coat
    6. BlueCoat
    7. Cisco
    8. cloud
    9. Data Center
    10. DataCenter
    11. DataCentre
    12. dedicated
    13. ESET, Spol
    14. FireEye
    15. ForcePoint
    16. Fortinet
    17. Hetzner
    18. hispeed.ch
    19. hosted
    20. Hosting
    21. Iron Port
    22. IronPort
    23. LeaseWeb
    24. MessageLabs
    25. Microsoft
    26. MimeCast
    27. NForce
    28. Ovh Sas
    29. Palo Alto
    30. ProofPoint
    31. Rackspace
    32. security
    33. Server
    34. Strong Technologies
    35. Trend Micro
    36. TrendMicro
    37. TrustWave
    38. VMVault
    39. Zscaler
    复制代码


    3. 基于NetValidateName结果的反伪装技术
    最初,这种技术是为绕过AV检测而设计的。它本身并不是一种规避技术--相反,而是在调用函数后滥用有趣的副作用。
    主要的想法是使用NetValidateName API函数调用的确定结果,将无效的参数作为服务器名称(例如 "123")来动态地计算跳转地址。这个跳转通常指向某些指令的中间,以绕过AV软件的启发式分析。但这种技术也有(至少)一个副作用。
    如果在操作系统中设置了默认的NetBIOS设置(NetBIOS over TCP/IP被启用),返回代码总是等于ERROR_BAD_NETPATH(0x35)。
    如果关闭了TCP/IP上的NetBIOS,那么返回代码是ERROR_NETWORK_UNREACHABLE(0x4CF)。
    因此,跳转地址将被错误地计算,这将导致样本崩溃。因此,这个技术可以用来破解沙盒中的伪装,在沙盒中,TCP/IP上的NetBIOS被关闭,以防止操作系统产生垃圾流量。
    注意:关闭TCP/IP上的NetBIOS是为了在通过DNS解析服务器IP时不产生额外的网络请求。关掉这个选项会取消本地网络的查询请求。
    代码样本 (函数GetAdaptersAddresses):
    1. void EntryPoint(void)
    2. {
    3.     HANDLE NetApi32 = LoadLibraryW(L"netapi32.dll");
    4.     TD_NetValidateName NetValidateName = (TD_NetValidateName)GetProcAddress(NetApi32, "NetValidateName");
    5.     DWORD Result = NetValidateName(L"123", L"", L"", L"", 1);

    6.     __asm
    7.     {
    8.         call dword ptr ds:[GetLastError]
    9.         add eax, offset TrueEntryPoint
    10.         sub eax, 0xCB  // ERROR_ENVVAR_NOT_FOUND
    11.         call eax
    12.     }
    13. }
    复制代码


    4. 基于Cuckoo ResultServer连接的反伪装技术
    这项技术可用于检测Cuckoo沙盒虚拟环境。恶意软件列举了所有已建立的出站TCP连接,并检查是否有连接到Cuckoo ResultServer使用的特定TCP端口(2042)。

    识别标志
    别标志对每种技术都是通用的:钩住使用的函数并跟踪它是否被调用。例如,很难说出应用程序为什么要获取适配器名称。这并不一定意味着应用规避技术。所以在这种情况下,最好的办法是拦截目标函数并跟踪其调用。
    反制措施
    • 与检查网络参数的对比:为虚拟环境更改;
    • 与检查安全周长相比:以适当的方式模拟网络响应;
    • 与NetValidateName基于结果的技术相比:通过TCP/IP打开NetBIOS;
    • 与基于Cuckoo ResultServer连接的技术相比:在Cuckoo配置中改变ResultServer端口。

    归功于
    归功于开源项目,代码样本取自该项目

    尽管Check Point工具InviZzzible已经实现了所有这些功能,但由于代码的模块化结构,需要更多的空间来展示这个工具的代码样本,以达到相同的目的。这就是为什么我们决定在整个百科全书中使用其他伟大的开源项目作为例子。
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    红盟社区--红客联盟 

    Processed in 0.060240 second(s), 24 queries.

    站点统计| 举报| Archiver| 手机版| 黑屋 |   

    备案号:冀ICP备20006029号-1 Powered by HUC © 2001-2021 Comsenz Inc.

    手机扫我进入移动触屏客户端

    关注我们可获取更多热点资讯

    Honor accompaniments. theme macfee

    快速回复 返回顶部 返回列表