内容简介: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!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
设计模式
[美] Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides / 李英军、马晓星、蔡敏、刘建中 等 / 机械工业出版社 / 2000-9 / 35.00元
这本书结合设计实作例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中最有价值的经验,并且用简洁可复用的形式表达出来。书中分类描述了一组设计良好、表达清楚的软件设计模式,这些模式在实用环境下特别有用。此书适合大学计算机专业的学生、研究生及相关人员参考。 书中涉及的设计模式并不描述新的或未经证实的设计,只收录了那些在不同系统中多次使用过的成功设计。一起来看看 《设计模式》 这本书的介绍吧!