对微信Android版的交互协议和加密模式的进一步分析及修复方案
我这里再对一些攻击点总结提炼下,加上了一些我自己的手工分析,作为对它的补充。
btw, 撰写时发现已经在微博转发了。。这里对它的安全性做些澄清,没有这个博客里写的那么严重。
原文见:https://blog.emaze.net/2013/09/a-look-at-wechat-security.html
我测试的版本:
3.6: https://static.apk.hiapk.com/html/2012/06/614689.html
4.3: https://apk.hiapk.com/html/2012/11/997381.html
4.5.1: https://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的。
老外这段写的很详细了,没测试。
漏洞证明:
对第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。