Merge pull request #51 from rapid7/feature/MSP-9711/vnc_login

refactor vnc_login
This commit is contained in:
Trevor Rosen 2014-06-11 13:35:26 -05:00
commit ad80ada86b
3 changed files with 61 additions and 74 deletions

View File

@ -1,5 +1,4 @@
source 'https://rubygems.org'
# Add default group gems to `metasploit-framework.gemspec`:
# spec.add_runtime_dependency '<name>', [<version requirements>]
gemspec
@ -8,7 +7,7 @@ group :db do
# Needed for Msf::DbManager
gem 'activerecord', '>= 3.0.0', '< 4.0.0'
# Metasploit::Credential database models
gem 'metasploit-credential', git: 'github-metasploit-credential:rapid7/metasploit-credential.git', tag: 'v0.4.0-electro-release'
gem 'metasploit-credential', git: 'github-metasploit-credential:rapid7/metasploit-credential.git', tag: 'v0.4.1-electro-release'
# Database models shared between framework and Pro.
gem 'metasploit_data_models', '~> 0.17.1'
# Needed for module caching in Mdm::ModuleDetails

View File

@ -1,9 +1,9 @@
GIT
remote: github-metasploit-credential:rapid7/metasploit-credential.git
revision: 0ee29f00303019bc0131880b03559d83c43e316b
tag: v0.4.0-electro-release
revision: 39fc93ded093ad862f62d257bcf9c5a08b614d30
tag: v0.4.1-electro-release
specs:
metasploit-credential (0.4.0.pre.electro.pre.release)
metasploit-credential (0.4.1.pre.electro.pre.release)
metasploit-concern (~> 0.1.0)
metasploit_data_models (~> 0.17.0)
rubyntlm

View File

@ -5,6 +5,8 @@
require 'msf/core'
require 'rex/proto/rfb'
require 'metasploit/framework/credential_collection'
require 'metasploit/framework/login_scanner/vnc'
class Metasploit3 < Msf::Auxiliary
@ -56,82 +58,68 @@ class Metasploit3 < Msf::Auxiliary
def run_host(ip)
print_status("#{ip}:#{rport} - Starting VNC login sweep")
begin
each_user_pass { |user, pass|
ret = nil
attempts = 5
attempts.times { |n|
ret = do_login(user, pass)
break if ret != :retry
cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS']
)
delay = (2**(n+1)) + 1
vprint_status("Retrying in #{delay} seconds...")
select(nil, nil, nil, delay)
scanner = Metasploit::Framework::LoginScanner::VNC.new(
host: ip,
port: rport,
proxies: datastore['PROXIES'],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
connection_timeout: datastore['ConnectTimeout']
)
service_data = {
address: ip,
port: rport,
service_name: 'vnc',
protocol: 'tcp',
workspace_id: myworkspace_id
}
scanner.scan! do |result|
if result.success?
credential_data = {
module_fullname: self.fullname,
origin_type: :service,
private_data: result.credential.private,
private_type: :password,
}
# If we tried all these attempts, and we still got a retry condition,
# we'll just give up.. Must be that nasty blacklist algorithm kicking
# our butt.
return :abort if ret == :retry
ret
}
rescue ::Rex::ConnectionError
nil
end
end
credential_data.merge!(service_data)
def do_login(user, pass)
vprint_status("#{target_host}:#{rport} - Attempting VNC login with password '#{pass}'")
credential_core = create_credential(credential_data)
connect
login_data = {
core: credential_core,
last_attempted_at: DateTime.now,
status: Metasploit::Credential::Login::Status::SUCCESSFUL
}
login_data.merge!(service_data)
begin
vnc = Rex::Proto::RFB::Client.new(sock, :allow_none => false)
if not vnc.handshake
vprint_error("#{target_host}:#{rport}, #{vnc.error}")
return :abort
create_credential_login(login_data)
print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}"
else
invalidate_login(
address: ip,
port: rport,
protocol: 'tcp',
public: nil,
private: result.credential.private,
realm_key: nil,
realm_value: nil,
status: result.status)
print_status "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})"
end
ver = "#{vnc.majver}.#{vnc.minver}"
vprint_status("#{target_host}:#{rport}, VNC server protocol version : #{ver}")
report_service(
:host => rhost,
:port => rport,
:proto => 'tcp',
:name => 'vnc',
:info => "VNC protocol version #{ver}"
)
if not vnc.authenticate(pass)
vprint_error("#{target_host}:#{rport}, #{vnc.error}")
return :retry if vnc.error =~ /connection has been rejected/ # UltraVNC
return :retry if vnc.error =~ /Too many security failures/ # vnc4server
return :fail
end
print_good("#{target_host}:#{rport}, VNC server password : \"#{pass}\"")
access_type = "password"
#access_type = "view-only password" if vnc.view_only_mode
report_auth_info({
:host => rhost,
:port => rport,
:sname => 'vnc',
:pass => pass,
:type => access_type,
:duplicate_ok => true,
:source_type => "user_supplied",
:active => true
})
return :next_user
# For debugging only.
#rescue ::Exception
# raise $!
# print_error("#{$!}")
ensure
disconnect()
end
end
end