100 lines
2.9 KiB
Ruby
100 lines
2.9 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::Tcp
|
||
|
include Msf::Auxiliary::Report
|
||
|
include Msf::Auxiliary::Scanner
|
||
|
|
||
|
def initialize
|
||
|
super(
|
||
|
'Name' => 'Gopher gophermap Scanner',
|
||
|
'Description' => %q{
|
||
|
This module identifies Gopher servers, and processes the gophermap
|
||
|
file which lists all the files on the server.
|
||
|
},
|
||
|
'References' =>
|
||
|
[
|
||
|
['URL', 'https://sdfeu.org/w/tutorials:gopher'],
|
||
|
],
|
||
|
'Author' => 'h00die',
|
||
|
'License' => MSF_LICENSE
|
||
|
)
|
||
|
|
||
|
register_options([
|
||
|
Opt::RPORT(70),
|
||
|
OptString.new('PATH',[false,'Path to enumerate',''])
|
||
|
])
|
||
|
|
||
|
end
|
||
|
|
||
|
def get_type(char)
|
||
|
return {'0' => 'Text file',
|
||
|
'1' => 'Directory',
|
||
|
'2' => 'CSO name server',
|
||
|
'3' => 'Error',
|
||
|
'4' => 'Mac HQX filer',
|
||
|
'5' => 'PC binary',
|
||
|
'6' => 'UNIX uuencoded file',
|
||
|
'7' => 'Search server',
|
||
|
'8' => 'Telnet Session',
|
||
|
'9' => 'Binary File',
|
||
|
'c' => 'Calendar',
|
||
|
'e' => 'Event',
|
||
|
'g' => 'GIF image',
|
||
|
'h' => 'HTML',
|
||
|
'i' => 'inline text',
|
||
|
's' => 'Sound',
|
||
|
'I' => 'Image',
|
||
|
'M' => 'MIME multipart/mixed message',
|
||
|
'T' => 'TN3270 Session'}.fetch(char.chomp)
|
||
|
end
|
||
|
|
||
|
def run_host(ip)
|
||
|
begin
|
||
|
connect
|
||
|
sock.put("#{datastore['path']}\r\n")
|
||
|
gophermap = sock.get_once
|
||
|
if gophermap
|
||
|
gophermap.split("\r\n").each do |line|
|
||
|
if line.split("\t").length >= 2
|
||
|
# syntax: [type_character]description[tab]path[tab, after this is optional]server[tab]port
|
||
|
line = line.split("\t")
|
||
|
desc = line[0]
|
||
|
type_char = desc.slice!(0) #remove first character which is the file type
|
||
|
file_type = get_type(type_char)
|
||
|
if file_type && file_type == 'inline text'
|
||
|
print_good(desc)
|
||
|
next
|
||
|
end
|
||
|
if file_type
|
||
|
print_good(" #{file_type}: #{desc}")
|
||
|
else
|
||
|
print_good(" Invalid File Type (#{type_char}): #{desc}")
|
||
|
end
|
||
|
if line.length >= 3
|
||
|
print_good(" Path: #{line[2]}:#{line[3]}#{line[1]}")
|
||
|
elsif line.length >= 2
|
||
|
print_good(" Path: #{line[2]}#{line[1]}")
|
||
|
else
|
||
|
print_good(" Path: #{line[1]}")
|
||
|
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
report_service(:host => ip, :port => rport, :name => 'gopher', :info => gophermap)
|
||
|
else
|
||
|
print_error('No gophermap')
|
||
|
end
|
||
|
rescue ::Rex::ConnectionError, ::IOError, ::Errno::ECONNRESET
|
||
|
rescue ::Exception => e
|
||
|
print_error("#{ip}: #{e} #{e.backtrace}")
|
||
|
ensure
|
||
|
disconnect
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|