根据思科高级恶意软件防护引擎(AMP)所报告的数据显示,思科的Talos部门在过去的两个月内一直在跟踪分析RAT感染事件。AMP能够在恶意软件感染主机前对其进行防御。然而,经过研究人员的分析发现,我们回收的样品中并没有RAT发生的迹象,反而是一种具有商业性质的封装软件。
RAT攻击可以逃避防御软件的检测与分析。过去,为了保护合法软件供应商的知识产权,我们通常使用一种叫做Obsidium
的软件封装器。而封装器中的payload也逐渐演化成叫做Imminent
的RAT恶意软件。而新研发的商用RAT零售价为25至100美元,并拥有大量的客户群。虽然这个软件不是被用于恶意行为,但是对其的检测必不可少。
虽然常规方法就可以做到对恶意软件的检测,但是并不是每个用户都能够组织PUA的威胁。除此之外,我们还有其他技术被用于检测,例如:Exploit Prevention引擎。读者在阅读完此文章后不仅能够更好的了解攻击的具体流程,而且还能够了解AMP是如何进行配置以防止检测的。本次分析采用了软件沙箱的动态分析方法。
在AMP检测到这种特殊的Imminent恶意行为之后,我们发现用于隐藏恶意软件的封装器有多复杂时,我们决定进一步进行研究。以下是动态运行的显示情况:
我们确定了商用级封隔器是如何使用的,但我们也对这种特定封隔器运行时所采用的反调试和反虚拟机技术感到好奇。 它从几个重写SEH异常
的处理程序开始。 这是通过在FS:0
之前就开始进行顺序处理,然后将堆栈指针移动到FS:0
。由于样本是32位并且未使用SafeSEH编译,所以这种方法很容易实现。所以程序故意访问非法指令并重定向到某些代码处,从而导致恶意代码的初始解密情况产生。
由于覆盖的主要目标是系统的起始代码,因此可以通过以下内容来跳过大部分内容:ntdll-> KiUserExceptionDispatcher
。 程序可以将异常传递给应用程序,并在跳转条件之前进行中断操作以确定链中是否存在另一个异常行为。
最后,按照存储在ECX中的指针来解析CONTEXT
结构,并确定在调用NtContinue时将执行哪些EIP指令。 EIP可以在运行时在此时跟随ECX并为32位上下文的CONTEXT结构提供手动解析能力。
恶意软件依次解密和重新加密恶意代码,使得分析人员很难确定完整解密点以及完整的时间线。 加密方案使用用户本机x86指令和包装的AES函数。
通过初始代码解密,我们可以看到一些复杂的API解析,其中第一个类似于二进制,但为了防反汇编的垃圾字节插入,所以整体来看分析被阻止了。
正如人们所预料的那样,这使得控制流图和功能块的反汇编渲染非常混乱。后面会有几个断点和调用返回,这里我们会注意到API字符串会在通用寄存器中被抛出。通过一些试验和错误调试,我们发现打破已解析的API地址并将其存储在EAX中并非不可能。然后,我们可以运行调试器,直到调用返回。但在这个过程中将遇到一些访问冲突和非法指令,如下所示。 如果用户通过打包器反复运行payload进行调试,那么最终会成功对非法指令进行访问。
还值得一提的是,这里我们进行处理的API地址不应该被修改,也不应该持续运行到点击调用。此处的打包程序并不总是需要用过调用来移动到API处。除此之外,API的地址并不是直接被使用的,而且通过在函数内调用一些指令来达到调用的效果。用户最好的做法就是避开API代码中的一些调用以便能够随意查看已解析API的原始参数。更重要的是,封装器代码将在重定向之前会检查软件断点目标(0xCC或int 3反汇编)。
在建立了此类控制对话之后,我们就可以开始处理反调试检查。这是成功解压缩原始payload的必要步骤。 在这种情况下,由于检查的存在,所以样本无法正常运行并显示出完整图像或相关代码段。 使用此打包程序,反调试检查包括以下内容:
类注册会将参数传递给CreateWindowsEx
,包含一个由CallWindowProc
调用的回调参数。 回调函数本身调用NtQueryInformationProcess
,并将ProcessDebugPort
设置为请求的ProcessInformationClass
枚举参数。
对于未记录的ProcessInformationClass
枚举值ProcessDebugObjectHandle
和ProcessDebugFlags
,我们再次调用API两次。
使用SystemInformationClass
参数中未记录枚举来调用NtQuerySystemInformation
:SystemKernelDebuggerInformation
。 在此特定情况下,程序不返回标准的SYSTEM_BASIC_INFORMATION
结构,而是返回SYSTEM_KERNEL_DEBUGGER_INFORMATION
结构,其中包含UCHAR KernelDebuggerEnabled
和UCHAR KernelDebuggerNotPresent
。 用户可以通过适当地切换标志来绕过此调试器检查。
调用CloseHandle
会成为抛出无效提示。 调试进程时,这将抛出异常,而不是导致API提示失败。 在这种情况下,异常会返回到检测到的调试器(EnumWindows-> MessageBoxA - >“Debugger detected ...”)
。 调试时忽略异常以绕过此检查。
多次调用CreateFileA
以检查是否可以在主机上进行实例化具有以下文件名的文件对象:
\\.SICE
\\.\NTICE
\\.\NTFIRE
之后的检查很有意思,它在开始调试器检查之前解析了20多个API。 幸运的是,只有最后几个API涉及检查操作(InternalGetWindowText,IsWindowVisible和EnumWindows)
。 如前文所述,在解压缩这一点上获取EnumWindows
是一个不好的迹象,表明未通过调试器检查。 传递给EnumWindows的回调函数必须使用断点处理并进行迭代,直到看到InternalGetWindowText
和IsWindowVisible
被调用作为独立调试器检查。
将任意值传递给SetLastError
会产生错误。 调用GetLastError
以检查设置值是否被保持,正如调试时所预期的那样。
GetCurrentThread
获取当前线程并将其传递给NtSetInformationThread
,并附加来自THREAD_INFORMATION_CLASS
的ThreadHideFromDebugger
枚举值。 如果存在,将从调试器中分离进程。
CheckRemoteDebuggerPresent。
FindWindowW
查找以下调试器类名,而不是窗口名:ObsidianGUI,WinDbgFrameClass,ID和OLLYDBG
。
CreateFileW检查创建\\.\ VBoxGuest
是否失败。
这只是反调试的一部分。 不幸的是,我们没有空间来覆盖恶意软件的反VM技术,但这是分析的一个良好开端。 我们决定继续在裸机主机上解压缩样本以转储二进制文件。 我们将最后阶段的分析确定为商业性的恶意RAT。 通过动态域名所显示的复杂打包程序(Themida等),我们发现主机上运行了多个控制面板上的RAT(包括我们解压缩)。
我们进一步对这一系列攻击进行分析。最初,这个商用性的包装器曾被用于保护合法软件供应商的知识产权。 此外,合法payload产生了商业上可用的RAT,其也被用于合法目的。 虽然在这种情况下PUA检测方法就足够对恶意软件进行检测,但除了防止遥测之外,我们还拥有诸如漏洞利用预防引擎之类的技术来动态检测此类威胁。 攻击者正在不断地尝试绕过威胁检测。 在这种特殊情况下,使用市场上的防御软件是无济于事的。这些攻击由思科高级恶意软件防护(AMP)漏洞利用预防引擎成功防御,由此产生的事件数据通过分析软件能够对以后的防御提供更多的帮助。
原始Obsidium打包样本
3bc0ae9cd143920a55a4a53c61dd516ce5069f3d9453d2a08fc47273f29d1cf3
分析的RAT样本
12cca4fcfe311d1136db6736e7f17854746a5e6c7a284c27ea84a5016bf982d7
本文翻译自:https://blog.talosintelligence.com/2019/01/what-we-learned-by-unpacking-recent.html