文章总结: 文档分析某设备固件漏洞挖掘过程,发现多个命令注入漏洞。核心问题包括:1)xxxxxxxcmd.php文件存在无回显命令注入,通过socket传递ECMD指令触发system执行;2)时区设置功能TSE参数未过滤直接拼接进system命令;3)用户创建功能存在命令注入但需鉴权绕过配合利用。漏洞涉及2.x/3.x版本差异,提供具体代码分析和复现方法。 综合评分: 85 文章分类: 漏洞分析,代码审计,WEB安全,渗透测试,红队
漏洞挖掘从黑盒到白盒
只会看监控的实习生
2026年6月13日 08:00 广东
在小说阅读器读本章
去阅读
因为在检索关键字的时候,发现虽然system函数在php代码里出现的很频繁,但是实际上可控的几乎没有,但是在最新版固件里发现了一个奇葩的东西,问题存放在xxxxxxxcmd.php文件里
在2.x和1.x版本中,这块是没有下面的exec()的,这也导致了更新后,反而这块出现了一个新的问题
所以这块复现也非常的简单粗暴,因为这个接口实际上还存在一个有回显的命令注入,但是这一处是没有回显的,所以需要把输出结果打印出来,方便我们进行查看
而后直接访问是否有东西输出出来,发现也是真实存在的
刚刚有提到过,除了这一处,其实还存在一个命令注入,这里是一接口双注入
跟踪代码xxxxxxxcmd.php可以看见,通过前端传入xxxxxug_cmd参数后,连接本地socket服务,利用eachMsg(“ECMD$DBGCMD”)进行消息传送而后执行
查看socket.php发现,eachMsg仅用来socket消息传递,里面并没有核心实现
所以其实还是要看二进制文件xxxxxonitor
继续追踪代码
核心代码如下
if ( !strncmp(s_1, "ECMD", 4uLL) ) { strcpy((char *)s_5, "/usr/local/apache/htdocs/ExecCmd.txt"); sub_423458(6LL, "recv commond(%s)", s_1); strcpy(s_3, "ECMDCB"); if ( sendto(fd, s_3, 6uLL, 0, (const struct sockaddr *)&addr_, 0x10u) < 0 ) { v200 = sub_421704(); sub_423458(4LL, "send data to %s failed,ErrCode = %d!", s_2, v200); } memset(s_4, 0, 0x800uLL); if ( !strncmp(&src__2, "cd", 2uLL) ) { n32 = src__3; path = (const char *)&src__3; do { if ( n32 != 32 ) break; n32_1 = *(unsigned __int8 *)++path; n32 = n32_1; } while ( n32_1 ); if ( chdir(path) == -1 ) { nptrh = *__errno_location(); v216 = strerror(nptrh); sprintf( (char *)s_4, "nohup echo \"change current work dir failed(errno(%d): %s)\" > %s 2>&1 &", nptrh, v216, (const char *)s_5); } else { sprintf((char *)s_4, "nohup echo \"change current work dir succeed\" > %s 2>&1 &", (const char *)s_5); } system((const char *)s_4); } else { sprintf((char *)s_4, "nohup %s > %s 2>&1 &", &src__2, (const char *)s_5); system((const char *)s_4); }
首先 !strncmp(s_1, “ECMD”, 4uLL)检查s_1的前4字节是否是”ECMD”,此处对应eachMsg(“ECMD$DBGCMD”),因为传入的是ECMD,所以会进入到后面的条件分支
此时发现进入后续判断 !strncmp(&src__2, “cd”, 2uLL),判断传入的参数是不是cd指令,当输入的不是cd指令的时候,就会执行sprintf((char *)s_4, “nohup %s > %s 2>&1 &”, &src__2, (const char *)s_5);
假设传入的参数为ls指令,那么指令构造为 nohup ls > ExecCmd.txt 2>&1 & ,而后将此指令存储在s_4变量后,经过system((const char *)s_4)执行,因此造成此处的命令执行漏洞
可以看到,这里也是利用
strcpy((char *)s_5, “/usr/local/apache/htdocs/ExecCmd.txt”);
进行写入,将执行结果最终写入到ExecCmd.txt里面,实现命令回显
查看执行结果,也是如愿所偿的执行成功了
继续挖掘,我们发现,在一个设置时令的功能里,出现了如下的代码
直接去ida里看一下对应的位置
核心代码如下
if ( !strncmp(s_1, "TSE", 3uLL) ) { sub_423458(6LL, "recv commond(%s)", s_1); s_4[0] = 0LL; strcpy((char *)s_4, &src__2); sprintf(s_6, "/root/timezone.shell %s &", (const char *)s_4); system(s_6);
后端传入”TSE:$TIMEZONE” 后,进入此步骤,而后将s_6 赋值为“/root/timezone.shell TIMEZONE &”,最后经过system(s_6);执行
/root/timezone.shell文件内容没什么东西,与本次漏洞无关,就不展示了,其实这个接口还有一个位置也存在这个问题,但是因为漏洞原理是一样的,所以不进行展示
然后查看执行效果
后续在审计的时候,发现了一个比较有意思的现象,在2.x和3.x固件版本中,系统在创建用户的时候,调用了一个不应该出现的代码
调用了一下系统的另一个用来创建用户的二进制文件,也就是说,创建用户和密码这块居然存在命令注入漏洞,只不过在3.x版本,这个接口做了鉴权,但是可以配合认证绕过和其他没鉴权的RCE去读密码然后解密,然后正常模拟登录拿到cookie后来执行
因为主要针对的还是认证的绕过以及密码的获取、命令的执行,所以以上就是这个设备主要的问题了
首发:https://forum.butian.net/share/4569
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:只会看监控的实习生 《漏洞挖掘从黑盒到白盒》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。







评论