OK,又是周末晚上,没有约会,只有一大瓶Shasta汽水和全是快节奏的音乐…那就研究一下程序吧。
一时兴起,我下载了D-link无线路由器(型号:DIR-100 revA)的固件程序 v1.13。使用工具Binwalk,很快的就从中发现并提取出一个只读SquashFS文件系统,没用多大功夫我就将这个固件程序的web server(/bin/webs)加载到了IDA中:
基于上面的字符信息可以看出,这个/bin/webs二进制程序是一个修改版的thttpd,提供路由器管理员界面操作功能。看起来是经过了台湾明泰科技(D-Link的一个子公司)的修改。他们甚至很有心计的将他们很多自定义的函数名都辅以“alpha”前缀:
这个alpha_auth_check函数看起来很有意思!
这个函数被很多地方调用,最明显的一个是来自alpha_httpd_parse_request函数:
我们可以看到alpha_auth_check函数接收一个参数(是存放在寄存器$s2里);如果alpha_auth_check返回-1(0xFFFFFFFF),程序将会跳到alpha_httpd_parse_request的结尾处,否则,它将继续处理请求。
寄存器$s2在被alpha_auth_check函数使用前的一些操作代码显示,它是一个指向一个数据结构体的指针,里面有一个char*指针,会指向从HTTP请求里接收到的各种数据;比如HTTP头信息和请求地址URL:
我们现在可以模拟出alpha_auth_check函数和数据结构体的大概样子:
- structhttp_request_t
- {
- charunknown[0xB8];
- char*url;//Atoffset0xB8intothedatastructure
- };
- intalpha_auth_check(structhttp_request_t*request);
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
<strong>alpha_auth_check</strong>本身是一个非常简单的函数。它会针对<strong>http_request_t</strong>结构体里的一些指针进行字符串<strong>strcmp</strong>比较操作,然后调用<strong>check_login</strong>函数,实际上就是身份验证检查。如果一旦有字符串比较成功或<strong>check_login</strong>成功,它会返回1;否者,它会重定向浏览器到登录页,返回-1;
</p>
<p style="text-align:center;background-color:#f8f8f8;text-indent:28px;color:#333333;">
<a class="cboxElement" href="http://s8.51cto.com/wyfs01/M00/31/14/wKioJlJl38bjSKZ1AACsy3Au8H8689.jpg"><img class="fit-image" alt="520131022091922" src="http://www.whatled.com/content/uploadfile/201405/e0f00abc9c08dabb1a93b79b2422a9bb20140524034047.jpg" width="498" /></a>
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
这些字符串比较过程看起来非常有趣。它们提取请求的URL地址(在<strong>http_request_t</strong>数据结构体的偏移量0xB8处),检查它们是否含有字符串“graphic/” 或 “public/”。这些都是位于路由器的Web目录下的公开子目录,如果请求地址包含这样的字符串,这些请求就可以不经身份认证就能执行。
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
然而,这最后一个strcmp却是相当的吸引眼球:
</p>
<p style="text-align:center;background-color:#f8f8f8;text-indent:28px;color:#333333;">
<a class="cboxElement" href="http://s5.51cto.com/wyfs01/M01/31/16/wKioOVJl38ag73MZAABsD3jBOsE374.jpg"><img class="fit-image" alt="620131022091938" src="http://www.whatled.com/content/uploadfile/201405/8dd549bf72f64aad422d60269763c3b020140524034048.jpg" width="498" /></a>
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
这个操作是将<strong>http_request_t</strong>结构体中偏移量0xD0的字符串指针和字符串“xmlset_roodkcableoj28840ybtide”比较,如果字符匹配,就会跳过<strong>check_login</strong>函数,<strong>alpha_auth_check</strong>操作返回1(认证通过)。
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
我在谷歌上搜索了一下“xmlset_roodkcableoj28840ybtide”字符串,只发现在一个俄罗斯论坛里提到过它,说这是一个在/bin/webs里一个“非常有趣”的一行。我非常同意。
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
那么,这个神秘的字符串究竟是和什么东西进行比较?如果回顾一下调用路径,我们会发现<strong>http_request_t</strong>结构体被传进了好几个函数:
</p>
<p style="text-align:center;background-color:#f8f8f8;text-indent:28px;color:#333333;">
<a class="cboxElement" href="http://s5.51cto.com/wyfs01/M02/31/16/wKioOVJl38eg1WuuAAAjCiWyF7E352.jpg"><img class="fit-image" alt="720131022091953" src="http://www.whatled.com/content/uploadfile/201405/4483c653bc26323686f32c24bc128f5c20140524034048.jpg" /></a>
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
事实证明,<strong>http_request_t</strong>结构体中处在偏移量 0xD0处的指针是由<strong>httpd_parse_request</strong>函数赋值的:
</p>
<p style="text-align:center;background-color:#f8f8f8;text-indent:28px;color:#333333;">
<a class="cboxElement" href="http://s4.51cto.com/wyfs01/M00/31/14/wKioJlJl38eyQmKOAABL9BaSzLM824.jpg"><img class="fit-image" alt="820131022092009" src="http://s4.51cto.com/wyfs01/M00/31/14/wKioJlJl38eyQmKOAABL9BaSzLM824.jpg" width="498" /></a>
</p>
<p style="text-align:center;background-color:#f8f8f8;text-indent:28px;color:#333333;">
<a class="cboxElement" href="http://s4.51cto.com/wyfs01/M01/31/14/wKioJlJl38fSVUpXAABaLUd6w0M742.jpg"><img class="fit-image" alt="920131022092023" src="http://www.whatled.com/content/uploadfile/201405/136d426128fec59688d0543d5375326420140524034104.jpg" width="498" /></a>
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
这代码实际上就是:
</p>
- if(strstr(header,"User-Agent:")!=NULL)
- {
- http_request_t-0xD0=header+strlen("User-Agent:")+strspn(header," ");
- }
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
知道了<strong>http_request_t</strong>偏移量0xD0处的指针指向User-Agent头信息,我们可以推测出<strong>alpha_auth_check</strong>函数的结构:
</p>
- #defineAUTH_OK1
- #defineAUTH_FAIL-1
- intalpha_auth_check(structhttp_request_t*request)
- {
- if(strstr(request-url,"graphic/")||
- strstr(request-url,"public/")||
- strcmp(request-user_agent,"xmlset_roodkcableoj28840ybtide")==0)
- {
- returnAUTH_OK;
- }
- else
- {
- //Theseargumentsareprobablyuser/passorsessioninfo
- if(check_login(request-0xC,request-0xE0)!=0)
- {
- returnAUTH_OK;
- }
- }
- returnAUTH_FAIL;
- }
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
换句话说,如果浏览器的User-Agent值是“xmlset_roodkcableoj28840ybtide”(不带引号),你就可以不经任 何认证而能访问web控制界面,能够查看/修改路由器的设置(下面是<span class="kl_auto_internal_links_tag"><a href="http://www.whatled.com/tag/D-Link" title="查看标签为 D-Link 的文章" target="_blank">D-Link</a></span><span class="kl_auto_internal_links_tag"><a href="http://www.whatled.com/tag/路由器" title="查看标签为 路由器 的文章" target="_blank">路由器</a></span>(DI-524UP)的截图,我没有 DIR-100型号的,但DI-524UP型号使用的是相同的固件):
</p>
<p style="text-align:center;background-color:#f8f8f8;text-indent:28px;color:#333333;">
<a class="cboxElement" href="http://s8.51cto.com/wyfs01/M02/31/16/wKioOVJl38expBWeAACthG2zxSw781.jpg"><img class="fit-image" alt="1020131022092040" src="http://www.whatled.com/content/uploadfile/201405/6954381040b23fe5083df58cda8122dc20140524034104.jpg" width="498" /></a>
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
基于HTML页上的源代码信息和Shodan搜索结果,差不多可以得出这样的结论:下面的这些型号的D-Link路由器将会受到影响:
</p>
<ul style="background-color:#f8f8f8;text-indent:0px;color:#333333;">
<li style="color:#333333;">
DIR-100
</li>
<li style="color:#333333;">
DI-524
</li>
<li style="color:#333333;">
DI-524UP
</li>
<li style="color:#333333;">
DI-604S
</li>
<li style="color:#333333;">
DI-604UP
</li>
<li style="color:#333333;">
DI-604+
</li>
<li style="color:#333333;">
TM-G5240
</li>
</ul>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
除此之外,几款Planex路由器显然也是用的同样的固件程序:
</p>
<ul style="background-color:#f8f8f8;text-indent:0px;color:#333333;">
<li style="color:#333333;">
BRL-04UR
</li>
<li style="color:#333333;">
BRL-04<span class="kl_auto_internal_links_tag"><a href="http://www.whatled.com/tag/C" title="查看标签为 C 的文章" target="_blank">C</a></span>W
</li>
</ul>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
你很酷呀,<span class="kl_auto_internal_links_tag"><a href="http://www.whatled.com/tag/D-Link" title="查看标签为 D-Link 的文章" target="_blank">D-Link</a></span>。
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
<strong>脚注:</strong>万能的网友指出,字符串“xmlset_roodkcableoj28840ybtide”是一个倒序 文,反过来读就是“editby04882joelbackdoor_teslmx”??edit by 04882joel backdoor _teslmx,这个后门的作者真是位天才!
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
原文链接:<a href="http://www.devttys0.com/2013/10/reverse-engineering-a-d-link-backdoor/">http://www.devttys0.com/2013/10/reverse-engineering-a-d-link-backdoor/</a>
</p>
<p style="background-color:#f8f8f8;text-indent:28px;color:#333333;">
译文链接:<a href="http://blog.jobbole.com/49959/">http://blog.jobbole.com/49959/</a>
</p>