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

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

明泰科技的自定义函数
这个alpha_auth_check函数看起来很有意思!
这个函数被很多地方调用,最明显的一个是来自alpha_httpd_parse_request函数:

调用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是一个指向一个数据结构体的指针
我们现在可以模拟出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函数代码片段
这些字符串比较过程看起来非常有趣。它们提取请求的URL地址(在http_request_t数据结构体的偏移量0xB8处),检查它们是否含有字符串“graphic/” 或 “public/”。这些都是位于路由器的Web目录下的公开子目录,如果请求地址包含这样的字符串,这些请求就可以不经身份认证就能执行。
然而,这最后一个strcmp却是相当的吸引眼球:

alpha_auth_check函数中一个非常有趣的字符串比较
这个操作是将http_request_t结构体中偏移量0xD0的字符串指针和字符串“xmlset_roodkcableoj28840ybtide”比较,如果字符匹配,就会跳过check_login函数,alpha_auth_check操作返回1(认证通过)。
我在谷歌上搜索了一下“xmlset_roodkcableoj28840ybtide”字符串,只发现在一个俄罗斯论坛里提到过它,说这是一个在/bin/webs里一个“非常有趣”的一行。我非常同意。
那么,这个神秘的字符串究竟是和什么东西进行比较?如果回顾一下调用路径,我们会发现http_request_t结构体被传进了好几个函数:

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

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

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

访问型号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,这个后门的作者真是位天才!
【转】反编译D-Link路由器固件程序并发现后门的更多相关文章
- 我是如何反编译D-Link路由器固件程序并发现它的后门的
OK,又是周末晚上,没有约会,只有一大瓶Shasta汽水和全是快节奏的音乐…那就研究一下程序吧. 一时兴起,我下载了D-link无线路由器(型号:DIR-100 revA)的固件程序 v1.13.使用 ...
- 【转】反编译获取任何微信小程序源码(完)
一.前言最近在学习微信小程序开发,半个月学习下来,很想实战一下踩踩坑,于是就仿写了一个阿里妈妈淘宝客小程序的前端实现,过程一言难尽,差不多两周时间过去了,发现小程序的坑远比想象的要多的多!!在实际练手 ...
- 【ILSpy反编译】C# 写的程序反编译查看是不是也太容易了点吧,太恐怖了。。。
最近由于要写一些界面的东西,写了几个月c#(之前一直做c/c++项目),发现c#写界面很方便,效果也不错,在这个过程中也听说c#程序可以很容易被反编译到,但一直也没时间去自己反编译去试着看看,心想就算 ...
- 教你如何一键反编译获取任何微信小程序源代码(图形化界面,傻瓜式操作)
一键获取微信小程序源代码 Tips: 一键获取微信小程序源码, 使用了C#加nodejs制作 直接解压在D盘根目录下后就可以使用 将小程序文件放到 wxapkg目录下3 这个目录下有一些demo 可以 ...
- 反编译.net下的exe程序
1. 什么叫.net平台 .NET框架是一个多语言组件开发和执行环境,它提供了一个跨语言的统一编程环境..NET框架的目的是便于开发人员更容易地建立Web应用程序和Web服务,使得Internet上的 ...
- 如何保护java程序不被反编译
Java是一种 跨平台的.解释型语言 Java 源代码编译中间“字节码”存储于class文件中.Class文件是一种字节码形式的中间代码,该字节码中包括了很多源代码的信息,例如变量名.方法名 等.因此 ...
- 如何找回微信小程序源码?2020年微信小程序反编译最新教程 小宇子李
前言:在网上看了找回微信小程序源码很多教程,都没法正常使用.微信版本升级后,会遇到各种报错, 以及无法获取到wxss的问题.查阅各种资料,最终解决,于是贴上完整的微信小程序反编译方案与教程. 本文章仅 ...
- Android安全攻防战,反编译与混淆技术完全解析(下)
在上一篇文章当中,我们学习了Android程序反编译方面的知识,包括反编译代码.反编译资源.以及重新打包等内容.通过这些内容我们也能看出来,其实我们的程序并没有那么的安全.可能资源被反编译影响还不是很 ...
- C#防止反编译
http://blog.csdn.net/wangpei421/article/details/42393095 http://www.cnblogs.com/tianguook/archive/20 ...
随机推荐
- selenium自动化定位方式
自动化定位方式 1.String Xpath = String.format("//*[@id=\"saveFileKeyWordsBtnHand\"]/../../.. ...
- C++ 中缀转后缀表达式并求值
//中缀转后缀 #include<iostream> #include<stack> using namespace std; int prio(char x){ ; ; ; ...
- Vue 知识整理—01-基础
一:Vue是什么? Vue是一个JS框架. Vue.js是一套构建用户界面的渐进式框架. 库和框架的区别: ☞库:提供一些 API 工具函数,体现了封装的思想,需要我们主动调用: ☞框架:提供一套完整 ...
- linux-基础命令篇-01
基本命令: who:目前有谁在在线 netstat -a:网络的联机状态 ps -aux:背景运行的程序 sync:将数据同步写入硬盘中的命令 shutdown:惯用的关机命令 reboot, hal ...
- count性能
表有主键列,count(1)的效率会稍微高于count(*),count(主键列)效率会高于count(1).表没有主键列,count(1)效率会高于count(*) count(1).count(* ...
- python----数据驱动@ddt.file_data结合yaml文件的使用
一.创建yaml文件1. 安装yaml模块 pip install pyyaml2. 新建yaml文件 右键任意文件夹-->New-->File,输入文件名并以.yaml或.yml结尾 二 ...
- springBoot 随笔(一)
服务化的世界,越来越多应用拆分为微服务,有些为了业务而拆,也有为了技术而拆,也有什么都不知道就瞎拆的,反正就是要微服务. 以下为一个认识springBoot的简单过程 1/eclipse 新建 mav ...
- 【Python】Part1 应用1-Netcat
01 简介 netcat的主要功能是通过tcp或udp协议传输读写数据. 下面代码用python编写了tcp客户端,服务端,从而实现上传文件,本地执行命令,反弹shell三种功能. 02 代码 imp ...
- PS笔刷的使用002
001设置好的页面如下: 开始002的小记 1.这一套笔刷最常用的五个笔刷: 下面画一个例图 2.画画时候分好图层很重要,把要画的图片一个图层,画纸一个图层,和一个灰色图层,灰色图层使你不会画的超过画 ...
- C# 加载并显示菜单
1,支持cui和cuix. 2,菜单组重复加载或显示,C#下都会崩溃.所以要判断. 3,菜单加到最后. public static AcadMenuGroup LoadMenu(AcadMenuGro ...