内容简介:This quick blog post highlights some of the flaws found in the Zoom application when attempting to do integrity checking, these checks verify that the DLLs inside the folder are signed by Zoom and also that no 3rd party DLLs are loaded at runtime. We can t
Introduction
This quick blog post highlights some of the flaws found in the Zoom application when attempting to do integrity checking, these checks verify that the DLLs inside the folder are signed by Zoom and also that no 3rd party DLLs are loaded at runtime. We can trivially disable this DLL, by replacing it with our own or simply unloading it from the process.
This post highlights how we can bypass Zoom’s anti-tampering detection, which aims to stop DLLs from being loaded or existing ones modified. The functionality is all implemented by Zoom themselves within a DLL named DllSafeCheck.dll
.
I have also included a YARA rule at the end of this blog post, in case this technique is used by an advisory in the future.
I’ll cover these flaws:
FreeLibrary DllSafeCheck
Zoom Client
Zoom is entirely programmed in C++ and makes heavy use of the Windows API. The executable and the DLLs that are used are installed to %APPDATA%\Zoom\bin
and is completely writeable. All of the executables that are used are signed by Zoom themselves, as we can see below when extracting the certificate.
PS AppData\Roaming\Zoom\bin_00> Get-PfxCertificate util.dll Thumbprint Subject ---------- ------- 0F9ADA46756C17EFFFD467D10654E2A766566CB3 CN="Zoom Video Communications, Inc.", O="Zoom Video Communications, Inc.", L=San Jose, S=California, C=US, SERIALNUMBER=4969967, OID.2.5.4.15=Pr...
Most of the functionality within Zoom resides within the DLLs. Below, we can see the DLLs which are included within the export table. Take notice of the DllSafeCheck.dll
; the is the library we will be analysing.
Looking further at the use of DllSafeCheck.dll, we can see that it exports a function named HackCheck
.
If we then cross-reference the calls to this function using our favourite disassembler, IDA in this instance, we can see that it is called at the entry point of the program within WinMain
before any other operations are completed. Below, we can see the function prologue and the immediate call to HackCheck
.
DllSafeCheck.dll
As abovementioned, the Zoom client will call the HackCheck
function (which is the only export from the DLL, apart from DllMain
), upon execution. Two events are created to detect the loading and unloading of the DLL, by resolving LdrUnregisterDllNotification
and LdrRegisterDllNotification
to register it.
To start, the export first starts by verifying that it is not running on an old version of Windows, using a mixture of VerSetConditionMask
and VerifyVersionInfoW
. After the Windows version has passed these checks, it will continue execution. It then will gather the Windows process token information through the usual means of getting a handle for the current process, then calling GetTokenInformation
. This data is then saved for further use.
A path to Zoom’s %APPDATA%
folder is then constructed, and a log file named dllsafecheck.txt
is created. A thread is then created, which waits for log events to be sent to it. Below, we can see the creation of this file.
We then get to the core functionality of the DLL, which is scanning the modules which are loaded in the current process and making sure that they’re signed by Zoom. It will gather a list of the modules, and then check to see if they are signed, below, we can see the enumeration of the certificate chain to check against the hardcoded Zoom Video Communications, Inc.
string.
if ( v10->csCertChain ) { do { v12 = WTHelperGetProvCertFromChain(v10, v11); if ( !v12 ) break; v13 = v12->pCert; if ( v13 ) { v15 = CertGetNameStringW(v13, 4u, 0, 0, 0, 0); // get alloc len v16 = v15; if ( v15 ) { v14 = HeapAlloc(NULL, 0, 2 * v15); if ( v14 ) { v20 = 0; do { v14[v20++] = 0; } while (v20 < (2 * v15)); if (!CertGetNameStringW(v13, 4u, 0, 0, (LPWSTR)v14, v16)) { HeapFree(NULL, 0, v14); v14 = 0; } } v10 = v26; } else { v14 = 0; } } else { v14 = 0; } if ( !v25 ) v25 = L"Zoom Video Communications, Inc.";
If the executable is not signed by Zoom, it will prompt the user to ask if it wants it to be run in the process.
Trivial to unload from process
Ironically while all the DLLs checked by the anti-tampering DLL must have a valid Microsoft Authenticode signature to pass the checks, the anti-tampering DLLs integrity or signing status are not checked at all. This seems like an oversight from the Zoom developers considering all the checks that are currently performed in the DllSafeCheck
DLL.
An immediate issue is that this DLL can be trivially unloaded, rendering the anti-tampering mechanism null and void. The DLL is not pinned, meaning an attacker from a 3rd party process could simply inject a remote thread, and call FreeLibrary after getting a handle to the DLL.
One possible fix for this would be to perform GetModuleHandleExA
, and passing in the GET_MODULE_HANDLE_EX_FLAG_PIN
flag. This ensures that the module stays loaded within the process until it terminates, rendering FreeLibrary
calls useless.
HMODULE hSafeCheck = NULL; if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_PIN, "DllSafeCheck.dll", &hSafeCheck)) { // Loaded module successfully }
We can unload it using the traditional, and well-documented method of: 1) HANDLE of Zoom process using OpenProcess
2) Enumerate the loaded modules in the process, using EnumProcessModules
, and find a handle to DllSafeCheck.dll
3) Resolve the address of “FreeLibrary” using GetProcAddress 4) Create a thread in the process using CreateRemoteThread, with the starting routine as the FreeLibrary address, and the parameter as the handle to DllSafeCheck. 5) The anti-tampering DLL is now unloaded 6) We can now inject any DLL we want
I’ve created simple POC (basic CreateRemoteThread DLL injection, nothing fancy) for unloading the anti-tampering DLL and injecting our own. You can contact me at[email protected] if you want to see it.
Anti-tampering DLL can be replaced on disk
When loading the DLL, Zoom does not check the signature of the integrity of the file. I’m not sure why this is not checked at all, considering all of the checks which are done in the DllSafecheck
DLL regarding executable signature vertification. This remains a mystery. A threat actor could leverage this to enable their unsigned, non-Zoom DLL to be loaded into the context of a signed executable as a host for their malicious code.
The folder which Zoom resides in is writeable, which also contributes to this attack.
A simple DLL named DllSafeCheck.dll
can be compiled implementing the HackCheck
export. For clarity, the malicious DLL which is used is not signed. We can see the result of querying the executable signature below.
PS AppData\Roaming\Zoom\bin_00> Get-AuthenticodeSignature DllSafeCheck.dll SignerCertificate Status Path ----------------- ------ ---- NotSigned DllSafeCheck.dll
The following code was used for this PoC:
VOID __declspec(dllexport) CheckHack() { MessageBox(NULL, L"LloydLabs", L"Oops!", MB_APPLMODAL); }
Here, we can see the the alert when loading Zoom.
How could a threat actor realistically exploit this?
A malicious DLL could be bundled with Zoom, and sent to a victim - this would result in the payload (e.g. Cobalt Strike), being executed under the context of the Zoom process. A threat actor could also abuse these issues to persist both across reboot and in memory on a target system, this is a much cleaner approach compared to the alternatives of registering some startup event.
YARA rule
import "pe" rule Zoom_Plant { meta: date = "2020-04-03" author = "LloydLabs" url = "https://blog.syscall.party" condition: pe.characteristics & pe.DLL and pe.exports("HackCheck") and pe.number_of_exports == 1 and (pe.issuer contains "Zoom Video Communications, Inc.") }
Conclusion
Thank you for reading this brief blog, if you wish to contact me I can be emailed at:[email protected] - I’m a 3rd year undergraduate student, and open to opportunities and collaboration. Cheers!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java学习指南(第4版)(上下册)
Patrick Niemeyer、Daniel Leuck / 李强、王建新、吴戈 / 人民邮电出版社 / 2014-7 / 128.00元
《Java学习指南(第4版)(上、下册)》是畅销Java学习指南的最新版,详细介绍了Java 6和Java 7的语言特性和API。本书全面介绍了Java的基础知识,力图通过完备地介绍Java语言、其类库、编程技术以及术语,从而成为一本名符其实的入门级图书。 《Java学习指南(第4版)(上、下册)》加入了从Java 6和Java 7发布以后的变化,包括新的语言功能、并发工具(Fork-Joi......一起来看看 《Java学习指南(第4版)(上下册)》 这本书的介绍吧!