分类 手机取证 下的文章

IMEI号,普通人可能感觉陌生,但对于电子数据取证从业者来说则不然。IMEI是手机的“身份证号”之一,在通信网络中用于唯一识别某台设备。网上传言的通过某个代码即可通过运营商对手机进行挂失,这个“代码”就是IMEI号。但准确来说,IMEI并不是“设备身份证号”,更像是SIM卡卡槽的身份证号。早期一部手机一般只有一个IMEI号,但为了满足监管需求,差不多十年前开始,设备厂商必须为每个SIM卡卡槽注册一个IMEI号。

今天不聊IMEI号的历史,而是站在一个电子数据鉴定人的角度记录一下最近遇到的一件与IMEI相关的有意思的事情。

大模型的兴起,让普通人也能从科技的发展中受益,我也不例外。为了加快文书材料的校对,我在本地用LM Studio加载了Qwen 3.6 Flash对文档进行自动化核验。最近我在提示词中增加了一条规则,要求对文档中提及的IMEI号检查,看是否为十五位数字并通过Luhn算法校验,希望通过此检查发现潜在的IMEI号记录错误。

这种方法极大地提高了校对效率,类似少录或多录入了一位数、数字录入错误等问题可以很方便地检查出来,比人工核对快很多。但这两天遇到一个IMEI号,Qwen检查说校验失败IMEI非法,但我仔细核对了检材手机,待检查的IMEI号与手机中记录的IMEI号完全一致。于是我又用Qwen写了一个Luhn校验脚本进行计算,结果依然是校验不通过!这部手机是国内很常见的品牌,型号就不说了,去年年中才发布。

按照规范,IMEI号的最后一位应通过Luhn算法计算得出,但实践中似乎并非所有IMEI号都能通过Luhn校验。至于原因,目前尚无明确结论,留待后续探究。

附:Luhn算法规则

Luhn算法也被称为模10算法,主要用来校验各种数字的正确性。Luhn算法规则很简单,对数字从右往左逐一遍历,奇数位不变,将偶数位的数字乘以2,如果乘积大于9则减9,将各位求和后加上校验位数字一定能被10整除,不能整除则说明校验失败。

例如针对IMEI号865498078589991,从右往左第1位到第15位分别是1、9、9、9、8、5、8、7、0、8、9、4、5、8、6,偶数位处理后15个数字分别是1、9、9、9、8、1、8、5、0、7、9、8、5、3、8,(1+9+9+9+8+1+8+5+0+7+9+8+5+3+8)%10= 0,即校验位通过。

目前针对手机微信数据恢复,已经有较为成熟的方法,商业的手机取证工具一般都能不同程度地支持。本文将以Android微信为例探讨判断微信聊天记录是否被删除过的方法,这一方法也可以用于检验取证工具恢复的聊天记录是否完整。

Android微信默认路径为data分区下的“data\com.tencent.mm\MicroMsg”目录,用户及应用产生的大部分数据都在此目录下,但用户产生的多媒体数据则保存在SDCard分区的“tencent\MicroMsg”目录下。在以上路径下,每个登录的帐号会产生一个以某MD5值(该值也和微信账号有关系,详情网上可以搜到)命名的文件夹,聊天记录、朋友圈信息、收藏记录全部位于各账号MD5值目录下。

Android微信聊天记录保存在数据库文件“EnMicroMsg.db”中,收藏信息保存在数据库文件“enFavorite.db”,朋友圈信息保存在数据库文件“SnsMicroMsg.db”中。“EnMicroMsg.db”和“enFavorite.db”都是加密的,密钥为(手机IMEI+微信uin)取MD5值后截取前7位,详细资料可以从网上搜到。

有了以上基础,可能大家会想到,既然是加密后的SQLite数据库,又知道加密规则,解密后直接进行SQLite数据库恢复不就可以了吗?实际情况还真没有这么简单,如何找到解密参数是第一个问题(本文暂不讨论),从Android微信5.3.1版本开始,删除操作使用了特殊的指令,通俗地说就是删除后在原记录处使用“0”进行填充。像短信、通讯录一样使用SQLite数据库原理对Android微信聊天记录进行恢复是行不通的。

下面进入正题。

将“EnMicroMsg.db”文件解密后,可以发现聊天记录保存在表“message”中。主要字段有“msgId”、 “status”、 “isSend”、 “createTime”、 “talker”、 “content”等。如图1所示。

图1
图 1

