Gives the finger user enumeration module an overhaul -- more descriptive status messages, more friendly connect/disconnect, and if the target supports multiple usernames per request, do that.
git-svn-id: file:///home/svn/framework3/trunk@9364 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
cfb850b41b
commit
bf4cf3cc85
|
@ -27,6 +27,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
)
|
||||
register_options([
|
||||
Opt::RPORT(79),
|
||||
OptBool.new('VERBOSE', [ true, "Whether to print output for all attempts", true]),
|
||||
OptString.new('USERS_FILE',
|
||||
[ true, 'The file that contains a list of default UNIX accounts.',
|
||||
File.join(Msf::Config.install_root, 'data', 'wordlists', 'unix_users.txt')
|
||||
|
@ -38,10 +39,13 @@ class Metasploit3 < Msf::Auxiliary
|
|||
@users = {}
|
||||
|
||||
begin
|
||||
print_status "#{rhost}:#{rport} - Sending empty finger request." if datastore['VERBOSE']
|
||||
finger_empty
|
||||
print_status "#{rhost}:#{rport} - Sending test finger requests." if datastore['VERBOSE']
|
||||
finger_zero
|
||||
finger_dot
|
||||
finger_chars
|
||||
print_status "#{rhost}:#{rport} - Fingering user list: #{finger_user_common.join(", ")}" if datastore['VERBOSE']
|
||||
finger_list
|
||||
|
||||
rescue ::Rex::ConnectionError
|
||||
|
@ -50,8 +54,10 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
report_service(:host => rhost, :port => rport, :name => "finger")
|
||||
|
||||
if(not @users.empty?)
|
||||
print_status("#{ip} #{@users.keys.sort.join(", ")}") if not @users.empty?
|
||||
if(@users.empty?)
|
||||
print_status("#{ip}:#{rport} No users found.")
|
||||
else
|
||||
print_status("#{ip}:#{rport} Users found: #{@users.keys.sort.join(", ")}")
|
||||
report_note(
|
||||
:host => rhost,
|
||||
:port => rport,
|
||||
|
@ -67,6 +73,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
sock.put("\r\n")
|
||||
buff = finger_slurp_data
|
||||
parse_users(buff)
|
||||
disconnect
|
||||
end
|
||||
|
||||
def finger_zero
|
||||
|
@ -74,6 +81,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
sock.put("0\r\n")
|
||||
buff = finger_slurp_data
|
||||
parse_users(buff)
|
||||
disconnect
|
||||
end
|
||||
|
||||
def finger_dot
|
||||
|
@ -81,22 +89,47 @@ class Metasploit3 < Msf::Auxiliary
|
|||
sock.put(".\r\n")
|
||||
buff = finger_slurp_data
|
||||
parse_users(buff)
|
||||
disconnect
|
||||
end
|
||||
|
||||
def finger_chars
|
||||
connect
|
||||
sock.put("m m m m m m m m\r\n")
|
||||
buff = finger_slurp_data
|
||||
if buff.scan(/\r?\nm\s/).size > 7
|
||||
@multiple_requests = true
|
||||
print_status "#{rhost}:#{rport} - Multiple users per request is okay." if datastore['VERBOSE']
|
||||
end
|
||||
parse_users(buff)
|
||||
disconnect
|
||||
end
|
||||
|
||||
def finger_list
|
||||
finger_user_common.each do |user|
|
||||
next if @users[user]
|
||||
connect
|
||||
sock.put("#{user}\r\n")
|
||||
buff = finger_slurp_data
|
||||
parse_users(buff)
|
||||
if !@multiple_requests
|
||||
finger_user_common.each do |user|
|
||||
next if @users[user]
|
||||
connect
|
||||
print_status "#{rhost}:#{rport} - Fingering #{user}..." if datastore['VERBOSE']
|
||||
sock.put("#{user}\r\n")
|
||||
buff = finger_slurp_data
|
||||
parse_users(buff)
|
||||
disconnect
|
||||
end
|
||||
else
|
||||
while !finger_user_common.empty?
|
||||
user_batch = []
|
||||
while user_batch.size < 8 and !finger_user_common.empty?
|
||||
new_user = finger_user_common.shift
|
||||
next if @users.keys.include? new_user
|
||||
user_batch << new_user
|
||||
end
|
||||
connect
|
||||
print_status "#{rhost}:#{rport} - Fingering #{user_batch.join(", ")}..." if datastore['VERBOSE']
|
||||
sock.put("#{user_batch.join(" ")}\r\n")
|
||||
buff = finger_slurp_data
|
||||
parse_users(buff)
|
||||
disconnect
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -118,7 +151,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
if(! @common)
|
||||
File.open(datastore['USERS_FILE'], "r") do |fd|
|
||||
data = fd.read(fd.stat.size)
|
||||
@common = data.split(/\n/)
|
||||
@common = data.split(/\n/).compact.uniq
|
||||
@common.delete("")
|
||||
end
|
||||
end
|
||||
@common
|
||||
|
@ -126,6 +160,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
def parse_users(buff)
|
||||
buff.each_line do |line|
|
||||
uid = nil
|
||||
next if line.strip.empty?
|
||||
|
||||
# Ignore Cisco systems
|
||||
|
@ -144,26 +179,32 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
# Solaris
|
||||
if(line =~ /^([a-z0-9\.\_]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)/)
|
||||
uid = $1
|
||||
uid = $1
|
||||
if ($2 != "Name")
|
||||
@users[uid] ||= {}
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
# IRIX
|
||||
if(line =~ /^\s*Login name:\s*([^\s]+)\s+/i)
|
||||
@users[$1] ||= {}
|
||||
next
|
||||
uid = $1
|
||||
@users[uid] ||= {} if uid
|
||||
end
|
||||
|
||||
# Debian GNU/Linux
|
||||
if(line =~ /^\s*Username:\s*([^\s]+)\s+/i)
|
||||
@users[$1] ||= {}
|
||||
uid = $1
|
||||
@users[uid] ||= {} if uid
|
||||
end
|
||||
|
||||
if uid
|
||||
print_good "#{rhost}:#{rport} - Found user: #{uid}" unless @users[uid] == :reported
|
||||
@users[uid] = :reported
|
||||
next
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue