• [ Регистрация ]Открытая и бесплатная
  • Tg admin@ALPHV_Admin (обязательно подтверждение в ЛС форума)

Статья Ghost in the PPL Part 1: BYOVDLL

admin

#root
Администратор
Регистрация
20.01.2011
Сообщения
7,665
Розыгрыши
0
Реакции
135
In this series of blog posts, I will explore yet another avenue for bypassing LSA Protection in Userland. I will also detail the biggest challenges I faced while developing a proof-of-concept, and discuss some novel techniques and tricks to load an arbitrary DLL in LSASS, or even dump its memory.

Bring Your Own Vulnerable DLL (BYOVDLL)​

In July 2022, Microsoft brought some changes to their Protected Process Light (PPL) implementation to mitigate a well-known flaw, originally discovered by Для просмотра ссылки Войди или Зарегистрируйся and Для просмотра ссылки Войди или Зарегистрируйся a few years prior, allowing this protection to be easily bypassed without the need to execute code in the Kernel.

This change effectively broke my Для просмотра ссылки Войди или Зарегистрируйся proof-of-concept (PoC) but, in October 2022, Для просмотра ссылки Войди или Зарегистрируйся posted a message on Twitter in which he alluded to the fact that this wasn’t completely true. To prove his point, he attached a screenshot showing how he used a technique called “Bring Your Own Vulnerable DLL” to bring the original vulnerability back from the dead, and run Для просмотра ссылки Войди или Зарегистрируйся again without any modification.

Для просмотра ссылки Войди или Зарегистрируйся
Since then, I kept thinking about this concept, and how I could use it to execute arbitrary code within a protected process using other DLLs, and most importantly, without having to reboot.

Choosing our Target​

As a reminder, there are currently two “protection levels”: Protected Process (PP) and Protected Process Light (PPL). Each protection level has its own set of “signer types”, such as “Windows”, “WinTcb”, or even “Lsa” in the case of LSASS. The combination of these two values defines a hierarchy, thereby making some processes “more protected” than others. Thus, we want to target a PP with the highest signer type available, but those processes usually present a smaller attack surface than PPLs, such as LSASS when Для просмотра ссылки Войди или Зарегистрируйся is enabled. Besides, LSASS is also a more appealing target when it comes to extracting in-memory credentials during post-exploitation. To illustrate what I mean by that, I listed all the services that may run within this process, as shown below.

Для просмотра ссылки Войди или Зарегистрируйся

PowerShell – List of services that may run in LSASS

Alternatively, Для просмотра ссылки Войди или Зарегистрируйся can be used to list services that are actually running within LSASS.

Для просмотра ссылки Войди или Зарегистрируйся

System Informer – List of services running in LSASS

Because I’m constantly monitoring for public documentation, PoCs and exploits for Elevation of Privilege (EoP) bugs, I knew that the CNG Key Isolation service, a.k.a. “KeyIso”, was a good target. More specifically, I knew that I wanted to target this service when I saw the blog post Для просмотра ссылки Войди или Зарегистрируйся by Для просмотра ссылки Войди или Зарегистрируйся, and the PoC exploit published by Для просмотра ссылки Войди или Зарегистрируйся on GitHub Для просмотра ссылки Войди или Зарегистрируйся, as they would offer the initial building blocks I needed for what I had in mind.

In their blog post, Для просмотра ссылки Войди или Зарегистрируйся actually discusses two separate bugs: an out-of-bound (OOB) read (Для просмотра ссылки Войди или Зарегистрируйся), which serves as an information disclosure primitive to then exploit a use-after-free (UAF) flaw (Для просмотра ссылки Войди или Зарегистрируйся). I won’t cover the details of these two issues, nor the implementation of the PoC exploit, as it goes way beyond my knowledge and skills. The only thing you need to know for now is that these bugs can be abused through a subset of RPC procedures exposed by the KeyIso service, and that their successful exploitation eventually leads to the control of a CALL instruction’s target (RAX register), and the first argument (RCX register).

Loading a Vulnerable Version of the KeyIso DLL​

The ImagePath configured for the KeyIso service is the path of lsass.exe. This is because its type is Win32ShareProcess (32), which means it shares the same process as other services, such as EFS or VaultSvc, as we saw earlier.

Для просмотра ссылки Войди или Зарегистрируйся

Registry – Configuration of the KeyIso service

The actual path of the module containing the implementation of the service is set in the Parameters key, and has the value %SystemRoot%\system32\keyiso.dll.

Для просмотра ссылки Войди или Зарегистрируйся

Registry – Parameters of the KeyIso service

Lastly, the default DACL of this key grants Full Control to the Administrators group, so we don’t even need to impersonate Trusted Installer to modify it. If we want to load a vulnerable version of this DLL in LSASS, we can just stop the service, change the path of the DLL in the Registry, and restart it.

Для просмотра ссылки Войди или Зарегистрируйся

Registry – Permissions of the Parameters key

I did just that, and got the system error code 577 (ERROR_INVALID_IMAGE_HASH) – “Windows cannot verify the digital signature for this file” – when trying to start the service. This is the error code you are supposed to get when attempting to load a non Microsoft-signed DLL in a PP(L). In my case though, I’m using a legitimate Windows DLL, so what’s causing this issue?

Для просмотра ссылки Войди или Зарегистрируйся

Attempting to start the KeyIso service with net.exe

To find out, we should first compare the signatures of the built-in keyiso.dll, and the imported one, using the PowerShell command Get-AuthenticodeSignature. In the case of the imported DLL, the status is just NotSigned, which is consistent with the previous error message at least…

Для просмотра ссылки Войди или Зарегистрируйся

PowerShell – Comparison of Authenticode signatures

The reason why Windows can’t find the DLL’s signature is simply because it isn’t stored in the file. For a binary such as lsass.exe, the signature is directly embedded into the file, but for most DLLs, this is not the case. We can see that by comparing the properties of lsass.exe and keyiso.dll for instance. One has a “Digital Signatures” tab, but not the other. So, where is the signature stored?

Для просмотра ссылки Войди или Зарегистрируйся

Properties of lsass.exe and keyiso.dll

A more common way to store file signatures on Windows consists in using Для просмотра ссылки Войди или Зарегистрируйся. As explained in the documentation, “A catalog file contains a collection of cryptographic hashes, or thumbprints.”, and “Each thumbprint corresponds to a file that is included in the collection.”. One way to see which catalog file is associated to a given binary is to use Для просмотра ссылки Войди или Зарегистрируйся with the option -i.

Для просмотра ссылки Войди или Зарегистрируйся

Checking the signature of keyiso.dll with SigCheck.exe

The screenshot above was taken on a Windows 11 machine manually updated with the package KB5023778 to get the version 10.0.22621.1485 of keyiso.dll, the version prior to the security patch for CVE-2023-28229 and CVE-2023-36906.

Для просмотра ссылки Войди или Зарегистрируйся

Applying the update package KB5023778 on Windows 11

We can thus extract both the vulnerable DLL and the catalog file containing its signature. After copying the catalog file to the CatRoot folder of a fully updated Windows 11 machine, we can confirm that the signature of the imported keyiso.dll file is now recognized by the OS.

Для просмотра ссылки Войди или Зарегистрируйся

Checking the signature of an imported keyiso.dll file

And there we have it, a vulnerable version of keyiso.dll loaded in our protected LSASS process!

Для просмотра ссылки Войди или Зарегистрируйся

Starting the KeyIso service using a vulnerable DLL

Testing the Information Disclosure (CVE-2023-36906)​

Before going any further, I wanted to make sure that the initial Для просмотра ссылки Войди или Зарегистрируйся worked as intended. However, even after running the exploit a few times, it still failed to go past the information disclosure step.

Для просмотра ссылки Войди или Зарегистрируйся

Running the original Proof-of-Concept exploit

The information disclosure vulnerability is due to an improper bound check in the function SPCryptGetProviderProperty, which can be abused by first calling SPCryptSetProviderProperty with a specially crafted input buffer. What I didn’t realize initially was that these two functions are not implemented in keyiso.dll, but in ncryptprov.dll.

The DLL ncryptprov.dll contains the implementation of the Для просмотра ссылки Войди или Зарегистрируйся. We can see that by opening the Registry editor, and checking the content of the Image value in its properties, as highlighted on the screenshot below.

Для просмотра ссылки Войди или Зарегистрируйся

Registry – Settings of the “Microsoft Software Key Storage Provider”

This is a problem because ncryptprov.dll is automatically loaded by LSASS when it starts. We could modify the value of the Image property in the registry to specify the name of a vulnerable version of this DLL instead, but then we would still have to restart the machine.

Для просмотра ссылки Войди или Зарегистрируйся

System Informer – DLL ncryptprov.dll loaded in LSASS

Therefore, for this exploit to work, we also need to figure out a way to load a vulnerable version of ncryptprov.dll.
[/QUOTE]

 
Activity
So far there's no one here