#1125 Code execution / Privilege escalation problems with NSIS installers

2.0 Series
closed-accepted
nobody
None
5
2016-10-10
2015-11-24
A. Heinecke
No

Hi,

We at gpg4win.org are happily using NSIS to create our Installers for over a
decade now. So first let me thank you for all the work providing and
maintaining NSIS.

It was recently brought to our attention that the Gpg4win installer could be
used to execute arbitrary code with Administrative privileges when an attacker
has control over the Folder in which the installer is placed or can modify the
temp directory. By either placing system DLL's like shfolder.dll or version.dll into the same directory as the installer or by modifing temporary extracted plugins an attacker could cause code to be executed. (And for Elevated installers this could also be used as a privilege escaltion attack). I've outlined the problems causing this below. As they are somewhat related I've decided not to split them up in different bugreports.

While this may be a general problem there are ways to prevent this and we would like to fix it as we see it a serious problem of our installer.

Attached patches try to mitigate this (in the patches.zip file as sourceforge only lets me attach one file). The patches are against 2.46 as provided by Debian GNU/Linux (as we needed fixes for this version and I'll also report a Bug with debian about this) but I'll port them to trunk if you want me to.
I just wanted to get opinions on our analysis and patches first. Patches tested on debian wheezy and debian jessie compiling NISIS with mingw. Minimum supported version for the code used is Windows XP (which I hope is ok)

We saw three problems:

Problem 1:
Use of LoadLibrary in NSIS. LoadLibrary by default looks in the current
directory of the process and into the Folder of the Executable. This is bad
(especially in the regular case that users execute our installer from the
downloads folder) because an attacker can just drop a dll in that folder and
it will be loaded with high privileges. To try it out just place a fake
shfolder.dll (That brings up a message box in it's DllMain) in the same
directory as an NSIS installer. This is also a Problem for LoadLibraryEx for
plugins because their dependencies are also loaded from the executables
directory first.

Solution: Using SetDefaultDllDirectories we can globally change the behavior
of LoadLibraryEx so that it only looks into the System32 folder and into any
directories explicitly added with AddDllDirectories.

While this is only available on Windows Vista and later with updates installed
I think that it is Ok to use for NSIS as it basically means that we won't
lower the security on maintained Windows Systems and privilege escalation is
not that relevant on Windows XP as it does not have the User Account Control.

Patch: 1_restrict_dll_directories.patch

Problem 2:
Plugins are extracted in the temporary folder and can be overwritten without
elevated privileges and the uninstaller is copied into a temporary directory
before it is executed. This also gives an attacker the chance to modify an
uninstaller.

Solution:
If the NSIS installer runs with elevated privileges create the temporary
directory in a way that only elevated users can write into it.

Patch: 2_secure_temp_directory.patch

Problem 3:
Even without delayload / direct loading Windows prefers DLL's from the
executables directory if they are not in the KnownDLL's [2] list. For NSIS
this is problematic for Version.dll

Solution:
No implicit linking against Version.dll instead we use wrapper functions that
resolve the dependency at runtime after we restricted the DLL Search order as
outlined for Problem 1.

Patch: 3_do_not_link_version_dll.patch

With these three patches I was no longer able to modify the Created Temporary
directory as a normal user, and I could execute the installer from a folder
where all libraries names from a Windows 7 System32 pointed to "fake"
libraries.

Uff, Long Text ;-)

Thanks for reading,
Andre

1: https://msdn.microsoft.com/en-us/library/windows/desktop/hh310515%28v=vs.85%29.aspx

2: http://blogs.msdn.com/b/larryosterman/archive/2004/07/19/187752.aspx

1 Attachments

Discussion

<< < 1 2 (Page 2 of 2)
  • San

    San - 2016-01-23

    The running code to copy system.dll to %temp%\ns.* location doesn't realy requires admin privileges
    If an installer asks for UAC then an evil system.dll could gain higher privileges than what it had.
    Flow:
    1. A payload script running with non admin privileges along with evil system.dll which doesn't have enough privileges to run exploit is present on user machine
    2. NSIS based installer is run by user
    3. UAC prompt shown to user, user accepts it
    4. Temp\ns folder created
    5. Script running with low privileges detects it and replaces system.dll
    6. Evil system.dll gets executed with high privileges

    PoC Batch Script attached
    Keep copy of evil system.dll & the attached batch file in same folder
    Run the batch script by double clicking on it (non admin privileges)
    Launch NSIS installer

     
    • Anders

      Anders - 2016-01-23

      Have can you post something like this without actually testing that it works? We change the ACL on our nsXXX temp folder when running elevated!

       
  • San

    San - 2016-01-24

    My mistake, I was using older version of NSIS. Thanks for sharing details on changing ACL

     
  • Son Dinh

    Son Dinh - 2016-01-25

    Hi,

    We are testing our installer using 2.50 and notice that when using NSIS with plugins, the temp folder that contains the plugin DLLs ($PLUGINSDIR) doesn't have a proper ACL. Digging through the NSIS patch (http://sourceforge.net/p/nsis/code/6657/), I understand that it didn't set the ACL for $PLUGINSDIR, which is created here: https://sourceforge.net/p/nsis/code/HEAD/tree/NSIS/tags/v250/Source/exehead/exec.c#l314

    Perhaps it might be a misunderstanding from my side, can anyone help me with this?

     
  • Anders

    Anders - 2016-10-10
    • status: open --> closed-accepted
     
<< < 1 2 (Page 2 of 2)

Log in to post a comment.