metasploit-framework/modules/auxiliary/scanner/gopher/gopher_gophermap.rb

104 lines
2.8 KiB
Ruby
Raw Normal View History

2017-10-13 01:32:01 +00:00
##
# 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',
2017-10-20 16:44:07 +00:00
'Description' => %q(
2017-10-13 01:32:01 +00:00
This module identifies Gopher servers, and processes the gophermap
file which lists all the files on the server.
2017-10-20 16:44:07 +00:00
),
2017-10-13 01:32:01 +00:00
'References' =>
[
2017-10-20 16:44:07 +00:00
['URL', 'https://sdfeu.org/w/tutorials:gopher']
2017-10-13 01:32:01 +00:00
],
'Author' => 'h00die',
'License' => MSF_LICENSE
)
2017-10-20 16:44:07 +00:00
register_options(
[
Opt::RPORT(70),
OptString.new('PATH', [false, 'Path to enumerate', ''])
]
)
2017-10-13 01:32:01 +00:00
end
2017-10-20 16:44:07 +00:00
TYPE_MAP = {
'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'
}.freeze
2017-10-13 01:32:01 +00:00
def get_type(char)
2017-10-20 16:44:07 +00:00
TYPE_MAP.fetch(char.chomp)
2017-10-13 01:32:01 +00:00
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|
2017-10-20 16:44:07 +00:00
line_parts = line.split("\t")
next unless line_parts.length >= 2
# syntax: [type_character]description[tab]path[tab, after this is optional]server[tab]port
line_parts = line.split("\t")
desc = line_parts[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_parts.length >= 3
print_good(" Path: #{line_parts[2]}:#{line_parts[3]}#{line_parts[1]}")
elsif line.length >= 2
print_good(" Path: #{line_parts[2]}#{line_parts[1]}")
else
print_good(" Path: #{line_parts[1]}")
2017-10-13 01:32:01 +00:00
end
end
2017-10-20 16:44:07 +00:00
report_service(host: ip, port: rport, service: 'gopher', info: gophermap)
2017-10-13 01:32:01 +00:00
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