GitHub - HyperSine/forensic-qqtoken: QQ安全中心 - 动态口令的生成算法
source link: https://github.com/HyperSine/forensic-qqtoken
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
README.md
QQ安全中心 - 动态口令的生成算法
鉴于该App的服务群体是中文用户,故本篇文章不提供英文版。
I won't provide English version for this article. Because the app serves for QQ users which are Chinese mainly.
1. 动态口令的生成算法
动态口令的生成算法和RFC6238协议类似。
这里我们用 secret
代表动态口令的生成密钥,它一般是长度为32的octets,例如:
b'\xa4\x22\x99\xe1\xce\xd4\xe7\x05\x48\x43\x92\x58\x3a\xd0\xb7\x6a\x8d\x6e\x89\x3c\x2d\xd1\x98\xbc\x39\x9b\x4c\x9a\x4e\x34\x21\xeb'
算法的大致过程如下:
-
将当前北京时间向下对齐到30s,并按下面的格式格式化:
yyyy-MM-dd HH:mm:ss
得到一个长度为19的octets,记为
timestamp
。例如,若当前北京时间为
2020-02-12 13:02:46
,则向下对齐到30s,得到timestamp
为:b'2020-02-12 13:02:30'
-
将
timestamp
添加到secret
后面,并对新的octets做SHA256运算,得到长度为32的octets,记为digest
。例如:
# digest = hashlib.sha256(secret + timestamp).digest() digest = b'\x89\x60\xf9\xeb\x42\x67\x61\x0e\x74\xc0\x98\x59\x76\x88\xaf\x6e\x25\xfb\xf2\x6b\x6c\xe3\xbe\x95\x02\xcb\xed\xd8\x3e\x0b\xf9\x44'
-
将
digest
的每个octet在原位分割成高四位和低四位,得到digest_exp
。例如:
digest_exp = [8, 9, 6, 0, 15, 9, 14, 11, 4, 2, 6, 7, 6, 1, 0, 14, 7, 4, 12, 0, 9, 8, 5, 9, 7, 6, 8, 8, 10, 15, 6, 14, 2, 5, 15, 11, 15, 2, 6, 11, 6, 12, 14, 3, 11, 14, 9, 5, 0, 2, 12, 11, 14, 13, 13, 8, 3, 14, 0, 11, 15, 9, 4, 4]
-
按照如下公式得到6位动态口令的每一位:
2. 如何获取secret
要求条件:
-
手机安装了“QQ安全中心”这个App,版本6.9.10或以上,并且在App里登录了QQ账号。
-
手机已经root。
secret
是存储在
/data/data/com.tencent.token/databases/mobiletoken.db
数据库文件中,该数据库是经过加密的。
并且在数据库中,secret
被加密保存,加密的密钥存在
/data/data/com.tencent.token/shared_prefs/token_save_info.xml
下面将会介绍如何提取 secret
:
-
确保“QQ安全中心”已经退出。
-
查看
/data/data/com.tencent.token/shared_prefs/token_save_info.xml
文件的内容。你可以用adb来查看:
$ adb shell gemini:/ $ su gemini:/ # cat /data/data/com.tencent.token/shared_prefs/token_save_info.xml <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <boolean name="token_status" value="true" /> <string name="token_info">14C27B6EC74543302F02C01B50E16ED7</string> <int name="token_type" value="2" /> </map> gemini:/ #
其中
14C27B6EC74543302F02C01B50E16ED7
就是加密secret
的密钥。每次“QQ安全中心”退出,这个值都会变化。
-
提取
mobiletoken.db
:$ adb root restarting adbd as root $ adb pull /data/data/com.tencent.token/databases/mobiletoken.db /data/data/com.tencent.token/databases/mobiletoken.db: 1 file pulled. 0.9 MB/s (13312 bytes in 0.013s)
-
使用
decrypt-database.py
解密mobiletoken.db
:Usage: ./decrypt-database.py <mobiletoken.db的路径>
例如:
$ ./decrypt-database.py ./mobiletoken.db
-
查看加密的
secret
:$ sqlite3 ./mobiletoken.db SQLite version 3.28.0 2019-04-15 14:49:49 Enter ".help" for usage hints. sqlite> select hex(data) from main.token_conf; AE28874351F682CFDD5263E3D71D74E7D8847F00D157923539811AD0920499B9A88A5B8021C1ED2E7B20BD597ADA33AE sqlite>
其中
AE28874351F682CFDD5263E3D71D74E7D8847F00D157923539811AD0920499B9A88A5B8021C1ED2E7B20BD597ADA33AE
就是加密的secret
。 -
解密出
secret
:Usage: ./decrypt-secret.py <加密的secret> <加密secret的密钥>
例如:
$ ./decrypt-secret.py AE28874351F682CFDD5263E3D71D74E7D8847F00D157923539811AD0920499B9A88A5B8021C1ED2E7B20BD597ADA33AE 14C27B6EC74543302F02C01B50E16ED7 a42299e1ced4e705484392583ad0b76a8d6e893c2dd198bc399b4c9a4e3421eb
其中
a42299e1ced4e705484392583ad0b76a8d6e893c2dd198bc399b4c9a4e3421eb
就是我们要找的secret
。
3. 使用secret生成动态密码
Usage:
./generate-qqtoken.py <secret>
例如:
$ ./generate-qqtoken.py a42299e1ced4e705484392583ad0b76a8d6e893c2dd198bc399b4c9a4e3421eb 530800
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK