一旦攻击者攻入系统内部,他将试图维持立足点以便维持权限,为下一步攻击做铺垫。
在实战过程中,基本上都会碰到一些杀软、防病毒等程序。即使做了免杀,像自启动、隐藏用户、定时任务、shift后门还是会被运维人员清除掉。这里分享三种有一定的隐蔽效果的持久化方式。
代码注入攻击(“Codeinjection”,代码注入)的正常理解是在基于正常应用软件寻找到漏洞安全隐患后,被攻击者打入进了恶意代码,使正常软件在运行的时候,同时加载运行了攻击者打入的恶意代码。
Application Verifier漏洞
ApplicationVerifier是用于非托管代码的运行时验证工具,可帮助开发人员快速发现细微的编程错误,而这些错误通常很难通过常规应用程序测试来识别。
在VisualStudio中使用ApplicationVerifier,可以通过识别由堆损坏、不正确的句柄和关键部分使用引起的错误,更轻松地创建可靠的应用程序。
DoubleAgent
Cybellum公司公开了一个漏洞的POC,对其命名为“DoubleAgent”,可用于控制主流的杀毒软件。
DoubleAgent使攻击者能够将任何DLL注入任何进程。代码注入在受害者的进程启动过程中非常早就发生,从而使攻击者可以完全控制该进程,而无法让进程保护自己。
Application Verifier+DoubleAgent组合拳
这里引用Cybellum团队的介绍,即便采取了重新启动、更新、重新安装或修补程序等行为,攻击也很难被阻止,DoubleAgent还可以继续注入代码。一旦攻击者将代码注入到一个进程中,则这个进程将永远被强制绑定。
“https://github.com/Cybellum/DoubleAgent”
编写自定义Verifierprovider DLL,然后通过ApplicationVerifier进行安装,这时受害者每次启动被注入的进程,都会加载我们的payload。
首先用vs修改DoubleAgent.dll下的main.c,在DllMainProcessAttach函数中添加自己payload,然后重新编译:
在实战过程中,可以将我们的恶意程序注入到explorer.exe,AV等进程里,具有一定的隐蔽效果。
这里我将我的cs马注入到explorer.exe中,当系统重启时,我们的后门是先于杀软运行的,所以可以绕过大部分杀软。
为了进一步达到更隐蔽的效果,这里我以不落地的方式去运行,因为没有实体文件,相对安全许多,并且还能逃避杀软的主动扫描。
把ps指令转换成base64编码,这样在自定义编写Verifierprovider DLL时可以避免有参数和语法的错误。
同样的方式也可以注入到一些常见的杀毒软件中,每次受害者打开电脑都会加载后门且先于杀软,并且以管理员直接提权到system。
即使杀毒软件会阻止注册尝试,代码注入技术和持久性技术也难被阻止,因为代码注入技术和持久性技术利用的是操作系统的合法进程。
COM组件的介绍
什么是COM,这里简单的概括就是,该技术的目的是提供一个接口,允许开发人员控制和操纵其他应用程序的对象,每个COM对象均由称为CLSID的唯一ID定义。
例如,用于显示桌面实例的CLSID为{3080F90D-D7AD-11D9-BD98-0000947B0257}。
COM组件的劫持原理
COM组件由DLL和EXE形式发布的可执行代码所组成,进程内组件就是组件和客户程序在同一进程内,进程外组件即组件和客户程序分别有自己的进程空间。
一个COM组件可以包含多个COM对象,一个COM对象又可以有多个接口。每个COM组件都有一个CLSID,这个CLSID是注册的时候写进注册表的,可以把这个CLSID理解为这个组件最终可以实例化的子类的一个ID,所以要想COM劫持,尽量选择应用范围广的CLSID。
COM劫持-CacheTask
攻击者可以利用COM插入恶意代码,这些代码可以通过劫持COM引用和关系作为持久性手段,来代替合法软件执行,原理和DLL劫持很相似。
InprocServer32和LocalServer32的键值是COM的引用点(在注册表中,LocalServer32键表示可执行(exe)文件的路径、InprocServer32键表示动态链接库(dll)文件的路径)。当攻击者发现某些注册表中的COM键没有调用或被弃用,这时可以将我们的payload投放其引用路径上,从而实现劫持。
用powershell指令来枚举可能被劫持的“LocalServer32 ”类:
$inproc = gwmiWin32_COMSetting | ?{ $_.LocalServer32 -ne $null }
$inproc | ForEach{$_.LocalServer32} > values.txt
$paths = gc.values.txt
foreach ($p in$paths){$p;cmd /c dir $p > $null}
这里我以劫持CacheTask为例。该文件存储在以下位置:
C:WindowsSystem32TasksMicrosoftWindowsWininet
由于默认情况下CacheTask会在任何用户登录期间启动,因此用户登录将永久执行,同样也先于杀软运行。
这个和对CAccPropServicesClass、MMDeviceEnumerator、MruPidlList等劫持类似,所以比较适合我们后门的持久化,这里就不一一举例了。
WMI事件的介绍
WMI(Windows 管理规范)是一项核心的Windows管理技术。
用户可以使用WMI管理本地和远程计算机。WMI采用统一的、基于标准的、可扩展的面向对象接口,可以直接调用WMI接口来检索性能数据,管理事件日志、文件系统、打印机、进程、注册表设置、计划程序、安全性、服务、共享以及很多其他的操作系统组件和配置设置,使系统开发者可以与Windows管理信息进行交互。
自从WMI被Stuxnet用于持久化控制后,越来越多的安全研究人员开始关注WMI技术。
WMI永久事件订阅(MOF)
__EventFilter,它使用WMI查询语言来检测特定事件;
“CommandLineEventConsumer”
__FilterToConsumerBinding,用于将事件和动作绑定在一起。
使用mofcomp编译一下,编译后记得要把原mof文件删掉,虽然不会报毒,但最好还是不要留下证据:
实战中可以根据实际情况,自己定义触发事件,比如监控用户登录成功或者监控windows事件日志,如果有用户登录成功,则加载后门。
instance of__EventFilter as $Filter
{
Name = "DeviceManager";
EventNamespace ="Root\Cimv2";
Query ="SELECT* FROM __InstanceModificationEvent "
"WhereTargetInstance Isa "Win32_LocalTime" "
"AndTargetInstance.Second = 3000";
QueryLanguage ="WQL";
};
监控windows事件日志,如果有用户登录成功则触发:
instance of__EventFilter as $Filter
{
Name = "DeviceManager";
EventNamespace ="Root\Cimv2";
Query ="SELECT* FROM __InstanceCreationEvent Within 5"
"WhereTargetInstance Isa "Win32_NTLogEvent" "
"AndTargetinstance.EventCode = "4624" "
"AndTargetinstance.Message Like "%administrator%" ";
QueryLanguage ="WQL";
};
监控登录日志用户admin登录成功时远程ps上线:
可以看到系统重启后powershell是以SYSTEM运行的,同样先于杀软运行:
实战中可根据所处的环境及时变通,如可以劫持或将恶意程序注入到目标业务应用程序里,即使报毒,一些工程师还是会以为误报或怕中断业务而放行,当然这么做风险也比较大,慎行。
在实战过程中,我们可能会遇到各种杀软AV等,利用以上三种方式劫持,或插入先于杀软运行的进程中,在一定程度上可以绕过大部分杀软,以便我们后门能更持久。
未知攻,焉知防,希望这篇文章能为大家带来些许帮助,在攻防学习的成长中,更好地守护网络安全。
原文始发于微信公众号(酒仙桥六号部队):Windows持久化小Tips | 技术精选0124