问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
wayos维盟路由器固件模拟与多个漏洞复现
硬件与物联网
针对于wayos固件利用FirmAE进行固件模拟,解包后进行多个漏洞复现,涉及到telent服务的mqtt协议问题、csrf漏洞、命令注入漏洞,并且在复现过程中详细解释了漏洞挖掘的流程与思路。
0x01 固件模拟 ========= 下载wayos相关固件:<http://www.wayos.com/products/WAM9900siWANquanqianzhaodedaiw.html> 尝试使用FirmAE进行固件模拟;  访问192.168.1.1,80端口,可以进入到wayos路由器的用户登录界面。  以默认账户口令root admin可以登录到用户管理界面;  0x02 固件解包获取文件系统 =============== `binwalk -Me WAN\_9900-21.10.09V.trx`  0x03 mqtt协议telnet账户泄露漏洞 ======================= rcS是linux启动配置脚本文件,在会linux启动后执行。查看他的rcS文件发现会自启动telnet,固件模拟之后对端口进行扫描发现确实开启了telnet服务。   利用grep命令搜索字符串:WayOS和login,然后取并集,发现这两个词同时出现在mqtt\_ai这个文件中,然后对这个文件进行逆向分析。  采用string字符串定位login,然后交叉引用跳转到相关的函数进行分析。  这里是MIPS架构的文件,我的IDA逆向F5反编译的时候发生问题,这里尝试使用Ghidra进行反编译,找到上述定位到的函数mqtt\_ai\_sw\_telnet\_login。 ```js undefined4 mqtt\_ai\_sw\_telnet\_login(int param\_1,int param\_2) { ssize\_t sVar2; int iVar3; size\_t sVar4; uint uVar5; int iVar6; char \*pcVar7; char local\_2028 \[4096\]; char acStack4136 \[4096\]; char cVar1; memset(acStack4136,0,0x1000); iVar6 = 0; memset(local\_2028,0,0x1000); do { while( true ) { #双层循环,外层循环为死循环 memset(local\_2028,0,0x1000); sVar2 = recv(param\_1,local\_2028,0x1000,0); if (sVar2 < 1) { #recv失败检查,local\_2028为缓冲区 return 0xffffffff; } for (pcVar7 = local\_2028; #字符处理 ((cVar1 = \*pcVar7, cVar1 == '\\r' || (cVar1 == '\\n')) || (cVar1 == ' ')); pcVar7 = pcVar7 + 1) { } iVar3 = strncmp(pcVar7,"User Name:",10); if (iVar3 != 0) break; #检查是否为User Name,如果是推出内部循环 if (3 < iVar6) { #iVar为尝试次数,3次失败后return 0xfffffff puts("login failed"); return 0xffffffff; } sVar4 = snprintf(acStack4136,0x1000,"root\\n"); 将acStack4136赋值为root if (0xfff < sVar4) { sVar4 = 0xfff; } send(param\_1,acStack4136,sVar4,0); #send发送root sVar4 = snprintf(acStack4136,0x1000,"admin\\n"); 将acStack4136赋值为admin if (0xfff < sVar4) { sVar4 = 0xfff; } send(param\_1,acStack4136,sVar4,0); #send发送admin sVar4 = snprintf(acStack4136,0x1000,"enable\\n"); if (0xfff < sVar4) { sVar4 = 0xfff; } send(param\_1,acStack4136,sVar4,0); #send发送enable pcVar7 = "configure\\n"; LAB\_0044c564: iVar6 = iVar6 + 1; #验证次数加一 uVar5 = snprintf(acStack4136,0x1000,pcVar7); sVar4 = 0xfff; if (uVar5 < 0x1000) { sVar4 = uVar5; } send(param\_1,acStack4136,sVar4,0); #send发送configure,而且这一步pcVar7改变,就不会再被进入其他strcmp验证 } #内层循环结束 iVar3 = strncmp(pcVar7,"Login:",6); #匹配关键指纹login:,进入login的验证模式 if (iVar3 == 0) { if (3 < iVar6) goto LAB\_0044c7bc; sVar4 = snprintf(acStack4136,0x1000,"root\\n"); if (0xfff < sVar4) { sVar4 = 0xfff; } send(param\_1,acStack4136,sVar4,0); #send发送root pcVar7 = "admin\\n"; goto LAB\_0044c564; #send发送admin,尝试次数加一,再去发送configure } iVar3 = strncmp(pcVar7,"Username:",9); #再次匹配Username: if (iVar3 == 0) { if (3 < iVar6) { LAB\_0044c7bc: puts("login failed"); return 0xffffffff; } sVar4 = snprintf(acStack4136,0x1000,"admin\\n"); if (0xfff < sVar4) { sVar4 = 0xfff; } send(param\_1,acStack4136,sVar4,0); iVar6 = iVar6 + 1; uVar5 = snprintf(acStack4136,0x1000,"admin\\n"); sVar4 = 0xfff; if (uVar5 < 0x1000) { sVar4 = uVar5; } send(param\_1,acStack4136,sVar4,0); \*(undefined \*)(param\_2 + 0x31) = 2; } else { #针对于configure处理 if (\*(char \*)(param\_2 + 0x31) == '\\x02') { sVar4 = strlen(pcVar7); iVar3 = strncmp(pcVar7 + (sVar4 - 2),"# ",2); if (iVar3 == 0) { return 0; } } else { sVar4 = strlen(pcVar7); } iVar3 = strncmp(pcVar7 + (sVar4 - 10),"(config)# ",10); if (iVar3 == 0) { \*(undefined \*)(param\_2 + 0x31) = 0; return 0; } pcVar7 = strstr(pcVar7,"WayOS#"); if (pcVar7 != (char \*)0x0) { \*(undefined \*)(param\_2 + 0x31) = 1; return 0; } } } while( true ); } ``` 首先理解wayos中telnetd的登录验证流程,telnetd文件是一个链接到busybox的链接文件,逆向分析busybox的telnetd的登录过程。  利用Ghidra逆向分析busybox,在string窗口中过滤login、login incorrect等关键词,然后通过交叉引用可以快速的定位到目标位置。 这里首先是通过login函数打印登录时的提示指纹login:,然后通过终端获取到输入的命令,进行基础的处理与检查,如果正常流程则进入到nvram函数。   获取解析之后所作的事情为利用nvram命令获取nvram信息,其中nvram get http\_username获取用户名,然后与输入相匹配。  如果用户名输入失败(ivar22==0)则直接到exit,正确则提示输入password,然后这里有time函数和random函数提供了一个校验码,  password可以通过一个循环实现,此循环最多循环三遍。  这里有一个关键跳转,这里uVar16与password相关,uvar24为校验码。  根据以上分析,telnet的登录机制应该是没有问题,此漏洞的问题在于talnet服务mqtt协议的自动登录机制,在接受到对应的username或者password提示之后,会自行发送用户和密码,这里泄露了telnet的用户和口令。 利用mqtt\_ai文件中mqtt\_ai\_sw\_telnet\_login函数中的可以账户和口令可以进行telnet的登录获取shell。 0x04 httpd命令注入漏洞 ================ 将文件系统中的httpd可执行程序进行逆向分析,首先对于system函数进行Ghidra逆向分析,在Function栏里面过滤出system函数,找到函数的位置后点击交叉引用,得到所有调用system函数的位置,如下图所示。  从中找出其中system执行的命令中含有可控数据流的部分,然后反向追溯,查看其是否对数据流进行了过滤等防护。 通过逐个调用点反汇编,发现如下可疑的system函数的参数数据流可控。    首先分析第一个,从用户输入获取usb\_username和use\_husername没有进行完全过滤,拼接的命令直接作为system()参数执行,引发命令注入。根据其关键词usb\_username和usb\_hosorname可以推断出其是有关于usb的,并且可能和用户有关。 从网页上找到对应可能有关的功能,先熟悉该防火墙的功能。可以发现其对于usb储存具有安全功能,而且其中具有一个共享服务,共享服务就有可能和用户相关系。  浏览器F12查看器network,设置usb共享服务之后有这样一个请求与上述的分析相类似。  利用burpsuit进行测试,漏洞点如下所示,可以利用;进行原来的用户名与嵌入的命令分割,同时利用``(单引号,键盘的左上角)将需要嵌入的命令包含,这样system执行命令时会首先执行引号内的命令,然后将结果与echo命令的内容相结合,然后通过echo执行输出。 `sprintf(acStack304,"echo \\"%s = %s\\" >> /etc/smbusers","smbadmin",uVar7); system(acStack304);` 这里首先需要对于嵌入的命令进行url编码。  然后利用burpsuit抓包,抓取到如下数据包,然后将hname部分字段替换后发送:  查看tmp文件夹,发现新建了一个1.txt文件,同样可以执行其他命令,比如反弹shell、写马、泄露文件等等。  另外的两个可疑漏洞点指定了数据流必须是%d为数字型,而且该数字是上面的函数根据nvram\_get(xxx)获取对应进程信息,难以有效控制,所以难以利用。 0x05 CSRF漏洞 =========== 继续在httpd文件逆向中字符串窗口筛选usb,发现有如下一些功能,尤其是usb.upload.htm文件可以在免登录的情况下访问,输入文件后进行删除功能。  输入需要删除的文件之后发现其在没有登录的情况下权限不够   然后会自动跳转到,需要usb\_share账户的认证登录。这个服务需要在配置端的usb储存共享服务中开启。  登录后再次访问到usb\_upload.htm文件,发现其报文cookie中没有tocken防护,也没有reference,而且再次点击删除提示文件不存在,说明执行了删除操作,则应该具有csrf漏洞。  抓包删除功能的请求,利用burpsuit进行csrf的poc的生成(需要pro版本的burpsuit)。然后使用usr\_share用户登录后的状态下打开poc文件,则执行文件删除功能。  文件上传功能相似: 
发表于 2022-11-15 10:18:25
阅读 ( 10514 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
用户180910387
5 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!