发展
一直以来,文件是恶意代码存在的最常见形式,安全软件也通常把磁盘上的文件作为重点检测对象。然而,一旦恶意代码以无文件形式存储在系统中,便难以对其追踪。早在十几年前,红色代码、Slammer蠕虫就利用缓冲区溢出进行攻击,通过网络传播,完全存在于内存之中,而不以文件作为载体。不过,这种基于内存的无文件(Fileless)攻击一旦进程或系统关闭,也就不复存在。为了实现攻击持久化,攻击者们找到新的突破口——将恶意软件实体隐藏在注册表的某个键值里,并通过各种加密手段,来逃脱安全软件的查杀。最早使用该技术的是2014年GData公司发现的点击欺诈软件Poweliks。随后,多款恶意程序甚至APT组织使用这种无文件持久化攻击技术。
攻击流程
1、初始样本执行
当初始样本通过钓鱼邮件、漏洞或其他方式感染系统后,就会在Windows注册表配置单元中以加密形式写入完整的负载,为无实体恶意代码执行做准备。
2、无实体恶意代码注册表执行
通常,恶意代码被创建为几个注册表子键,每个键值中会分别存储脚本代码或者二进制数据,自启动后,通过层层解密,最终执行核心代码。
a)第一阶段键值Auto-Start
系统启动后会自动读取某些特殊的键值,这就为恶意代码自启动创造了条件。一般通过在rundll32.exe里运行RunHTMLApplication来执行一段JS脚本。引申来看,任何能加载MSHTML模块都是潜在的利用对象。详细了解该原理可以参考链接[1]
b)第二阶段键值Loader
第一阶段的代码会用来解密并执行第二阶段的数据。在调研的几个案例中,第二阶段的数据通常会是一段加密脚本,例如PowerShell、VBScript等,这里主要是为了执行第三阶段的数据。
c)第三阶段键值Binary
第三阶段的键值通常用来存储Payloads。通过阶段二的脚本命令来将其注入到系统合法进程之中,实现无进程ShellCode执行。
当然,并不是所有的无文件恶意软件都是按照三个阶段执行,像Poweliks则是将二、三阶段的数据存放在一个子键中,通过PowerShell脚本解密并执行对应模块的数据,其基本原理和目的是一致的。一旦恶意代码被注入内存之中,就会按照攻击者最初的设计来实施恶意行为,比如连接控制服务器、收集主机信息、接受命令执行其他操作等。
代码隐藏
存储在注册表中的脚本和数据经过了精心的加密隐藏,以达到让安全软件和用户不可见的目的。
a)撤销访问权限:在访问控制列表(ACL)中撤销用户对注册表访问权限。
b)添加无效字符:利用Windows注册表编辑器无法显示包含无效字符的注册表键,在注册表键值中写入一个或多个无效字符,用户访问时会显示错误消息。
结束语
基于注册表的无文件攻击利用操作系统特性来达到数据隐藏的意图,并将恶意程序运行在合法进程之中,这种方式能让基于文件监测的查杀手段失效,为此安全厂商们也积极做出响应,然而随着技术的进一步发展,恶意代码的隐藏方式很可能并不只局限于Windows注册表。攻防对抗,永无止境。