一、前言
数字取证分析人员在分析macOS时,很难获得关于程序执行的相关信息,但现在情况已有所改观。在macOS 10.13(High Sierra)中,Apple推出了CoreAnalytics,这是一种系统诊断机制,可以获取系统上执行过的Mach-O程序记录,时间跨度大约为1个月左右。CoreAnalytics可以为内部威胁调查任务以及应急事件响应提供许多非常有价值的信息,可以用于以下场景:

1、确定系统的使用时长,粒度以天为单位;

2、确定特定日期有哪些程序被运行过,是以前台还是以后台模式运行;

3、大致确定程序处于运行或活动状态的时长,也能大致给出程序启动或者以交互式前台方式运行的次数。

本文从技术角度大致介绍并分析了macOS 10.13中的CoreAnalytics机制,同时也介绍了如何将这类信息解析为更容易理解的格式,帮助调查人员分析取证。

二、概览
CoreAnalytics可以提供关于程序执行的历史纪录以及当前记录,基本上以天为单位。这些数据来自于两个源:

1、/Library/Logs/DiagnosticReports/目录中以.core_analytics为扩展名的文件,内容为JSON格式:解析前两条记录可以获得有关诊断过程的启动及结束时间戳信息,解析后面的数据可以获得诊断期间系统及应用的使用情况;

2、/private/var/db/analyticsd/aggregates/目录中文件名类似GUID的文件,内容为嵌套数组:在当前诊断过程期间,子系统将临时阶段性程序执行数据以聚合文件形式报告给数据分析守护程序。阶段性数据通常会在诊断周期结束时推送到.core_analytics文件中。

诊断周期由.core_analytics文件的前两行定义,分别确定诊断周期的开始及结束时间。每个诊断周期在在00:00:00 UTC后的系统首次休眠或者关闭时就会结束。前面提到过,在诊断周期结束时,当日的数据在提交到.core_analytics文件用作长期存储前,会先存放在聚合文件中。因此,CoreAnalytics无法用来确定程序运行的时间范围(只能大约给出24小时的时间区域)。

为了处理这种场景,我们编写了一个Python脚本(请访问我们的GitHub下载),该脚本可以解析CoreAnalytics以及聚合文件,将结果写入到更加清晰的JSON或者CSV文件中。CoreAnalyticsParser脚本可以支持如下功能:

1、解析每个.core_analytics文件中记录的诊断周期开始及结束时间,并将其转换为UTC以及IOS8601时间;

2、从每个.core_analytics文件中提取与每条记录相关的可用字段;

3、将以秒数表示的原始值转换为更容易理解的%H:%M:%S strftime格式;

4、将与comappleosanalyticsappUsage子系统关联的聚合文件解析为每个 .core_analytics文件中该子系统所生成的相同字段。

在.core_analytics文件中某个应用的执行记录大致如下所示:

{ ‘message’: { ‘activations’: 105,
‘activeTime’: 4250,
‘activityPeriods’: 12,
‘appDescription’: ‘com.google.Chrome ||| 67.0.3396.87 (3396.87)’,
‘foreground’: ‘YES’,
‘idleTimeouts’: 4,
‘launches’: 0,
‘powerTime’: 12537,
‘processName’: ‘Google Chrome’,
‘uptime’: 26110},
‘name’: ‘comappleosanalyticsappUsage’,
‘uuid’: ‘4d7c9e4a-8c8c-4971-bce3-09d38d078849’}
表1. Google Chrome对应的CoreAnalytics记录样例

由CoreAnalyticsParser解析后,同一个记录会被解析成如下结果:

{ ‘src_report’: ‘/path/to/Analytics_2018-06-29-173717_ML-C02PA037R9QZ.core_analytics’,
‘diag_start’: ‘2018-06-29T00:00:09Z’,
‘diag_end’: ‘2018-06-30T00:37:17.660000Z’,
‘name’: ‘comappleosanalyticsappUsage’,
‘uuid’: ‘4d7c9e4a-8c8c-4971-bce3-09d38d078849’,
‘processName’: ‘Google Chrome’,
‘appDescription’: ‘com.google.Chrome ||| 67.0.3396.87 (3396.87)’,
‘appName’: ‘com.google.Chrome’,
‘appVersion’: ‘67.0.3396.87 (3396.87)’,
‘foreground’: ‘YES’,
‘uptime’: ‘26110’,
‘uptime_parsed’: ‘7:15:10’,
‘powerTime’: ‘12537’,
‘powerTime_parsed’: ‘3:28:57’,
‘activeTime’: ‘4250’,
‘activeTime_parsed’: ‘1:10:50’,
‘activations’: ‘105’,
‘launches’: ‘0’,
‘activityPeriods’: ’12’,
‘idleTimeouts’: ‘4’}
表2. CoreAnalyticsParser脚本将图1中CoreAnalytics的结果解析成JSON数据

注意:如上解析结果为JSON格式数据,可以使用-j选项输出为JSON数据。默认情况下,解析脚本会将结果输出为CSV格式。

该脚本可以在实时系统上运行,也可以处理包含CoreAnalytics或者聚合文件的目录。

三、技术分析
CoreAnalytics文件
.core_analytics文件中包含JSON记录,这些记录可以表示程序执行历史及时间戳信息,时间戳可以划出历史数据所对应的特定诊断周期。这些文件位于/Library/Logs/DiagnosticReports/目录中,文件名采用Analytics_YYYY_MM_DD_HHMMSS_.core_analytics格式。文件名中的时间戳基于的是系统的本地时间信息。在10.13版本之前,DiagnosticReports目录只包含程序故障及崩溃报告,现在,不论程序是否崩溃,该目录中都会包含与程序执行有关的数据。

负责生成和收集系统分析及诊断数据的守护程序同样会维护/private/var/db/analyticsd目录中已预先写好的CoreAnalytics文件信息。在该目录中,currentConfiguration.json文件貌似维护着一个字典集,对应与子系统相匹配的名称、UUID以及数据类型。