微信二维码崩溃原理分析
2023-4-25 16:55:26 Author: 401SecNote(查看原文) 阅读量:11 收藏

点击蓝字 关注我们

2023.4.23 晚,一张带有模糊二维码的图片引起了大家的关注,只要打开该图片或长按就能直接导致微信崩溃。这个BUG除了Windows客户端,在iOS、Android、macOS均存在。一时间圈里人都在疯狂转发,甚至有人玩笑说将图片要发到朋友圈、设为头像等。当然,玩笑之外更关心的是其崩溃的原因,下面将会结合这两天其他大佬的分析文章以及自己的一些分析过程对此进行简单的阐述,如有不正确的地方欢迎大家指正。

下图是最开始的图片。

崩溃原因分析

获取崩溃log

在苹果手机 设置—>隐私与安全性—>分析与改进—>分析数据可以拿到微信崩溃日志,通过log KERN_INVALID_ADDRESS at 0x000000000 可以看出在访问一下地址为0的内存,表明这是一个空指针访问触发的崩溃。

获取栈回溯信息

通过Android Studio监控安卓手机崩溃现场可以获取以下log:

通过上图不仅可以看到backtrace还有崩溃现场的寄存器信息。null pointer deference 也说明了和苹果手机log给出的结果一样,这是一个空指针解引用。backtrace中出现问题的是一个so库libwechatQrMod.so,将该so库拖出来ida看一下。结合backtrace信息,第0栈帧是在libc库中memcpy函数,第一栈帧在libwechatQrMod.so 地址为0x773bc 。直接跳转到该地址,可以看到BL .memcpy 结合寄存器x1值为0x0,可以确定是memcpy的src地址为0x0导致的崩溃。

分析到这其实我们知道了这是一个空指针解引用导致的崩溃,具体为何长按图片会触发到这里,可以通过backtrace信息一层函数一层函数的来追下去,不过对于这样一个没有符号的binary来说需要很强的逆向能力,并且这个过程是十分枯燥的。而通过搜索这个库名可以获取不少信息,其主要逻辑是解析二维码的算法,而图片中那张模糊的二维码正是触发问题的关键。后来在github上发现有个开源的项目WeChatQRCode[1]下载下来直接运行,扫描恶意图片发现和微信出现同样的问题。

通过backtrace中libopencv_java4.so关键字直接找到开源项目opencv [2],在该项目的modules中找到了wechat_qrcode,很快知乎上[3]有人就公布了问题的核心代码根据知乎答主的提示也找到了对应的补丁修复[4]在 DecodedBitStreamParser: : decdeByteSegment 中,攻击者可以在数据段的末尾添加一个字节段,其字符计数器非零但内容为空。对应到下方代码中即nbytes 等于count是用户控制的非零,但available是0,因为该字节段的内容是空的。关键在于199行本来是想将count范围修正,但是开发手误写错了,这里count直接等于available

这里count为0, 203行readBytes是一个空指针。

后面DecodedBitStreamParser::decodeByteSegment

会调用DecodedBitStreamParser::append函数,其中nBytes的值是一开始用户传入的count的值不是0

最后在108行会触发空指针访问。

修复

1. 199行运算符优先级错误改为count = (available +7)/8

2. 在count值改变后没有及时更新nBytes的值,导致这两个变量的不一致,这个问题是导致漏洞的根本原因。后来修改为在199行count值改变后再定义nBytes ,将count值赋值给nBytes ,后面分配readBytes指针的长度和调用append函数传入的值都使用nBytes 。

复现

满足前面填充合适的block充满二维码再在最后一个block中构造内容为空,长度不为0的情况即可。在hack_put函数中增加了判断,当num等于0的时候,改为233。当执行到qr.add_data(hack_data)时,因为hack_data的内容为空,会触发到上面的判断,结果就将这段数据段改成了count等于0,内容为空,触发空指针解引用导致微信崩溃。下面是生成的图片。

总结

本来以为23号晚上发生的事件微信会连夜加班,第二天早晨就会修复。不过没想到截止到4月24日下午5点,这个BUG依旧存在[6]。今天Android端已经通过热补丁修复,而IOS由于无法下发热补丁依然存在,需要等待新版本发布进行更新,不过目前依然没收到微信发布的新版本。

参考链接

[1]https://github.com/jenly1314/WeChatQRCode

[2]https://github.com/opencv/opencv_contrib

[3]https://www.zhihu.com/question/597372415/answer/2998008132

[4]https://github.com/opencv/opencv_contrib/pull/3480

[5]https://gist.github.com/GZTimeWalker/3ca70a8af2f5830711e9cccc73fb5270

[6]https://mp.weixin.qq.com/s?__biz=MjM5NjA0NjgyMA==&mid=2651223085&idx=1&sn=c36480a0fe22634de5f442da9cad284d&chksm=bd1de6a68a6a6fb083c4d7e07620e09564ea0001847cfe5709e62f04ef831671d01e6c11617c&scene=126&sessionid=1682406729#rd

欢迎关注团队公众号平台:

我知道你  在看  哦


文章来源: http://mp.weixin.qq.com/s?__biz=MzU4NzAyMDM4Mw==&mid=2247484086&idx=1&sn=831a1013387785dc63ec19548da05a44&chksm=fdf32386ca84aa90e69e3f9c7105163fc8db9614110e563390c243401490d46b0943bb55bea2#rd
如有侵权请联系:admin#unsafe.sh