Search code examples
securityencryptionwindows-installer

Securing some EXE applications within MSI Installer - which approach - Encryption or Separate MSI packages?


Current setup: Lots of .exe (and other files) are packaged inside an MSI installer (using WIX) which installs the exe files in ProgramFiles directory. Bootstrapper exe is normally used (it installs prerequistes) and launches the MSI installer package. Installer package is usually started from network share (access to which can be controlled on user/group basis).

Background: It is requested that not all users should be able to get access to all applications that get installed via the MSI installer.

Problem:

  1. How to secure the installer in a way such that even if someone who normally does not have access to the MSI installer file, gets hold of it, won't be able to install it and thereby the applications (exe:s within it) or extract the applications (using orca or some other tool for instance)?

Possible solutions considered so far:

  1. Create two installers - one which contains All applications and one which only contains the applications that should be used by those who should have access. This may impact maintainability when creating new releases, but also the problem remains that if someone gets hold of the entire MSI package, they can extract and/or install it to get the application exe files.

  2. Encryption - By encrypting the .exe files before embedding them into the MSI package, only those that have means for decryption can run the applications even if someone gets hold of the MSI installer. And, in that case, maybe only one single MSI installer package is needed (containing all applications, some of which are encrypted). But, when the MSI installer puts those encypted exes in ProgramFiles folder for instance, how can an authorized user (having a decryption key in some form) decrypt them, since I suppose that the user would need elevated rights to write (the decrypted resulting app.exe) to the installation folder under ProgramFiles? Or, should the decrypted file be output into a [User]\AppData[MainApplicationName]\ folder where-to the user can actually output/write it and then let the application be run from there (and maybe the "sensitive" application(s) can be removed after main application closes for instance)?

  3. Or are the abovementioned solutions inferior and should/could be handled in some easier or more secure manner? Some completely other ideas may exist maybe?


Solution

  • This is the way I handled this at a previous company:

    1. The exe file is encrypted and distributed as a raw file.
    2. We provide a launcher that will query user information and prompt for a passkey.
    3. We send all the data to a back-end server which verifies the details, ensures that a time window is still valid, and if everything looks ok, sends down the decryption key.
    4. The launcher decrypts the application file and saves it to disk, scrubs the keys from memory, then launches the target app (we saved it to an obfuscated location so it wasn't immediately easily found).
    5. The launcher waits until the application exits and then deletes the runnable file.

    As an aside, we used a Job Object to terminate the app if the launcher died unexpectedly.

    We also had the option to let the server send down a "kill switch" command which would cause the launcher to uninstall the application files.


    If you can't support a server component, then it becomes much more difficult to provide an encrypted version as you don't have good ways to secure the decryption keys.