我是如何反编译D-Link路由器固件程序并发现它的后门的_最新动态_新闻资讯_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 新闻资讯 > 最新动态 > 我是如何反编译D-Link路由器固件程序并发现它的后门的

我是如何反编译D-Link路由器固件程序并发现它的后门的

 2013/10/22 9:57:53    程序员俱乐部  我要评论(0)
  • 摘要:英文原文:ReverseEngineeringaD-LinkBackdoorOK,又是周末晚上,没有约会,只有一大瓶Shasta汽水和全是快节奏的音乐…那就研究一下程序吧。一时兴起,我下载了D-link无线路由器(型号:DIR-100revA)的固件程序v1.13。使用工具Binwalk,很快的就从中发现并提取出一个只读SquashFS文件系统,没用多大功夫我就将这个固件程序的webserver(/bin/webs)加载到了IDA中
  • 标签:程序 编译 发现
class="topic_img" alt=""/>

  英文原文:Reverse Engineering a D-Link Backdoor

  OK,又是周末晚上,没有约会,只有一大瓶 Shasta 汽水和全是快节奏的音乐…那就研究一下程序吧。

  一时兴起,我下载了D-link 无线路由器(型号:DIR-100 revA)的固件程序 v1.13。使用工具 Binwalk,很快的就从中发现并提取出一个只读 SquashFS 文件系统,没用多大功夫我就将这个固件程序的 web server (/bin/webs)加载到了 IDA 中:

Strings inside /bin/websoriginal="http://ittopic.gotoip1.com/qee/wordpress/wp-content/uploads/2013/7397/dir-100_loaded_in_ida.png" />

/bin/webs 中的字符信息

  基于上面的字符信息可以看出,这个/bin/webs 二进制程序是一个修改版的 thttpd,提供路由器管理员界面操作功能。看起来是经过了台湾明泰科技(D-Link 的一个子公司)的修改。他们甚至很有心计的将他们很多自定义的函数名都辅以“alpha”前缀:

Alphanetworks' custom <a href=functions" width="290" height="434" data-original="http://ittopic.gotoip1.com/qee/wordpress/wp-content/uploads/2013/7397/alpha_functions.png" />

明泰科技的自定义函数

  这个alpha_auth_check函数看起来很有意思!

  这个函数被很多地方调用,最明显的一个是来自alpha_httpd_parse_request函数:

Function call to alpha_auth_check

调用 alpha_auth_check 函数

  我们可以看到alpha_auth_check函数接收一个参数(是存放在寄存器$s2 里);如果alpha_auth_check返回-1(0xFFFFFFFF),程序将会跳到alpha_httpd_parse_request的结尾处,否则,它将继续处理请求。

  寄存器$s2 在被alpha_auth_check函数使用前的一些操作代码显示,它是一个指向一个数据结构体的指针,里面有一个 char*指针,会指向从 HTTP 请求里接收到的各种数据;比如 HTTP 头信息和请求地址 URL:

$s2 is a pointer to a data structure

$s2 是一个指向一个数据结构体的指针

  我们现在可以模拟出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;

alpha_auth_check code snippet

alpha_auth_check 函数代码片段

  这些字符串比较过程看起来非常有趣。它们提取请求的 URL 地址(在http_request_t数据结构体的偏移量 0xB8 处),检查它们是否含有字符串“graphic/” 或 “public/”。这些都是位于路由器的 Web 目录下的公开子目录,如果请求地址包含这样的字符串,这些请求就可以不经身份认证就能执行。

  然而,这最后一个 strcmp 却是相当的吸引眼球:

An interesting string comparison in alpha_auth_check

alpha_auth_check 函数中一个非常有趣的字符串比较

  这个操作是将http_request_t结构体中偏移量 0xD0 的字符串指针和字符串“xmlset_roodkcableoj28840ybtide”比较,如果字符匹配,就会跳过check_login函数,alpha_auth_check操作返回1(认证通过)。

  我在谷歌上搜索了一下“xmlset_roodkcableoj28840ybtide”字符串,只发现在一个俄罗斯论坛里提到过它,说这是一个在/bin/webs 里一个“非常有趣”的一行。我非常同意。

  那么,这个神秘的字符串究竟是和什么东西进行比较?如果回顾一下调用路径,我们会发现http_request_t结构体被传进了好几个函数:

call_graph

  事实证明,http_request_t结构体中处在偏移量 0xD0 处的指针是由httpd_parse_request函数赋值的:

Checks for the User-Agent HTTP <a href=header" width="644" height="215" data-original="http://ittopic.gotoip1.com/qee/wordpress/wp-content/uploads/2013/7397/user_agent_struct_1.png" />

检查 HTTP 头信息中的 User-Agent 值

Populates http_request_t + 0xD0 with a pointer to the User-Agent header string

将 http_request_t + 0xD0 指针指向头信息 User-Agent 字符串

  这代码实际上就是:

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 型号使用的是相同的固件):

Accessing the admin page of a DI-524UP

访问型号 DI-524UP 路由器的主界面

  基于 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,这个后门的作者真是位天才!

发表评论
用户名: 匿名