@@ -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
205105end
0 commit comments