A look at WeChat security

原文地址:http://blog.emaze.net/2013/09/a-look-at-wechat-security.html

TL;DR: Any (unprivileged) application installed on an Android phone can instruct WeChat to send an hash of your password to an external, attacker-controlled server. If you are a WeChat user, it is probably worth reading the rest of this post :-)

Introduction

Nowadays, instant messaging (IM) has become one of the main applications of mobile phones, with plenty of "apps" available and literally billions of messages exchanged every day. With the widespread diffusion of mobile Internet traffic plans, IM applications are rapidly replacing other forms of mobile communication, such as text messages and, in some situations, even e-mails. 

As conversations are rapidly converging to IM applications, it is natural to start asking how secure this communication channel actually is, and if users can really trust IM apps and their back-end infrastructure. We decided to pick one of these applications and look "under the hood", in order to see how the developers tried to ensure the confidentiality of in-transit communications. 

After a quick survey of available IM applications, we decided to start with WeChat, a popular mobile IM platform developed by the China-based Tencent company. The choice of this specific application was quite arbitrary and mainly based on the fact that, in this period, WeChat is publicized a lot on the Italian TV. 

WeChat is a feature-rich and sophisticated mobile application, which allows users to communicate via text messages, voice calls, to share photos and videos, and much more. The app is available for several mobile platforms, but we focused on the Android version only: according to Google Play, WeChat for Android alone has more than 50 million downloads. Most of the issues discussed in this post should affect Android versions of WeChat up to 4.5.1. On August 5th, 2013, Tencent released version 5.0, which introduced some major changes; we still have to analyze this version in detail.

A glimpse at the network traffic

The most obvious and easy thing to start with was an analysis of the network traffic generated by the application during normal usage. At this aim, we instructed our Android emulator to save all network traffic to file, we installed WeChat, we logged in and sent a couple of text messages. Part of the traffic generated by WeChat is shown below.

As can be seen from the figure, most of the traffic travels on TCP port 8080, typically reserved for HTTP connections (previous versions of WeChat were using the standard HTTPS port, tcp/443). However, at a first sight, the payload of these packets looks quite strange; indeed, Wireshark is not even able to dissect the HTTP payload. 

Looking more closely, we noticed WeChat developers implemented a custom communication protocol: we were able to recognize an initial packet header, right at the beginning of the payload, that confirms these are actually not HTTP/HTTPS sessions. More precisely, we identified the following header fields: 

  • Packet length (4 bytes)
  • Header length (2 bytes, always equal to 0x0010)
  • Protocol version (2 bytes, always equal to 0x0001)
  • Opcode (4 bytes, specifies the actual command encapsulated in this packet)
  • Sequence number (4 bytes)

This initial header is followed by an opcode-dependent message body, usually in encrypted form. Briefly, the first message is encrypted by the application using RSA, with an hard-coded public key; next messages are encrypted in AES. In WeChat versions up to 4.3.5 we identified several vulnerabilities which allow an attacker who can intercept the traffic to quickly decrypt the message body, thus being able to access the messages sent and received by the user. More recent versions seems to be immune to these attacks, but we still have to perform a more in-depth analysis of the encryption scheme implemented in the latest WeChat releases. 

Debugging

Here we come to the interesting part :-) WeChat includes an undocumented debugging infrastructure, probably used by developers for testing purposes. However, this infrastructure can also be abused by attackers to steal sensitive information concerning a WeChat user account. 

In detail, WeChat reads debug settings from an Android ContentProvider, identified by URI "com.tencent.mm.coolassist.debugprovider/config". This ContentProvider is used by the application as a centralized source of debug configuration parameters, and can be employed to specify which debug messages should be logged to the Android console (adb logcat), to save log messages to the sdcard, and even configure a remote logger. 

From a security perspective, the remote logging feature is surely the most interesting one. By exploiting this functionality, an attacker can develop a malicious application which exposes the aforementionedContentProvider and, through specially-crafted debug settings, makes WeChat to send logs to an external, attacker-controlled, server. Such a malicious application would not require any special Android permission.

It is worth considering that logged messages disclose sensitive information about the users, including the user ID, password hash and other details. As an example, here is an excerpt from a remote log session: 

