Module: Rex::Proto::NATPMP

Included in:
Msf::Auxiliary::NATPMP
Defined in:
lib/rex/proto/natpmp/packet.rb,
lib/rex/proto/natpmp/constants.rb

Constant Summary collapse

DefaultPort =
5351
Version =
0
TCP =
2
UDP =
1

Instance Method Summary collapse

Instance Method Details

#external_address_requestObject

Return a NAT-PMP request to get the external address.


13
14
15
# File 'lib/rex/proto/natpmp/packet.rb', line 13

def external_address_request
  [ 0, 0 ].pack('nn')
end

#get_external_address(udp_sock, host, port, timeout = 1) ⇒ Object


17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/rex/proto/natpmp/packet.rb', line 17

def get_external_address(udp_sock, host, port, timeout=1)
  vprint_status("#{host}:#{port} - Probing NAT-PMP for external address")
  udp_sock.sendto(external_address_request, host, port, 0)
  external_address = nil
  while (r = udp_sock.recvfrom(12, timeout) and r[1])
    (ver, op, result, epoch, external_address) = parse_external_address_response(r[0])
    if external_address
      vprint_good("#{host}:#{port} - NAT-PMP external address is #{external_address}")
      break
    end
  end
  external_address
end

#map_port(udp_sock, host, port, int_port, ext_port, protocol, lifetime, timeout = 1) ⇒ Object


38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rex/proto/natpmp/packet.rb', line 38

def map_port(udp_sock, host, port, int_port, ext_port, protocol, lifetime, timeout=1)
  vprint_status("#{host}:#{port} - Sending NAT-PMP mapping request")
  # build the mapping request
  req = map_port_request(int_port, ext_port,
    Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), datastore['LIFETIME'])
  # send it
  udp_sock.sendto(req, host, datastore['RPORT'], 0)
  # handle the reply
  while (r = udp_sock.recvfrom(16, timeout) and r[1])
    (_, _, result, _, _, actual_ext_port, _) = parse_map_port_response(r[0])
    return (result == 0 ? actual_ext_port : nil)
  end
  nil
end

#map_port_request(lport, rport, protocol, lifetime) ⇒ Object

Return a NAT-PMP request to map remote port rport/protocol to local port lport for lifetime ms


54
55
56
57
58
59
60
61
62
# File 'lib/rex/proto/natpmp/packet.rb', line 54

def map_port_request(lport, rport, protocol, lifetime)
  [ Rex::Proto::NATPMP::Version, # version
    protocol, # opcode, which is now the protocol we are asking to forward
    0, # reserved
    lport,
    rport,
    lifetime
  ].pack("CCnnnN")
end

#parse_external_address_response(resp) ⇒ Object

Parse a NAT-PMP external address response resp. Returns the decoded parts of the response as an array.


33
34
35
36
# File 'lib/rex/proto/natpmp/packet.rb', line 33

def parse_external_address_response(resp)
  (ver, op, result, epoch, addr) = resp.unpack("CCnNN")
  [ ver, op, result, epoch, Rex::Socket::addr_itoa(addr) ]
end

#parse_map_port_response(resp) ⇒ Object

Parse a NAT-PMP mapping response resp. Returns the decoded parts as an array.


66
67
68
# File 'lib/rex/proto/natpmp/packet.rb', line 66

def parse_map_port_response(resp)
  resp.unpack("CCnNnnN")
end