Technical Advisory – Nullsoft Scriptable Installer System (NSIS) – Insecure Temporary Directory Usage
Title: Nullsoft Scriptable Installer System (NSIS) - Insecure Temporary Directory Usage Vendor URL: https://nsis.sourceforge.io/Main_Page Versions Affected: NSIS 3.08 (September 25, 2021) and below CVE Identifier: CVE-2023-37378 Risk: 7.8 CVSS:3.0/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H 7.3 CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N Author: Richard Warren <richard.warren[at]nccgroup.com>
The NSIS uninstaller package did not enforce appropriate permissions on the temporary directory used during the uninstall process. Furthermore, it did not ensure that the temporary directory was removed before running executable content from it. This could potentially result in privilege escalation under certain scenarios.
A low-privileged, local attacker could exploit this vulnerability to execute arbitrary code with the privileges of the user that launched the uninstaller – potentially resulting in privilege escalation. An example of this could be a privileged Windows service that runs as SYSTEM , and runs an NSIS
uninstall.exe package. A malicious user could exploit this vulnerability to gain code execution with the privileges of that service.
During the uninstall process, the NSIS
uninstaller.exe executable creates a temporary
sub-directory under the current user’s
%TEMP% folder. It then copies itself to this directory before executing the a new temporary executable with
CreateProcess. However, the uninstaller executable does not protect this temporary directory from removal when it has been launched from a privileged context. Additionally, it ignores the
ERROR_ALREADY_EXISTS code returned by
CreateDirectory, and applies an overly-permissive ACL to the existing directory instead.
This allows users in the
Everyone group permission to delete the folder and re-create it with malicious content.
A malicious user could exploit these weaknesses to create a “poisoned” temporary directory containing a payload – which would get executed by the uninstaller. Looking at the
nsis-3.08 source code, we can find the following line in
On line 352, the program makes a call to
UserIsAdminGrpMember and sets the admin variable to the return value. The
UserIsAdminGrpMember function calls the
shell32!IsUserAnAdmin Windows API function.
This function is simply a wrapper for SHTestTokenMembership, which checks that the user’s token contains the RID
0x220 (i.e. SID
If an uninstaller is launched as
SYSTEM, it will pass the
UserIsAdminGrpMember function, which the
uninstaller.exe process token will contain the administrator SID. Furthermore, its
%TMP% variables will be set to the global
C:\Windows\Temp temporary directory (via a call to
GetTempPath), which all users have Write access to.
As such, the NSIS code will go on to call the
CreateRestrictedDirectory, as the value of admin will be 1 . However, if we look at the code for this function, we can see that the ACL applied using
SetFileSecurity includes an ACE which allows Everyone to have
Additionally, in the
CreateRestrictedDirectory, although the
CreateDirectory return code is checked for the
ERROR_ALREADY_EXISTS return code, it does not re-create the folder. Instead, it applies the permissive ACL to the existing folder. This means that if the folder already contains malicious content, it will not be removed.
The NSIS uninstaller does attempt to remove any existing
Un_X.exe executables from the
~nsuA.tmp folder. However, any other content will be left in place.
There is also a potential TOCTOU issue, since
CopyFile is used to write the
Un_X.exe file, no exclusive handle is maintained on the file. Therefore an attacker may be able to race between when the file is written with
CopyFile and when it is launched with
CreateProcess. The attacker could potentially improve their chances of winning this race by using oplocks.
Whilst it is tricky to exploit a race-condition, and DLL Hijacking is generally mitigated by the use of
SetDefaultDllDirectories in NSIS – another way to exploit this vulnerability would be to abuse Windows Side-by-Side (WinSxS) assembly loading and DotLocal redirection.
This is a relatively lesser-known technique that allows us to create a DLL hijacking primitive by creating a
.local folder in the executable directory. DotLocal abuse has been documented and exploited previously by multiple researchers, and is used in the UACME UAC bypass tool.
As mentioned earlier, an attacker can delete the
C:\Windows\Temp\~nsuA.tmp folder and re-create it with their own chosen permissions. Once the folder has been re-created with write permissions, the attacker can create an
Un_A.exe.local sub-directory inside the
~nsuA.tmp folder. This will cause Windows to attempt to load SxS assemblies from this folder – which is controlled and write-able by the attacker.
In the following screenshot we can see the
Un_A.exe process attempting to open the
.local directory under normal usage:
If we delete the
~nsuA.tmp folder, re-create it with weak permissions, and create the
.local folder sub-directory described above, we can see it now attempts to open the
C:\Windows\Temp\~nsuA.tmp\Un_A.exe.local\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.1110_none_60b5254171f9507e subdirectory from a
If we create the
amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.1110_none_60b5254171f9507e sub-directory too, then it will finally attempt to load the
comctl32.dll library, giving the attacker a DLL hijacking primitive:
Therefore, to exploit this issue, an unprivileged attacker simply has to:
- Delete any existing
- Recreate the folder with Read/Write permissions
- Create the
.localSxS redirection subfolder containing a malicious
- Trigger the
uninstaller.exeprocess to run as a privileged (e.g. SYSTEM ) user (this will be product specific – e.g. RPC/COM).
This would give the attacker code execution within the
Un_A.exe process, which runs with the same privileges as the
Proof of Concept
Whilst a full Proof of Concept is not provided, some example code can be found here which shows how to determine the required SxS folder name.
The following screenshot shows the PoC being run against a simple test NSIS package.
- At 1: the PoC exploit is run, creating the neccessary folder structure.
- At 2: the folder structure shows
~nsuA.tmpdirectory, and the
.localfolder containing the SxS DLL Hijack.
- At 3: the
uninstaller.exepackage is run under the SYSTEM account using PSExec (for example purposes).
- At 4: the DLL hijack is triggered, resulting in a new
cmd.exeWindow being spawned as SYSTEM.
We have identified multiple products using NSIS where this vulnerability is exploitable and leads to privilege escalation.
If your software package makes use of NSIS versions prior to 3.09 and allows a low-privileged user to initiate an uninstall operation from a privileged context; for example, auto-updaters, or software which uses a service for maintenance tasks (e.g. repairing an application install) – then it is likely be exploitable.
Furthermore, if your software can be (un)installed through a deployment service such MDM or Configuration Management software, then it may also be exploitable via this vulnerability – as many of these products install software packages as SYSTEM.
A proposed patch was provided to the NSIS project maintainers, which removed the permissive ACE allowing all users to delete the temporary directory, and added error handling to delete the directory if it already existed.
This was reviewed by the project maintainers and multiple fixes were implemented, which:
- Creates an isolated temporary directory for each uninstaller process, deleting any existing directories if present.
- Checks that the temporary directory does not contain a symlink before deleting it.
- Removes the permissive ACL.
These fixes were released in NSIS version 3.09.
2023-02-08 - Reported to NSIS Maintainers 2023-02-22 - Confirmation from maintainers, and patch provided for review 2023-05-21 - Initial patch committed to NSIS project 2023-05-30 - Feedback provided by NCC regarding proposed patch 2023-06-03 - Additional hardening added 2023-05-05 - Further feedback provided about patches 2023-06-21 - Additional hardening added 2023-07-01 - NSIS version 3.09 released 2023-07-11 - NCC Group advisory published
About NCC Group
NCC Group is a global expert in cybersecurity and risk mitigation, working with businesses to protect their brand, value and reputation against the ever-evolving threat landscape. With our knowledge, experience and global footprint, we are best placed to help businesses identify, assess, mitigate respond to the risks they face. We are passionate about making the Internet safer and revolutionizing the way in which organizations think about cybersecurity.
Published date: 2023-07-11
Written by: Richard Warren