“status”记录了消息阅读状态,“isSend”记录了消息是发送还是接收的,“createTime”记录了消息时间,“talker”记录了消息的创建者(如果是群消息,则是群聊ID,具体消息创建者标示在“content”字段内),“content”记录了消息的详细内容。

本文的主角是“msgId”字段。该字段记录的是消息在本地的序号,该序号是自增长的,正常情况下,所有对话中,时间上相邻的两条记录“msgId”字段值必定是相邻的。所有记录按“msgId”字段排序后,如果发现有相邻的记录“msgId”字段值不连续,则说明此处有记录被删除了,具体删除的条数也可以判断出来。

图2
图 2

我们再观察一下上面的截图。按“msgId”字段排序后,第11786条记录的“msgId”字段值为11822,而第11787条记录的“msgId”字段值为11824,由此可以推断,这两条记录之间本还有一条记录。第11786条记录的“createTime”字段值“1495527020001”转换成可视化时间为2017-05-23 16:10:20 (UTC+08:00),第11787条记录的“createTime”字段值1495527161000转换成可视化时间为2017-05-23 16:12:41 (UTC+08:00)。即在本例中,2017年5月23日16:10:20之间有一条聊天记录被删除。

总结及说明:

  1. 可以通过“EnMicroMsg.db”表“message”的“msgId”字段值来判断是否有聊天记录被删除。
  2. 本文介绍的方法无法判断被删除记录的创建者和接收对象,也无法判断被删除的具体内容。
  3. 本文讨论的“删除”操作不包括“撤销”,撤销的消息记录还在,只是“content”字段值被改成了“‘xxx’撤回了一条消息”。

本文最早发布于本人微信公众号“取证杂谈”,发布日期为2017年7月9日。

手机取证中,手机号是确定手机机主的重要途径,同时也可以在众多检材或线索中起串联作用,其重要性不言而喻。确定手机号的一个重要途径是通过SIM卡,SIM卡中可能记录有手机号,通过SIM卡的ICCID也可以从运营商查询得到对应的手机号。

实践中机主可能更换过手机号,所以仅对手机附带的SIM卡进行取证可能还不够。本文将介绍Android及iOS设备中检验历史SIM卡信息的方法。

iOS设备

使用iTunes或其他工具创建手机备份,使用iBackupBot等工具浏览备份数据。SIM卡历史记录记录保存在”WirelessDomain /Library /Database /CellularUsage.db"文件中。

CellularUsage.db是SQLite数据库文件,可以使用免费的DB Browser for SQLite或iBackupBot自带的查看器查看,SIM卡历史记录保存在表“subscriber_info”中。如图1所示。

图 1 CellularUsage.db文件中记录的SIM卡历史信息
图 1 CellularUsage.db文件中记录的SIM卡历史信息

subscriber_info字段即SIM卡的ICCID,subscriber_mdn字段即手机号,last_update_time字段即最后更新时间,为MAC Absolute Time时间格式。MAC Absolute Time时间记录的是2001年1月1日 00:00:00 UTC+0:00至今流逝的秒数,可以用免费的工具DCode进行转换。如图2所示。

图 2 使用DCode解析MAC Absolute Time格式的时间
图 2 使用DCode解析MAC Absolute Time格式的时间

需要注意的是,last_update_time字段记录的最后更新时间与手机系统时间相关,如果手机时间不准,会影响此处的最后更新时间。图1所示的第二条记录中,“-978306735.184363”经过转换为1970年1月1日,显然是错误的时间。如图3所示。

图 3 CellularUsage.db文件中记录的错误的时间
图 3 CellularUsage.db文件中记录的错误的时间

Android设备

Android手机的SIM卡使用记录一般保存在data分区的“data \com .android .providers .telephony \databases \telephony.db”文件中,该文件也是SQLite数据库。表“sim_info”会记录使用过的SIM卡的ICCID、手机号等信息。如图4所示。

图 4 telephony.db文件中记录的SIM卡历史信息
图 4 telephony.db文件中记录的SIM卡历史信息

对于小米手机,SIM卡信息还在“data \com .android .providers .telephony \databases \siminfo.db”文件中。如图5所示。

图 5 siminfo.db文件中记录的SIM卡历史信息
图 5 siminfo.db文件中记录的SIM卡历史信息

注意事项

上面分别介绍了iOS和Android设备提取SIM卡历史记录的方法,其中iOS设备不需要越狱,只要能创建iTunes备份即可;对于Android设备,由于相关信息保存在data分区,普通权限无法访问相关数据,一般需要root或制作镜像后才能进行分析。

SQLite数据库数据恢复技术是手机取证的基石之一,无论iOS还是Android,SIM历史记录都保存在SQLite数据库中,我们可以使用取证软件对上述文件进行处理,以获取删除的记录。本人在实践中也曾成功恢复出SIM卡历史记录。


本文最早发布于本人微信公众号“取证杂谈”,发布日期为2017年6月14日。
写这篇文章的时候,国内外很多手机取证产品对手机号取证还不支持或支持的不完善,一年后的今天,国内手机取证产品已经都支持的比较好了。

最近接连遇到几部手机都安装有一款名为“Blued”的即时通讯应用,而手头的手机取证工具竟然没有一个支持此应用的解析,于是只好自己想办法了。

Blued是一款同性交友工具,据说在特定群体中使用挺广泛的,iPhone中的App Store中的应用简介如图1、图2所示。

Blued应用
图1 Blued应用
Blued应用简介
图2 Blued应用简介

下面以一部iPhone6S手机为例,介绍怎么手工提取Blued聊天记录内容。

首先使用iTunes或手机取证产品提供的iOS备份工具对手机创建备份,得到了一个名为“7c2dbde4b7**”的文件夹,具体的名称每部手机都不同。使用免费的iTuens备份工具iBackupbot加载备份,浏览备份数据。

在“User App File”下找到了一个名为“com.bluecity.blued”的目录,此目录中的数据即是Blued应用的数据。展开“com.bluecity.blued”目录,有两个名称分别为“Documents”和“Library”的子目录,“Documents”子目录中会有一个名为“LoginDB.sqlite”和“DB.sqlite”的文件文件,分别为所登录的Blued帐号信息和帐号“”的聊天记录数据库。如图3所示

Blued应用数据
图3 Blued应用数据

将“LoginDB.sqlite”和“*DB.sqlite”导出,使用“DB Browser for SQLite”加载。

“LoginDB.sqlite”文件中就一张表,名为“loginUserTable”,记录了帐户uid、加密后的密码、绑定的邮箱、帐户基本信息、更新时间等信息。如图4所示。

“LoginDB.sqlite”数据库结构
图4 “LoginDB.sqlite”数据库结构

“*DB.sqlite”的文件有四张表,表名分别为“dynamicReleaseQueueTable”、 “messageTable”、 “sessionSettingTable”和“sessionTable”。第一张表和第三张表中没有数据。第二张表和第四张表保存着聊天记录,其中“messageTable”中的聊天记录远多于后者,这两张表结构类似,暂时还没有弄清楚到底哪些情况下存储在“messageTable”中,哪些情况存储在“sessionTable”中。如图5所示。

“*DB.sqlite”数据库结构
图5 “*DB.sqlite”数据库结构

表“messageTable”结构如图6所示,经过一番猜测,主要字段含义如表1所示。

表“messageTable”结构
图6 表“messageTable”结构
表messageTable字段含义
表1 表messageTable字段含义

将表“messageTable”导出为“messageTable.csv”,使用WPS表格打开,去掉无关列,将第一行开启自动筛选,按照“sendTime”列升序排列,得到的结果部分内容如图7所示。

初步处理后的数据
图7 初步处理后的数据

接下来将时间列转换成通用格式。编辑“G2”单元格,输入“=TEXT(F2/86400+25569, ”yyyy-m-d h:mm:ss”)”,按回车键确认后,G2单元格内容变成了“2016-3-7 14:06:48”,与手机上的消息时间对比发现晚了8个小时,看来数据库中存储的是UTC时间,将G2单元格中的公式改为“=TEXT(F2/86400+25569+8/24, ”yyyy-m-d h:mm:ss”)”,确认后G2显示为“2016-3-7 22:06:48”,与手机中的一致。选中G2单元格后,鼠标移至G2单元格右下角,等鼠标变为实心“╋”字的时候,双击鼠标左键,实现G列所有单元格的自动填充。如果要过滤与某人的对话,只需在sessionId列表筛选出改用户的uid即可。图8是经我处理后的最终效果。

与某人的聊天记录
图8 与某人的聊天记录

本文最早发布于本人微信公众号“取证杂谈”,发布日期为2016年10月30日,微信公众号“电子物证”2016年11月14日授权转载,其他网站及平台均为未授权转载。