随着全球远程办公的常态化,路由器等家庭数码设备正在成为黑客的重点攻击对象。在2020年举行的Pwn2Own大赛上,参赛的漏洞赏金猎人们在第一天就成功入侵了NETGEAR路由器。在活动的第一天,高端路由器Nighthawk R7800受到了包括Black Coffee团队、Flashback团队以及网络安全公司Starlabs和Trapa Security团队的围攻。
其实NETGEAR路由器出现漏洞已是家常便饭了,自2016年开始,PSV-2019-0076就开始影响Nighthawk X4S Smart Wi-Fi Router(R7800),2020年初,一个超危远程代码执行漏洞影响了运行1.0.2.68之前版本固件的Netgear Wireless AC Router Nighthawk(R7800),未经身份认证的攻击者可利用该漏洞控制路由器。
MDSec的渗透测试工具会经常对NETGEAR路由器的运行环境进行安全测试,在这些环境中,通常需要相当程度的内存和开发后操作安全来抵消可能存在的防御控制。在渗透测试中,MDSec的研究人员发现了可用的c2工具,无论是开源的还是现成的,都存在着被攻击的风险。
创建 Nighthawk 时的关键设计决策之一是使信标尽可能可定制和可扩展。为此,我们选择使用 HTTP API 构建管理界面,这背后的基本原理是操作员控制台操作将从实际的信标管理中抽象出来,因此可以使用脚本内置自动化和可扩展性,与用户界面分离。
一个典型的使用Nighthawk操作的渗透测试基础设施部署可能看起来如下,其中黄色区域包含API管理服务器(操作员通过UI与之交互)和n个C2服务器,可以部署这些服务器以支持多个配置文件配置:
Nighthawk支持用于出口和 SMB 命名管道的 HTTP(S) 和用于点对点 c2 的 TCP(稍后会详细介绍)。但是,传输机制是从 c2 中抽象出来的,并且支持同一信标内的多个自定义传输,这意味着 c2 网络中的每个链接都可以完全自定义以使用独特的协议。这一概念为运营商提供了独特的优势,因为这意味着不仅可以通过将 c2 流量与合法网络通信混合,而且还可以避免在每个 p2p 链路上重复使用相同的传输,从而使 c2 变得更加复杂,从而减少网络层的危害指标去寻找。
这里有注入到teams.exe进程中的信标的一个简单示例,并通过Microsoft Teams通道进行出口通信。更极端的是,甚至可以自定义 Nighthawk,使其可以绕过气隙,例如通过使用 USB 作为攻击媒介。
原生 HTTP(S) c2 传输也非常灵活和可扩展,为运营商提供对请求和响应的完全控制,并支持多个 URI、信标主机和重试计数。管理 c2 请求和响应的逻辑使用正则表达式进行模式匹配,这意味着只要正则表达式匹配,就可以以操作员选择的任何方式混合 c2 通信。例如,可以将任务请求/响应嵌入到图像的元数据或 JavaScript 块中发送。由于我们的 c2 服务器支持从可塑性配置文件中执行任意 python,所以c2 可以轻松扩展到多层混淆、加密、随机或智能。
原生 HTTP(S) 也可以在离开信标时通过使用 .NET 自定义编码器进行编码,这允许运营商以编程方式改变 c2 流量以与经典网络流量融合。这是一个简单的示例,我们对c2进行“Hot Swap”,并将流量转换为意大利语。
总体而言,Nighthawk 的架构和设计为运营商提供了极大的灵活性,以实现自动化并将信标扩展到其默认功能集之外。
操作安全
Nighthawk 是用 C++ 开发的,作为反射 DLL 提供,可以导出到许多不同的工件中,包括用于与其他工具集成的压缩 shellcode。 Nighthawk 使用的反射加载器是一个自定义实现,可以选择性地配置为使用直接系统调用或原生 API;用于此的引导代码当然会在执行后被清除。
Nighthawk 信标是多线程的,这意味着任务将同步执行,并且还可以通过 UI 进行批处理。信标根据配置的概要文件欺骗其线程的起始地址和堆栈,使它们在休眠时在内存中更容易被找到,并且不会影响其他 c2 的 IoC,例如源自虚拟内存的线程。此外,由于 MDSec 的研发,所有线程创建都包含多种技术来混淆通过内核回调和 EtwTi 获得的 EDR追踪分析。
Nighthawk 会周期性地内联睡眠时间和抖动,然后醒来接收任务。当信标处于休眠状态时,反射DLL在内存中保持完全加密,这可以在不暂停进程中的所有线程的情况下实现,这意味着我们能够在被注入的进程中平稳地操作,而不会中断用户体验。此外,自我加密过程是完全可配置的操作符,可以使用多种策略进行自我解密,所有这些策略都可以以 OpSec 安全的方式执行,以避免被许多内存扫描器和搜索工具搜索到 IoC,包括公开可用的如 pe-sieve 和 Moneta。
许多 c2的问题是通过内存获取泄漏或在内存扫描期间识别的数据。为了解决这个问题,除了在睡眠时加密 Nighthawk反射 DLL 之外,Nighthawk 还提供了一个相对独特的功能,允许操作员加密放置在堆上的数据。为此,我们提供两种操作模式; “植入”或“处理”堆加密。前者确保源自 Nighthawk 线程的任何堆分配都是加密的,包括来自 BOF 的那些,稍后会详细介绍。虽然此策略非常有效,但从 Windows 库进行的分配仍然不受我们控制,并且不一定依赖于以 OpSec 友好的方式释放或清除分配。例如,任何使用 winhttp.dll 执行 HTTP(S) 请求的 c2 可能会无限期地以明文形式在堆中找到其 c2 URL。这样,我们提供的另一种堆保护模式是“进程”,它会导致Nighthawk在进程中的堆例程中部署许多挂钩,用Nighthawk安全分配实现来替换它们,加密和清理内存。
在许多操作中,由数据记录器放置的用户模式挂钩是一个众所周知的挑战。Nighthawk通过删除EDR挂钩的激进策略缓解了这些问题,它有许多可配置的选项,不仅可以取消挂钩 DLL,还可以取消可能已被 EDR 修改的内存中系统调用存根。我们的策略仅在必要时删除挂钩,使用与 Moneta 类似的技术来检测 EDR 何时篡改进程,并使用可配置选项来确定是否应使用系统调用或 NT API 来执行取消挂钩策略。然后使用源自 NTDLL 的 ROP 小工具动态计算和执行这些。
几年前,Cobalt Strike 引入了“block DLL”功能,以防止 EDR 将非 Microsoft 签名的 DLL 注入进程。在当时,这是一种比较有效的技术,可以防止 EDR 追踪分析、挂钩和其他控件,在某些情况下今天仍然可以使用,但是当然这留下了PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON 缓解标志的问题,这对于许多进程来说有点不规则,并且会经常被攻击者发现。尽管从概念上讲,我们觉得这个前提是可行的,而且我们希望能够防止dll被加载到我们的植入过程中。因此,我们引入了我们自己的“block-dll”配置选项,它允许操作符定义一个dll列表,这些dll将被阻止在进程中加载;这是通过连接到Windows库加载例程来实现的。这不仅可以用来防止 EDR 加载他们的用户模式 DLL,而且还可以非常有效地防止 AMSI 在 CLR 加载期间被实例化,避免了传统的AMSI绕过,例如许多 EDR 现在正在检测的 AMSIScanBuffer 修复。
当然,要实现OpSec的目标还有很多工作要做,但希望这篇文章能让你了解其中的一些亮点。这是一段Nighthawk欺骗线程堆栈的视频。
进程注入
Nighthawk主要用于进程内操作,并在终端上保持最小的占用空间。当然,在某些情况下,你可能想要执行注入,通常这可能包括部署一个备份信标,获得对备用桌面会话的访问权,或者想要将攻击技术与一个特定的进程混合在一起。Nighthawk在UI中提供了spawn-rdll、spawn-shellcode、inject-rdll和inject-shellcode命令来执行这些操作。
为了适应这种情况,Nighthawk提供了许多可配置的选项,将注入链的每个步骤都留给了操作员。为了实现这一点,我们将注入链分为以下几个步骤,分别用于fork 和 run 以及跨进程注入:
ProcessCreate:当操作员想要创建一个新进程时应该使用的注入器函数;
ProcessOpen:用于打开进程句柄的函数;
AllocMemory:进程中用于分配内存的策略;
WriteMemory:将内存写入远程进程的技术;
ProtectMemory:应该用来在远程进程中改变内存保护的注入器函数;
ThreadOpen:用于在远程进程中打开线程的技术,通过线程创建或劫持现有线程;
ExecuteMemory:用于在远程线程中执行内存的注入器函数。
对于Windows或NT api,每个步骤中都存在许多选项,或者如果use-syscalls配置选项设置为true,则为系统调用。此外,当执行跨架构注入时,在WoW64模式下,策略将使用x64系统调用(不要与NT API 混淆),动态计算使用ASM实现的SSN哈希查找技术,之前在我们的博客中描述过。我们的注入器链策略完全支持跨架构注入。
信标配置中的示例注入器链可能如下所示:
使用这样的链执行跨进程注入可以使用NtOpenProcess打开进程的句柄,通过NtCreateSection在其中分配内存,使用NtMapViewOfSection映射内存到进程,通过NtProtectVirtualMemory设置适当的页面权限,使用NtGetNextThread找到一个已经存在的线程,然后使用NtQueueApcThread对APC进行排队。当然,如果设置了use-syscalls配置选项,我们的API将动态枚举等效的系统调用,并使用随机来源的小工具使用ROP执行它们。
在操作员控制台中,我们还提供了set-injector-step命令,允许操作员在运行时动态更新这些步骤,这意味着操作期间的注入可以根据从终端收集的信息进行配置:
工具集成
与许多其他渗透测试团队一样,我们在 .NET 中或使用Beacon Object File开发了大部分工具。因此,对我们而言,Nighthawk整合了这两种工具,这样我们不仅可以执行我们自己的内部工具,还可以执行社区贡献的工具。因此,我们通过execute-bof命令为x86和x64 BOF提供了一个BOF加载器。Nighthawk完全支持 Cobalt Strike BOF API,因此 BOF 不需要修改,并且可以预编译以在 Cobalt Strike 或 Nighthawk 中执行:
对于 Nighthawk中的任何操作,我们都支持别名(使用可变参数),这允许你轻松扩展信标中可用的命令,例如上面的演示如何将 BOF 别名为内部 Nighthawk命令。这些将永久存储在 Nighthawk UI 配置中,这意味着操作员可以通过建立方便的快捷方式列表来自定义他们的控制台。
Nighthawk的CLR安全带避免了 fork and run 模型,提供两种操作模式:进程内或远程进程,后者允许你将一个程序集注入到一个已经运行的进程中(例如,一个可能已经加载了CLR的进程),并捕获输出。在注入场景中,它当然会尊重前面提到的注入器步骤策略,并在适用的地方使用系统调用。
也许在进程内执行 CLR 听起来很冒险,而且许多用于进程内 .NET 执行的公共 PoC 都是有风险的,并且在程序集表现不佳的情况下可能会使你的信标不稳定,但我们做过详细的研究。
你可能还想知道可能阻碍 .NET 后开发的其他因素,例如 ETW 和 AMSI。我们当然引入了各种可配置选项来阻止这些控制,包括修补 EtwEventWrite、ETW 系统调用和 AMSI,以及前面描述的可以完全阻止 AMSI 的 block-dlls 选项。
进程和主机分类
对主机和其他正在运行的进程进行分类的能力对于操作员在其行业做出决策时很重要。为此,Nighthawk 提供了许多内置的 Windows API 驱动命令,包括:
logons: 恢复有关主机上登录会话的详细信息;
pipelist: 列出主机上可用的命名管道;
proflist:列出用户配置文件和用户信息;
windows:恢复给定进程的注册windows列表;
Applist:提供主机上安装的应用程序的详细列表,包括发布者、版本和注册的卸载处理程序;portlist:列出类似于 netstat 的当前网络连接;
services:检索有关主机上服务的详细信息;
threads:列出远程进程中线程的详细信息,包括支持的图像位置;
modules:显示有关远程进程中加载的 DLL 的信息,包括图像路径和描述,
objects:列出 NT 目录管理器中的对象,包括它们的类型,
handles:显示有关远程进程句柄的信息。
用户监控
在尝试实现目标时,监视用户的能力通常对操作至关重要,尤其是在需要深入了解业务流程的情况下。 Nighthawk为操作员提供与我们的 OpSec 原则一致的内置屏幕截图和键盘记录命令,允许操作员密切监控用户行为:
凭证和令牌访问
恢复和利用现有用户访问权限是攻击者必做的事情,Nighthawk 为操作员提供了许多功能来劫持令牌和凭证材料。
当我们第一次发布它的详细信息时,其中的第一个似乎触发了其他 c2,并允许操作员从主机上的其他用户的会话中窃取模拟令牌。令牌的复制句柄被放置在信标内的令牌存储中,并允许操作员在它们之间进行热交换。此功能对于操作员已入侵具有多个用户登录的主机,比如跳转服务器,并且希望能够捕获令牌来在本地或跨网络上的其他资源模拟用户:
我们提供的另一个内置的证书恢复命令是" credman ",这个命令使用James Forshaw的自定义实现的" dump Stored Credentials with setrustedcredmanaccesprivilege "技术从Windows凭据管理器中恢复存储的凭据:
除了Windows凭证库,攻击者还喜欢收集那些隐藏在lsass或其他进程(如密码管理器)中的纯文本凭证。这就是为什么,我们提供了一个OpSec友好的进程内存转储器,它将通过 c2 提取完整的转储并直接联系到操作员终端,而无需接触受感染主机上的磁盘。
本文翻译自:https://www.mdsec.co.uk/2021/12/nighthawk-0-1-new-beginnings/如若转载,请注明原文地址