欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

对微信Android版的交互协议和加密模式的进一步分析及修复方案

程序员文章站 2022-03-16 12:04:09
老外做的,credit属于老外。虽然我觉得老外没有找到真正直接可用的漏洞,但是我觉得分析很透彻,已经为之后可能更深入的攻击做了铺垫。 我这里再对一些攻击点总结提炼下,加上了一些我...
老外做的,credit属于老外。虽然我觉得老外没有找到真正直接可用的漏洞,但是我觉得分析很透彻,已经为之后可能更深入的攻击做了铺垫。

我这里再对一些攻击点总结提炼下,加上了一些我自己的手工分析,作为对它的补充。

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的。

 

 

 

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。