查看原文
其他


摘要:近几年,随着通讯技术的迅猛发展,各式各样的手机软件APP被广泛的应用在各类案件中,给公安机关的案件侦破带来了很大的挑战。本文结合了手机取证的方法和技巧,从手机程序逆向分析角度来进行手机取证的原理介绍。

关键词:手机取证、程序分析、APP逆向、解密与取证

近几年,随着通讯的迅猛发展,违法犯罪份子的反侦察意识也越来越越高,在最近配合警署办理的多起案件中,嫌疑人使用了大量的小众应用,而这些涉案程序往往取证公司的取证软件都暂时不支持自动解析,给公安机关的案件侦破带来了很大的挑战。所以我们需要了解手机程序分析的方法的原理。

手机取证其实简单来说主要分两个方向,一个方向是手机本地数据取证,也是目前手机取证的主要方向,针对的是手机离线缓存数据的提取解析和展示。这里为了和手机云取证区分,手机本地取证就简称手机取证。

另一个就是手机云端数据取证。因为手机本地数据提取在有的时候无法满足取证的要求,逐渐提出的一些新的取证需求,尽管这个需求其实在比较早的时候就被执法人员提出,但是市场上一直也没有成型完善的取证产品来应对,直到2018年各大取证厂家才开始逐渐研发出手机云取证的产品,有的支持的应用数量较少,集成进了手机取证中,有的支持的应用比较多,就单独集成的手机云取证设备。

这两种取证的差异点:
手机取证:针对飞行模式下的手机,完成对手机离线缓存的数据提取分析。
手机云取证:针对手机离线模式下无法查看的数据提取分析。

简单来区分就是开启飞行模式看是否能正常查看数据,当然这个只是一个简单的区分手段,笔者也遇见过有的聊天工具开启自身独有的安全模式,飞行模式软件就处于未登录状态,无法启动软件直接查看数据,但是实际分析发现本地还是缓存的有聊天数据,只是离线就下线,无法正常在软件查看数据。所以这种也是属于手机取证的范畴。有的应用还是需要具体情况具体分析,其根本性还是要看本地数据目录(data/data/包名)下是否有缓存用户数据。才能最终确定采取何种手段完成数据提取。

本文与各位读者共同讨论手机取证的取证方法和原理。


一、手机取证--聊天软件解析


手机取证的核心取证项一般是即时通讯的聊天软件的提取解析。首先,我们先看看聊天软件分析的方法。

1、不加密的聊天工具分析
实验素材与环境:
程序名称:Fincy
应用程序包名:lxtx.im.app
应用程序图标:
实验环境:雷电模拟器3.37
APK运行环境:安卓5.1

分析步骤:
  1. 获取实验素材:导出原始APP素材

  2. 简单逆向,查看配置文件

  3. 安装测试,制作数据

  4. 提取数据,查看数据库


第一个步骤:获取原始素材的方法有很多个,大家可以根据自身情况选择使用

  1. 利用厂商取证软件导出APK文件,可以使用手上有的取证软件提取。

  2. 可以使用市面上的手机助手,比如各大手机厂商的官方手机助手,它们在备份的时候都可以选择备份的应用。选择应用的时候通常可以选择APK和数据,如果我们只需要APK包,那就只勾选APK就好,这里就不做演示了。

可以手工ADB导出,适用于爱动手的小伙伴,这个其实也是软件导出的原理。它和取证厂商导出其实一样的,但是会有一个好处,就是不需要安装一个代理程序,因为大部分公司做这步时,还是会先推送一个代理程序用于提权和数据转发的,其实这里没有必要。接下来我来演示一下:

1.同样确定手机和计算机相连,需要adb环境,如果常用的,可以把adb添加进环境变量,这个大家不了解的可以自行百度。

2.adb devices这里为了方便展示,以模拟器为例


3.启动软件输入这个命令:adb shell dumpsys activity top 很多大佬喜欢用这个命令来捕获包名

但是笔记不喜欢,因为这个命令输出的信息太多了,我喜欢用这个非常简洁准确,输出信息只有一行:adb shell dumpsys window | findstr mCurrentFocus


这样我们就获取到了包名:lxtx.im.app

4.adb shell pm path lxtx.im.app  查看安装包所在路径

5.adb pull /上图的路径  /本地路径  导出安装包

这样就提取出来了这个APK,这种方法适用所有的安卓手机。其实这上面的这几个命令是可以写成批处理脚本或者Python脚本一键执行的。感兴趣的可以自己编写一下,这里就不过多介绍了。了解原理和方法就行。

第二个步骤:简单逆向,查看配置文件,这一步的目的其实从分析角度来说主要是观察这个属性allowBackup是否="true“,因为这个属性会决定它是否支持ADB备份。如果这个属性是”true“,那么后面数据提取就可以用adb backup来备份,这样是最快的。否者数据提取就是一个问题。我们可能需要借助各类的手机助手来实现高级备份,如果有的案件中的手机没有官方提供的备份协议,那么数据提取就几乎不可能了。


当前这个APK它是允许备份的,所以这个APK我们是可以直接利用ADB接口直接备份,无论装在什么型号的手机其实都可以直接备份,而且数据提取还很快。
不过这个例子我们先用个取巧的方式,下一个例子再用ADB接口获取。

第三个步骤:我们用模拟器安装这个应用,并初步制作一些聊天记录,以便于我们分析数据库。

第四个步骤:提取数据,查看数据库
这里我们利用模拟器的便利性,因为首先模拟器有ROOT权限,所以做实验会非常方便,只要应用正常安装并且正常打开,实验就很方便。
我们直接利用文件中转来导出数据:首先要知道需要提取的数据存储在什么路径,其实绝大多数应用的数据库都存放在/data/data/包名/databases/。我们先打开文件管理找到它。勾选这个目录,然后打开共享文件,打开电脑文件夹和安卓文件夹,在安卓文件夹中点击菜单,粘贴选择项。之后在电脑文件夹中就可以看到这个文件夹了。



因为小众的聊天工具数据库一般不会太复杂,所以一一浏览很快发现存储聊天记录的库和表。

2、数据库不加密,聊天字段加密的聊天工具分析
实验素材与环境:
程序名称:亿般
应用程序包名:com.example.xunfei
应用程序图标:
实验环境:逍遥模拟器7.5.2
APK运行环境:安卓4.4
Hook框架:xpoesd
Hook插件:hook AES算法的自定义插件
同样的实验步骤,但是多一步解密

分析步骤:
1.获取实验素材:导出原始APP素材
2.简单逆向,查看配置文件
3安装测试,制作数据
4.提取数据,查看数据库
5.解密加密聊天内容

前三步与上面的例子一样,就不浪费篇幅了介绍了,我们这里直接进行第四步:提取数据
这次我们用不一样的手法,提取真机的这个应用的聊天数据库。


同样也是因为配置文件中定义的备份属性是允许,所以我们才能在这个原生安卓系统中提取这个应用的数据,否则它也没有历史的可以降级的版本,而这个安卓10也几乎无法ROOT,那么它的数据就非常难提取出来,这里我就没有直接用adb backup命令来提取了,直接使用手机取证系统的PanADB来直接提取,原理是一样的。提取完成,直接右击导出即可。



这样就得到了这个应用的数据库,当然如果还需要进一步解析附件或者其他,那么我们还需要慢慢实验分析其他数据,这里仅仅只是分析聊天的数据库。


我们很快找到了数据库,因为库很少,很快就浏览了一遍,但是发现并没有找到和我们制作的聊天记录能对应的表,所以很奇快,又回去分析了其他文件,发现确实没有聊天记录,但是不联网确实还是能看到聊天记录,说明一定缓存在手机里面的。所以我又仔细看了数据库发现有一个表高度可疑,大家来看看:

聊天记录我制作了7条,数据库中也是对应的7条记录,同时我也验证了时间戳确实也是一致的,这里说明应该聊天内容被加密处理了,没有存储原文。


然后在表里后面还有一个字段也很可疑,因为里面有一个code的值是明显的base64编码。我们先开始简单的去HOOK一下标准的加密算法,看看情况。

这里直接使用的是DDMS配合Xposed来观察hook结果。

我们还是尝试发送一个:“你好呀“,看看HOOK结果


我们发现发送“你好呀“  hook到了AES算法加密,并且获取到了密文:6qh5Z5CCn8roGTmWgVkvA==,然后我们发现数据库第一个code也是它。数据库第一个记录应该对应着”你好呀“


这里我们简单的找个在线加密的网站验证一下是否正确:
首先我们HOOK到的有:
算法类型:AES/CBC/PKCS5Padding
IV:16-Bytes—String
SecretKeySpec: oWcPk4Ep5lisD8NZ
我们先验证解密:
密文:6qh5Z5CCn8roGTmWgVkvA==


我们在验证第二个聊天内容:


密文是:wBZI67kILsH+Wsw4G8jpoHwSkroqIeKPzkvxW6qpZkg=


在线解密:包括换行都是完整还原的,所以分析到这就明白了。


这个应用数据库不加密,但是聊天内容存储在数据库是加密的,加密用的标准的对称加密算法AES/CBC/PKCS5Padding;IV向量:16-Bytes—String;SecretKeySpec: oWcPk4Ep5lisD8NZ。

至此我们只要知道原文或者密文其中的一个都可以根据这个加密方式获取另一个值,那么这个应用就可以正常解析了,这个其实也是因为截图有时候工作量太大,可能需要截上千张图。那其实还不如手工解析一下。

这个时候,我们只需要会python编写一个解密的脚本,然后进行表结构的重构,可以只要发送者,接收者,发送时间,聊天内容这几个字段。然后最后选择数据入excel表就算是完成了一次最简单的应用解析了。

3、数据库加密的聊天工具分析

程序名称:约聊
应用程序包名:com.tkm.summer
应用程序图标:
实验环境:雷电模拟器 4.0.39
APK运行环境:安卓7.1
Hook框架:frida

分析步骤:
1.获取实验素材:导出原始APP素材
2.安装测试,制作数据
3.定位数据库
4.逆向程序
5.获取数据库密钥,解密数据库

前两步不做介绍了,我们直接开始第三步,我们制作完了聊天记录,发现默认databases目录下的数据库没有记录聊天记录。



这种其实也很常见,一般情况,绝大部分应用默认的结构化数据都会存储在databases,但是有些应用处于安全考虑,没有使用默认的存储路径,而是自定义的路径。那么我们必须先找到真实的数据库。如果一个应用的数据文件目录没有过于复杂,那么我们遍历所有文件即可。



我们发现文件确实也不复杂,全部遍历,我们发现了一个可疑的加密数据库。


路径:
com.tkm.summer/files/P1y9b9II/a81c929683bca1731630307295327/data
而这个目录中的P1y9b9II和a81c929683bca1731630307295327都像是用户账户的标识信息,带有某种规律的特定字符串,一般做即时通讯分析,做多了都会有这种经验,因为聊天工具可以登录不同的虚拟身份,那么本都数据库也会跟随虚拟身份存储于不同数据库中,而这些数据库通常都会在带有用户标识信息的目录下。

对于这个应用文件并不是很多,我们可以通过遍历找到真实数据库。但是如果这个目录的文件非常多,而且有大量的数据库文件我们难以确定,那我们该如何去快速准确定位呢?

我们可以选择去使用一些辅助手段,比如:聊天软件在运行中,我们制作数据时,它会写入数据库,那么写入数据库操作的时候,必然会加载读取数据库文件。或者我们查看历史聊天记录的时候,软件也会读取数据库的记录,也会加载读取数据库文件。那么我们就有快速定位的思路了,我们去尝试hook系统的open函数,测试浏览历史记录和制作新信息的时候,看会加载哪些文件,在进一步判断。

Hook open源码:




我们经过测试,hook open函数也没发现加载数据库,只是加载各种资源文件,配置文件,一般shared_prefs下就是配置文件。我们猜测应该有子进程。否则不会没有数据库加载动作。

Hook 多线程下的open源码:

使用frida-ps -U 查看到
com.tkm.summer:marsservice
com.tkm.summer:pushservice
那我们hook 多线程下的open


成功发现了:
com.tkm.summer/files/P1y9b9II/a81c929683bca1731630307295327/data
被操作的地方,并且附加了libmarsstn.so。
反编译apk


发现是在com.tencent.mars.Mars这个类下初始化的。然后使用IDA PRO 反编译libmarsstn.so,因为测试环境是x86的模拟器,所以我们也查看x86目录下的libmarsstn.so。逆向数据库密钥,一般有一些技巧,通常我们可以通过搜索一下关键字来定位关键函数,关键字可以是sqlite相关的,或者一些异常处理。这里我们用sqlite来做关键字。


在字符串窗口搜索sqlite f,,出现了三个结果,我们查看第二个


发现没有被引用,我们查看第三个


这个有被引用,双击跳转地址sub_2611D0


按F5转成伪代码


我们滑到最上面:


这里我需要了解sqlite数据库加密的一些常见函数,因为实现加密,所使用的大概率也是同样的接口。下面我把常见的函数罗列出来了,我们比较一下。


char *__cdecl sub_2611D0(int a1, void *src, int a3, int a4)
这个函数原型应该是:
void * sqlite3Codec(void *pArg, unsigned char **data_addr, Pgno nPageNum, int nMode);
sqlite3Codec()会被sqlite3CodecAttach()调用,然后附加密钥到数据库。
int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen)
所以这里的第三个参数*pkey,应该就是我们需要的密钥。


我们查看一下函数的外部调用,发现调用地址sub_23A540


还是滑到顶部:
unsigned int __usercall sub_23A540@<eax>(int a1@<edx>, int a2@<ecx>, void *src, size_t n)
这个函数的原型应该就是:
int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen)
也验证了我们的分析。
那我们就开始编写hook 密钥的脚本。


Hook oncreate方法,这里函数初始化的地方,然后我们找一下sqlite3CodecAttach的函数地址,libmarsstn的地址+函数的偏移地址

函数偏移地址就是sub_23A540,一般来说在x86架构下函数偏移地址需要加1。不然会报错。我们去hook第三个参数,因为c语言这边是栈,先进后出,我们虽然需要的是第三个参数,但是它出栈的时候是第二个,所以打印的内存数据是arg[1]。


打印密钥:d004cfbe-4f89-4e64-a706-0f40a19b562c



其实这个例子和十百千计划的手机APK分析的比武题目很类似,但是这个例子确实也是笔者实战中发现了真实案例,它和十百千的手机项的APK其实都是利用的野火IM的源码,所以分析的思路很类似。大部分的加密其实都是运用的标准的加密算法来加密,深入了解常见加密算法对于解密会有很大的帮助,而一套源码随便修改一下就换成了一个新的APK,厂家很难全部都及时支持,所以掌握必要的分析手段对于这类案件有非常重要的帮助。


二、总结


小众即时通讯一直都是困扰电子取证人员的难题之一,本文结合常见的三种即时通讯分析的类型:数据库不加密、聊天字段加密、数据库加密。全面的阐述了聊天数据库的识别和解密方法,希望可以给从事电子取证的技术人员带来相应的帮助。


作者介绍

刘聪,从事 5 年电子数据取证工作,擅长手机手工取证,APK 逆向分析,多次参与全省电子数据取证培训,支撑部里手机高级取证培训。第六届全国电子数据取证大赛团队赛第一名。奇安信虎符名师堂认证讲师。


郑文鑫,电子数据鉴定师,前苹果中国区高级技术工程师,iOS 系统移动终端高级工程师,mac OS 系统高级工程师, 盘古石取证认证培训授权讲师,撰写并发表专业文章多篇。





RECOMMEND


往期回顾


安全数字化建设|科技创新型企业专刊·安全村

无为有处有还无,旁观阿里云无影的新进展|安全村

漫谈信息共享与证券监管机构的作用|证券行业专刊·安全村



关于 电子数据取证与网络犯罪调查专刊


网络犯罪是科技发展中的必然产物,而且随着技术创新在不断转变,加大信息安全防范技术和电子数据取证技术的研究力度势在必行。在我国,电子数据作为证据种类被法律认可的时间并不长,从技术到法律法规都还存在着很多悬而未决的问题,需要有志之士一起努力,产、学、严用、政通力合作。专刊汇集一线人员经验,主题兼容并包,从网络犯罪手法揭秘到团伙分析溯源,从电子数据取证法律法规到实务运用,从电子数据取证知识的梳理到前沿技术探索,总有一款适合你。


关于 安全村


安全村始终致力于为安全人服务,通过博客、文集、专刊、沙龙等形态,交流最新的技术和资讯,增强互动与合作,与行业人员共同建设协同生态。

投稿邮箱:info@sec-un.org


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

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