diff --git a/modules/payloads/singles/windows/x64/messagebox.rb b/modules/payloads/singles/windows/x64/messagebox.rb index 55cd00c3215a..7472f80eec4d 100644 --- a/modules/payloads/singles/windows/x64/messagebox.rb +++ b/modules/payloads/singles/windows/x64/messagebox.rb @@ -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 @@ def initialize(info = {}) ) 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 @@ def generate(_opts = {}) 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