在后渗透或者取证阶段,快速收集用户信息是第一位的,今天这篇文章来记录下关于telegram数据解密和账号劫持的内容,本文实验环境为最新版的telegram windows端5.1.7版本。
1. telegram的一些说明
1.1 常见特性
- 多端登录: telegram支持多端同时登录,这也是telegram能够被账号无感劫持的基础
- 数据存储:telegram存储在本地的数据都是加密的,包括文字、媒体和其他类型的数据,但是在云端也会保存这些数据,用于多端的数据同步
- 数据传输加密:telegram在普通对话时并不是端到端加密,而是客户端到服务端加密,只有私密对话才会端到端加密,所以私密对话无法同步到不同的端上,见https://core.telegram.org/techfaq#q-how-does-server-client-encryption-work-in-mtproto
- Telegram的客户端都是开源的,windows端的源码地址:https://github.com/telegramdesktop/tdesktop
1.2 数据存储结构
telegram的默认数据存储在C:\Users\<YourUsername>\AppData\Roaming\Telegram Desktop\tdata目录下,如果是potable文件,则数据存储和在Telegram.exe同目录下的tdata目录,下面是我本地的目录结构

其中比较关键的几个文件如下:
- key_datas:这个文件保存了账户基本信息,包括账号数量,当前处于active状态的账号,更重要的是保存了其他文件解密的密钥localKey
- settingss:这个文件保存了当前客户端的设置,比如语言、ip代理、下载目录、软件主题、软件分辨率等等
- D877F783D5D3EF8Cs:这个文件保存了用户的userId,以及与telegram云端进行数据通信时所使用到的加密密钥
- D877F783D5D3EF8C/maps:这个文件保存了用户的基本信息,包括用户userId,头像,姓名,电话,还有一些配置或者资源文件的文件名
这个D877F783D5D3EF8C看起来很突兀,其实这是telegram的一套命名规则,第1个用户相关数据保存在就是
data目录
D877F783D5D3EF8Cs文件
D877F783D5D3EF8C文件夹
第二个用户相关的数据保存在
data#2目录
A7FDF864FBC10B77s文件
A7FDF864FBC10B77文件夹
第三个用户相关的数据保存在
data#3目录
F886DDC461824Fs文件
F886DDC461824F文件夹
依次类推。telegram客户端会根据登录的次序进行编号,分别为data,data#2,data#3,然后根据这个编号来生成目录名称,这部分代码在Telegram\SourceFiles\storage\storage_account.cpp中,
使用python来构造生成规则的代码如下
import hashlib
def compute_data_name_key(dataname: str):
filekey = hashlib.md5(dataname.encode('utf8')).digest()[:8]
return file_to_to_str(filekey)
def file_to_to_str(filekey: bytes):
return ''.join(f'{b:X}'[::-1] for b in filekey)
if __name__=="__main__":
print(compute_data_name_key("data"))
print(compute_data_name_key("data#2"))
print(compute_data_name_key("data#3"))
print(compute_data_name_key("data#4"))
print(compute_data_name_key("data#5"))
print(compute_data_name_key("data#6"))
print(compute_data_name_key("data#7"))
结果为:
D877F783D5D3EF8C
A7FDF864FBC10B77
F886DDC461824F
C2B598D9127787
0CA814316818D8F6
45DFC5B510146D
93987688214F8E69
2. telegram数据解密
这一部分我的需求主要是解密账户信息,拿到登录账号的手机号、昵称、用户名等信息,所以暂不涉及对缓存数据比如媒体图片视频信息的解密。
3.1 key_datas文件
key_datas文件主要保存了两个信息:
- 账户数量和当前处于激活状态的账号编号
- 解密密钥localKey,这是解密其他文件的前提
key_datas的解析在解密流程在Telegram\SourceFiles\storage\storage_domain.cpp的startModern函数中,文件结构为:4字节的魔数+4字节的版本号+加密data+最后16字节的hashsum,解析文件结构的代码在Telegram\SourceFiles\storage\details\storage_file_utilities.cpp
其中:
- 0-4字节的魔数固定为
TDF$,这是判断文件类型的标志 - 4-8字节是version,取出来转int类型即可
- [8:-16]是加密data
- 最后16字节是hashsum,这是为了校验文件的完整性
解密加密data的步骤如下:
1.解析Data,得到salt, keyEncrypted, infoEncrypted
2.调用createLocalKey(),根据salt和passcode生成一个本地密钥passcode_key生成passcodeKey
3 调用DecryptLocal()和密钥导出函数,使用导出密钥解密keyEncrypted,得到localKey
4.调用DecryptLocal(),使用localkey解密infoEncrypted,得到info
上面的passcode是telegram隐私设置里的local passcode,默认为空,具体的逻辑看源代码即可,下面是解析完的结果:

3.2 settingss文件解密
settingss文件的结构和key_datas文件一样,也是:4字节的魔数+4字节的版本号+加密data+最后16字节的hashsum
其中加密data的解析步骤在Telegram\SourceFiles\storage\localstorage.cpp的start函数中,简略步骤如下:
1. 解析data,得到 salt 和 settingsEncrypted
2. 调用CreateLegacyLocalKey()根据salt生成加密密钥SettingsKey
3. 调用DecryptLocal()解密settingsEncrypted得到settings
4. 使用ReadSetting解析settings,形成key和value的对应关系
需要注意的是第4步骤的解析过程,key和value的关系在Telegram\SourceFiles\storage\details\storage_settings_scheme.cpp的ReadSetting函数中,算法还原时如果有问题可以仔细看下这里。
最终结果如下,有一些参数比如dbiFallbackProductionConfig这些,需要二次解析,这里我暂时用不着所以就不解析了

3.3 7FDF864FBC10B77s
文件的结构和上面一样,也是4字节的魔数+4字节的版本号+加密data+最后16字节的hashsum
加密data的解析过程如下:
1. 调用DecryptLocal(),解密data,其中key为上面提到的localKey
2. 调用ReadSetting()解析上一步解密后的data,形成key和value的对应关系
3. 调用setMtpAuthorization()解析得到userId和 客户端-服务端 通信密钥

这里的userID在软件上是看不到的,可以给@userinfobot发送信息查看自己的userId:

3.4 7FDF864FBC10B77/maps
maps文件是我主要需要解析的文件,这个文件可以拿到用户的基本信息,包括用户名、手机号等。还是一样先解析成4字节的魔数+4字节的版本号+加密data+最后16字节的hashsum
然后对data进行解密
1. 使用decryptLocal()对data进行解密,密钥是localKey
2. 使用readMapWith()对解密后的data进行解析,形成key和value的对应关系
这部分代码在Telegram\SourceFiles\storage\storage_account.cpp,主要是对lskSelfSerialized的二次解析比较费劲,用户信息都存在这个blockid里。最终结果如下:

3. telegram账号劫持
telegram的账号劫持,就是将受害者的登录态session文件给复制到本地,然后就可以在本地登录对方账号,劫持时只需要复制下面三个文件即可
key_datas
D877F783D5D3EF8Cs
D877F783D5D3EF8C/map
如果受害者有两个账户,只需要追加下面两个文件即可,以此类推
A7FDF864FBC10B77s
A7FDF864FBC10B77/map
复现步骤如下:
- 清空本地telegram的tdata文件夹
- 打开本地的telegram,重新生成tdata文件目录结构
- 将受害者的文件,复制覆盖到本地,重新打开telegram即可实现账号劫持
劫持时对方是无感的,需要注意下面几个点:
- 本地的telegram最好使用最新版,以保证兼容性
- 如果受害者设置了local passcode(注意这里并不是Two-Step Verification),则账号劫持后也需要输入锁定密码,似乎目前只能通过爆破的手段来获取passcode,因为比较小众,故未研究此场景,劫持后会弹出下图所示的验证:

4. telegram安全措施
为避免账号劫持以及减少被盗后的危害,可以采取下面的措施
- 设置local passcode
- 日常沟通使用端到端加密,但是已经2024年了,windows客户端还不支持双向加密
- 定期检查在线登录设备
浙公网安备 33010602011771号