Cylab在线靶场——挑战图书馆初学者指南

CyLab Security Academy 是一个面向网络安全初学者的在线实战靶场平台,提供大量 CTF(Capture The Flag)风格的挑战题目,覆盖密码学、逆向工程、Web 安全、二进制漏洞利用等多个方向。平台采用「启动实例 + 在线提交 Flag」的模式,每道题都会分配一个独立的可连接实例,你需要在实例中分析、破解并找到形如 academy{...} 的 Flag,提交到页面底部即可得分。本文记录了我在 CyLab 靶场从入门到通关的完整 WriteUp,包含每道题的解题思路、操作步骤和踩坑提醒,希望能给同样在刷题的你一些参考。

靶场链接:

CyLab Security Academy - Dashboardhttps://learn.cylabacademy.org/dashboardhttps://learn.cylabacademy.org/dashboard

之后还会实时更新wp!

第一节:理智

听话的猫

直接记事本打开

academy{s4n1ty_v3r1f13d_61ddac22}

超级SSH

感觉这个不知道是不是靶场问题,密码总是不对

启动实例之后

进入实例之后:

这题其实就是考最基础的 SSH 远程登录,跟逆向没关系。核心就一句话:用 ssh 连到题目给的地址和端口,密码登录后把 flag 文件读出来。

打开你电脑的 PowerShell(macOS/Linux 用终端也行),执行:

复制代码
ssh ctf-player@xebec.cylabsacademy.net -p 37939

然后按提示操作:

  1. 第一次连接会问 Are you sure you want to continue connecting (yes/no/[fingerprint])?,输入完整的 yes 回车(这就是题目说的"接受指纹")。

  2. 提示 password: 时输入 8d1db23byes 回车。注意输密码时屏幕上不会显示任何字符,这是正常的,粘贴后直接回车即可。

  3. 登录成功后先看看有什么文件:

    ls

一般会看到 flag.txt,直接读:

复制代码
cat flag.txt
  1. 输出的内容形如 picoCTF{...},把它复制到页面底部的输入框点"提交"即可。

几个容易踩的坑:

  • 端口参数是小写 -p,别写成 -P 或漏掉,用户名是带连字符的 ctf-player。
  • 页面左上角有实例倒计时(截图里 14:56)。如果连接报 Connection refused 或一直超时,说明实例过期了,点"重启实例",端口可能会变,要以页面刷新后显示的新端口为准。
  • 如果你本机没有 ssh 命令(老版本 Windows),去"设置 → 应用 → 可选功能"里安装 OpenSSH 客户端,或者直接用题目里给的 webshell 网页终端,在里面跑同样的命令。
  • 如果 ls 里没有 flag.txt,用 ls -la 看看隐藏文件,或 find . -name "*flag*" 找一下,位置可能略有不同。

登录成功后随手敲 exit 就能退出,不退出的话它会占着你的终端。

什么是网猫

还是在上一题的实例中

复制代码
nc xebec.cylabacademy.net 25485

通俗解释

你可以把服务器(xebec.cylabacademy.net)想象成一栋有很多门的大楼,而端口号(25485)就是其中某一扇特定的门。

  • 这道题的出题人在服务器的第 25485 号门上,藏了一个自动应答的"小机关"。
  • 这个"小机关"的作用非常简单:一旦有外人敲门(连接它),它就会立刻把门上的密码(也就是 Flag)喊出来。

为什么要用 netcat(nc)?

netcat(简称 nc)是黑客和网络安全人员最常用的工具之一,它的核心作用就是 "万能网络连接工具"。

  • 你可以把它理解为网络世界的"万能钥匙"或"对讲机"。
  • 平时我们用浏览器(HTTP协议)去连接服务器,但 nc 可以让你绕过浏览器的限制,直接用原始的 TCP 或 UDP 协议去连接服务器的任意端口,和上面那个小机关直接对话。

总结一下

所以,这道题的操作逻辑其实非常简单:

你拿着 nc 这把万能钥匙,去敲响服务器的第 25485 号门,对方就会自动把 Flag 给你。

academy{nEtCat_Mast3ry_abbFbc0e}

第二部分

mod26

values.txt

复制代码
npnqrzl{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_5p5s5o36}

这题是 picoCTF 2021 的 Mod 26,考点就是 ROT13:每个字母往后移 13 位(到 z 就绕回 a),数字、标点和花括号都不变;再 ROT13 一次就能还原。

把 values.txt 里的内容拿去 ROT13:

复制代码
npnqrzl{argk gvzr V'yy gel 2 ebhaqf bs ebg13 5p5s5o36}

解出来是:

复制代码
academy{next time I'll try 2 rounds of rot13 5c5f5b36}

逐个对照一下,方便你验证:npnqrzl → academy,argk → next,gvzr → time,V'yy → I'll,gel → try,ebhaqf → rounds,bs → of,ebg13 → rot13,5p5s5o36 → 5c5f5b36。

提交时有两个细节要注意:

  1. 先原样提交 ROT13 的结果,空格保留;
  2. 如果平台提示格式不对,多半是旗标里用了下划线,把空格换成 _ 再试,也就是 academy{next_time_I'll_try_2_rounds_of_rot13_5c5f5b36}。

另外记住题目的暗示"2 rounds of rot13"------ROT13 是自逆的,转两圈就回到原文,所以这题不需要密钥。

如果你以后想用工具验证,页面里那个"赛博厨师"就是 CyberChef,拖入文件内容后加一个 ROT13 操作即可;命令行也可以一行搞定:

复制代码
python -c "import codecs; print(codecs.decode(\"npnqrzl{argk gvzr V'yy gel 2 ebhaqf bs ebg13 5p5s5o36}\", 'rot13'))"

或者直接使用工具:

academy{next_time_I'll_try_2_rounds_of_rot13_5c5f5b36}

热身

题目要求将十六进制数 0x3D 转换为十进制数。

1.使用 Python(最推荐,CTF 必备)

Python 是 CTF 选手的神器,几乎可以处理所有编码转换问题。

  • 操作方法 :打开你的 Webshell 或者本地终端,输入以下命令:bash编辑

    python3 -c "print(0x3D)"

  • 原理 :Python 能够直接识别以 0x 开头的十六进制数,并自动将其作为整数处理,print 函数默认输出十进制。

2. 使用 Linux 命令行工具

如果你正在使用 Linux 环境(比如你之前的 Webshell),系统自带的计算器 bc 非常好用。

  • 操作方法 :bash编辑

    echo "ibase=16; 3D" | bc

  • 原理 :ibase=16 告诉 bc 计算器输入的数据是十六进制的,然后它会自动输出对应的十进制结果。

3. 使用 Windows 自带的计算器

如果你是在自己的电脑上做题,不需要写代码也能算。

  • 操作方法:
    1. 按 Win + R,输入 calc 打开计算器。
    2. 点击左上角菜单,选择 "程序员" (Programmer) 模式。
    3. 点击左侧的 Hex(十六进制)单选框。
    4. 输入 3D。
    5. 点击左侧的 Dec (十进制)单选框,屏幕上的数字就会瞬间变成 61。

4. 使用浏览器的开发者工具 (F12)

既然题目说可以在浏览器完成,你也可以直接利用浏览器控制台。

  • 操作方法:
    1. 在浏览器页面按 F12 打开开发者工具。
    2. 点击 Console(控制台)标签页。
    3. 输入 0x3D 并回车。
    4. 浏览器会自动显示结果 61。

总结

无论用哪种工具,核心逻辑都是一样的:识别十六进制格式 -> 转换为十进制整数 。对于这道题,答案就是 61。

academy{61}

二暖

1. 使用 Python(最推荐,CTF 必备)

Python 是 CTF 选手的神器,处理进制转换非常简单。

  • 操作方法 :打开你的终端或 Webshell,输入以下命令:bash编辑

    python3 -c "print(bin(42))"

  • 结果 :0b101010

  • 注意 :0b 是 Python 表示二进制的"前缀",实际答案只需要后面的数字 101010。

2. 使用 Windows 自带计算器

如果你不想写代码,Windows 计算器也是神器。

  • 操作方法:
    1. 按 Win + R,输入 calc 打开计算器。

    2. 点击左上角菜单,选择 "程序员" (Programmer) 模式。

    3. 点击左侧的 Dec(十进制)单选框。

    4. 输入 42。

    5. 点击左侧的 Bin (二进制)单选框,屏幕上的数字会瞬间变成 101010。

3. 使用 Linux 命令行工具 (bc)

如果你习惯用 Linux 终端,bc 命令非常好用。

  • 操作方法 :bash编辑

    echo "obase=2; 42" | bc

  • 原理 :obase=2 告诉计算器输出的目标进制是二进制。

4. 浏览器开发者工具 (F12)

既然题目提示可以在浏览器完成,直接用控制台最快。

  • 操作方法:
    1. 按 F12 打开开发者工具。
    2. 点击 Console(控制台)。
    3. 输入 (42).toString(2) 并回车。
    4. 结果直接显示为 "101010"。

无论用哪种工具,算出来的核心数字都是:101010。

academy{101010}

基地(Bases)

academy{l3arn_th3_r0p35}

第三条

挥旗

academy{b1scu1ts_4nd_gr4vy_57d8c79}

Tab,Tab,攻击,

傻瓜做法:(进很多层文件夹之后打开c文件就找到了)

进阶做法(在放压缩包的文件夹里打开终端):

复制代码
wsl

输入解压命令

最后获取到这些,然后在c语言文件中找到flag

academy{l3v3l_up!_t4k3_4_r35t!_9d928112}

Insp3ct0r

这道题是典型的"网页源代码审查"入门题,

核心就是找到藏在网页三个文件(HTML、CSS、JS)注释里的三段 flag,最后拼起来提交。

🛠️ 解题步骤

  1. 查看网页源代码 (HTML) :在题目对应的网址页面里,右键选择"查看网页源代码"(或者按 Ctrl+U / Mac按 Cmd+U)。在最底下找到一部分 flag:academy{tru3_d3

  2. 查看 CSS 文件 :在源代码的 <head> 部分,找到 mycss.css 的链接并打开。在文件末尾的注释里找到第二段:t3ct1ve_0r_ju5t

  3. 查看 JavaScript 文件 :同样在 HTML 源代码里找到 myjs.js 的链接并打开。在文件末尾的注释里找到第三段:_lucky?aa3ae7c8}

把三段拼起来就得到完整的 flag 了,注意保留花括号的格式

academy{tru3_d3t3ct1ve_0r_ju5t_lucky?aa3ae7c8}

弦乐

记事本打开,直接就找到了

academy{5tRIng5_1T_b1e21039}

First Grep

academy{grep_is_good_to_find_things_3FCACd2A}

机器人在哪里

这道题考的是网站里的一个特殊文件 robots.txt。只要找到这个文件,就能顺着线索找到 flag。

robots.txt 是网站根目录下的一个公开文本文件,作用是告诉搜索引擎的爬虫(也就是"机器人")哪些页面可以抓取,哪些不该碰。但问题是,这个文件谁都能看,所以它反而会暴露网站不想让人发现的位置。

  1. 打开题目链接
    访问你截图里的地址 http://xbec.cylabacademy.net:37009。

访问 robots.txt

在浏览器地址栏的网址后面直接加上 /robots.txt,完整地址变成 http://xbec.cylabacademy.net:37009/robots.txt。

这个页面会显示类似下面的内容:

复制代码
User-agent: *
Disallow: /xxxxx.html
  1. 访问被禁止的页面
    把 Disallow 后面的路径(例如 /xxxxx.html)拼接到原网址后面,直接访问这个页面。
    http://xbec.cylabacademy.net:37009/xxxxx.html

页面上应该就显示着 flag 了。

academy{ca1cu1at1ng_Mach1n3s_5ed99}

第四部分(python)

python wrangling

下载好附件

  1. 查看密码文件 :先打开 pw.txt 看看里面写了什么,这串字符就是解密用的密码。可以在终端里用 cat pw.txt 查看,也可直接打开查看。

    复制代码
    <p class="img-center"><img alt="" height="179" id="u3875da20" isbindedload="true" src="https://i-blog.csdnimg.cn/img_convert/52d726cd44dedaed709d1bbbcf3dfab6.png" width="848"/></p>
  2. 然后可以打开py文件看一下内容

    import sys
    import base64
    from cryptography.fernet import Fernet
    usage_msg = "Usage: "+ sys.argv[0] +" (-e/-d) [file]"
    help_msg = usage_msg + "\n" +

    "Examples:\n" +

    " To decrypt a file named 'pole.txt', do: " +

    "'$ python "+ sys.argv[0] +" -d pole.txt'\n"
    if len(sys.argv) < 2 or len(sys.argv) > 4:
    print(usage_msg)
    sys.exit(1)
    if sys.argv[1] == "-e":
    if len(sys.argv) < 4:
    sim_sala_bim = input("Please enter the password:")
    else:
    sim_sala_bim = sys.argv[3]
    ssb_b64 = base64.b64encode(sim_sala_bim.encode())
    c = Fernet(ssb_b64)

    with open(sys.argv[2], "rb") as f:
    data = f.read()
    data_c = c.encrypt(data)
    sys.stdout.write(data_c.decode())
    elif sys.argv[1] == "-d":
    if len(sys.argv) < 4:
    sim_sala_bim = input("Please enter the password:")
    else:
    sim_sala_bim = sys.argv[3]
    ssb_b64 = base64.b64encode(sim_sala_bim.encode())
    c = Fernet(ssb_b64)

    with open(sys.argv[2], "r") as f:
    data = f.read()
    data_c = c.decrypt(data.encode())
    sys.stdout.buffer.write(data_c)
    elif sys.argv[1] == "-h" or sys.argv[1] == "--help":
    print(help_msg)
    sys.exit(1)
    else:
    print("Unrecognized first argument: "+ sys.argv[1])
    print("Please use '-e', '-d', or '-h'.")

  3. 运行解密命令 :在包含这三个文件的目录下,用 Python 运行脚本,参数 -d 代表解密,后面接上需要解密的文件 flag.txt.en。

    python3 ende.py -d flag.txt.en

  4. 输入密码 :运行命令后,程序会提示 Please enter the password:,把刚才从 pw.txt 里看到的字符串粘贴进去回车就行。

如果报错显示如图

就是没有缺少库,安装一下就好了:pip install cryptography

如果安装速度慢或报错,可以换成国内镜像源(清华源):

pip install cryptography -i Simple Index

如果安装失败啥的,就自己问AI自己的环境什么的怎么搞,毕竟每个人环境不一样

cryptography 是 Python 的加密库,ende.py 解密文件时就依赖它。如果你用的是虚拟环境(比如 conda、venv),要确认在这个环境里也装上了才行。

academy{4p0110_1n_7h3_h0us3_d6af8f37}

PW Crack1

这是一道经典的逆向/密码学入门题,名叫 PW裂缝1(原名通常叫 Crack the Password,或者带点 XOR 操作)。

题目核心是:你需要用脚本里的密码校验逻辑,把加密的 flag 解密出来。 提示里写了 str_xor,这意味着加密方法是字符串异或(XOR)。

因为这道题是 CTF 的改编版,我们先理清思路,然后你可以直接在终端里跑脚本解题。

💡 解题思路与原理

  1. 查看文件 :按照提示,你可以用 nano level1.py 看看源代码。
    • 里面通常会有个 str_xor 函数(把字符串每个字符跟一个 key 异或加密)。
    • 会有一个加密后的十六进制字符串(或者乱码)作为 encrypted_flag。
    • 还会有一段逻辑,要求你输入密码,如果密码正确,就把 encrypted_flag 解密并打印出来。
  1. 密码从哪来? 提示说"下载密码检查器给你"。你可以在附件里找到一个可执行文件(通常是 .exe 或 Linux ELF 文件)。
  2. 思路 :我们不需要去破解那个可执行文件,直接用 Python 把 level1.py 里的解密逻辑跑一遍,用正确的密码去解密那个字符串就行了。

🛠️ 动手操作

第一步:进入目录并查看文件

在终端里输入 ls,看看附件里有什么。然后用 nano level1.py 打开脚本看看(看完按 Ctrl+X 退出)。

看懂代码之后可以直接运行代码

academy{545h_r1ng1ng_329bb7f6}

PW Crack2

和上题一样,先看看py文件

上题的密码是直接告诉你的

复制代码
    if( user_pw == "691d"):

而这题:

复制代码
if( user_pw == chr(0x33) + chr(0x39) + chr(0x63) + chr(0x65) ):
  • chr() 的作用是:把括号里的十六进制数字(ASCII码),转换成对应的字符。
  • 后面的 + 号是字符串拼接的意思。

我们把这四个十六进制数转换一下:

  • chr(0x33) -> 字符 3
  • chr(0x39) -> 字符 9
  • chr(0x63) -> 字符 c
  • chr(0x65) -> 字符 e

连起来,真正的密码就是: 39ce。

那怎么把十六进制数字先转换成十进制,然后去查 ASCII 码表。

以你上一题里的四个十六进制数为例,我们来手动算一下:

📝 手动转换步骤

  1. 0x33
    • 十六进制的 33 转换成十进制: 3×16+3=48+3=513×16+3=48+3=51。
    • 查 ASCII 码表,十进制 51 对应的字符是:3
  1. 0x39
    • 十六进制的 39 转换成十进制: 3×16+9=48+9=573×16+9=48+9=57。
    • 查 ASCII 码表,十进制 57 对应的字符是:9
  1. 0x63
    • 十六进制的 63 转换成十进制: 6×16+3=96+3=996×16+3=96+3=99。
    • 查 ASCII 码表,十进制 99 对应的字符是:c
  1. 0x65
    • 十六进制的 65 转换成十进制: 6×16+5=96+5=1016×16+5=96+5=101。
    • 查 ASCII 码表,十进制 101 对应的字符是:e

把它们拼起来,就是密码 39ce 啦。


💻 怎么用代码一键转换?

如果你不想每次都手动算,或者在 CTF 比赛中遇到很长的一串十六进制,可以用 Python 代码一键转换:

方法一:用现成的工具网站(最快)

直接百度搜索"在线 Hex 转 ASCII "(或者直接搜 CyberChef),把 33 39 63 65 粘贴进去,瞬间出结果。

方法二:用 Python 代码

在 Python 里,只需要三行代码就能搞定:

hex_str = "33 39 63 65" # 你的十六进制字符串(去掉0x)

ascii_str = bytes.fromhex(hex_str).decode('utf-8')

print(ascii_str) # 输出结果就是 39ce

方法三:用命令行工具 xxd(Linux/Mac 常用,你现在的 MSYS2 终端也可以用)

把十六进制转成文本:echo "33 39 63 65" | xxd -r -p

💡 进阶小知识

记住几个常见的 ASCII 范围,以后会非常方便:

  • 0x30- 0x39 对应数字 '0' - '9'
  • 0x41- 0x5A 对应大写字母 'A' - 'Z'
  • 0x61- 0x7A 对应小写字母 'a' - 'z'
  • 比如 0x33 看到是 30 多,就知道肯定是数字 '3';0x65 看到是 60 多,就知道是小写字母 'e'。

解出密码后,就和上题一样,运行题目的python代码

academy{tr45h_51ng1ng_82234aa4}

PW Crack3

这道题是 PW 裂缝系列的第三关,考点从"明文密码"升级到了**"哈希(Hash)破解"**。

之前两关,密码就藏在代码里;但这一关,密码检查器不再告诉你密码是什么,而是只给你一个**"哈希值"**(文件的指纹)。你需要拿这个指纹去网络上比对,找出是哪个明文密码生成了它。

这关的提示里说得很清楚:无需逆向工程,而且给出了 7 个潜在密码的线索。

🛠️ 解题步骤

1. 提取哈希值

根据提示 1,在终端里查看 level3.hash.bin 文件。因为你的终端在 MINGW64 里,你可以直接用 cat 命令看(或者用 xxd 看十六进制):

复制代码
cat level3.hash.bin

你可能会看到一串类似 f2d8e6... 这样的字符串(或者二进制乱码)。这就是密码的哈希值。如果是乱码,你可以用 xxd level3.hash.bin 查看它的十六进制表示。

2. 获取 7 个潜在密码

题目说"有7个潜在密码",这些密码通常写在 level3.py 源码里。打开看看:

复制代码
cat level3.py

在代码里找找类似 passwords = ["123456", "password", ...] 这样的列表。

3. 在线比对(最省力)

拿到哈希值后,直接打开网页搜索:"在线 MD5 解密" 或 "Hash Decrypt" (比如 cmd5.com 或 crackstation.net)。

把那个哈希值贴进去,看看能不能反查出明文。

  • 如果查出来了,而且刚好在代码里的 7 个密码里,那它就是真密码。
  • 如果查不出来,说明这 7 个密码里,你需要找出哪个生成了这个哈希值(用下面第 4 步的办法)。

4. 本地写代码验证(最稳妥)

如果没有网络,或者哈希解密网站查不到,你可以写个简单的 Python 脚本,把 level3.py 里那 7 个潜在密码挨个算一遍哈希,看哪个和 level3.hash.bin 里的值一样。

复制代码
import hashlib
假设你从 level3.py 里找到了这 7 个密码
potential_pwds = ["123456", "password", "12345678", "qwerty", "123456789", "12345", "1234"]
读取目标哈希(假设是 MD5 的话)
with open('level3.hash.bin', 'rb') as f:
target_hash = f.read().strip().decode()
for pwd in potential_pwds:
# 计算哈希(注意看看 level3.py 里用的是 md5 还是 sha256)
hashed = hashlib.md5(pwd.encode()).hexdigest()
# 比对
if hashed == target_hash:
    print(f"找到正确密码啦!是: {pwd}")
    break</code></pre>
根据我们的题目:py爆破文件如下:
import hashlib
你的 7 个候选密码
pos_pw_list = ["6997", "3ac8", "f0ac", "4b17", "ec27", "4e66", "865e"]
读取目标哈希文件
with open('level3.hash.bin', 'rb') as f:
correct_pw_hash = f.read()
遍历候选密码,挨个算 MD5 比对
for pw in pos_pw_list:
# 算出 MD5
m = hashlib.md5()
m.update(pw.encode())
pw_hash = m.digest()
# 对比
if pw_hash == correct_pw_hash:
    print(f"找到正确密码啦!是: {pw}")
    break
else:
print("这7个都不对,是不是环境变了?")
(注意:上面代码里的哈希算法 hashlib.md5 需要根据原题 level3.py 里的代码来调整,也可能是 sha1 或 sha256)
5. 解密 Flag

找到真密码后,和上一关一样,直接运行原脚本:
python level3.py
输入你刚才找出来的那个密码,flag 就自动打印出来了!
其实也还有笨方法,就是7个都试一下
academy{m45h_fl1ng1ng_b8034615}
PW Crack4
和3差不多,先xxd,后看py代码,发现100个潜在密码列表,我们就还是对比哈希找正确密码就好了
xxd level4.hash.bin
74cf fc59 c290 c80a 3884 63cc 1c19 ff78
之前写的那个python脚本还可以复用,
1.改一下密码列表,就第4行,直接把题目给的py文件密码列表复制过来(上图红框框的)
2.改一下第7行哈希文件名称(3改成4)
import hashlib
你的候选密码
pos_pw_list = ["158f", "1655", "d21e", "4966", "ed69", "1010", "dded", "844c", "40ab", "a948", "156c", "ab7f", "4a5f", "e38c", "ba12", "f7fd", "d780", "4f4d", "5ba1", "96c5", "55b9", "8a67", "d32b", "aa7a", "514b", "e4e1", "1230", "cd19", "d6dd", "b01f", "fd2f", "7587", "86c2", "d7b8", "55a2", "b77c", "7ffe", "4420", "e0ee", "d8fb", "d748", "b0fe", "2a37", "a638", "52db", "51b7", "5526", "40ed", "5356", "6ad4", "2ddd", "177d", "84ae", "cf88", "97a3", "17ad", "7124", "eff2", "e373", "c974", "7689", "b8b2", "e899", "d042", "47d9", "cca9", "ab2a", "de77", "4654", "9ecb", "ab6e", "bb8e", "b76b", "d661", "63f8", "7095", "567e", "b837", "2b80", "ad4f", "c514", "ffa4", "fc37", "7254", "b48b", "d38b", "a02b", "ec6c", "eacc", "8b70", "b03e", "1b36", "81ff", "77e4", "dbe6", "59d9", "fd6a", "5653", "8b95", "d0e5"]
读取目标哈希文件
with open('level4.hash.bin', 'rb') as f:
correct_pw_hash = f.read()
遍历候选密码,挨个算 MD5 比对
for pw in pos_pw_list:
# 算出 MD5
m = hashlib.md5()
m.update(pw.encode())
pw_hash = m.digest()
# 对比
if pw_hash == correct_pw_hash:
    print(f"找到正确密码啦!是: {pw}")
    break
else:
print("都不对,是不是环境变了?")
记得哈希文件要和脚本放同一个目录下,或者使用绝对路径写脚本
运行py文件
academy{fl45h_5pr1ng1ng_c1e14a37}
PW Crack5
这题我们可以进行一个通用脚本的整理
修改路径:把你电脑上的真实路径填到 hash_file_path 和 dict_file_path 里。建议路径前面加个 r(代表 Raw string),这样不用管反斜杠转义的问题。
准备字典:题目如果提供下载了一个 dictionary.txt(或者你看一下附件里有没有叫 rockyou.txt 之类的文件),直接把这个 txt 的路径填进去。
运行脚本:在终端里运行 python crack.py。
import hashlib
import os
================= 配置区域 =================
1. 你的哈希文件绝对路径 (注意 Windows 路径建议用双反斜杠 \ 或正斜杠 /)
比如: "E:/desktop/网安/课程/.../level5.hash.bin"
hash_file_path = r"E:\desktop\网安\课程\大三上\产业班\课外学习\CyLab\挑战图书馆初学指南\4\level5\level5.hash.bin"
2. 你的字典文件绝对路径 (txt格式,每行一个密码)
比如: "E:/desktop/网安/课程/.../dictionary.txt"
dict_file_path = r"E:\desktop\网安\课程\大三上\产业班\课外学习\CyLab\挑战图书馆初学指南\4\level5\dictionary.txt"
============================================
def crack_hash():
# 检查文件是否存在
if not os.path.exists(hash_file_path):
print(f"❌ 找不到哈希文件: {hash_file_path}")
return
if not os.path.exists(dict_file_path):
print(f"❌ 找不到字典文件: {dict_file_path}")
return
# 读取目标哈希(以二进制形式读取)
with open(hash_file_path, 'rb') as f:
    correct_hash = f.read()

print("🔍 开始爆破...")
found = False

# 读取字典文件,逐个尝试
with open(dict_file_path, 'r', encoding='utf-8', errors='ignore') as f:
    for line in f:
        # 去除行尾的换行符和空白字符
        pw = line.strip()
        if not pw:
            continue
        
        # 计算当前密码的 MD5
        m = hashlib.md5()
        m.update(pw.encode('utf-8'))
        
        # 对比二进制哈希值
        if m.digest() == correct_hash:
            print("\n" + "="*40)
            print(f"🎉 爆破成功!正确密码是: 【 {pw} 】")
            print("="*40)
            found = True
            break
            
if not found:
    print("\n❌ 字典跑完了,没有找到匹配的密码。请检查字典是否完整或密码格式是否正确。")
if name == "main":
crack_hash()
正确密码是: 【 eee0 】
运行py文件
academy{h45h_sl1ng1ng_27d64792}
第5部分
增强(Enhance)
这个图片文件是 .svg 格式,它不是普通的像素图片,而是一个文本格式的矢量图文件。它的内部结构是用 XML 代码描述的,所以 flag 可能就藏在代码里。
你截图里下载的文件名是 drawing.flag.svg,这已经提示了它是个 SVG 文件。题目里关于"放大"的提示可能是个干扰,直接查看它的文本内容就好。
你不需要用图像处理软件去"放大"图片,只要用文本方式打开它就行:
用浏览器打开文件:直接把这个 .svg 文件拖进浏览器窗口。在浏览器里按 Ctrl + U 查看网页源代码,你会看到一堆 XML 代码。
或者用文本编辑器打开:在文件上右键选择"打开方式",用记事本(Notepad++、VS Code 都可以)打开。
搜索 flag 片段:在代码里按 Ctrl + F 搜索 picoCTF{。你可能没法直接搜到完整的 flag,因为出题人把每个字符拆开放在了不同的 <tspan> 标签里。
为啥知道是在tspan里的
SVG 是个啥?(基础知识)
.svg 文件不是像 .jpg 或 .png 那种由像素点组成的图片,它是可缩放矢量图形(Scalable Vector Graphics)。

本质上,它是一个 纯文本的 XML 文件。如果你用记事本打开它,里面全是代码。

在 SVG 代码里,如果你想画一个方块,会用 <rect>;画个圆,用 <circle>;如果你想写几个字,就必须用 <text> 或者 <tspan> 标签。
出题人的"把戏"
如果出题人想在一张普通的图片里藏字,他可能会把字体颜色改得和背景一样,或者把字缩得无限小。

但在 SVG 里,出题人不想让你直接一眼看到完整的 flag(比如 picoCTF{...}),于是他用了一个很经典的办法:把 flag 拆成一个个单独的字母,分别放进不同的 <tspan> 标签里。
他可能会把字符画得极其微小,或者用各种坐标(x, y)把它们打散。当你直接打开图片时,眼睛看不出来;但当你查看源代码时,就能看到类似下面这样的结构:
<tspan>p</tspan>
<tspan>i</tspan>
<tspan>c</tspan>
<tspan>o</tspan>
...
所有能显示在 SVG 上的文本,必然被包裹在文本标签里。
怎么"猜"出来的?(逆向思维与经验)
CTF 的套路:遇到图片隐写题,老手的第一反应就是用 strings 命令扫一下,或者直接拿去记事本里搜 { 或 picoCTF。
试错:如果你第一次提取,用 grep "text" 没找到,或者搜出来的不对,你就会去观察文件结构。你会发现大量重复的 <tspan> 标签。
工具验证:我给你的那条命令,其实就是直接针对这种"每个字符单独一个标签"的情况写的。
💡 如果不用命令,怎么肉眼找?
很简单,你直接用浏览器或记事本打开那个 .svg 文件,按 Ctrl + F 搜索:
先搜 {,看看 flag 的开头在哪。
再搜 <tspan,看看紧跟着 > 符号后面的那个字母是什么。
把 <tspan> 和 </tspan> 中间夹着的单个字母一个个挑出来,按顺序拼起来就行了。
这就是为什么我知道它在 <tspan> 里。在以后的 CTF 比赛中,看到 .svg 文件,直接找文本标签(<text> 或 <tspan>)绝对是第一步!
拼出完整 flag:把 </tspan> 标签前面的那些文本片段(比如 p、i、c、o......)按顺序连起来,并去掉中间的空格,就能得到完整的 flag。
💻 用命令行快速提取(推荐)
如果你想像写脚本一样一步到位,可以用下面这条命令(在终端里进入文件所在目录后执行):
strings drawing.flag.svg | grep "</tspan" | cut -d '>' -f2 | cut -d '<' -f1 | tr -d '\n' | tr -d ' '
这条命令会自动帮你把文件里分散的字符拼接并删掉空格,直接输出完整的 flag。
这是一条经典的 Linux/Unix 命令行"管道(Pipeline)"操作。它的核心思想是:把上一个命令输出的结果,当作下一个命令的输入,像流水线一样层层加工。
这条命令由 6 个部分组成(用 | 符号隔开),我们拆开来一段一段看:
1. strings drawing.flag.svg
作用:提取文件中的可打印字符。
解释:strings 是 Linux 下的一个工具,专门用来在二进制文件里找文本。虽然 .svg 是个文本文件,但用 strings 能帮你过滤掉一些没用的不可见字符,让后面的处理更干净。
2. grep "</tspan"
作用:过滤包含 </tspan 的行。
解释:grep 是文本搜索工具。SVG 文件里,文字都是用 <tspan>文字</tspan> 这样的标签包裹的。这步操作把所有包含文字的行单独挑了出来。
3. cut -d '>' -f2
作用:以 > 为分隔符,取第 2 部分。
解释:cut 用来切割字符串。-d '>' 表示用大于号作为刀,-f2 表示取切出来的第二块。
假设一行是:<tspan id="...">c</tspan>
切一刀后变成两块:<tspan id="..." 和 c</tspan>
取第 2 块,结果就是:c</tspan>
4. cut -d '<' -f1
作用:以 < 为分隔符,取第 1 部分。
解释:刚才的结果是 c</tspan>。现在用 < 再切一刀。
切出来两块:c 和 /tspan>
取第 1 块,结果就只剩下了纯文本:c (这就是我们要的字符)
5. tr -d '\n'
作用:删除换行符。
解释:因为 grep 找出来的每一行都会自带一个换行符,tr -d '\n' 的作用就是把换行符删掉,让所有字符挤在同一行。比如原本是:
p
i
c

	现在变成了:pic
6. tr -d ' '
作用:删除空格。
解释:有时候 SVG 的代码里会有多余的空格,这步把所有的空格全删掉,确保最后拼出来的 flag 是连贯的。
💡 总结
这行命令的逻辑链条是:
提取文本 ➡️ 找带字符的行 ➡️ 去前标签 ➡️ 去后标签 ➡️ 去换行 ➡️ 去空格。
academy{3nh4nc3d_9f31c04b}
big zip
是 picoCTF 里非常经典的文件处理基础题。
题目要求很简单:"解压这个档案,找到旗帜(flag)"。但出题人通常不会让你舒舒服服地解压完就看到 flag,里面往往藏着"套娃"或者超大量的干扰文件。
🛠️ 解题思路与步骤
1. 下载并识别压缩包

下载题目提供的压缩包。先看看它是个什么格式(.zip、.tar.gz 还是其他的)。
2. 尝试普通解压

如果你用的是 Windows 系统,可以直接右键解压。

也可以使用命令行解压:
如果是 zip 文件:unzip 文件名.zip -d 解压目标文件夹
如果是 tar.gz 文件:tar -zxvf 文件名.tar.gz
3. 寻找 Flag(关键点)

解压后,你可能会遇到两种情况:
情况 A(套娃):解压出来还是个压缩包,甚至好几层。继续解压,直到看到文本文件为止。
情况 B(海量文件):解压后,文件夹里可能有成千上万个文件(比如 file1.txt 到 file10000.txt),肉眼根本找不到。
怎么破? 用命令行搜索关键字!在终端里进入解压后的文件夹,执行:
grep -r "picoCTF" .
(如果是 CyLab 改版的题目,关键字可能是 academy,你可以试试 grep -r "academy" .)

这个命令的意思是在当前目录及子目录下,递归搜索包含 picoCTF 或 academy 的文件,并直接把包含 flag 的那一行打印出来。
💡 进阶大招:在不解压的情况下找(装逼必备)
如果压缩包非常大,或者解压出几万个文件太占空间,你可以直接"透视"压缩包:
对于 zip 文件,直接用 grep 穿透搜索:
unzip -p 文件名.zip | grep "picoCTF"
(-p 参数表示把解压的内容输出到屏幕而不是写入文件,配合管道 | 直接交给 grep 过滤)
对于 tar.gz 文件:
tar -xOzf 文件名.tar.gz | grep "picoCTF"
academy{gr3p_15_m4g1c_ef8790dc}
vault-door-training(金库门训练)
题目背景说,特工拿到了金库电脑的源代码,让你阅读代码找出密码。这其实是在告诉你:答案(密码/Flag)就明明白白地写在代码里,不需要去破解或者运行它。
🛠️ 解题步骤
下载源码:点击题目里的 VaultDoorTraining.java 链接,把 Java 源码文件下载下来。
打开查看:用记事本(或者 VS Code、Notepad++)打开这个 .java 文件。
	
寻找密码:直接看代码,找到一个叫做 checkPassword 的方法(函数)。里面会有一行类似下面这样的判断代码:
javareturn password.equals("w4rm1ng_Up_w1tH_jAv4_...");
提取 Flag:equals 括号里的那串字符串就是真正的密码。把它直接复制出来,套上 picoCTF{}(或者 CyLab 平台的格式 academy{})提交即可。
这个代码咋看
虽然不用跑代码,但你可以顺便了解一下这代码在干嘛,对你后面解逆向题有帮助:
String input = userInput.substring("academy{".length(), userInput.length()-1);

	这行代码的意思是:把你输入的内容,砍掉开头的 academy{(长度 8 个字符)和最后的}。只把中间真正的密码部分提取出来存到 input 变量里。
if (vaultDoor.checkPassword(input))

	把提取出来的密码交给 checkPassword 去比对。
checkPassword 里的 password.equals("...")

	如果提取出来的密码和括号里的完全一致,就返回 true,然后打印 Access granted。
其实这道题,知道格式,大概看到下面框框的一长串大概就知道是拼接的意思,其他代码看不懂也解的出来
💡 为什么这么简单?
这是作为"训练"的第一关,主要是为了让你熟悉 CTF 中逆向工程的第一步:代码审计。

在后面的进阶题中,代码里的密码会被隐藏、加密、或者通过复杂的算法动态生成,那时就需要你真正去分析算法甚至写脚本逆推了。但这道题,纯粹是让你体验一下"白盒"看代码的快乐。
这是一系列问题中的第一个。去picoGym看看其他项目,难度会逐渐提升!
academy{w4rm1ng_Up_w1tH_jAv4_8352733cecd}
keygenme-py
keygenme-trial.py
🔍 逻辑拆解
Flag 的结构

	代码开头定义了完整的 Flag 模板:
前缀:academy{1n_7h3_kk3y_of_
中间动态部分:xxxxxxxx(8个字符)
后缀:}
完整长度:31 个字符。
		
然后后面发现调用了很多函数
动态部分的生成规则

	代码里有一个 check_key 函数,它逐位校验了这 8 个 x 到底是什么。它使用了 MILLER 这个用户名的 SHA-256 哈希值。

	校验顺序是:取哈希值的第 4, 5, 3, 6, 2, 7, 1, 8 位(索引从0开始)。
注意 Python 版本差异
极度重要:由于 Python 3 中字符串是 Unicode 编码,hashlib.sha256(username_trial).hexdigest() 如果直接传字符串会报错。必须先编码成字节(bytes),也就是代码里定义的 bUsername_trial = b"MILLER"。原版 picoCTF 题目用的是 Python 2,而在 CyLab 的 Python 3 环境里,我们需要自己算一下。
🛠️ 一键提取脚本
你可以直接把下面这段 Python 代码复制到终端里运行(或者存成 solve.py),它会自动计算出正确的 License Key:
代码里,是把 MILLER 写死的(只适用这一道题)如果在别的题目里,用户名变成了 ALICE 或者 BOB,那段代码就废了。
(后面我会给个可复用的脚本,并解释意思)
import hashlib
1. 计算 MILLER 的 SHA-256 哈希值 (注意要转成 bytes)
username = b"MILLER"
hash_val = hashlib.sha256(username).hexdigest()
2. 按照代码里的顺序提取字符
校验顺序:4, 5, 3, 6, 2, 7, 1, 8
dynamic_part = hash_val[4] + hash_val[5] + hash_val[3] + hash_val[6] + 

hash_val[2] + hash_val[7] + hash_val[1] + hash_val[8]
3. 拼接完整 Flag
flag = "academy{1n_7h3_kk3y_of_" + dynamic_part + "}"
print("正确的 License Key 是:", flag)
🔍 逐行解释:
import hashlib:引入 Python 的哈希库,里面包含 SHA-256 算法。
username = b"MILLER":这里的 b 非常关键,代表 Bytes(字节串)。原题目代码里写的是 bUsername_trial = b"MILLER"。因为 Python 3 的 SHA-256 算法只能处理字节,不能处理普通文本,所以必须加 b。
hash_val = hashlib.sha256(username).hexdigest():
先用 sha256() 把 MILLER 变成一堆乱码(二进制)。
再用 .hexdigest() 把这堆二进制乱码转换成十六进制字符串(也就是由 0-9, a-f 组成的 64 位长串)。
dynamic_part = ...:这就是照抄原题 check_key 的逻辑。原题要求 key 的第 1 个字符等于哈希值的第 4 位,第 2 个字符等于第 5 位......以此类推。我们用 + 号把这 8 个单字符拼成一个 8 位的字符串。
flag = ...:把你之前从代码里找到的固定前缀、算出来的 8 位动态字符、以及固定的后缀 } 拼在一起。
🚩 最终结果
运行上面那段代码,你会得到类似这样的结果(具体哈希值由 MILLER 决定,是固定的):
academy{1n_7h3_kk3y_of_[8位字符]}
直接把算出来的这串字符串提交即可!
academy{1n_7h3_kk3y_of_9edf443b}
扩展
作为新手,看到这种一百多行、里面还夹杂着一大串乱码(加密数据)的代码,第一反应觉得头晕是非常正常的。
在 CTF 逆向(Reverse)和代码审计中,你不需要看懂每一行代码。老手的秘诀是:"顺藤摸瓜,只找关键线索"。
下面我教你一套"五步拆解法",以后遇到再长的代码,你也能迅速看透它:
第一步:找"入口",看它要你干嘛(找 Main 函数)
程序就像一栋楼,你得先找到大门。

在 Python 里,通常从最底下开始看,找类似 ui_flow()、main() 或者没有任何缩进的函数调用。
你往下翻,看到 ui_flow()。顺藤摸瓜找到 ui_flow 函数,发现它调用了 menu_trial()。
在 menu_trial 里,你看到了选项 (c) Enter License Key,对应调用了 enter_license()。
结论:这题的突破口在 enter_license() 这个函数里。
	
第二步:找"命门",看它怎么判断输对没(找 Check 逻辑)
找到 enter_license() 后,看里面的判断语句:
if check_key(user_key, bUsername_trial):
这就意味着,你输入的 key 必须通过 check_key 的检查。
立刻往下找 def check_key(key, username_trial): 这个函数。这就是这道题的心脏。
第三步:看"目标",明确它长什么样(找变量定义)
别急着看复杂的逻辑,先看开头定义了什么固定值。
扫一眼最上面,发现了 key_part_static1_trial = "academy{1n_7h3_kk3y_of_"
还有 key_full_template_trial = ... + "xxxxxxxx" + "}"
结论:哦!我知道我要找的 Flag 长啥样了,开头和结尾是固定的,中间缺 8 个字符。
第四步:看"规则",它怎么校验这 8 个字符(看核心逻辑)
现在回到 check_key 函数里,看它是怎么检查这 8 个 x 的。
它用了一堆 if 语句,写的是:
if key[i] != hashlib.sha256(username_trial).hexdigest()[4]:
新手不用管 hashlib.sha256 的具体数学原理(就当它是一个黑盒加工厂),你只需要知道:它把用户名变成了哈希值,然后强行规定了你的密码的第 1 个字符必须等于哈希值的第 4 位,第 2 个字符等于第 5 位......
这就是它在"规定"答案。
	
第五步:无视"垃圾",不要被吓到(跳过无关代码)
代码里最长、最吓人的就是中间那段 full_version = b"""gAAAAAB..."""。
直接跳过! 这通常是作者用来混淆视听的,或者是程序真正验证通过后才会用来解密的密文。
判断标准:只要它不参与 check_key 里的判断逻辑(比如它没有出现在 if 语句里让你去算它),你就当它不存在。只关注和 check_key 相关的变量和运算。
💡 给新手的 3 个小习惯建议:
善用 Ctrl + F(搜索):看长代码,先搜 flag、key、check、if 这样的关键词,直接跳过去看。
画流程图:用纸笔写下 主菜单 -> 输入密码 -> 比对函数 -> 哈希计算 -> 生成flag,理清数据流向。
写注释:把关键的几句代码复制到你的新文件里,加上自己的大白话注释(比如 # 这里要提取第4位字符),这样就不会乱了。
可复用的脚本
import hashlib
定义了一个函数,接收三个参数:用户名、前缀、后缀
def generate_key(username_str, prefix, suffix):
# 1. 将用户名转换为 bytes,并计算 SHA-256 哈希值
username_bytes = username_str.encode('utf-8')
hash_val = hashlib.sha256(username_bytes).hexdigest()
# 2. 按照目标代码里的顺序提取字符(可能需要改)
dynamic_part = (hash_val[4] + hash_val[5] + hash_val[3] + hash_val[6] + 
                hash_val[2] + hash_val[7] + hash_val[1] + hash_val[8])

# 3. 拼接完整 Flag
full_key = prefix + dynamic_part + suffix
return full_key
判断是否是直接运行这个脚本(如果是,才会执行下面的代码)
if name == "main":
# ==== 这里是你可以自由修改的配置区 ====
target_username = "MILLER"
target_prefix = "academy{1n_7h3_kk3y_of_"
target_suffix = "}"
# =====================================

print(f"当前输入的用户名: {target_username}")
correct_key = generate_key(target_username, target_prefix, target_suffix)
print(f"算出的 License Key: {correct_key}")</code></pre>
🔍 逐行解释:
def generate_key(username_str, prefix, suffix)::定义了一个工具函数。这里的 username_str、prefix、suffix 是占位符(形参),你在后面调用它时传什么,它就处理什么。
username_str.encode('utf-8'):这是替代脚本一里 b"MILLER" 的做法。encode('utf-8') 的作用就是把普通的字符串(比如 "MILLER")转换成字节串,这样就能喂给 SHA-256 了。
if __name__ == "__main__"::这是 Python 的经典写法。意思是:"如果这个文件是我直接双击运行(或者用 python 脚本.py 执行的),那么下面的代码才生效;如果我是被别的文件 import 进去调用的,下面的代码就不执行。"
f"...":这是 Python 的 f-string 格式化字符串,可以在字符串里直接嵌入变量。比如 f"当前输入的用户名: {target_username}",运行出来就会把 {target_username} 替换成实际的 MILLER。
最后调用 generate_key 并把算出的结果打印出来。
💡 总结与以后怎么用?
脚本一 是"点对点"打击,适合没有复用价值,只为快速出答案的题。
脚本二 是"模块化"打击,你把它存好(比如存在一个叫 tools 的文件夹里)。
以后遇到新题怎么用脚本二?

假设你遇到一道新题,源码里显示:
用户名是 "BOB"
要求的前缀是 "picoCTF{"
要求后缀是 "}"
算法逻辑完全一样。
你连代码都不需要重新写,只需要打开脚本二,把配置区改成:
target_username = "BOB"
    target_prefix = "picoCTF{"
    target_suffix = "}"
然后一运行,答案就出来了。
这就是从"做题"到"做工具"的思维转变。在后续的 CTF 比赛中,这种自己写的自动化脚本,往往能帮你省下大量的时间。
academy{1n_7h3_kk3y_of_9edf443b}
buffer overflow 0
这道题叫 "缓冲溢出 0"(Buffer Overflow 0),是 picoCTF 的经典入门题。从截图可以看出,这里涉及到了 gets 这个函数。gets 在 C 语言中是一个极其危险的函数,因为它不检查输入长度,直接往内存里塞数据,这正是"缓冲区溢出"的源头。
点击"启动实例":这是必须的,启动后平台会给你分配一个可以直接连接的目标(通常是一个 IP 和端口,比如 nc xbec.cylabacademy.net 12345)。
查看源代码:题目里有一句"你可以查看来源给你"。点击那个链接,或者下载对应的 .c 文件。用记事本打开它。
	
🔍 代码拆解与分析
读取 Flag 和设置陷阱
fgets(flag,FLAGSIZE_MAX,f);
signal(SIGSEGV, sigsegv_handler); // Set up signal handler
程序从 flag.txt 里读取真正的 Flag 存到全局变量 flag 里。
signal(SIGSEGV, ...):这是这道题的核心。SIGSEGV 代表"段错误"(Segmentation Fault)。如果程序崩溃了(比如你乱写内存),它不会直接闪退,而是会去执行 sigsegv_handler 函数。这个函数的作用只有一个:把 flag 打印出来,然后退出。
漏洞函数
void vuln(char *input){
  char buf2[16];
  strcpy(buf2, input);
}
这里定义了一个只有 16 字节大小的缓冲区 buf2。
strcpy 是一个非常危险的函数,它不管 input 有多长,都会死命地把数据往 buf2 里塞。一旦塞超过 16 字节,就会发生溢出,覆盖掉栈上的其他数据(比如返回地址)。这会导致程序崩溃(触发段错误)。
主函数里的交互
char buf1[100];
gets(buf1); 
vuln(buf1);
主函数里有一个 100 字节的 buf1,使用 gets 读取你的输入。gets 同样不检查长度,你输入多少它吃多少。
然后,它把你的输入传给 vuln 函数,vuln 试图把这几百个字符强行塞进 16 字节的 buf2 里。
寻找漏洞:在代码中,你会看到类似这样的逻辑:
char buf[100];
gets(buf); // 或者 fgets(buf, 100, stdin)
if (strcmp(buf, "特定字符串") == 0) {
    // 打印 flag
}
(如果不看代码,直接运行程序,它也会问你输入什么,你随便输点东西它会告诉你失败了)。
看代码发现存在栈溢出漏洞
直接自己终端nc连接,输入多个垃圾代码,就可获得flag
academy{ov3rfl0ws_ar3nt_that_bad_eb3cbdf1}
完结撒花!
相关推荐
qq_443132411 小时前
数字资产安全治理平台是什么:定义、核心能力与典型应用场景
安全
2301_777998343 小时前
ARP协议进阶:ARP缓存、RARP与ARP欺骗原理解析
linux·服务器·网络·网络协议·缓存
拆房老料3 小时前
【第四部分:Agentic 智能体设计模式】16. 一个 Prompt 搞不定复杂任务?试试 Prompt Chaining
java·前端·人工智能·设计模式·prompt
运维行者_4 小时前
应用性能监控怎么选?从调用链到用户体验的五个能力维度
运维·服务器·数据库·人工智能·mysql·性能优化·应用性能监控
m0_715674438 小时前
可视化易用·低误报率·跨区域部署:知源-AI数据分类分级系统在金融行业的落地实践
网络·安全·网络安全
国科安芯8 小时前
四重证据,一条逻辑链:商业航天级微控制器MCU抗辐射验证方法学综述——以国科安芯AS32S601为例
人工智能·单片机·嵌入式硬件·mcu·安全·抗辐射
dk_tjy8 小时前
AI驱动的自动化攻击背景下:企业端点安全体系的技术架构与建设路径
网络·人工智能·安全·自动化·终端安全管理·数据防泄漏
曹牧8 小时前
C#:空合并运算符
java·前端·数据库