查看原文
其他

【Signal】数据分析

电子物证 2023-02-19


 前言





Signal是款号称全球最安全的聊天APP,得到很多巨头的高度认可。前段时间协助某地区做案件分析时遇到了该APP,通过研究员加班工作顺利完成了该APP的解析。
   以下介绍安卓Signal的分析过程。该思路也是APP数据分析的典型思路,可以为办案人员提供一定的参考。


01 准备工作




分析一个安卓APP,首先要拿到包名并提取apk样本(为什么不网上直接搜索下载呢?因为小众的APP有可能网上下载的和手机上使用的不一致,为了不出现这种差异让分析工作出现异常,所以一般都是直接从检材中提取apk样本)。 

获取应用包名

首先手机上打开目标APP,然后执行命令:

adb shell dumpsys activity top | grep  ACTIVITY

ACTIVITY  org.thoughtcrime.securesms/.ApplicationPreferencesActivity 

确认Signal的包名是org.thoughtcrime.securesms。

 

获取应用apk路径

adb shell pm path org.thoughtcrime.securesms

package:/data/app/org.thoughtcrime.securesms-y7sU-2ioiaHagBFGo4QN9w==/base.apk

 

提取apk样本

adb pull  /data/app/org.thoughtcrime.securesms-y7sU-2ioiaHagBFGo4QN9w==/base.apk  signal.apk

 

提取应用数据文件,提取数据这里不做陈述。


02 初步数据分析     





安卓常见的数据文件类型和常用的目录存储的数据类型

帐号信息检索
推荐使用FileLocator直接检索数据文件来查找明文信息,直接搜索注册的手机号码,在shared_prefs目录中的org.thoughtcrime.securesms_preferences.xml文件中,找到了注册的手机号码信息。

同时也发现了几个名字涉及到数据库加密密钥的字段描述,这里还不知道有何作用,先记下来后续分析看看是否会用到。


确认数据库文件几乎所有的APP应用数据都会存储在SQLite数据库中,在Signal数据的databases中存在“signal.db”,测试发现随着聊天内容增多,该db文件大小增长,基本判断数据在此db中。该文件无法直接打开,hex查看无“SQLite format 3”头部,基本断定该db已加密。那么开始分析“signal.db”。


03 聊天数据db初步分析




Signal是开源的当然可以使用官方github上的代码来分析,但是不排除该样本apk可能是由官方代码修改自行编译或者版本不同等原因导致跟官方代码有差异,所以直接使用样本apk反编译来分析。
使用jadx反编译工具打开apk样本。全局搜索“signal.db”,在package org.thoughtcrime.securesms.database.helpers的SQLCipherOpenHelper类中发现了引用。


此引用是唯一的引用,基本上可以确认该db使用的是SQLCipher加密库,加密初始化参数如下
sQLiteDatabase.rawExecSQL("PRAGMA  kdf_iter = '1';");
sQLiteDatabase.rawExecSQL("PRAGMA cipher_page_size =  4096;");
其中也有疑似数据库密钥初始化的对象(上图蓝色行),那么接下来就要分析SQLCipher的密钥信息。

04 数据库加密秘钥分析 




    直接搜索“SQLCipherOpenHelper”类的引用,发现没有搜索到任何结果,可能是工具问题。

那直接尝试搜索“new SQLCipherOpenHelper”类构造的代码:

就一个结果。发现第四行就是“signal.db”的初始化构造类。基本可以确认就是这里创建的实例。

数据库构造函数最后一个参数“DatabaseSecret”类的变量,是由函数“getOrCreateDatabaseSecret”返回的,函数名的英文翻译过来就是“获取或者创建数据库密钥”,很有可能就是数据库密钥生成的方法,看下该函数的内容:


方法不多,依次分析(不一一截图了)。

  • “getDatabaseUnencryptedSecret”是从上述的org.thoughtcrime.securesms_preferences.xml里面读取字段名为“pref_database_unencrypted_secret”的内容;

  • “getDatabaseEncryptedSecret”是从该xml里面读取字段名为“pref_database_encrypted_secret”字段的内容。


    该检材提取到的数据中只有“pref_database_encrypted_secret”字段,所以走得是“return getEncryptedDatabaseSecret(databaseEncryptedSecret); ”这个条件分支。该字段的内容是一段json(因为存储到了xml里面所以被编码了),编码后的json内容为:

{“data“:“Wpin1YTzuYYLrFL/rKQCDXH1Zfyr60Vs2eiwrvnS6AO6zzhcmRi0FzjR5wM/nOkx“,

“iv“:“C7RWgb7kIkUAkpyG“}


继续分析。

ANDROID_KEY_STORE = "AndroidKeyStKEY_ALIAS = "SignalSecret"

上面的方法还是非常清晰的,APP运行后完整的解密数据库密钥的流程和算法都有了,总结一下:




05 KeyStore的思考




    解密过程中,使用了“AndroidKeyStore”容器,并从中读取了一个名字为“SignalSecret”的数据。经常查询Android密钥库系统KeyStore,类似苹果的keychain,是一个APP私有存储数据的容器。只有创建者(APP)可以读取,其他APP无权访问,多层可信任加密保护,一般情况下很难离线破解。

 
已Root的测试手机截图



提取KeyStore中存储的数据是Signal分析最困难的地方。想到的最容易实现的方法是root或临时提权后通过内存方式提取key。

跟办案单位沟通后,完成了手机的提权操作。提权完毕后,利用Frida这款HOOK框架工具提取keyStore。


06 选择Frida的切入点



最直接的就是HOOK数据库构造类的构造函数,然后打印出来解密后的数据库密钥,不过后来分析发现了一个静态方法:

 

通过“DatabaseFactory”类的静态方法“getInstance”可以直接获取到实例,有了实例就可以直接输出变量内容,那么利用此函数,无需hook写出一个非常简便的Frida脚本:

得到了数据库密钥,解析就非常容易了。C++调用SQLCipher读取数据库初始化代码:




07资源文件解密 




  聊天中涉及到的图片、语音等资源文件,数据库中存储signal.db的part表中,字段名为_data。资源文件存储在应用数据的app_parts目录中,例:

“part3292***7.mms”。同样也是加密存储的。




上面数据库分析的过程中,
在“org.thoughtcrime.securesms_preferences.xml”文件中留意到了还有一个“pref_attachment_encrypted_secret”的字段,看名字疑似与“附件”有关。而在“DatabaseFactory”类的构造函数里面,还有一个“AttachmentDatabase”类的初始化过程,与数据库操作非常类似。有了上面分析数据库密钥的思路和流程,那么以“AttachmentDatabase”类的构造函数为入口,继而分析后

(过程不贴了,与上述的思路雷同)得到了关键函数:



总结下来与数据库密钥的流程差不多但是更复杂一些,也依赖于KeyStore完成解密,算法及参数为:


 


同样,上述的Frida脚本中增加“附件”的key读取,捕捉到key后,解密出可以正常浏览的资源文件。至此Signal分析初步完成,接下来通过查询逻辑关联即可完成聊天记录等数据的分析和保存。

 总结


Signal分析过程不算难,目前难点在于存储在KeyStore中的信息如何提取,目前也没有什么太好的突破思路。


转自:上海歆仁


Signal已被破解
FBI应对暗网犯罪能力缺失,美司法部要求制定暗网治理战略

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存