new version using Metasm
parent
3a02e9e80f
commit
8d9bd33222
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue