漏洞挖掘从黑盒到白盒
只会看监控的实习生
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
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论