09-09 14:32:51 594 V/MicroMsg.MMBuiltInIP <-- data-blogger-escaped-br="" data-blogger-escaped-dump="" data-blogger-escaped-end="" data-blogger-escaped-mmbuiltinip=""> 09-09 14:32:51 626 D/MicroMsg.AccInfo update session info: session=, uin=-1893467821
09-09 14:32:51 635 I/MicroMsg.AutoAuth sending remote request, network.active=false
09-09 14:32:51 666 I/MicroMsg.AutoAuth.SceneInfoQueue inQueue: netid=0
09-09 14:32:51 691 V/MicroMsg.SDK.SyncTask sync task done, return=0, cost=56(wait=0, run=56)
09-09 14:32:51 783 V/MicroMsg.NetStatWatchDog dkreport status:9999002 nowCount:1 ret:1
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)
09-09 14:32:51 885 D/MicroMsg.NetStatWatchDog item.toByteArray() :433
09-09 14:32:52 101 D/MicroMsg.GYNet encoding, type=380, key=, time=284
09-09 14:32:52 108 I/MicroMsg.GYNet sendImp reqData.len:866
09-09 14:32:52 114 D/MicroMsg.NetStatusUtil activeNetInfo extra=internet, type=0

 

As can be seen from these logs, the application forwards to the remote server the user name (ukcd_ao03gex3y2731v), another user identifier (uin, with value -1893467821), and even the user's password hash (5f4dcc3b5aa765d61d8327deb882cf99). It should be noted the hash value is a plain MD5 of the user's password, sent to the server for the authentication. Obviously some parameters in the above logs have been edited to prevent readers from hacking our account but, yes,5f4dcc3b5aa765d61d8327deb882cf99 is the MD5 for string "password" and this was really our account's password :-) 

The next section details the communication protocol used by WeChat to interact with the remote log server. 

Remote logging protocol

Remote logging can be enabled by configuring the following debug keys: 

  • .com.tencent.mm.debug.log.level = 0
  • .com.tencent.mm.debug.log.mmlog.url.mm.log = <ip1>:<port1>
  • .com.tencent.mm.debug.log.mmlog.url.push.log = <ip2>:<port2>

The first key defines the log level ("0" simply means to log everything), while others are used to set the log server address for the two main WeChat application modules (mm and push). 

WeChat developers implemented a trivial key derivation scheme to allow the application and the remote log server to agree on an encryption key to cipher debug logs. In a nutshell, the app reads three ASCII lines from the server and uses these lines to derive a DES key. Before transmitting debug messages, the application encrypts them in DES/ECB using this key. 

The key generation function is implemented by the following Python code snippet. Functiongeneratekey() receives in input the three lines sent by the server and returns the corresponding DES key. 

import hashlib

def mangle(data):
    charset = "0123456789abcdef"
    r = ""
    for c in hashlib.md5(data).digest():
        r += charset[(ord(c) >> 4) & 0xf]
        r += charset[ord(c) & 0xf]
    return r

def generatekey(line0, line1, line2):
    seed = line1[2:]
    seed += str(int(line2[2:]))
    seed += "dfdhgc"
    key = mangle(seed)[7:21]
    return key

 

We also implemented a buggy "quick & dirty" Python script that listens for incoming connections, sends out three ASCII lines, computes the key and deciphers incoming messages. The script is available here

As a final note, we would like to point out that the ".com.tencent.mm.debug.log.mmlog.url.* " configuration keys are not supported by the latest version of WeChat (5.0). However, this version still queries the ContentProvider for debug settings and part of the logging functionalities have been moved to a dedicated JNI library. We plan to investigate these new features in the future, so at the moment we cannot exclude that the remote logging mechanism has simply been moved elsewhere. 

Local database encryption

WeChat locally stores application data in an encrypted SQLite database named "EnMicroMsg.db". This database is located in the "MicroMsg" subfolder inside the application's data directory (typically something like "/data/data/com.tencent.mm"). 

The database is encrypted using SQLCipher, an open source extension for SQLite that provides full database encryption. The encryption password is derived from the "uin" parameter (see previous sections) combined with the device identifier through a custom function. More precisely, the key generation function leverages the mangle() function shown in the previous Python snippet. The actual database encryption key can be generated through the following pseudo-code: 

password = mangle(deviceid + uin)[:7]

 

Here deviceid is the value returned by the Android API functionTelephonyManager.getDeviceId(). Follows a sample SQLCipher console session that demonstrate how the EnMicroMsg.db database can be decrypted. 

