第三届“盘古石杯”全国电子数据取证大赛初赛服务器

第二届服务器稳定发挥混了个决赛一等奖,今年服务器爆零让队友抗压了

结束后对第三届“盘古石杯”全国电子数据取证大赛初赛UNRAID服务器部分做了比较完整的复盘,部分题目答案可能因为考虑不足,不一定对,在这里分享一下UNRAID仿真与LUKS ZFS数据盘的解密。如有错误,欢迎师傅们指出。

# 仿真与解密

# 基本信息

服务器启动模式: UEFI/BIOS (SYSLINUX)
镜像模式: DD
引导盘/系统盘: server1.001
数据盘: server2.001
数据盘文件系统: LUKS加密(ZFS文件系统)

# 思路

先说为什么找不到 keyfile
UNRAID使用SYSLINUX作为引导程序
其模式是系统和引导在U盘上
系统以CPIO ROOTFS的方式打包为文件进行存储
启动时解包文件挂载为目录
U盘作为EFI分区的同时也储存了系统

bzroot 存储了根文件系统
bzfirmware 存储了各类设备驱动
bzimage 存储了Linux内核
bzmodules 存储了内核模块

启动盘会挂载在 /boot 路径下
系统启动时,解包bzroot,bzmodules,bzfirmware等CPIO ROOTFS文件挂载为根文件系统

读取 /boot/config/ 下的各类配置文件作为系统配置

整个系统是运行在内存的
这就导致 /root 是无法存储文件的,只要系统重启 /root/目录下的文件 就会丢失

而配置文件中keyfile的路径是 /root/keyfile
实际上整个服务器检材里就没有 LUKS 的 keyfile

分区表错误是因为启动盘原先是64GB优盘,但检材只截断了前 7.5GB 左右的数据
导致尾部的分区表丢失

所以该服务器每次断电重启后,需要重新上传keyfile进行解密

keyfile 既然不在服务器内,那只能在其他检材里了
经过一轮爆搜
以keyfile为关键词可以搜到PC检材pc-disk.e01中有一个RAR文件,其中存储了keyfile.keyfile

解压后是BASE64编码过的一句话

密钥即为

1
emZz5Yqg5a+GcG9vbOWvhumSpeaWh+S7tg==

注意密钥不能有换行符

1
sudo cryptsetup luksDump --dump-master-key /dev/loop2p1

使用该文件内容能够成功 dump 磁盘的 master-key 主密钥
证明密钥正确

# 提示

本篇使用了UEFI+QEMU KVM进行仿真
核心思路就是要把启动盘以EHCI/XHCI总线(USB)的方式挂载
VMware下可以尝试使用LegacyBIOS + MBR + 物理优盘方式
或将DD镜像转换为VMDK再挂载EHCI总线

# 仿真

接下来就是服务器的仿真了
unraid 这玩意只认优盘,以SCSI/SATA总线挂镜像会导致扫描不到UNRAID卷标的分区。
需要走ehci/xhci总线

之前写了一版使用物理U盘挂载引导的教程
受群友Cn5uk思路启发,可以直接把镜像挂载为USB设备,故以下操作均基于虚拟XHCI总线设备实现

先按照以下步骤把启动盘挂载为环回设备,添加密钥文件
并把luks密钥路径从/root/keyfile改为/boot/config/keyfile

1
2
3
4
5
cp server1.001 usb.raw
sudo losetup -P --show -f usb.raw
sudo mount /dev/loop6p3 /unraid-boot/
sudo cp keyfile /unraid-boot/config/keyfile
sudo sed -i s#/root/keyfile#/boot/config/keyfile#g /unraid-boot/config/disk.cfg

由于手头暂时没Windows PC,我这里使用服务器的 QEMU KVM开虚拟机

远程服务器不方便改网桥模式,使用QEMU USER NET网卡需要改为DHCP

super.dat 存储了硬盘信息

由于虚拟机硬盘ID以及名称可能会变化,我们先把 unraid super.dat 备份后删除

使用该 QEMU 参数挂载XHCI总线(USB)设备

1
2
3
-device qemu-xhci,id=xhci
-drive file=usb.raw,id=usbstick,format=raw,if=none
-device usb-storage,drive=usbstick,bus=xhci.0

这里不细讲QEMU KVM的原理以及使用了
确保安装了UEFI的固件,以及创建了UEFI_VARS

1
2
apt install ovmf
dd if=/dev/zero of=OVMF_VARS.fd bs=4096 count=1

按照以下内容进行配置
具体配置项不清楚的可以让Ai解释一下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Author: S1EEPS0RT
# From: https://r1.pub/p/pangushi-pgs-forensics-2025-pre-unraid-server/
kvm \
  -m 8192 \ #内存
  -smp 8 \ #vCPU
  -cpu host \ #CPU Mode
  -boot c \
  -machine accel=kvm,usb=on \ # KVM 加速,开启USB
  -device qemu-xhci,id=xhci \ # XHCI总线
  -drive file=usb.raw,id=usbstick,format=raw,if=none \ # 添加虚拟启动盘
  -device usb-storage,drive=usbstick,bus=xhci.0 \ # 将上面的虚拟启动盘挂到XHCI总线 USB STORAGE模式
  -device virtio-scsi-pci,id=scsi0 \ # VirtIO SCSI
  -device virtio-net-pci,netdev=vnet \ # VirtIO NET
  -netdev user,id=vnet,hostfwd=tcp::8080-:80,hostfwd=tcp::8443-:443,hostfwd=tcp::2222-:22 \ #User Net端口转发
  -device usb-kbd,bus=xhci.0 -device usb-tablet,bus=xhci.0 \ # 鼠标指针
  -drive id=Data,format=raw,file=/v3/server2.001.raw,if=none \ # 数据盘挂载
  -device scsi-hd,drive=Data,bus=scsi0.0 \ # 数据盘走VirtIO SCSI总线
  -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd \ # UEFI固件
  -drive if=pflash,format=raw,file=./OVMF_VARS.fd \ # UEFI 变量存储
  -boot menu=on \
  -vnc :1 \ # VNC PORT 5901
  -monitor stdio

可以顺利引导进入系统

账户 root 密码 P@ssw0rd

实际控制面板端口是80,我这里使用了端口转发故需要走SSH隧道代理访问

1
ssh -D 12345 root@10.1.1.1

如果你的虚拟机是桥接网卡模式,直接访问 80和22 端口

这里由于运行环境变了我们需要重新配置一下硬盘

新添加磁盘1,选择挂载的129GB数据盘

启动磁盘阵列

可以看到LUKSZFS已解密

docker 容器也正常显示

# 题目解析

以下是UNRAID服务器题解。

# 1、分析服务器检材,找出服务器系统启动盘的GUID?【标准格式:数字、字母、-的组合,字母大写】 (1分)

1
223DCB83-82B0-4C62-864A-DB28D84735B8

# 2、找出服务器网关IP?【标准格式:1.1.1.1】 (1分)

1
192.168.56.128

启动盘配置文件 config/network.cfg

# 3、找出服务器数据盘的文件系统格式?【标准格式:ntfs】 (1分)

1
zfs

启动盘配置文件 config/disk.cfg

仿真起来也可以看

# 4、找出服务器数据盘的解密密钥文件名?【标准格式:abcd】 (1分)

1
keyfile

启动盘配置文件 config/disk.cfg

# 5、找出服务器密码?【标准格式:key@123】 (3分)

1
P@ssw0rd

在启动盘 shadow 文件 用hashcat跑字典

# 6、找出服务器版本号?【标准格式:0.0.0】 (1分)

1
7.0.1

在启动盘 changes.txt

也可以在 logs/tower-diagnostics-20250416-0148.zip/unraid-7.0.1.txt

# 7、找出服务器内Docker虚拟硬盘位置?【标准格式:/home/abc/adc.raw】 (2分)

1
/mnt/disk1/docker.img

在启动盘 config/docker.cfg

# 8、找出服务器启动盘的启动标识?【标准格式:D100,写出型号即可】 (3分)

1
U210

在 logs/tower-diagnostics-20250416-0148.zip 有 aigo_U210_6005911262432474746-0-0-20250416-0148 flash (sda).txt

aigo_U210 即为型号

VID 0x3535
PID 0x200

1
2
3
4
smartctl 7.4 2023-08-01 r5530 [x86_64-linux-6.6.78-Unraid] (local build)
Copyright (C) 2002-23, Bruce Allen, Christian Franke, www.smartmontools.org

/dev/sda: Unknown USB bridge [0x3535:0x5678 (0x200)]

# 9、找出服务器内共有多少个容器镜像?【标准格式:10】 (2分)

1
9

仿真起来,连接上去

# 10、找出服务器内网站服务器所用数据库运行的容器名?【标准格式:abc-abc-1】 (3分)

1
www-db-1

这题启动盘的syslog里也有。

# 11、找出服务器内虚拟币容器对外暴露的端口号?【标准格式:8000】 (3分)

1
22556

# 12、找出投资理财网站的域名?【标准格式:3w.baidu.com】 (3分)

1
2025.pgscup.com

这题答案不确定

在手机检材里,QQ的聊天记录中,发过 2025.pgscup.com

dkewl.com 应该是卖源码的域名。

后台又配置了

1
panguite.cup

# 13、找出投资理财网站内连接数据库的密码?【标准格式:password】 (3分)

1
www_dkewl_com

可以看到挂载了目录 ThinkPHP 在 /mnt/disk1/www/Public/config.php

1
2
3
4
5
6
7
8
9
<?php
define('DB_TYPE', 'mysql');
define('DB_HOST', 'db');
define('DB_USER', 'www_dkewl_com');
define('DB_PWD', 'www_dkewl_com');
define('DB_NAME', 'www_dkewl_com');
define('DB_PREFIX', '');
define('DB_PORT', '3306');
define('DB_CHARSET', 'utf8');

# 14、找出投资理财网站后台访问地址?【标准格式:http://www.baidu.com/login.html】 (4分)

1
2
http://www.dkewl.com/www9nwcc/login.html
http://2025.pgscup.com/www9nwcc/login.html

路径是对的,域名有很多,结合手机材料可能是 2025.pgscup.com 查看网站模版结构,有神必目录 绕密登录

# 15、找出投资理财网站会员等级设置存放在那个数据库表内?【标准格式:user】 (3分)

1
user

按格式是 user

user_member 也存了会员等级的详细设置
网站仿真,倒查数据库

# 16、找出投资理财网站提现成功的金额?【标准格式:10000】 (4分)

1
5769477
1
SELECT SUM(money) FROM cash WHERE status = 1;

mysql_data/generate_10k_records.sql 的cash表

把数据插入数据库

# 17、找出投资理财网站内用户王欣的银行卡号?【标准格式:16位数字】 (4分)

1
2114313505182218

找到了填充测试数据脚本,以及 mysql_data/generate_10k_records.sql

按出题人的思路,那应该是 generate_10k_records.sql

1
INSERT INTO `bank` VALUES (2908, 2908, '招商银行', '上海市分行', '2114313505182218', '王欣', '13236474221', 'ZZYU0919');

# 18、找出投资理财网站用户的最低提现金额?【标准格式:10000】 (5分)

1
100

# 19、给出存放投资理财用户表内clock为0表示用户处于那种状态?【标准格式:核实】 (5分)

1
正常

user 表内

clock int(11) NOT NULL DEFAULT 0 COMMENT ‘是否锁定,0否/1是’,

结合源码可以发现是两种状态
冻结或正常
如果 clock == 0 则为正常
如果 clock == 1 则为冻结

# 20、找出投资理财网站内通过支付宝支付充值状态为未支付的金额?【标准格式:10000】 (5分)

1
11642201

把 generate_10k_records.sql 的recharge部分导入线上数据库

recharge 表

1
SELECT SUM(money) FROM recharge WHERE type = "支付宝扫码" AND status = 0;


这可能是我最后一次打信息安全相关的竞赛了。再找不到工作就要喝西北风了。

现在信安环境差,海投了不少简历还是没相关的岗位。如果有大佬觉得我的技术还凑活的话,求个信安/网安/机房运维/设备交付相关的内推,感激不尽。

Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy