121 lines
3.2 KiB
Ruby
121 lines
3.2 KiB
Ruby
##
|
|
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
|
# If you'd like to improve this script, please try to port it as a post
|
|
# module instead. Thank you.
|
|
##
|
|
|
|
|
|
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
|
#-------------------------------------------------------------------------------
|
|
################## Variable Declarations ##################
|
|
@client = client
|
|
@@exec_opts = Rex::Parser::Arguments.new(
|
|
"-h" => [ false, "Help menu." ],
|
|
"-i" => [ false, "Enumerate Local Interfaces"],
|
|
"-r" => [ true, "The target address range or CIDR identifier"],
|
|
"-s" => [ false, "Save found IP Addresses to logs."]
|
|
)
|
|
|
|
|
|
|
|
def enum_int
|
|
print_status("Enumerating Interfaces")
|
|
client.net.config.interfaces.each do |i|
|
|
if not i.mac_name =~ /Loopback/
|
|
print_status("\t#{i.mac_name}")
|
|
print_status("\t#{i.ip}")
|
|
print_status("\t#{i.netmask}")
|
|
print_status()
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
def arp_scan(cidr)
|
|
print_status("ARP Scanning #{cidr}")
|
|
ws = client.railgun.ws2_32
|
|
iphlp = client.railgun.iphlpapi
|
|
i, a = 0, []
|
|
iplst,found = [],""
|
|
ipadd = Rex::Socket::RangeWalker.new(cidr)
|
|
numip = ipadd.num_ips
|
|
while (iplst.length < numip)
|
|
ipa = ipadd.next_ip
|
|
if (not ipa)
|
|
break
|
|
end
|
|
iplst << ipa
|
|
end
|
|
iplst.each do |ip_text|
|
|
if i < 10
|
|
a.push(::Thread.new {
|
|
h = ws.inet_addr(ip_text)
|
|
ip = h["return"]
|
|
h = iphlp.SendARP(ip,0,6,6)
|
|
if h["return"] == client.railgun.const("NO_ERROR")
|
|
mac_text = h["pMacAddr"].unpack('C*').map { |e| "%02x" % e }.join(':')
|
|
print_status("IP: #{ip_text} MAC #{mac_text}")
|
|
found << "#{ip_text}\n"
|
|
end
|
|
})
|
|
i += 1
|
|
else
|
|
sleep(0.05) and a.delete_if {|x| not x.alive?} while not a.empty?
|
|
i = 0
|
|
end
|
|
end
|
|
a.delete_if {|x| not x.alive?} while not a.empty?
|
|
return found
|
|
end
|
|
|
|
def save_found(found_ip)
|
|
info = @client.sys.config.sysinfo
|
|
# Create Filename info to be appended to downloaded files
|
|
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
|
|
|
# Create a directory for the logs
|
|
logs = ::File.join(Msf::Config.log_directory,'scripts', 'arp_scanner',Rex::FileUtils.clean_path(info['Computer'] + filenameinfo))
|
|
# Create the log directory
|
|
::FileUtils.mkdir_p(logs)
|
|
|
|
#log file name
|
|
dest = Rex::FileUtils.clean_path(logs + "/" + info['Computer'] + filenameinfo + ".txt")
|
|
|
|
print_status("Saving found IP's to #{dest}")
|
|
file_local_write(dest,found_ip)
|
|
|
|
end
|
|
save2log = false
|
|
cidr2scan = ""
|
|
@@exec_opts.parse(args) { |opt, idx, val|
|
|
case opt
|
|
when "-h"
|
|
print_line "Meterpreter Script for performing an ARPS Scan Discovery."
|
|
print_line(@@exec_opts.usage)
|
|
raise Rex::Script::Completed
|
|
when "-i"
|
|
enum_int
|
|
raise Rex::Script::Completed
|
|
when "-r"
|
|
cidr2scan = val
|
|
when "-s"
|
|
save2log = true
|
|
end
|
|
}
|
|
if client.platform == 'windows'
|
|
if args.length > 0
|
|
if save2log
|
|
save_found(arp_scan(cidr2scan))
|
|
else
|
|
arp_scan(cidr2scan)
|
|
end
|
|
else
|
|
print_line "Meterpreter Script for performing an ARPS Scan Discovery."
|
|
print_line(@@exec_opts.usage)
|
|
raise Rex::Script::Completed
|
|
end
|
|
else
|
|
print_error("This version of Meterpreter is not supported with this Script!")
|
|
raise Rex::Script::Completed
|
|
end
|