$ sqlcipher EnMicroMsg.db
sqlite> PRAGMA key = 'b60c8e4';
sqlite> PRAGMA cipher_use_hmac = OFF;
sqlite> .schema
CREATE TABLE conversation (unReadCount INTEGER, status INT, ...
CREATE TABLE bottleconversation (unReadCount INTEGER, status INT, ...
CREATE TABLE tcontact (username text PRIMARY KEY, extupdateseq long, ...
...

 

It is also worth pointing out that, as the key generation algorithm truncates the password to 7 hex characters, it would be not so difficult for motivated attackers who are able to get the encrypted database to brute force the key, even without knowing the uin or the device identifier. 

Conclusions

In this post we discussed some security weaknesses that affect Android versions of WeChat up to 4.5.1 (and possibly others). We tried to contact developers to notify our findings, but with no luck: we wrote an e-mail to Tencent technical support both on August 30th and on September 3th, but we got no reply. With the recent widespread diffusion of mobile instant messaging, app developers should take security into more serious considerations, as their application will probably rapidly become an attractive target for attackers.

时间: 2024-11-02 07:14:03

A look at WeChat security的相关文章

移动安全初探:窃取微信聊天记录、Hacking Android with Metasploit

在这篇文章中我们将讨论如何获取安卓.苹果设备中的微信聊天记录,并演示如何利用后门通过Metasploit对安卓设备进行控制.文章比较基础.可动手性强,有设备的童鞋不妨边阅读文章边操作,希望能激发大家对移动终端的安全兴趣. (文章内容存在一定攻击性,目的在于普及终端安全知识.提高安全意识,如有非法使用,后果自负) "如何获取Android.iPhone手机上的微信聊天记录? " 0×00 条件: 安卓设备已获取root权限,安装SSHDroid(通过ssh.ftp连接手机) Apple设

java.security.Guard翻译

  Overview Package  Class Use Tree Deprecated Index Help JavaTM 2 PlatformStd. Ed. v1.4.2  PREV CLASS   NEXT CLASSFRAMES    NO FRAMES     All Classes SUMMARY: NESTED | FIELD | CONSTR | METHODDETAIL: FIELD | CONSTR | METHOD java.security Interface Gua

【资料整理】Security Features in the CRT

     本文简要整理了 MSDN 上关于 "Security Features in the CRT" 方面的内容.详细参考官网.      许多老旧的 CRT 函数都有更新且更加安全的后续版本.在安全版本存在的情况下,老旧版本都会被标识为废弃(deprecated)的状态,而安全版本都会以 "_s" 作为后缀. 注意:上面提到的废弃的状态不代表函数已经从 CRT 中被移除,而是表示不推荐使用.而安全版本同样不能阻止或者自行修正安全错误,而是其能够在这类错误发生时

PHP Security Consortium

PHP Security Consortium[31-Jan-2005] An international group of PHP experts today announced the official launch of the PHP Security Consortium (PHPSC), a group whose mission is to promote secure programming practices within the PHP community through e

java.security.PublicKey翻译

  Overview Package  Class Use Tree Deprecated Index Help JavaTM 2 PlatformStd. Ed. v1.4.2  PREV CLASS   NEXT CLASSFRAMES    NO FRAMES     All Classes SUMMARY: NESTED | FIELD | CONSTR | METHODDETAIL: FIELD | CONSTR | METHOD java.security Interface Pub

Jboss EJB3.0 security

  Calculator.java package org.jboss.tutorial.security.bean;   import javax.ejb.Remote;   @Remote public interface Calculator {    int add(int x, int y);    int subtract(int x, int y);    int divide(int x, int y); }       CalculatorBean.java package o

SECURITY INVOKER存储过程权限提升漏洞

MySQL AB SECURITY INVOKER存储过程权限提升漏洞. 受影响系统: MySQL AB MySQL 5.1.x < 5.1.18. MySQL AB MySQL 5.0.x < 5.0.40. 不受影响系统: MySQL AB MySQL 5.1.18. MySQL AB MySQL 5.0.40. 描述: MySQL是一款使用非常广泛的开放源代码关系数据库系统,拥有各种平台的运行版本. MySQL在处理SQL SECURITY INVOKER存储过程的返回状态时存在漏洞,本

PHP安全《PHP Security》

安全 [  原书信息 ]<SAMS Teach Yourself PHP in 10 Minutes>Author: Chris Newman    Publisher : Sams Publishing Pub Date : March 29, 2005 ISBN : 0-672-32762-7 Pages : 264 [  翻译信息 ]翻译人员:heiyeluren翻译时间:2006-3-15翻译章节:<Lesson 24. PHP Security>中文名称:PHP安全 PH

Online CPU Console using a Web Control Library with .NET Security(1)

web ABSTRACTAdministering applications and servers when not connected to the network can be a nightmare, especially when only a few people manage the application. Just imagine going out for an evening on the town and then you're paged at one o'clock