High
CVE-2021-41379
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
CVE-2021-41379
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
Windows Installer Elevation of Privilege Vulnerability
Add Assessment
Technical Analysis
According to Florian Roth: “You can detect the exploitation of Windows InstallerFileTakeOver LPE CVE-2021-41379 with the published PoC with events from the ‘Application’ Eventlog
Search for EventID 1033 and the keyword ‘test pkg’
https://twitter.com/cyb3rops/status/1462711685484101634
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportRatings
-
Attacker ValueHigh
-
ExploitabilityHigh
Technical Analysis
The variant of CVE-2021-41379 that was released as a zero-day exploit is a local privilege escalation issue that is the result of a few issues with msiexec.exe
. See the Rapid7 analysis for more details.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportTechnical Analysis
The patch bypass for this vulnerability is now being exploited in the wild as noted at https://blog.talosintelligence.com/2021/11/attackers-exploiting-zero-day.html. I have not labeled this bug as exploited in the wild though as the code noted below by @kevthehermit is an exploit for a variant of this bug, not this bug itself, however it is important to note that the bugs are related and no patch exists yet for the variant at the time of writing (November 24th 2021).
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportCVSS V3 Severity and Metrics
General Information
Vendors
- microsoft
Products
- windows 10 1507,
- windows 10 1607,
- windows 10 1809,
- windows 10 1909,
- windows 10 2004,
- windows 10 20h2,
- windows 10 21h1,
- windows 11 21h2,
- windows 7 -,
- windows 8.1 -,
- windows rt 8.1 -,
- windows server 2004,
- windows server 2008 -,
- windows server 2008 r2,
- windows server 2012 -,
- windows server 2012 r2,
- windows server 2016,
- windows server 2019,
- windows server 2022,
- windows server 20h2
Exploited in the Wild
Would you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportReferences
Additional Info
Technical Analysis
Update: At the time of writing, the below described a zero-day vulnerability in Windows that was related to CVE-2021-41379. On Decemeber 14, 2021, Microsoft published CVE-2021-43883 to address this vulnerability.
Description
On November 9, 2021, Microsoft published details on CVE-2021-41379, a vulnerability that allows low privileged Windows users to delete protected files. Microsoft credited Abdelhamid Naceri for discovering this issue. On November 21, Naceri published an exploit that allows low privileged users to overwrite protected files, resulting in privilege escalation to SYSTEM. Naceri stated that the exploit targets a variation of CVE-2021-41379 that Microsoft did not fix. The exploit therefore targets a zero-day vulnerability. Microsoft has not issued a security bulletin for this issue, but, when they do, it will likely be scored as CVSSv3 7.8.
The zero-day exploit abuses a few issues to escalate privileges. A crafted “msi” installer, when installed, causes msiexec.exe
to write to a user controlled directory without checking for junctions or symlinks. msiexec.exe
also fails to impersonate the low privileged user when doing so. This allows the attacker to trick msiexec.exe
into altering the permissions of any file on the system. The zero-day exploit uses this trick to change the permissions on a service binary, overwrites the binary, and then starts the service to obtain SYSTEM privileges.
This issue has reportedly been exploited quite widely across multiple sectors in a variety of countries. At the time of writing, the issue remains unfixed so there is little reason to expect exploitation to abate.
Affected products
An official affected product list has not yet been published. However, CVE-2021-41379 is known to affect:
- Windows 7 / 8.1 / 10 / 11
- Windows Server 2008 / 2012 / 2016 / 2019 / 2022
Rapid7 has successfully tested this new variant on newer Windows versions, but has had less success on older Windows. However, that does not directly rule them out as they might simply require a special twist. At this stage, it is probably safe to assume the affected versions are similar.
Rapid7 analysis
At the time of publication, this zero-day exploit will be almost two weeks old. However, there are only scant, or frankly incorrect, details regarding how the exploit actually works. As such, this analysis is going to focus on the mechanics of the attack, and less on the specific bits of code within msiexec.exe
/ msi.dll
that allow this behavior. At this stage of exploitation in the wild, an attacker/defender-oriented analysis is worth more than a vulnerability-hunter oriented analysis.
Successful exploitation of this issue happens in four parts:
- Generation of an MSI that will trigger bad behavior.
- Preparing a directory for MSI installation.
- Inducing an error state.
- Racing to introduce a junction and a symlink to trick
msiexec.exe
to modify the attacker specified file.
We’ll examine each of these four sections and then discuss specifically how Naceri’s InstallerFileTakeOver exploit pops a SYSTEM terminal.
Generating an MSI
The first step of this attack is generating an MSI. As Naceri noted in their write-up, a number of anti-virus products are flagging the MSI dropped by their exploit. While that certainly catches use of one exploit in the wild, you’ll see it’s trivial to generate a new MSI.
Naceri provided a very helpful hint when they shared a .aip
file in their repository. This file is used by Advanced Installer to generate installers. To generate your own, follow the simple layout of:
- Application Folder/ - Some exe - Directory/ - Some exe
Trial and error showed that additional files or different file types elicited different behaviors from msiexec.exe
. As such, sticking with this simple layout is preferable. To generate the MSI for this analysis, the binary of choice was calc.exe
.
To understand later analysis, it’s important to note that the directory structure created by this MSI is:
- Application Folder/ - teeswift.jpg (calc.exe) - shakeitoff/ - lockfile.jpg (calc.exe)
Using meld, we can quickly visualize the minor changes between Nicera’s .aip
and ours:
The changes are fairly minor. But the msi
we generate isn’t detected by any AV on VirusTotal.
The MSI, as generated, produces a specific behavior that we’ll be able to exploit. But before we get to that behavior, we have to lay some groundwork.
Preparing the Install Directory
The exploit uses MsiInstallProductA to install the MSI. MsiInstallProductA
is called using, at least, two properties:
- ACTION=ADMIN
- TARGETDIR=
The first property, ACTION=ADMIN
instructs the Windows Installer to perform an administrative installation. The second property informs the installer where to install the MSI’s files. For this attack, it’s important to induce an error state that prevents the installer from running correctly. We achieve this first by creating the entire directory structure and then telling the installer to install in the created location. In our proof of concept, the directory structure creation function looks like this:
bool Exploit::create_temp_files() { std::cout << "[+] Create the temp directory structure we'll install into" << std::endl; if (!std::filesystem::create_directories(m_tmp_base_path + m_tmp_inner_path)) { return false; } if (!std::filesystem::create_directories(m_tmp_inner_tmp)) { return false; } std::ofstream teeswift(m_tmp_base_path + m_tmp_outter_file); if (!teeswift.is_open()) { return false; } teeswift.close(); std::ofstream lockfile(m_tmp_base_path + m_tmp_inner_path + "\\" + m_tmp_lock_file); if (!lockfile.is_open()) { return false; } lockfile.close(); return true; }
And the install function is called like so (note that REBOOT=ReallySuppress is just to ensure the MSI doesn’t trigger a reboot):
bool install_msi(const std::string& p_msi_path, const std::string& p_install_path) { MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); std::string properties("ACTION=ADMIN REBOOT=ReallySuppress TARGETDIR="); properties.append(p_install_path); std::cout << "[+] MSI install: " << properties << " " << p_msi_path << std::endl; int result = MsiInstallProductA(p_msi_path.c_str(), properties.c_str()); std::cout << "[+] MsiInstallProductA return value: " << result << std::endl; return (result == 1603); }
However, the exploit does not immediately call MsiInstallProductA
after setting up the install directory. The attacker first needs to take steps to induce the error state.
Inducing the Error State
The attack requires the MSI installation to fail. The attacker can ensure that happens by holding a handle open to one of the files created in the previous step. The installer won’t be able to access the file since the attacker is holding it open. The specific error induced should be 1603.
In our proof of concept, we launch a thread before calling MsiInstallProductA
and the first thing the thread does is grabs shakeitoff\lockfile.jpg
:
std::cout << "[+] Grabbing handle to lock " << m_tmp_base_path + m_tmp_inner_path + "\\" + m_tmp_lock_file << std::endl; m_lock_handle = CreateFileA((m_tmp_base_path + m_tmp_inner_path + "\\" + m_tmp_lock_file).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE | SYNCHRONIZE, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_BACKUP_SEMANTICS, 0); if (m_lock_handle == INVALID_HANDLE_VALUE) { std::cerr << "[-] Failed to get a handle to the rbf file" << std::endl; return; }
That’s sufficient to induce the error state. In procmon
the initial error looks like so:
The result of the error state is that the msiexec.exe
drops rollback files (.rbf
) into the \shakeitoff
directory we created in the previous step. Note below that msiexec.exe is writing to the directory as SYSTEM.
Now that msiexec.exe
is writing to the directory of our choosing, it’s a race to implement redirection logic.
Racing to file manipulation
msiexec.exe
will try to write a couple of rbf files to the shakeitoff
directory and alter file permissions on them. If the attacker can overwrite the expected file path with a junction and symlink, then they can trick msiexec.exe
into modifying a file that the symlink points to.
There is a fair amount of file manipulation in the proof of concept, but the most important steps are:
- Create a new directory (\cb_directory)
- Turn \cb_directory\ into a directory junction that points to \BaseNamedObjects\Restricted
- Move \shakeitoff\ to another name
- Move \cb_directory\ to \shakeitoff
- Drop a symlink for the expected .rbf in \BaseNamedObjects\Restricted\ that points to the attacker chosen file.
- That’s it.
msiexec.c
will write through the symlink.
As mentioned, there are a lot more moving parts, but here are some of the highlights pulled out of procmon
. The first is renaming the directory junction to shakeitoff
:
Then msiexec.exe
applying a DACL to the targeted file (C:\Program Files(x86)\lol) that allows the attacker to modify it.
And finally, the attacker modifying the file.
That’s the whole attack! The attacker is free to overwrite or introduce arbitrary files anywhere on the system.
Popping SYSTEM Shell
Naceri’s exploit pops a shell for the attacker. Their exploit does everything we discussed above except they specifically overwrite a program named elevation_service.exe
that is part of Microsoft Edge’s update mechanism. After overwriting the executable, the exploit starts the MicrosoftEdgeElevationService which executes their code with SYSTEM privileges. They then have some additional logic to pop a shell for the user.
Indicators of Compromise
As mentioned in the Rapid7 blog, this attack generates event logs that defenders can look for to determine if they’ve been exposed to this attack. Specifically, event ID 1033 will indicate that MsiInstaller failed with error status 1603. That is the error that is required for the attack to be performed (e.g. msiexec.exe
fails because the attacker is holding open a required file).
Similarly, Event ID 11306 will indicate which file triggered the error state. That may help track down other malicious files.
Defenders can also check the signature of elevation_service.exe to detect Naceri’s exploit. The binary should be signed by Microsoft Corporation. Naceri’s exploit overwrites the binary and therefore removes any type of signature.
There is little else to do until Microsoft puts out guidance or a patch. Unfortunately, it seems that defenders cannot rely on AV to detect this attack. While Naceri’s exploit gets flagged by Windows Defender and others AV, our simple proof of concept does not. Which indicates that these services are flagging the exploit and not the behavior.
Guidance
Monitor system event logs for signs of exploitation. Continue monitoring Microsoft bulletins for a potential fix or remediation guidance. Otherwise, practice good network hygiene and remember that attackers can only use this atack once they have a presence within your network.
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
PoC is publicly available https://github.com/iilegacyyii/PoC-CVE-2021-41773/blob/main/CVE-2021-41773.py
Think this is the wrong CVE POC
Correct one seems to be – https://github.com/klinix5/InstallerFileTakeOver
I see it thanks