带有 Ubuntu Linux AMI 的 AWS EC2 作为攻击者 C2 服务器。
带有 Windows Server 2019 AMI 的 AWS EC2 作为受害者机器。
安装 Visual Studio 2022 社区的本地 Windows 10 计算机用于恶意软件开发和编译
本地 Kali Linux 攻击机。
Mimikatz
、Rubeus
、Certify
、PowerView
、BloodHound
等工具之所以受欢迎是有原因的:它们在单个包中实现了很多功能。这对恶意行为者非常有用,因为他们可以仅使用一些工具自动传播恶意软件。然而,这也意味着杀毒软件很容易通过注册其签名字节(例如,菜单字符串、C#
中的类/命名空间名称等)来关闭整个工具。
为了解决这个问题,也许不需要整个 2-5MB 的充满注册签名的工具来执行需要的一两个功能。例如,要转储登录密码/哈希值,可以利用带有 sekurlsa::logonpasswords
函数的整个 Mimikatz
项目,但也可以以完全不同的方式编写自己的 LSASS
转储器和解析器,但具有相似的行为和 API 调用。
对于第一个示例,使用Cracked5pider
的 LsaParser
。
对于第二个示例,假设目标是枚举整个 Active Directory
域中的共享。为此,可以使用 PowerView
的 Find-DomainShare
,但是,它是最著名的开源工具之一,因此,为了更加隐蔽,可以基于本机 Windows API
开发自己的共享查找器工具,如下所示。
//RemoteShareEnum.cpp#include <windows.h>#include <stdio.h>#include <lm.h>#pragma comment(lib, "Netapi32.lib")int wmain(DWORD argc, WCHAR* lpszArgv[]){ PSHARE_INFO_502 BufPtr, p; PSHARE_INFO_1 BufPtr2, p2; NET_API_STATUS res; LPTSTR lpszServer = NULL; DWORD er = 0, tr = 0, resume = 0, i,denied=0; switch (argc) { case 1: wprintf(L"Usage : RemoteShareEnum.exe <servername1> <servername2> <servernameX>\n"); return 1; default: break; } wprintf(L"\n Share\tPath\tDescription\tCurrent Users\tHost\n\n"); wprintf(L"-------------------------------------------------------------------------------------\n\n"); for (DWORD iter = 1; iter <= argc-1; iter++) { lpszServer = lpszArgv[iter]; do { res = NetShareEnum(lpszServer, 502, (LPBYTE*)&BufPtr, -1, &er, &tr, &resume); if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) { p = BufPtr; for (i = 1; i <= er; i++) { wprintf(L" % s\t % s\t % s\t % u\t % s\t\n", p->shi502_netname, p->shi502_path, p->shi502_remark, p->shi502_current_uses, lpszServer); p++; } NetApiBufferFree(BufPtr); } else if (res == ERROR_ACCESS_DENIED) { denied = 1; } else { wprintf(L"NetShareEnum() failed for server '%s'. Error code: % ld\n",lpszServer, res); } } while (res == ERROR_MORE_DATA); if (denied == 1) { do { res = NetShareEnum(lpszServer, 1, (LPBYTE*)&BufPtr2, -1, &er, &tr, &resume); if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) { p2 = BufPtr2; for (i = 1; i <= er; i++) { wprintf(L" % s\t % s\t % s\t\n", p2->shi1_netname, p2->shi1_remark, lpszServer); p2++; } NetApiBufferFree(BufPtr2); } else { wprintf(L"NetShareEnum() failed for server '%s'. Error code: % ld\n", lpszServer, res); } } while (res == ERROR_MORE_DATA); denied = 0; } wprintf(L"-------------------------------------------------------------------------------------\n\n"); } return 0;}
该工具利用 Win32 API
中的 NetShareEnum
函数远程检索从任何输入端点提供的共享。默认情况下,它会尝试特权 SHARE_INFO_502
访问级别,显示一些额外信息,如磁盘路径、连接数等。如果失败,它会回退到访问级别 SHARE_INFO_1
,它仅显示资源名称但可以枚举任何非特权用户(除非特定的 ACL 阻止它)。
现在,可以像下面这样使用它:
当然,自定义工具可能是一项非常耗时的任务,并且需要非常深入的 Windows
内部知识,但它有可能超越本系列中介绍的所有其他方法。因此,如果其他一切都失败了,应该考虑到这一点。也就是说,它对 Defender/AV 来过于牛逼了,它更适合 EDR 规避,因为可以控制并包括自己选择的 API 调用、断点、顺序、垃圾数据/指令、混淆等。