阅读对象:软件开发从业者、网络安全从业者、Linux桌面运维、信创运维
摘要(省流版)
微信Linux版(低于4.1.0.16)这几天出现一个漏洞,当用户在聊天界面点击接收的文件时,若文件名存在恶意字符串,会出现任意命令远程执行漏洞。
从根源来看,是微信开发犯了极其低下的错误,即在WeChatAppEx中,直接通过字节符拼接命令行,来试图执行xdg-mime命令。
对于信创和linux桌面运维,根本解决方法是升级到最新的微信Linux版本(4.1.0.16及以上);旧版本仍能通过某些方式触发该漏洞。
对于开发的教训是,永远不要自行使用字符串拼接的方法,来执行系统命令。
--------------------
免责声明
本文仅用于软件开发学习和讨论,以提高软件开发的安全编码水平。请勿使用本文所提供的内容及相关技术从事非法活动,由于传播、利用此文所提供的内容或工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果均与文章作者及本账号无关。
--------------------
xdg-open不背这黑锅
这几天微信Linux版本(低于4.1.0.16)出现了一个比较大的漏洞。攻击者可通过微信,发一个有问题的文件给受害者。这个有问题的文件特征是,文件名带有一些特殊字符(如分号、反引号、$()、换行符等,比如【`$(whoami)`.docx】)。当用户在微信Linux版本内点击后该文件后,会执行文件名里面的命令,从而导致远程执行漏洞(RCE)。
由于微信Linux版本的最大市场之一,是用在当前政企领域的信创市场,因此影响面还是有点广的。

(复现成功结果)
有文章认为,微信Linux的漏洞,是微信用了Electron框架,并且以字符串拼接方式运行了xdg-open命令行。但笔者认为这个说法是错误的。第一,众所周知,微信采用QT框架而非Electron框架;第二,从报错截图来看,漏洞触发时,微信并非在运行xdg-open,而是在运行xdg-mime。

(错误:微信什么时候用了Electron框架?这是QQ吧?)
大厂开发也犯低级错误
那么为什么微信要运行xdg-mime?笔者的理解是,用户点击文件后,微信会调用自己的文件处理逻辑。如果是pdf、doc等文件,微信会调用自己的文档查看器。在这个过程中,微信Linux的开发使用xdg-mime程序来探测文件。

(微信Linux的文档查看器。至于为啥会打开一份内存规格PDF文件,因为内存贵啊嘤嘤嘤)
从pstree和strace来看,xdg-mime的触发路径,是微信主体程序传递接收文件的路径给WeChatAppEx后,由WeChatAppEx执行。那么现在唯一要确定的是,WeChatAppEx究竟是如何运行xdg-mime命令,结果导致了漏洞的产生?
wechat,35652|-WeChatAppEx,35712|-sh,36033 -c xdg-mime query filetype "/微信Linux用户接收文件路径/恶意文件名.docx"`- 正在执行的RCE攻击命令
(pstree关系)
IDA反编译WeChatAppEx的结果让人大吃一惊:还真是无过滤,直接字符串拼接方式!
啊,不是,您大厂居然也犯这种低级错误?

(IDA反编译关键代码)
所以漏洞成因很明显了,确实是一个命令注入(Command Injection)漏洞。微信Linux开发直接通过字符串拼接的方式,拼接了如下命令:
xdg-mime query filetype "文件路径字符串"在这个过程中,文件路径字符串没有做过滤和转义,结果在下一步使用popen()执行的时候,由于是在shell环境下,恶意文件名里面的恶意字符串被激活和执行解析,从而导致命令行注入,比如把【`$(whoami)`.docx】里面的【$(whoami)】执行了。
高级点的攻击的话,确实还可以在恶意文件名内写入下载脚本执行的命令,从而将受害者的桌面Linux变为肉鸡。
因此可以确定,这次微信Linux版的漏洞,既不是QT的问题,也不是C++的问题;即便用Rust,你这么写,下场也是身败名裂。
解决方法
漏洞发生之后,微信Linux版紧急升级到4.1.0.16版本,并且在服务器端做了紧急拦截,现在有问题的文件名均无法发送。从“strings WeChatAppEx”命令行猜测,微信Linux版似乎是去掉了通过xdg-mime来检测文件类型。
因此对于使用Linux的普通用户,以及做信创和linux桌面运维的工作人员,根本解决方法只有一个,是升级到最新的微信Linux版本,即4.1.0.16及以上。使用旧版本后患无穷,因为仍能通过某些刁钻的方式触发漏洞——比如通过软连接方式触发。当然这种触发方式,已经超出微信旧版本能做的防御范畴了。
而对于开发,在这里面得到的教训是,永远永远不要自行使用字符串拼接的方法,来执行系统命令。