当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2013-037507

漏洞标题:对微信Android版的交互协议和加密模式的进一步分析

相关厂商:腾讯

漏洞作者: 学习乌云

提交时间:2013-09-18 21:18

修复时间:2013-11-02 21:18

公开时间:2013-11-02 21:18

漏洞类型:敏感信息泄露

危害等级:中

自评Rank:10

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2013-09-18: 细节已通知厂商并且等待厂商处理中
2013-09-22: 厂商已经确认,细节仅向厂商公开
2013-10-02: 细节向核心白帽子及相关领域专家公开
2013-10-12: 细节向普通白帽子公开
2013-10-22: 细节向实习白帽子公开
2013-11-02: 细节向公众公开

简要描述:

老外做的,credit属于老外。虽然我觉得老外没有找到真正直接可用的漏洞,但是我觉得分析很透彻,已经为之后可能更深入的攻击做了铺垫。
我这里再对一些攻击点总结提炼下,加上了一些我自己的手工分析,作为对它的补充。
btw, 撰写时发现已经在微博转发了。。这里对它的安全性做些澄清,没有这个博客里写的那么严重。

详细说明:

原文见:http://blog.emaze.net/2013/09/a-look-at-wechat-security.html
我测试的版本:
3.6: http://static.apk.hiapk.com/html/2012/06/614689.html
4.3: http://apk.hiapk.com/html/2012/11/997381.html
4.5.1: http://apk.hiapk.com/html/2013/05/1495796.html
5.0.1: https://play.google.com/store/apps/details?id=com.tencent.mm
1. 老外提到微信之前版本用了a custom communication protocol,在HTTP上的。
并简单弄出了它的协议规范。这个没测试。
2. 微信的Debugging和Remote logging protocol。
这个主要依赖于一个并不存在的Content Provider,它的scheme是com.tencent.mm.coolassist.debugprovider/config。我仔细分析了以上四个版本,相应的Provider是不存在的,应该只是在微信内部测试版里有,方便调试。所以这也是为什么老外说了这句:“an attacker can develop a malicious application which exposes the aforementioned ContentProvider”。也就是说,只有被攻击者重打包的微信,才会出现老外说的“Any (unprivileged) application installed on an Android phone can instruct WeChat to send an hash of your password to an external, attacker-controlled server”。
在下面的【漏洞证明】里,微信的四个版本全部有对debugprovider进行query。
用户登录认证时,password是直接md5的,没有加salt。可想在腾讯服务器上,用户的密码也是直接md5的。
3. 本地数据库加密模式被破解:
老外这段写的很详细了,没测试。

漏洞证明:

对第2点做下证明,其他的老外都说了。
(1) 四个版本都存在那个debugprovider的URL,但相应的Provider是不存在的。

$ grep -r debugprovider *
com.tencent.mm_134345_apktool/smali/com/tencent/mm/coolassist/DebugProviderConstants$Config.smali: const-string v0, "content://com.tencent.mm.coolassist.debugprovider/config"
com.tencent.mm_134345_src/src/com/tencent/mm/coolassist/DebugProviderConstants$Config.java: public static final Uri a = Uri.parse("content://com.tencent.mm.coolassist.debugprovider/config");
com.tencent.mm_134600_apktool/smali/com/tencent/mm/g/b.smali: const-string v0, "content://com.tencent.mm.coolassist.debugprovider/config"
com.tencent.mm_134600_src/src/com/tencent/mm/g/b.java: public static final Uri CONTENT_URI = Uri.parse("content://com.tencent.mm.coolassist.debugprovider/config");
com.tencent.mm_145215_apktool/smali/com/tencent/mm/c/b.smali: const-string v0, "content://com.tencent.mm.coolassist.debugprovider/config"
com.tencent.mm_145215_src/src/com/tencent/mm/c/b.java: public static final Uri CONTENT_URI = Uri.parse("content://com.tencent.mm.coolassist.debugprovider/config");
com.tencent.mm-352-v5.0.1_apktool/smali/com/tencent/mm/h/b.smali: const-string v0, "content://com.tencent.mm.coolassist.debugprovider/config"
com.tencent.mm-352-v5.0.1_src/src/com/tencent/mm/h/b.java: public static final Uri CONTENT_URI = Uri.parse("content://com.tencent.mm.coolassist.debugprovider/config");


(2) 可以进而搜出谁用了这个URI

$ grep -r "b.CONTENT_URI" *
com.tencent.mm_134600_src/src/com/tencent/mm/ui/LauncherUI.java: Cursor var1 = this.getContentResolver().query(com.tencent.mm.g.b.CONTENT_URI, this.Az, (String)null, (String[])null, (String)null);
com.tencent.mm_134600_src/src/com/tencent/mm/booter/h.java: Cursor var2 = var1.getContentResolver().query(com.tencent.mm.g.b.CONTENT_URI, this.Az, (String)null, (String[])null, (String)null);
com.tencent.mm_145215_src/src/com/tencent/mm/booter/e.java: Cursor var2 = var1.getContentResolver().query(com.tencent.mm.c.b.CONTENT_URI, this.iZ, (String)null, (String[])null, (String)null);
com.tencent.mm-352-v5.0.1_src/src/com/tencent/mm/ui/LauncherUI.java: Cursor var1 = this.getContentResolver().query(com.tencent.mm.h.b.CONTENT_URI, this.aSA, (String)null, (String[])null, (String)null);
com.tencent.mm-352-v5.0.1_src/src/com/tencent/mm/booter/i.java: Cursor var2 = var1.getContentResolver().query(com.tencent.mm.h.b.CONTENT_URI, this.aSA, (String)null, (String[])null, (String)null);


(3) 主要的代码类似这样:

private void adx()
{
Cursor localCursor = getContentResolver().query(com.tencent.mm.g.b.CONTENT_URI, this.Az, null, null, null);
if (localCursor == null)
o.ak("MicroMsg.LauncherUI", "setDebug, cursor is null");
while (true)
{
return;
int i = localCursor.getColumnIndex("key");
int j = localCursor.getColumnIndex("type");
int k = localCursor.getColumnIndex("value");
while (localCursor.moveToNext())


(4) 对于下面这段隐私信息泄漏:

09-09 14:32:51 810 D/MicroMsg.AutoAuth account info updated:AccInfo:
|-uin =-1893467821
|-user =ukcd_ao03gex3y2731v
|-session =
|-pass =5f4dcc3b5aa765d61d8327deb882cf99
|-pass2 =5f4dcc3b5aa765d61d8327deb882cf99
`-cookie =(null)


应该就是来源于下面的代码(四个版本全部感染)

$ grep -r "MicroMsg.AutoAuth" * | grep account
com.tencent.mm_134345_src/src/com/tencent/mm/network/MMAutoAuth.java: Log.d("MicroMsg.AutoAuth", "account info updated:" + var0.a);
com.tencent.mm_134600_src/src/com/tencent/mm/ad/ao.java: com.tencent.mm.sdk.platformtools.o.an("MicroMsg.AutoAuth", "account info updated:" + var0.aee);
com.tencent.mm_145215_src/src/com/tencent/mm/t/am.java: com.tencent.mm.sdk.platformtools.l.Z("MicroMsg.AutoAuth", "account info updated:" + var0.Io);
com.tencent.mm-352-v5.0.1_src/src/com/tencent/mm/network/al.java: com.tencent.mm.sdk.platformtools.y.aw("MicroMsg.AutoAuth", "account info updated:" + var0.bzu);

修复方案:

腾讯:
1. 再仔细评估下自己的协议交互、加密模式如果attacker已知的话,微信是否还安全。
2. 再评估下password直接md5这点,似乎有点弱。虽然比国内大部分公司都好了。
3. debug信息,以及相关的设置应该完全从release版移出。虽然你们没有把最重要的那个Content Provider给放进来。
用户:
1. 千万别root,要不然攻击者就可以拿到微信加密的数据库,然后在知道加密模式的情况下一样可以破。
2. 别用被重打包的微信,从官方可信渠道下载apk。

版权声明:转载请注明来源 学习乌云@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2013-09-22 10:08

厂商回复:

感谢反馈,我们已经在跟进确认中

最新状态:

暂无


漏洞评价:

评论

  1. 2013-09-18 21:20 | xsser 认证白帽子 ( 普通白帽子 | Rank:254 漏洞数:18 | 当我又回首一切,这个世界会好吗?)

    谢谢

  2. 2013-09-18 21:27 | insight-labs 认证白帽子 ( 普通白帽子 | Rank:623 漏洞数:75 | Security guys)

    这个?http://blog.emaze.net/2013/09/a-look-at-wechat-security.html

  3. 2013-09-18 21:31 | 学习乌云 ( 实习白帽子 | Rank:95 漏洞数:14 | 学习ing...)

    @insight-labs 是的。但它不是完全正确的。尤其开头那段【Any (unprivileged) application installed on an Android phone can instruct WeChat to send an hash of your password to an external, attacker-controlled server.】。只有被重打包的微信才可能被利用。

  4. 2013-09-18 21:39 | xsser 认证白帽子 ( 普通白帽子 | Rank:254 漏洞数:18 | 当我又回首一切,这个世界会好吗?)

    @学习乌云 回头帮你转发到drops沉淀下来 :)

  5. 2013-09-18 22:42 | 学习乌云 ( 实习白帽子 | Rank:95 漏洞数:14 | 学习ing...)

    @xsser thanks. 不知道啥时候能不能寄个北京方便面过来?^_^

  6. 2013-09-19 00:44 | 熊猫 ( 实习白帽子 | Rank:64 漏洞数:33 | panda)

    ^=_=^ 厉害

  7. 2013-09-19 01:21 | Blackeagle ( 实习白帽子 | Rank:62 漏洞数:10 | 向WooYun致敬)

    @学习乌云 mark 北京方便面的威信真搞啊/偷笑@xsser

  8. 2013-09-19 10:40 | 学习乌云 ( 实习白帽子 | Rank:95 漏洞数:14 | 学习ing...)

    @Blackeagle 哈哈,因为某人想吃。。

  9. 2013-09-27 16:28 | 学习乌云 ( 实习白帽子 | Rank:95 漏洞数:14 | 学习ing...)

    Update: 今天跟那个老外交流了下,发现我之前的认识有盲区。我太专注漏洞一定要出现在微信本身了,而没考虑到“合谋”的情况:即有问题的Provider不需要一定要在微信里有,嵌入在同一个手机里的任意一个app即可(比如attack app)。然后微信就会根据query结果进行输出日志。虽然4.*以上android不允许第三方app读取logout日志了,但这确实个比较严重的安全问题(比如root过的和低版本的手机)。 @xsser 帮忙把这个帖子撤了吧!

  10. 2013-09-27 16:30 | 学习乌云 ( 实习白帽子 | Rank:95 漏洞数:14 | 学习ing...)

    根据我文中的代码扫描,最新版的5.0.1微信很可能也是有这个问题的。另外可以猜测微信开发人员的工作模式:他们利用一个单独的app来控制主微信里的log信息输出,这样就不区分微信的调试版和release版了。这种开发模式虽然方便,但是对安全很不好! @腾讯