A-A+

D-Link 路由器固件潛藏後門程序 backdoor _teslmx

[英文原文:Reverse Engineering a D-Link Backdoor, by Craig, http://www.devttys0.com/]
[中文譯者:外刊IT評論 ]

Craig 他下載了D-link無線路由器(型號:DIR-100 revA)的固件程序 v1.13。使用工具Binwalk,很快的就從中發現並提取出一個只讀SquashFS文件系統,沒用多大功夫就將這個固件程序的web server(/bin/webs)加載到了IDA中:

1382385034_90_resized

基於上面的字符信息可以看出,這個/bin/webs二進製程序是一個修改版的thttpd,提供路由器管理員界面操作功能。看起來是經過了台灣明泰科技(D-Link的一個子公司)的修改。他們甚至很有心計的將他們很多自定義的函數名都輔以「alpha」前綴:

1382385034_378

這個alpha_auth_check函數看起來很有意思!

這個函數被很多地方調用,最明顯的一個是來自alpha_httpd_parse_request函數:

1382385034_759

我們可以看到alpha_auth_check函數接收一個參數(是存放在寄存器$s2里);如果alpha_auth_check返回-1(0xFFFFFFFF),程序將會跳到alpha_httpd_parse_request的結尾處,否則,它將繼續處理請求。

寄存器$s2在被alpha_auth_check函數使用前的一些操作代碼顯示,它是一個指向一個數據結構體的指針,裡面有一個char*指針,會指向從HTTP請求里接收到的各種數據;比如HTTP頭信息和請求地址URL:

1382385034_355_resized

我們現在可以模擬出alpha_auth_check函數和數據結構體的大概樣子:

struct http_request_t
{
    char unknown[0xB8];
    char *url; // At offset 0xB8 into the data structure
};

int alpha_auth_check(struct http_request_t *request);

alpha_auth_check本身是一個非常簡單的函數。它會針對http_request_t結構體里的一些指針進行字符串strcmp比較操作,然後調用check_login函數,實際上就是身份驗證檢查。如果一旦有字符串比較成功或check_login成功,它會返回1;否者,它會重定向瀏覽器到登錄頁,返回-1;

1382385034_3

這些字符串比較過程看起來非常有趣。它們提取請求的URL地址(在http_request_t數據結構體的偏移量0xB8處),檢查它們是否含有字符串「graphic/」 或 「public/」。這些都是位於路由器的Web目錄下的公開子目錄,如果請求地址包含這樣的字符串,這些請求就可以不經身份認證就能執行。

然而,這最後一個strcmp卻是相當的吸引眼球:

1382385034_171

這個操作是將http_request_t結構體中偏移量0xD0的字符串指針和字符串「xmlset_roodkcableoj28840ybtide」比較,如果字符匹配,就會跳過check_login函數,alpha_auth_check操作返回1(認證通過)。

我在谷歌上搜索了一下「xmlset_roodkcableoj28840ybtide」字符串,只發現在一個俄羅斯論壇里提到過它,說這是一個在/bin/webs里一個「非常有趣」的一行。我非常同意。

那麼,這個神秘的字符串究竟是和什麼東西進行比較?如果回顧一下調用路徑,我們會發現http_request_t結構體被傳進了好幾個函數:

1382385034_412

事實證明,http_request_t結構體中處在偏移量 0xD0處的指針是由httpd_parse_request函數賦值的:

1382385034_107

1382385034_983

這代碼實際上就是:

if(strstr(header, "User-Agent:") != NULL)
{
    http_request_t->0xD0 = header + strlen("User-Agent:") + strspn(header, " \t");
}

知道了http_request_t偏移量0xD0處的指針指向User-Agent頭信息,我們可以推測出alpha_auth_check函數的結構:

#define AUTH_OK 1
#define AUTH_FAIL -1

int alpha_auth_check(struct http_request_t *request)
{
    if(strstr(request->url, "graphic/") ||
       strstr(request->url, "public/") ||
       strcmp(request->user_agent, "xmlset_roodkcableoj28840ybtide") == 0)
    {
        return AUTH_OK;
    }
    else
    {
        // These arguments are probably user/pass or session info
        if(check_login(request->0xC, request->0xE0) != 0)
        {
            return AUTH_OK;
        }
    }

    return AUTH_FAIL;
}

換句話說,如果瀏覽器的User-Agent值是 「xmlset_roodkcableoj28840ybtide」(不帶引號),你就可以不經任何認證而能訪問web控制界面,能夠查看/修改路由器的 設置(下面是D-Link路由器(DI-524UP)的截圖,沒有 DIR-100型號,但DI-524UP型號使用的是相同的固件):

1382385034_8

基於HTML頁上的源代碼信息和Shodan搜索結果,差不多可以得出這樣的結論:下面的這些型號的D-Link路由器將會受到影響:

  • DIR-100
  • DI-524
  • DI-524UP
  • DI-604S
  • DI-604UP
  • DI-604+
  • TM-G5240

除此之外,幾款Planex路由器顯然也是用的同樣的固件程序:

  • BRL-04UR
  • BRL-04CW

你很酷呀,D-Link。

腳註:萬能的網友指出,字符串「xmlset_roodkcableoj28840ybtide」是一個倒序文,反過來讀就是 「editby04882joelbackdoor_teslmx」——edit by 04882joel backdoor _teslmx,這個後門的作者真是位天才!

標籤: