2024龙信杯wp
注意:中间存在一些试错过程,也保留在了WP中,参考时需注意。
00. 挂载并提取检材
首先我们使用VeraCrypt挂载容器:

然后直接输入密码即可:

挂载完成后,能看到刷新出了一个M盘:


打开M盘,可取出内部的检材:

手机取证
01.分析手机检材,请问此手机共通过 adb 连接过几个设备?[标准格式:3]
本来是直接用AXIOM分析,结果分析不出什么。
于是用WinHex打开dd文件,发现又是tar包……(这就有点神人了23年才这样镜像里面塞压缩包24年又这样……)

于是将镜像文件改成 .tar 后缀,然后管理员模式打开7-zip软件做解压(不用管理员模式有一部分文件不会解压成功),解压后重新用AXIOM分析,也顺带用ALEAPP分析一下。
这边ALEAPP分析速度会快一些,先看一下。可见ADB记录中:

这边有两条记录,虽然详细信息缺失,但可以确认应该是连接过 2 个设备。
但更有效的做法应该是这样的:
Android 设备在通过 ADB 连接时,通常会要求用户授权连接,会要求用户确认设备授权,并将该设备的公钥保存在
/misc/adb/adb_keys文件中。
使用X-Ways查看:

此处存在两条Key,因此应当是连接过 2 个设备:

02.分析手机检材,机主参加考试的时间是什么时候?[标准格式:2024-06-17]
这类日期的记录有两种猜测:
日历、备忘录、便签等记事软件中会记录;
短信、微信、QQ等聊天软件中会提到。
首先,通过X-Ways查看相关文件夹发现,日历数据库中不存在相关内容:

其次,通过ALEAPP查看发现,短信、彩信中不存在相关内容:

然后,通过X-Ways查看相关文件夹发现,便签中存在相关内容:
\data\com.miui.notes\databases\note.db

这边使用Dcode解密相关时间戳,发现机主是2024年6月17日记下这条便签的:

通过看日历发现,认为所谓“下周五”指的是2024年6月28日。
但这边有坑:
data 表: 是备忘录 APP 根据笔记的内容生成的预览文件, 其创建/修改时间是 APP 内数据刷新的时间。
note 表: 是备忘录中保存的原始数据, 随备忘录内容修改而更新。
因此刚才看到的data表中的时间并不是准确的时间,如果需要准确的时间得去看note表才对。并且考虑到机主对于一个便签可能有循环使用的情况,因此要以修改时间为准:

再次Dcode解密可得:

通过看日历发现,认为所谓“下周五”指的是2024年8月23日。因此答案是:2024-08-23 。
03.分析手机检材,请问手机的蓝牙 Mac 地址是多少?[标准格式:12:12:12:12:12:12]
使用AXIOM查看,相关模块下列出了一个蓝牙MAC地址:

或者使用ALEAPP也可见:

或者直接X-Ways翻看相关配置文件也行:
/misc/bluedroid/bt_config.conf


总之,蓝牙MAC地址是:48:87:59:76:21:0f 。
04.分析手机检材,请问压缩包加密软件共加密过几份文件?[标准格式:3]
根据题目描述,能找到一个疑似文件压缩软件的东西:

但可惜这边文件夹内貌似没数据。
用户文件夹下也没有:

这边在该目录中找到:

里面文件都是被加密了的:

因此,加密过的文件应该有 6 个。
05.分析手机检材,请问机主的另外一个 155 的手机号码是多少?[标准格式:15555000555]
这题和上一题的加密文件相关。
使用everything搜索,能看到相关文件在app目录中的位置:

打开后,可见 .apk 文件:

然后DIE查壳,发现程序没有壳:

然后jadx打开,由 AndroidManifest.xml 找到主函数入口点,双击跳转:

这边可见异常的字符串。异常字符被制作为字符数组后作为ZipFile函数的第二个参数,与第一个参数file一同传入:

于是我们双击跟进ZipFile函数,从多个函数重载中找到对应函数,于是就发现了第二个传入的参数被作为密码使用:

因此软件的加密密码是写死的,是 1!8Da9Re5it2b3a. 。
用该密码访问第 4 题中的加密文件 mm.txt ,即可见:

因此机主的另一个手机号码是:15599555555 。
06.分析手机检材,其手机存在一个加密容器,请问其容器密码是多少。(标准格式:abc123)
用该密码访问第 4 题中的加密文件 重要.txt ,即可见:

因此容器密码是:d7Avsd!Y]u}J8i(1bnDD@<-o 。
07.分析手机检材,接上问,其容器中存在一份成员名单,嫌疑人曾经误触导致表格中的一个成员姓名被错误修改,请确认这个成员的原始正确姓名?[标准格式:张三]
经浏览目录,此处怀疑上题所述的容器在此处:

尝试用VeraCrypt去开挂这些镜像,但发现只有当 data 启用了 TrueCrypt 模式的时候才能挂载成功:

挂载后发现两个文件,提取出来:

这题我参考了很多wp,最终认为比较能接受的做法还是这个:
首先根据WPS的记忆功能,最后编辑并离开的位置应当可以在下次打开文档的时候自动定位,这边定位到了此处:

所以首先这边可能有 杨云奉 、陆陆 这两个名字有疑问。
按 E(邀请人手) 排序后,发现 陆陆 和上文 陆俊梅 一同对应了同一个手机号:

所以是 陆俊梅 被误改到了。
08.分析手机检材,接上题,请确认该成员的对应的最高代理人是谁(不考虑总部)?[标准格式:张三]
题目说的大概是 陆俊梅 的除总部外的最高上一级是谁。
通过查找,发现 陆俊梅 的上一级是 肖玉莲 :

同理可知,肖玉莲 的上一级是 刘珏兰 :

而 刘珏兰 的上一级就是总部了:

因此符合题目要求的人是:刘珏兰 。
(x)09.分析手机检材,请确认在该组织中,最高层级的层次是多少?(从总部开始算第一级)[标准格式:10]
(以我目前水平做不懂这题,去求助AI了)
首先,我们先处理一下表格。
表格中有一些不作数的东西,应该是可以直接删除掉:

然后把表格和相关要求提供给Claude,他会提供python脚本:
import pandas as pd
df = pd.read_excel('名单数据.xlsx')
df['手机号_str'] = df['手机号'].astype(str).str.strip().str.replace(r'\.0$', '', regex=True)
df['邀请人手机号_str'] = df['邀请人手机号'].apply(lambda x: str(int(x)) if pd.notna(x) else None)
all_phones = set(df['手机号_str'])
phone_to_inviter = dict(zip(df['手机号_str'], df['邀请人手机号_str']))
phone_to_name = dict(zip(df['手机号_str'], df['姓名']))
phone_to_inviter_name = dict(zip(df['手机号_str'], df['邀请人']))
def get_depth(phone, memo={}):
if phone in memo:
return memo[phone]
inviter_phone = phone_to_inviter.get(phone)
if inviter_phone is None or inviter_phone not in all_phones:
# 总部算第1层,其直属成员算第2层
memo[phone] = 2
return 2
depth = 1 + get_depth(inviter_phone, memo)
memo[phone] = depth
return depth
memo = {}
max_depth, deepest_phone = 0, None
for phone in all_phones:
d = get_depth(phone, memo)
if d > max_depth:
max_depth, deepest_phone = d, phone
print(f"最大层数(含总部): {max_depth} 层")
# 追溯完整链条
chain, p, visited = [], deepest_phone, set()
while p and p in all_phones and p not in visited:
visited.add(p)
chain.append((phone_to_name.get(p, '?'), p, phone_to_inviter_name.get(p, '')))
p = phone_to_inviter.get(p)
chain.reverse()
print("\n完整邀请链条:")
print(" 第1层: 总部")
for i, (name, phone, inv_name) in enumerate(chain, 2):
print(f" 第{i}层: {name}({phone})← 邀请人: {inv_name}")
运行结果:

因此最高能达到 12 层。
(x)10.分析手机检材,请问第二层级(从总部开始算第一级)人员最多的人是多少人?[标准格式:100]
(以我目前水平做不懂这题,去求助AI了)
这题问的应该差不多是,总部的下一级有多个子分支,分支上总人数最多的分支是多少人。然后再加上总部就是答案。
接着询问Claude:
import pandas as pd
from collections import defaultdict
df = pd.read_excel('名单数据.xlsx')
df['手机号_str'] = df['手机号'].astype(str).str.strip().str.replace(r'\.0$', '', regex=True)
df['邀请人手机号_str'] = df['邀请人手机号'].apply(lambda x: str(int(x)) if pd.notna(x) else None)
all_phones = set(df['手机号_str'])
phone_to_name = dict(zip(df['手机号_str'], df['姓名']))
# 建立子节点映射
children = defaultdict(list)
for _, row in df.iterrows():
p = row['手机号_str']
inv_p = row['邀请人手机号_str']
if inv_p and inv_p in all_phones:
children[inv_p].append(p)
# 总部直属成员(邀请人字段为"总部")
hq_direct = df[df['邀请人'] == '总部']['手机号_str'].tolist()
# 递归统计子树总人数(含分支负责人本身)
def count_subtree(phone, memo={}):
if phone in memo:
return memo[phone]
total = 1 + sum(count_subtree(c, memo) for c in children.get(phone, []))
memo[phone] = total
return total
memo = {}
results = [(phone_to_name.get(p, '?'), p, count_subtree(p, memo)) for p in hq_direct]
results.sort(key=lambda x: -x[2])
print(f"总部直属分支数: {len(results)}\n")
print(f"{'分支负责人':<12} {'手机号':<15} {'分支总人数':>8}")
print("-" * 40)
for name, phone, cnt in results:
print(f"{name:<12} {phone:<15} {cnt:>8} 人")
best = results[0]
print(f"\n人数最多的分支: {best[0]}({best[1]}),共 {best[2]} 人")
运行结果:

但至此,还需要再算上总部,所以答案是:1065 。
11.分析手机检材,机主共开启了几款 APP 应用分身?[标准格式:3]
据说与用户隐私有关,于是能找到相关记录应用:
\data\com.qh.privacysec
在其数据库中可找到分身相关记录:
\data\com.qh.privacysec\databases\fenshen.db

使用DB_Browser查看可见:

存在 2 个应用分身。
12.分析手机检材,请问机主现在安装了几款即时通讯软件(微博除外)?[标准格式:1]
首先在数据目录中做一些筛选,排除掉系统应用的影响:

下面列出几个有嫌疑的:
裸聊软件:

MChat:


默往:


微信:

腾讯会议,不知道算不算:

这边有一台虚拟机:


在其中可以找到QQ和连信:


但这题官方答案是 3 个,估计是只算默往、MChat和微信。
13.分析手机检材,请问勒索机主的账号是多少(非微信 ID)?[标准格式:AB123CD45]
大概要看上题中找到并且官方承认的即时通讯软件的聊天记录,但说不是微信ID,那应该就是另外两款软件中的一款。
先看默往:
默往的数据库也有加密,口令是
md5(uid)的前6位。UID 可以在/data/com.mostone.life/shared_prefs/im.xml中找到。
这边先找到UID:( .xml 文件在X-Ways中直接打开貌似有异常,这边需要用VSCode打开)

然后计算:

因此解密口令是:019019 。
然后默往的聊天记录数据库在这边:(竟然不是在database文件夹里面……)
\data\com.mostone.life\IMMsg\0190199C9DDA4ACBC0E42F65EFE35A6C\msg.db

此处需要用SQLCipher打开,否则会提示说“不是数据库文件”:

这边经尝试,发现需要用SQLCipher3:

然后可以找到聊天记录,但实际上,这边聊天记录不全:

如果想要全部聊天记录,就不能在X-Ways中直接看,而是要将这个数据库相关的文件导出到本机的同一目录下,然后再查看:

首先能看到一个支付宝账号:

但答案不是这个。
在联系人相关表下能找到目标账号:

经测试,答案为:1836042664454131712 。
14.分析手机检材,接上问,请问机主通过此应用删除过几个聊天记录?[标准格式:300]
聊天记录相关表下存在 delStatus 字段,只有一条消息有标明:

因此应该只有 1 个聊天记录被删除。
15.分析手机检材,请问会盗取手机信息的 APP 应用包名是什么?[标准格式:com.lx.tt]
这边还有微信聊天记录没看。
首先,我们无法找到 shared_prefs 目录。但据说在高版本微信中,IMEI值通常为 1234567890ABCDEF ,因此先这样认为。
而在高版本中,腾讯使用了自研的MMKV数据库,所以我们能在这边找到与UIN相关的配置文件:
\data\com.tencent.mm\files\mmkv\system_config_prefs

然后我们还需要MMKV解析工具,可以参考这个github项目:
https://github.com/spak9/mmkv_visualizer
这样便能找到UIN:

然后根据公式计算一下:
解密密码: MD5(手机IMEI + 微信UIN) 的前 7 位。

因此解密口令是:d5d90f2 。
然后,使用X-Ways找到聊天数据库文件:
\data\com.tencent.mm\MicroMsg\a0b534ccdb7db6ab0acbec2945cb2748\EnMicroMsg.db

(上面这五个文件都应该导出到同一目录下)
然后,微信连接参数需要特殊配置:(SQLCipher 1)
cipher_page_size = 1024
kdf_iter = 4000
cipher_use_hmac = OFF
cipher = AES-256-CBC
可惜新版本的DB_Browser已经不支持这样的连接参数了,因此用SQLiteStudio打开,加密算法配置写为:
PRAGMA cipher_compatibility = 1;

这样就能成功连接,看到内部的聊天记录:

红框中的XML内容:
<?xml version="1.0"?>
<msg>
<appmsg appid="wx6618f1cfc6c132f8" sdkver="0">
<title>滴滴滴.apk.1.1.1</title>
<type>6</type>
<action>view</action>
<appattach>
<totallen>801127</totallen>
<fileext>apk.1.1.1</fileext>
<attachid>@cdn_3057020100044b3049020100020467a0449e02032e930d02049d28aa3d020466728d87042435366233376536342d656337632d346264312d393733302d6239313038623664376334360204051400050201000405004c53d900_b6023164b4c4a29473102f4533fb7ec0_1</attachid>
<cdnattachurl>3057020100044b3049020100020467a0449e02032e930d02049d28aa3d020466728d87042435366233376536342d656337632d346264312d393733302d6239313038623664376334360204051400050201000405004c53d900</cdnattachurl>
<cdnthumbaeskey />
<aeskey>b6023164b4c4a29473102f4533fb7ec0</aeskey>
<encryver>0</encryver>
<filekey>wxid_5g23d5g40ck022_25_1718783763</filekey>
<overwrite_newmsgid>5267632616733053699</overwrite_newmsgid>
<fileuploadtoken>v1_AjhNBJdK5EQ5vtzEZRHYhJ/VjcY4E3ItBfKwMxmGFZnc7YijfIkVRPklmkjJ/Xwoudz1j+SdWHaaTiFbznNpSlBUM9q1fghVlg4QEmsowRJUTUzKB+EGcB3mPXUP/8KogKOou3cXOvuhIDJxsDVPiXhIbelY/QmF/3fuDI87V5PPRcE2KoUn3e7aL2+v8ES3E5m6o67cZXGoxto=</fileuploadtoken>
</appattach>
<md5>4c6e3dfdb7ec0c6b5f4b87a0131a4e51</md5>
<statextstr>GhQKEnd4NjYxOGYxY2ZjNmMxMzJmOA==</statextstr>
<webviewshared>
<jsAppId><![CDATA[]]></jsAppId>
</webviewshared>
<mpsharetrace>
<hasfinderelement>0</hasfinderelement>
</mpsharetrace>
<secretmsg>
<isscrectmsg>0</isscrectmsg>
</secretmsg>
</appmsg>
<fromusername>wxid_bmdgbk9b7v1929</fromusername>
<scene>0</scene>
<appinfo>
<version>7</version>
<appname>微信电脑版</appname>
</appinfo>
<commenturl></commenturl>
</msg>
至于后面两段XML,根据特征,应当是图片,其中一段如:
<?xml version="1.0"?>
<msg>
<img aeskey="6275a87c79bf64939baa425d79af08e8" encryver="1" cdnthumbaeskey="6275a87c79bf64939baa425d79af08e8" cdnthumburl="3057020100044b30490201000204a23e83bb02032e930d02046e28aa3d0204667290ae042461396235313930302d626130352d343039632d383064622d363864363764336438316633020405150a020201000405004c511d00" cdnthumblength="12867" cdnthumbheight="100" cdnthumbwidth="150" cdnmidheight="0" cdnmidwidth="0" cdnhdheight="0" cdnhdwidth="0" cdnmidimgurl="3057020100044b30490201000204a23e83bb02032e930d02046e28aa3d0204667290ae042461396235313930302d626130352d343039632d383064622d363864363764336438316633020405150a020201000405004c511d00" length="2764" md5="24c1dd73a1639149d1d75b606537cd97" hevc_mid_size="2764" originsourcemd5="0614f8966cb0681a239c0898d13b1814" />
<platform_signature />
<imgdatahash />
<ImgSourceInfo>
<ImgSourceUrl />
<BizType>0</BizType>
</ImgSourceInfo>
</msg>
可能是与机主相关的私人图片,后续对方开始借此展开索赔流程。
上面的聊天记录中有出现APK文件的名字,于是尝试用Everything去搜:

这边将APK文件取出来放到jadx中分析,在 AndroidManifest.xml 中可见包名和各种敏感权限的调用:

因此相关包名是:com.lxlxlx.luoliao 。
16.接上题,请问该软件作者预留的座机号码是多少?[标准格式:40088855555]
在 AndroidManifest.xml 中能找到主函数入口点:

这边在主函数中发现了可疑字符串,可能是密钥之类的,全部与 m439a 函数有关:

双击查看函数,发现应该是CBC模式的AES,传入的两个参数第一个是base64+AES加密过的密文,第二个是密钥(并且前16位兼为IV值):

前面主函数中列出了多段密文,都可以解密试试:

分别放CyberChef中解密:(注意那个密钥和IV不是Hex的(解密函数没拆Hex的逻辑),不要看错了)



但是发现这三句直接解解不开:

由下文可知,这两个字符串是要拼在一块用的:

因此在CyberChef中可见:

所以座机号码是:40085222666 。
17.接上题,恶意程序偷取数据的收件邮箱地址的 gmail 邮箱是多少?[标准格式:lx@gmail.com]
我们关注这个解出来是这个结果的变量对应的用例:

这边是有新建数组,然后分别加入 13024169815@189.cn 和 1304567895@gmail.com ,然后传入到函数 m443a 中:

双击跟进函数,发现传入的数组被备份到新的数组 c0235eArr 中,然后又被放入了新的函数 m585a 中:

m585a 整体逻辑复杂一些,因此先看和他一同传入的变量 f1075c ,发现是字符串 To :

逻辑上,整体构成一个 To 邮箱 的逻辑,说明前面邮箱列表就是数据收取方,因此选出其中的gmail邮箱提交即可:1304567895@gmail.com 。
18.接上题,恶意程序偷取数据的发件邮箱地址是多少?[标准格式:lx@gmail.com]
既然有 To ,那应该就会有对应的 From 。
于是我们在周围找找,发现有可疑的解密:


放CyberChef中解密看看,发现是个邮箱:

因此我们查看相关函数 m584a 的逻辑(可能涉及到这个邮箱的使用):

点进去之后,发现有 From 字眼:

因此发送的邮箱是:temp1234@gmail.com 。
19.接上题,恶意程序偷取数据的发件邮箱密码是多少?[标准格式:abc123]
前面的变量定义中,有发现一个没有用例的变量:

解密可见:

这个看起来还是比较像密码的,虽然没有用例能证明。
但是没有找到其他的类似于密码的东西,所以应该就是这个了。
因此密码是:qwer123456 。
20.接上题,恶意程序定义收发件的地址函数是什么?[标准格式:a]
这边包含收和发的函数在这里:

但这边需要注意jadx自动规范重命名的习惯,所以上面这个不是实际的函数名。
这边只需要关掉反混淆功能即可:

但后面提交了发现有问题,因为这个函数只是包含这些行为,还不够准确。
后续发现,这个和字符串 To 有关:

这个和字符串 From 有关:

因此认为定义收发地址的函数应当是:b 。
计算机取证
21.分析计算机检材,嫌疑人在将其侵公数据出售前在 Pycharm 中进行了 AES 加密,用于加密的 key 是多少?[标准格式:1A23456ABCD]
这边我们有 E01 文件,先放X-Ways中查看。
这边在下面目录查看注册表:
分区1\Windows\System32\config\SOFTWARE

然后在注册表中找到下面路径:
Microsoft\Windows NT\CurrentVersion

在此处可见目标系统为 Win 10 。
于是去仿真。
这边先用AIM挂载镜像:

挂载后可见目标磁盘是MBR类型的,因此等下仿真的时候引导模式只能选 BIOS ;然后这边是 PhysicalDriver2 ,仿真时需要选择对应的:

然后以管理员模式启动VMWare,以“自定义”模式创建新的虚拟机。
下面是一些需要选的选项:
稍后安装操作系统
Microsoft Windows
Windows 10 x64
BIOS
使用网络地址转换(NAT)
LSI Logic SAS
SATA
使用物理磁盘(适用于高级用户)
PhysicalDriver2(根据自己之前在AIM中看到的情况选择)
内存我觉得可以多给点,我自己通常会给到8个G。
然后开启虚拟机,这边选择“否”即可:

这边尝试弱密码登录,失败了:

但这边有密码提示,应当是一个生日号码,假如用SAM+SYSTEM配合Mimikatz生成NTLM,则这个NTLM应该有很大概率能被破解成功(因为只是普通的8位数而已)。
首先在X-Ways中找到这两个文件,右键恢复出来:
分区1\Windows\System32\config\SAM
分区1\Windows\System32\config\SYSTEM

然后将文件放到Mimikatz目录下:

然后打开Mimikatz,使用下面命令提取NTLM:
lsadump::sam /sam:SAM /system:SYSTEM

1699741e90e0be37532c22fe84baefe8
然后到在线网站解密:
https://hashes.com/en/decrypt/hash

至此得到 Administrator 的密码:990528 。
这样就能成功登录目标PC。
登录目标PC后,我们看到桌面上有PyCharm:

打开PyCharm后,会自动打开 encrypted.py 文件,此处俨然写着密钥:

因此密钥是:65B2564BG89F16G9 。
22.分析计算机检材,身份证为 "371963195112051505" 这个人的手机号码是多少?[标准格式:13013524420]
PyCharm的历史记录中,我们能看到一个 data.txt ,查看发现里面有含用户身份证号和手机号的信息。但是搜索题目中提到的身份证号找不到对应的记录:

可能是相关记录被删除了。
这边用X-Ways同步搜索这个身份证号,没搜索到什么。
这边还有一份加密过的文件,解密试试看:

根据加密代码写解密代码:
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from tqdm import tqdm
# AES加密函数
def aes_decrypt(padded_data, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
# 解密数据
decrypted_data = cipher.decrypt(padded_data)
# 对数据去除填充
data = unpad(decrypted_data, AES.block_size)
return data
# AES加密密钥和初始向量
key = b'64A1454AF78E06F9'
iv = b'93E8CBEF768944CF'
input_file = "encrypted.txt"
output_file = "data_dec.txt"
def process_data(input_file, output_file, key, iv):
with open(input_file, "r") as f_in, open(output_file, "w") as f_out:
total_lines = sum(1 for _ in f_in)
f_in.seek(0)
for line in tqdm(f_in, total=total_lines, desc="Processing"):
parts = line.strip().split(',')
index = parts[0]
f_out.write(index + ",")
decrypted_parts = []
for part in parts[1:]:
encrypted_part = bytes.fromhex(part)
decrypted_part = aes_decrypt(encrypted_part, key, iv)
decrypted_parts.append(decrypted_part.decode())
f_out.write(",".join(decrypted_parts) + "\n")
process_data(input_file, output_file, key, iv)
print("解密完成。")
右上角这个一定要小心,否则会执行其它代码。假如不小心重新执行了加密代码,可以到X-Ways中捞回原本的密文文件来用:

但这边仍然找不到:

而另外这个文件夹中,也有加密代码:

对应的密文文件貌似要大很多:

于是我们修改一下代码逻辑,尝试解密这个文件:
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from tqdm import tqdm
# AES加密函数
def aes_decrypt(padded_data, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
# 解密数据
decrypted_data = cipher.decrypt(padded_data)
# 对数据去除填充
data = unpad(decrypted_data, AES.block_size)
return data
# AES加密密钥和初始向量
key = b'65B2564BG89F16G9'
iv = b'83E6CBEF547944CF'
input_file = "encrypted_data.txt"
output_file = "data_dec.txt"
def process_data(input_file, output_file, key, iv):
with open(input_file, "r") as f_in, open(output_file, "w") as f_out:
total_lines = sum(1 for _ in f_in)
f_in.seek(0)
for line in tqdm(f_in, total=total_lines, desc="Processing"):
parts = line.strip().split(',')
index = parts[0]
f_out.write(index + ",")
decrypted_parts = []
for part in parts[1:]:
encrypted_part = bytes.fromhex(part)
decrypted_part = aes_decrypt(encrypted_part, key, iv)
decrypted_parts.append(decrypted_part.decode())
f_out.write(",".join(decrypted_parts) + "\n")
process_data(input_file, output_file, key, iv)
print("解密完成。")
这边改一下key、iv和输入文件名就能直接用了,但是要解密很久:

解密完成后,我们直接搜索关键词,就能搜索到了:(位置还挺靠前的)

因此对应的手机号码是:15075547510 。
23.分析计算机检材,对解密后的身份证数据列进行单列去重操作,重复的身份证号码数量是多少?(身份证不甄别真假)[标准格式:100]
这边尝试写python代码来实现:
with open('data_dec.txt', 'r') as f:
shenfenzheng = [i.split(',')[2] for i in f.readlines()]
f.close()
ori_len = len(shenfenzheng)
new_len = len(list(set(shenfenzheng)))
print(ori_len-new_len)
运行发现:

因此重复数量为:0 。
24.分析计算机检材,接上题,根据身份证号码(第 17 位)分析性别,男性的数据是多少条?[标准格式:100]
这边尝试写python代码来实现:
with open('data_dec.txt', 'r') as f:
shenfenzheng = [i.split(',')[2] for i in f.readlines()]
f.close()
count = 0
for i in shenfenzheng:
if int(i[16]) % 2 == 1:
count += 1
print(count)
运行发现:

因此男性的数据条数为:5001714 。
25.分析计算机检材,接上题,对解密后的数据文件进行分析,甄别身份证号码性别值与标识性别不一致的数量是多少?[标准格式:100]
这边尝试写python代码来实现:
shenfenzheng = []
xingbie = []
with open('data_dec.txt', 'r') as f:
for i in f:
shenfenzheng.append(i.strip().split(',')[2])
xingbie.append(i.strip().split(',')[4])
f.close()
count = 0
for i in range(len(shenfenzheng)):
if (int(shenfenzheng[i][16]) % 2 == 1 and xingbie[i] == '女') or (int(shenfenzheng[i][16]) % 2 == 0 and xingbie[i] == '男'):
count += 1
print(count)
运行发现:

因此不一致的数量为:5001185 。
26.分析计算机检材,计算机中存在的 “VPN” 工具版本是多少?[标准格式:1.1]
目标PC的数据盘中可见可疑文件WinXray:


直接打开其中的软件查看发现:

因此工具版本是:4.4 。
27.分析计算机检材,计算机中存在的 “VPN” 节点订阅地址是什么?[标准格式:http://xxx.xx/x/xxx]
软件中,此处可见订阅地址:

因此订阅地址是:https://paste.ee/d/4eIzU 。
28.分析计算机检材,eduwcry 压缩包文件的解压密码是什么?[标准格式:abcabc]
向目标PC中投送工具Everything,直接搜关键词 eduwcry ,找到文件位置:

这边用默认的压缩包查看工具打开文件,查看 选项 - 密码查看器 :

可见:

(尝试使用此密码解压该压缩包,发现有效)
因此密码是:yasuomima 。
29.分析计算机检材,接上题,请问恶意程序释放压缩包的 md5 值是多少。[标准格式:全小写]
我们将恶意程序放到其他有快照的虚拟机中运行,运行后,能看到各种乱七八糟的东西生成:

第二阶段,假如我们去运行那个有握手图标的exe,则会看到桌面生成神秘文件,然后壁纸被替换,有很明显的勒索消息出现:

但到这边我们还不知道压缩包在哪。
此处准备做逆向分析,首先用DIE查壳 wcry.exe ,发现这疑似是个压缩包:

于是我们尝试用7-zip打开,发现可以成功打开:

这应该就是所谓exe释放出来的压缩包了,那么exe本身主要功能应该只是实现把压缩包从自身取出来然后解压运行而已。
那么这边就要思考如何拿里面的ZIP。
假如尝试WinHex手工提取,会发现符合条件的ZIP文件头文件尾太多了,无从下手:

尝试使用 Resource Hacker 识别,发现可以直接识别到具有ZIP文件头的东西:

于是 右键 - Save *.bin resource ,然后保存为 .zip 文件,这样就能拿到具有原始文件名的压缩包文件:

然后丢到HashCalc中计算哈希值:

因此哈希值是:b576ada3366908875e5ce4cb3da6153a 。
30.分析计算机检材,接上题,请问恶意程序记录的洋葱浏览器下载地址是多少?[标准格式:http://xxx.xxx/xxx/xxx]
首先,我们用IDA简单分析一下 wcry.exe 。
这边首先进去之后看WinMain主函数,会看到一堆复杂的东西:

于是试着先 Shift+F12 看字符串,然而并没看到什么特别的东西,不包含洋葱浏览器下载地址什么的。
于是这边就随便点点主函数反汇编代码中的函数看看。这边倒是看到了一些东西:
发现可疑字符串:

分析相关行为,可能和注册表操作之类的有关。
然后是这个变量:


但是涉及到的函数是什么意思看不懂。
那么这个有没有可能是上一题提取出来的压缩包的密码?
于是尝试用这个作为密码解压压缩包:
WNcry@2ol7
发现解压成功:

题目要我们找浏览器下载地址,如果 wcry.exe 只是用来释放这些东西的而已,那么相关的信息应该是记录在被释放出的东西里面了。
于是逐个分析。
经过浏览,msg文件夹貌似是用来存放语言配置文件的,和题目关联不大:

然后首先对其他文件一一查壳,发现 s.wnry 是个 .dll 文件,貌似和洋葱浏览器相关关键词 Tor 有关联:

但是如果用IDA分析,也没发现什么下载地址。可能地址并不记录在这个文件中。
这个下载地址可能有两种存储方式,一种是明文存储,一种是密文存储。我们从简单的开始尝试,先假设地址是明文。
于是使用notepad++的“在文件中查找”功能来找关键字:

然后考虑到下载地址可能是一个差不多http协议的东西,所以带上关键词 http :

于是能发现 c.wnry 中存在可疑内容:

因此洋葱浏览器下载地址是:https://dist.torproject.org/torbrowser/6.5.1/tor-win32-0.2.9.10.zip 。
题外话:为什么不再使用VSCode来搜索文件中的关键词了?
因为在参考其他博主的wp时我意识到,VSCode面对编码有异常的文件,会选择忽略处理,而不会加入搜索。这样可能让我们遗漏关键信息。而我发现notepad++对此会坚持处理,所以改用notepad++了。
31.分析计算机检材,接上题,请问恶意程序解密了 t.wnry 后该 dll 的 md5 值是多少。[标准格式:全大写]
首先我们IDA分析 wcry.exe ,在主函数中能找到类似于 t.wnry 处理的语句:

于是查看这个函数,发现内部一片混乱:

在执行过程中,我们应该能看到 t.wnry 被加载,然后解密后做成 .dll 文件。
这期间涉及读写文件,因此内存中可能会存在解密结果,我们可以尝试动态调试截取解密结果。
这边发现 sub_4014A6 函数内,存在一个开内存空间的操作。这里的内存空间大概就是要放解密后的东西,v16应该会存放指向文件内容的地址,a3指向的内存应该会存放文件大小:

于是再一个 Tab 键再加空格键,找到对应语句的内存地址:

这两句的内存地址分别是 0x401673 和 0x4016CE 。到达 0x401673 时,寄存器EAX中应该会存放指向文件内容的地址;到达 0x4016CE 时,寄存器ECX中应该会存放文件内容。
所以打开x32dbg,载入程序后先按 Ctrl+G ,写入刚才的内存地址然后跳转到这两个语句,接着 F2 下断点。然后 F9 运行。然后就看到了:


所以 .dll 的文件大小应该是 0x10000 ,存放内容的地址是 0xA238F8 ,所以我们截取对应内存的0x10000字节大小的内容。
在x32dbg下方的命令框执行下面命令以快速保存0x10000字节大小的内容:
savedata C:\Users\HelloCTF_OS\Desktop\t_dec.dll,0xA238F8,0x10000
这边用winhex查看导出的文件,发现有PE文件头,说明我们的导出没有问题:

于是计算哈希:(注意,文件名不影响哈希校验,因为哈希校验只校验内容,而文件名和内容分离)

因此结果应该是:932274D9B56BB250E8C96FF09B001D00 。
32.分析计算机检材,接上题,恶意程序运行起来后第一个循环调用了几次 taskkill.exe。[标准格式:2]
拿到了上面的 .dll 文件之后,我们继续用IDA分析。这边直接 Shift+F12 查看字符串,搜索关键词 taskkill ,发现五个记录:

保险起见,交叉编译过去看看,发现是顺序执行,因此一个循环能执行到所有的taskkill:

因此调用次数为:5 。
33.分析计算机检材,接上题,请问 @WanaDecryptor@.exe.lnk 文件是通过什么函数创建的。[标准格式:Aabcdef]
继续 Shift+F12 查看字符串,搜索关键词 @WanaDecryptor@.exe.lnk ,发现:

双击后 Ctrl+X 交叉编译,找到用这个字符串的地方:

这个和 Format 变量相关,而 Format 的值是上面这一大串。
这边有个快捷方式创建函数,大概就是这个了:

因此函数是:CreateShortcut 。
34.分析计算机检材,接上题,恶意程序修改系统桌面壁纸是在哪个函数实现的 [标准格式:sub_xxx]
尝试运行这个恶意程序,会发现壁纸被替换,相关壁纸文件在桌面上,叫这个名字:
@WanaDecryptor@.bmp

于是到IDA中 Shift+F12 查看字符串,搜索关键词 @WanaDecryptor@.bmp ,但发现无结果。
但这边发现一个比较特别的现象,就是上一题的函数,从这边点进去,能发现旁边俨然放着目标关键词:


Ctrl+X 交叉编译跟踪,发现有两个调用点:

在第一个函数中,除了用来做字符串长度比较,貌似就没其他用途了,相关的壁纸替换实现逻辑应该不在这边:

在另外一个函数中,利用会丰富很多:

这边我们发现目标字符串和Buffer变量挂钩,而这个变量和下面的 SystemParametersInfoW 函数挂钩。
查询一下相关函数的含义,发现:

因此相关逻辑在这个函数中实现:sub_10004F20 。
35.分析计算机检材,VeraCrypt 加密容器的密码是什么?[标准格式:abc]
在之前的PC中,我们在数据盘下能看到一个dd文件:

在PC中的其他位置没有发现密码。
假如拿出来用WinHex打开,会发现是ZIP的文件头(思路比较特殊,感觉要自己想到比较难):

于是解压,可发现有密码文件:

因此密码是:qwertyuiop1 。
36.分析计算机检材,其中存在一个苹果手机备份包,手机备份包的密码是什么?[标准格式:12345]
使用VeraCrypt挂载上一题压缩包中的镜像文件(密码就是上一题同目录下找到的密码):

挂载后能看到一个苹果手机备份包:

下面目录存在一个 Manifest.plist ,可以以破解该文件为切入点爆破出对应密码。
该文章展示了对应的操作方法:
https://blog.csdn.net/wow0524/article/details/131519669
但在执行爆破之前,应该会有相关信息能帮助我们缩小爆破的范围。
这边在目标PC的谷歌浏览器浏览记录中发现:

因此目标的密码应该是5位数字。
后面试了一下,不管使用hashcat还是 Passware Kit Forensic(下载与使用方法可参考:https://www.forensics-wiki.com/node/0198134d-e00b-710d-ab92-a0709a78a3dd )来做,这个都很耗时:(这边展示的是 Passware Kit Forensic )

压榨4050ing……

在 Passware Kit Forensic 中,相关操作方法如:




耗时近半小时破解完成:

密码是:75966 。
37.分析计算机检材,接上题,机主实际篡改多少微信数据?[标准格式:1]
(参考大佬们的wp的时候发现这题实在是过于抽象了……简单复现一下就好了)
在备份包的 Info.plist 中可见已安装应用列表:

这边的确是有微信,大概可以看这边的。
但这边上一题找到的密码还没有去用,目前除了 爱思助手 没找到其他靠谱的备份包恢复工具。
这边直接用爱思助手恢复吧:

这边导出单文件可能出错,推荐直接导出整个文件夹。并且爱思助手的微信聊天预览不全,直接看数据库好了。
这边能找到微信数据库:
d:\Users\DELL\Desktop\新建文件夹\AppDomain-com.tencent.xin\Documents\0f622b1ed0cec997394177e4a0d5d9e2\DB


使用 SQLiteStudio 查看:

微信还有消息碎片文件,可以对消息是否被篡改这件事做交叉验证。相关文件:
AppDomain-com.tencent.xin\Documents\0f622b1ed0cec997394177e4a0d5d9e2\session\lsm_data\level_0
可使用winhex打开,然后浏览一下,可以发现一些微信ID:

那么应该拿着其中一个微信ID,就能追踪这一整个对话(后面发现 用wxid_bmdgbk9b7v1929 两段都能追踪到)。
于是搜索文本:

肉眼发现第一处不同:

第二处:

第三处:

因此篡改的数据有 3 处。
38.分析计算机检材,接上题,机主共存款了多少金额?[标准格式:10万]
这边在爱思助手中找到可疑应用文件夹并导出:

然后在这边找到数据库:
AppDomain-com.titashow.tangliao\Documents\IM5_CN\9031bc3c805ac5e55ecaa151092c2c4b\IM5_storage\1438793628033019010\

放到DB_Browser中,查看 message 表可见:

所以存款了 98万 。
39.分析计算机检材,在手机模拟器中勒索 apk 软件的 sha256 值是什么?[标准格式:全小写]
手机模拟器应该就是目标PC中的夜神模拟器。
这边能发现一个夜神模拟器备份:
C:\Users\Administrator\Documents\backup.npbk

根据龙信这两届往镜像里面塞压缩包的鬼操作,这边再用winhex打开看看,果不其然……

于是改后缀为 .7z 并打开,可以拿到镜像:

因此把vmdk取出来,用X-Ways分析。
首先我们找到 packages.xml 来看应用程序安装情况:
\system\packages.xml

用notepad++打开后,查找关键词:(如果是用户自己装的东西,一般都会有这个属性来表明安装来源)
installer=

于是可找到三个包名:



com.fankes.tmoreplus
com.chengxin.talk
tv.danmaku.bili
针对于后两个包名网上可搜到:


而第一个搜不到什么,那么应该就是第一个了。
接着在 /app 目录的对应包名的目录下找到 .apk 文件:

于是放到HashCalc中计算:

因此sha256值是:
340bd211955996c5d62bbde94a0bed4eb3a7965b23af52114991bca02346928e
40.分析计算机检材,接上题,请问勒索 apk 软件的解锁密码是什么?[标准格式:qwer.com]
使用jadx打开。
在源码的这个类文件中可见:

因此解锁密码是:anzhuo.com 。
(分析完这个APK的感想:这个可能是真实案件改来的,因为我发现赛事方那边疑似是APK没处理干净,资源文件里面留存有不可描述的图片……)
流量分析
41.分析流量包检材,给出管理员对 web 环境进行管理的工具名。(标准格式:小皮)
由第42题,我们知道服务器IP地址为 192.168.209.147 。
而如果使用带Web端的管理工具,应该会有相关页面的回显,所以我们可以筛选一下去看服务器的发包:
ip.src == 192.168.209.147
然后就可以看到宝塔的痕迹:

因此管理工具是:宝塔 。
42.分析流量包检材,给出攻击者的 ip 地址是多少。(标准格式:127.0.0.1)
通过筛选 http 然后浏览发现,攻击者对目标执行了目录扫描:

这边攻击者IP是:192.168.209.135 。
43.分析流量包检材,给出攻击者爆破出的网站非管理员用户名是。(标准格式:admin)
这边筛选出攻击者的发包,可见对登录框的爆破行为:
ip.src == 192.168.209.135 && http

右键跟踪HTTP流,我们可以看到一些网站回显,其中如果用户不存在的话,这边应该是会回显“未注册”:

对于用户存在但密码错误的包,这边直接找应该是很难找到的,因为爆破包的数量太多了。
这边我们先观察一下数据包,发现攻击者的登录爆破主要是在编号为12094到17696之间,再往后的 /wp-login.php 访问貌似是用于尝试SQL注入的。于是我们筛选出登录爆破包的回显包。
可见相关回显包到这边截止:

然后目标服务器IP地址是 192.168.209.147 。整体过滤语句如:
ip.src == 192.168.209.147 && http && frame.number >= 12094 && frame.number <= 17733
然后尝试按长度排序,能看到一些长度明显有异常的包:

查看发现,那个长度为 1250 的是提交了空用户名上去,不算。而另外两个是:


这边提示“密码不正确”而已,也就是说这两个用户存在:luna 和 saber 。
然后我们可以尝试过滤出有出现这两个关键词相关的条目:
http && frame contains "luna"
http && frame contains "saber"
针对于用户 luna ,攻击者扫到了之后就没有其他行动了:

针对于用户 saber ,这边有比较多的与 admin 相关的记录:

所以攻击者可能是盗用了这个用户的cookie,然后去访问了管理员页面相关内容。
所以非管理员用户是:luna 。
(网络上wp对这题貌似众说纷纭,但根据上面分析我疑心DIDCTF中这道题的答案有误。目前提交了题目纠错,但被驳回了。但仍然不知道上面这段分析是否正确,也就给各位师傅参考一下吧)
44.分析流量包检材,攻击者进行目录扫描得到的具有后门的页面 url 路径为。(标准格式:/abc.html)
通过筛选 http 然后浏览发现,下面这边有疑似文件上传点的访问,而这个上传文件功能依靠相关HTML页面来调用:

因此路径为:/up_load.html 。
45.分析流量包检材,攻击者通过修改请求包中的哪个字段导致恶意文件成功上传。(标准格式:test-type)
接上题,既然攻击者依靠 /up_load.php 上传恶意文件,那么我们可以追踪HTTP流看一下:

这边能看懂攻击者的恶意文件上传请求,还能看到冰蝎的特征:

这边摘出两段恶意请求,用CyberChef的diff功能找不同:

数字串、文件名和数据包大小不一样很好理解,那么现场就只剩下 Content-Type 不一样,这恰好也对应了文件上传漏洞利用中的 Content-Type绕过 操作。
因此修改的字段是:Content-Type 。
46.分析流量包检材,攻击者上传成功的恶意文件,该文件的临时存放路径是。(标准格式:/abc/edf)
接上一题,在追踪HTTP流中,我们能看到在传入恶意文件后目标服务器的回显:

但如果贸然提交这个答案会发现是错的,因为这边显示的是“文件已存在”,换句话说就是文件没有上传成功。
于是我们接着看后面的HTTP数据包:
http && frame.number > 17944

这边经过了上传之后,攻击者就开始使用后门文件,因此这边可能是有上传成功。
于是对编号为18355的数据包追踪HTTP流,在这边可见成功上传的回显:

因此临时存放位置应该是:/tmp/php38mbeJ 。
47.分析流量包检材,服务器 php 配置文件的存放位置(标准格式:/www/sev/php.ini)
(注意,这一题问的是“服务器php配置文件”,而不是“网站配置文件”)
下面可能涉及到对攻击者的行为分析,比如说,他是不是拿到了shell之后去读取这些东西之类的。
而我们知道目标使用的webshell管理工具是冰蝎,因此我们需要解密目标的加密流量。而做这个解密需要密钥。
于是同之前一样,我们去看目标上传的恶意代码:
ip.src == 192.168.209.135 && http && frame.number > 17733


因此密钥是:e45e329feb5d925b 。
然后后续有很多webshell的访问操作,可能是在做交互了,所以可以随便找一条追踪HTTP流:

然后就可以看到很多加密流量之类的:

攻击者应该是从目标的回显中得知配置文件路径的,所以我们就在左下角筛选响应包即可:

然后浏览,这边有一段特别长的,可以拿去解密流量一下:

这边解密流量我们选用希潭实验室的蓝队分析工具箱( https://github.com/abc123info/BlueTeamTools )。
尝试解密,可以解密得下面结果:

怀疑这边的basicinfo是base64加密过了,而解密结果末尾有比较短的数据,比如当前目录:(其实这边能看到base64的特征了)

于是先试一下,拿去做base64解密,发现成功解出有意义的内容:

于是把上面的basicinfo也拿去解密,然后查看。
能发现这边可能是phpinfo:

而且这边明显能感受到这是个html文件,所以将文件后缀改为 .html 后打开,发现:

因此配置文件存放路径是:/www/server/php/82/etc/php.ini 。
48.分析流量包检材,被攻击的 web 环境其数据库密码是。(标准格式:qwer1234)
我们接下来继续解密剩下的内容,发现攻击者基本是在做一些信息收集:
文件列出:


网络情况:

去查看 /etc/passwd :

但是到这边也没看到什么密码。
可能是不在上面这一块流量中,而我们尝试做之前的筛选:
ip.src == 192.168.209.135 && http && frame.number > 17733
能看到这边还有一块对木马文件的访问,于是也右键追踪HTTP流查看:

但这边追踪流貌似一次只能看一次交互了,所以我们挨个查看即可。
这边对着编号为27262的数据包追踪HTTP流:

解密流量后能在末尾看到cmd变量,有明显的base64特征:

于是尝试base64解密,发现攻击者正常试着找密码文件:

顺带一提,考虑到要看的条目比较多,这边也可以不用追踪流了,直接点进数据包,然后对着数据右键提取ASCII文本即可:

在之前编号为20450的数据包中能发现攻击者正在尝试mysql登录,说明这时候攻击者可能已经知道数据库密码了:


这边通过看服务器的回包验证一下:
ip.src == 192.168.209.147 && http && frame.number > 17733


貌似没法肯定是成功了还是失败了。
但攻击者如果要知道密码,说明前面可能泄露了什么。
所以继续看攻击者的发包:
ip.src == 192.168.209.135 && http && frame.number > 17733
再往前,可以看到一个:


这边发现攻击者查看网站配置文件的操作,那么可能配置文件中存在数据库密码。
于是查看服务器的回包,发现数据库密码:
ip.src == 192.168.209.147 && http && frame.number > 17733

因此数据库密码是:X847Z3QzF1a6MHjR 。
49.分析流量包检材,服务器管理存放临时登录密码的位置。(标准格式:/tmp/pass)
经过耐心解密,发现编号29743和编号29854数据包中内容解密后分别得到:


这边明显是攻击者把相关密码文件全都搜出来,然后放 /tmp/tmppass 目录下。
因此临时存放位置是:/tmp/tmppass 。
50.分析流量包检材,黑客获取的高权限主机的登录密码。(标准格式:qwer1234)
接上题,编号29854数据包中,攻击者cat了临时登录密码文件,那么相应回包应该会有密码。
于是筛选并找到服务器的对应回包:
ip.src == 192.168.209.147 && http && frame.number > 17733

解密对应冰蝎流量发现:

因此密码是:passwd!@# 。
服务器取证
51.分析服务器检材,服务器会做登录密码验证,该登录验证文件位置在?[标准格式:/xxx/xxx/xxx.xxx]
首先我们有一个服务器检材的E01文件。
这边先放到X-Ways中查看。
通过查看 /usr/lib/os-release( /etc/os-release 指向该文件发现):

至此我们知道了目标系统为 CentOS7 。
于是尝试AIM挂载,然后VMWare仿真:

VMWare挂载时需要注意选择:
稍后安装操作系统
Linux
CentOS 7 64位
使用网络地址转换(NAT)
LSI Logic SAS
SATA
使用物理磁盘(适用于高级用户)
PhysicalDriver2(根据自己之前在AIM中看到的情况选择)
然后启动虚拟机,进入包含多条CentOS Linux开头的可选项的页面后,我们选中第一条后按 E 键,然后向下翻到底在中间位置找到存在关键词 ro 代码,然后将 ro 更改为:
rw init=/sysroot/bin/sh
修改完成后我们按 Ctrl+X 进入单用户模式,执行命令 chroot /sysroot 访问系统,输入 passwd root 修改root用户密码(交互式),执行 touch /.autorelabel 对文件系统赋予标签,接着输入 exit 退出chroot环境,最后 reboot 命令重启虚拟机。

上面这一套改完之后,我们重启,用刚才设置的密码登录 root 用户,首先是会看到乱七八糟的东西,疑似是识别到异常登录,然后删了一堆东西:


Linux 中开机自启的脚本可能在下面位置中:
/etc/profile /etc/profile.d/ ~/.bashrc ~/.profile
这边用X-Ways打开分析,发现相关文件:
\etc\profile.d\check-system.sh


因此这边的登录验证文件为:/etc/profile.d/check-system.sh(照着题目给的格式来)。
这边我们的仿真还没完成。
重新仿真虚拟机,进入包含多条CentOS Linux开头的可选项的页面后,我们选中第一条后按 E 键,然后向下翻到底在中间位置找到存在关键词 ro 代码,然后将 ro 更改为:
rw init=/sysroot/bin/sh
修改完成后我们按 Ctrl+X 进入单用户模式,执行命令 chroot /sysroot 访问系统,然后 cd /etc/profile.d 进入到登录验证文件所在目录,然后 rm check-system.sh 删掉这个验证文件,然后输入 passwd root 修改root用户密码(交互式),执行 touch /.autorelabel 对文件系统赋予标签,接着输入 exit 退出chroot环境,最后 reboot 命令重启虚拟机。
这样就能成功了:

52.分析服务器检材,服务器 ssh 端口是多少?[标准格式:1234]
直接检查sshd服务状态:
systemctl status sshd

发现ssh端口是:12320 。
这边可以顺带用tabby连接,终端会好使一些:
(先看一眼IP地址)


这边我们也可以靠看配置文件的方式来看端口号:
cat /etc/ssh/sshd_config

53.分析服务器检材,服务器 docker 内有多少个镜像。[标准格式:100]
直接使用docker相关命令查看:
docker images

因此有 7 个docker镜像。
或者看下面目录也行(但感觉就复杂多了):
/var/lib/docker/image/overlay2/imagedb/content/sha256/

54.分析服务器检材,服务器内 sqlserver 默认账号的密码是?[标准格式:xxx]
服务器的什么 /etc 目录下之类的看不到 mssql 字眼,但是在docker镜像中有一个这样的:

这边我们能看到,目标服务器中存在一个未启动的容器,我们首先启动这个容器,然后接管这个容器的终端:
docker ps -a
docker start 392e # 392e是我这边容器ID的前4位
docker exec -it 392e /bin/sh
这边如果要浏览目录的话会比较难找,这边其实看环境变量能找到:
env

因此密码是:<i7uFtnkTv8> 。
55.分析服务器检材,服务器内 sqlserver 存放了阿里云存储下载地址,该下载地址是?[标准格式:https://xxx]
目标容器实际上把mssql的默认端口 1433 映射了出来:


这意味着我们可以尝试直接连接目标数据库。
而通过上一题可知,默认账户的密码是 <i7uFtnkTv8> ,而mssql的默认账户是 sa :

于是打开Navicat,尝试连接 SQL Server :

(这边添加时遇到了问题 “[IM002] [Microsoft][ODBC驱动程序管理器]未发现数据源名称并且未指定默认驱动程序” ,可以参考这篇文章解决:https://blog.csdn.net/Mr_Blackk/article/details/120907783 )
这边打开后只有一个 cjj 库,耐心浏览可发现 cmf_config 表下存在相关信息:

因此下载地址是:https://xinfenfa.oss-accelerate.aliyuncs.com 。
56.分析服务器检材,服务器内 sqlserver 内 “cmf_user_action_log” 表,表内存在的用户操作日志,一共操作次数是多少?[标准格式:100]
这是用户操作日志,总操作次数应当就是表中数据的条目数。
于是写mssql语句并执行:
SELECT count(id) FROM [dbo].[cmf_user_action_log]

但这边如果去交DIDCTF是错的。
实际上,每一条操作都内置更多的操作次数,用 counts 字段来体现:

于是累加所有数据的counts值,写出新的mssql语句:
SELECT sum(counts) FROM [dbo].[cmf_user_action_log]

因此总操作次数是:99684318 。
57.分析服务器检材,该服务器正在使用的数据库的持久化目录是什么?[标准格式:/xxx/xxx]
这边说的应该是docker中,即使我们删掉了这个容器,数据库中的内容还会留存在目标服务器的某个目录中,这个就是持久化目录。
这边我们用 inspect 查看容器配置:(查看包含字符串 "Mounts" 在内的内容及其后的10行)
docker inspect 392e | grep -A 10 '"Mounts"'
发现没有内容:

但题目说的是该服务器“正在使用”的数据库。
所以这边需要先搞清楚服务器正在用的数据库是哪个。
这边看看服务器里面还有什么没启动的容器:
docker ps -a

还有mongo和mysql,分别查看容器相关配置:
docker inspect d496 | grep -A 20 '"Mounts"'
docker inspect 9fc3 | grep -A 10 '"Mounts"'
这边目前都有绑定,不好确定:( Source 属性的是物理机上的持久化目录)

于是考虑一下查看历史命令,但历史命令基本没有留存。
去看 /www ,发现里面什么也没有,可能站点根目录在其他地方。
然后看中间件,这边在 /etc 目录下看到nginx:

于是跟进,查看配置文件可见站点目录:
ls /etc/nginx/conf.d
cat /etc/nginx/conf.d/bl.dsnbbaj686.fit.conf

这边跟进查看,发现是mongo:
cat /opt/bl.dsnbbaj686.fit/www/app/database.php

因此持久化目录为:/data/mongo 。
58.分析服务器检材,该网站后台正在使用的数据库有多少个集合?[标准格式:100]
这边如果不懂mongo可能一时理解不了题目。mongo是非结构化数据库,“集合”这个东西感觉上类似于mysql、mssql等结构化数据库中所说的“表”。
接上一题,这边数据库配置文件中写着mongo的连接用户名和密码,端口也是默认端口:

端口映射也是没有变化的,因此这边直接启动容器:
docker start d496 # d496是我这边容器ID的前4位

然后Navicat连接:

完成连接后可见所有集合:

因此一共有 13 个集合。
59.分析服务器检材,该网站的后台登录地址是?[标准格式:/xxx/xxx.xxx 全小写,不加域名]
浏览一下数据库内容,可在 app_urlconfig 集合下看到一个后台登录地址:

但这段是在ThinkPHP中的写法,还不是后台登录地址本身。
感觉这个会比较难看懂一点,还可以看其他地方,比如日志。这边在 runtime 目录下随便找了一个日志:
/opt/bl.dsnbbaj686.fit/www/runtime/log/202406/12.log

搜索关键词 login 可见URL如:

但提交答案发现这个仍然不是答案要的后台登录地址,遇到这种错误感觉概率不高呀。
那么换一下其他方法,比如这边我们看看能不能重建网站。
假如我们浏览器访问目标网站,则会看到报错:

而我们SSH登入时,则会发现:(但这个其实还挺难发现的……)

然后进入目标容器中:
docker exec -it 9fc3 /bin/sh
这边有个“入口点”脚本,大概是启动脚本,cat一下:

这边能看到,mysql密码可能和环境变量有关:

于是查看环境变量:
env

于是尝试Navicat连接:

这边mysql中也有 lok1 库,但其中没有表,说明数据要从mongo迁移到mysql中:

于是将mongo中的lok1中的集合导出为 CSV 文件:

然后在mysql中导入:

然后修改一下网站的数据库配置文件,改一下数据库类型、用户名、密码、端口号:
vim /opt/bl.dsnbbaj686.fit/www/app/database.php

这时候再访问网站,就不报错了:

尝试了这些,发现都不重定向:




于是再看网站结构,发现可以试着访问:
http://192.168.213.129/appmanager

发现成功重定向:

因此网站后台登录地址是:/appmanager/common/login.shtml 。
60.分析服务器检材,该网站后台使用的管理员加密算法是?[标准格式:全大写]
首先查看网站数据库的 app_admin 表,可见:

看上去是 bcrypt 。
如果不了解的话,可以找到这个文件中有相关逻辑,存在一个加密函数:
/opt/bl.dsnbbaj686.fit/www/app/appmanager/controller/Admin.php

查找相关函数位置:
grep -r "encryptpass" /opt/bl.dsnbbaj686.fit/www

于是查看:
/opt/bl.dsnbbaj686.fit/www/app/appmanager/common.php

因此加密算法是:BCRYPT 。
61.分析服务器检材,该网站最早使用超级管理员进行删除管理员操作的 IP 地址是?[标准格式:x.x.x.x]
此处在 app_admin_menu 表中可见,删除管理员相关操作的ID是 26 :

这边 app_admin_log 表中有两个可能的字段:

但 operation_id 的部分值是空的,所以应该不是我们要的。那么就是 admin_menu_id 。
于是执行MySQL语句:
SELECT * FROM `app_admin_log` where admin_menu_id = 26 order by create_time ASC

因此相关IP地址是:117.132.191.203 。
62.分析服务器检材,该网站后台上传过 sha256 值为 “b204ad1f475c7716daab9afb5f8d61815c508f2a2b1539bc1f42fe2f212b30d1” 的压缩包文件,该文件内的账单交易订单号是多少?[标准格式:123456]
这边说的是压缩包,app_attachment 表中有上传记录,但没有压缩包相关的上传记录。
于是到服务器中去看,在这个目录下能找到上传的文件:

通过查看,发现只有这个文件夹下出现了3个压缩包:
/opt/bl.dsnbbaj686.fit/www/public/uploads/admin/admin_thumb/20240614

全都下载下来,用HashCalc来看,发现这个文件符合题目描述:

尝试开这个压缩包,发现里面有加密,但这边注释有给到提示:

需要尝试爆破,但这边用 APCHAR 貌似无法识别:

于是尝试使用 passware :



4050显卡大概2分多钟就能找到密码:

据此解压压缩包,发现是base64编码的图片:

尝试解码:


因此订单号是:20240321000000005443369778283185 。
63.分析服务器检材,该网站存在网站数据库备份功能,该功能的接口地址是?[标准格式:/xxx/xxx 全小写,不加域名]
在这个目录下发现备份相关的操作文件:
/opt/bl.dsnbbaj686.fit/www/app/appmanager/controller/Databackup.php

打开后可见,可能可以参考一下日志:

于是在相关日志文件夹下查找关键词:
grep -r "backup" /opt/bl.dsnbbaj686.fit/www/runtime/log

因此接口地址是:/appmanager/databackup 。
64.分析服务器检材,该网站存放银行卡信息数据表中,其中信息数量前十的公司对应旗下 visa 银行卡一共有多少金额?[标准格式:100.00]
这边能看到是在 app_card 表下:

这边能观察到,不同数据可能company值是一样的。
于是执行mysql语句:
SELECT sum(t.sum1) from
(SELECT sum(money) as sum1
FROM `app_card`
group by company
order by count(*) DESC
limit 10
) as t;
但如果只是这样就错了,题目中说的是“VISA”银行卡,而VISA银行卡的卡号首位为 4(这个真的挺坑的……):

这边已经完全弄不明白这里mysql语句要怎么写了……
于是右键“导出向导”导出excel表,然后先在表中筛选计数前10的项:(如果找不到那个向下的三角标志,就对着“company”右键“筛选”即可)

然后这时候一定要记得把筛选出来的数据捞到新的sheet中,否则等一下计算sum会把筛选外的数据也算进来。然后以 card_no 字段做升序排序,借助Shift快速选择删掉6开头的所有数据,然后用SUM函数计算:

因此总和是:21701599.63 。
65.分析服务器检材,该网站在 2023 年二月一共获取了多少条通信记录?[标准格式:100]
发现可能是 app_mobile 表,这边有个addtime字段:

我们先去获取题目要的时间区间:


因此可写出mysql语句:
SELECT count(*) FROM `app_mobile` where addtime>=1675180800 and addtime<1677600000

因此通信记录为 2879 条。
66.分析服务器检材,该网站的一条管理员信息存在数据篡改,请分析是哪个管理员信息遭到篡改,该管理员用户名是?[标准格式:ABCDE]
这边查看 app_admin 表,发现有一条数据创建时间晚于登录时间,有异常:

因此推断被篡改过的管理员用户名为:xYpMLuROhNl 。