Web
题目名称 ez_php
在登陆界面发现有cookie,base64解码应该是打反序列化


然后我们构造admin发现有检测,则要绕过检测。然后访问直接进入dashboard
1 | |
点击1.txt发现有filename参数,尝试读取flag.php发现有限制

绕过php检测限制读取flag.php
1 | |

题目名称 pcb5-Uplssse
注册并登录系统发现告知只能admin访问上传页面,然后查看有一个user_auth
然后我们将is_admin值改成1
1 | |

然后这里什么都可以上传,上传到tmp,然后是先上草再检测,很容易想到条件竞争,于是exp


1 | |
题目名称 pcb5-ezDjango
漏洞分析
任意文件写入/复制
在 cacheapp/views.py 中,copy_file 视图存在严重漏洞:
1 | |
该接口允许用户将服务器上任意可读文件 (src) 复制到任意可写路径 (dst)。这为我们提供了在服务器指定位置写入文件的能力。
不安全的反序列化
在 cacheapp/views.py 中,cache_trigger 视图直接调用了 Django 的缓存获取接口:
1 | |
而在 app/settings.py 中,缓存后端被配置为 FileBasedCache:
1 | |
Django 的 FileBasedCache 在读取缓存文件时,使用 Python 的 pickle 模块进行反序列化。如果我们能够控制缓存文件的内容,就可以利用 pickle 的特性执行任意代码。
缓存文件名可预测
Django FileBasedCache 将缓存 Key 转换为文件名的逻辑是固定的。默认情况下(版本为 1,无前缀),缓存 Key 会被转换为 :1:<key>,然后计算 MD5 值作为文件名,后缀为 .djcache。 例如,Key 为 pwn_key,则文件名为 md5(":1:pwn_key").hexdigest() + ".djcache"。
路径泄露
cache_viewer 接口在读取不存在的缓存文件时,会报错并泄露完整的缓存目录路径:
return json_error(f’Cache file not found: {path}’)
我们可以利用这一点获取真实的 CACHE_PATH。
我们的攻击路径如下:
- 构造 Payload:生成一个恶意的 Pickle 数据,该数据在反序列化时执行系统命令。
- 上传 Payload:利用
/upload/接口将 Payload 上传到临时目录(如/tmp/exploit.cache)。 - 获取缓存路径:利用
/cache/viewer/接口泄露服务器的真实缓存目录。 - 计算缓存文件名:根据我们选定的 Key(如
pwn_key),计算出 Django 对应的缓存文件名。 - 复制:利用
/copy/接口,将我们上传的 Payload 复制到缓存目录下,并重命名为合法的缓存文件名。 - 触发 RCE:访问
/cache/trigger/接口,指定 Key 为pwn_key,触发服务器读取并反序列化我们的恶意文件。



exp脚本
1 | |
题目名称 pcb5-ez_java


访问题目环境,发现是一个文件管理系统的登录页面。通过查看前端源码或直接尝试,发现可以访问 http://192.168.18.25:25004/admin.html,该页面加载了 /dashboard/list 等接口。
通过观察 admin.js,我们发现了以下关键接口:
/dashboard/list: 列出文件/dashboard/download: 下载文件/admin/rename: 重命名文件/admin/challengeResourceDir: 修改静态资源目录
把class文件都下下来
1 | |
通过对下载的 AdminDashboardServlet.class 进行逆向分析,发现 validateAdmin 方法存在严重的逻辑漏洞:
1 | |
这意味着我们可以在不携带任何 Cookie 的情况下,直接调用 /admin/* 下的所有接口。
AdminDashboardServlet 提供了 /challengeResourceDir 接口,允许我们将 resourceDir 修改为任意路径(如 . 即 WebRoot)。结合 /admin/rename 接口,我们可以将 WEB-INF 下的受保护文件(如 web.xml、.class 文件)重命名到 WebRoot 下,并修改后缀为 .txt,从而绕过下载限制,获取源码。
服务器默认未启用 JSP 解析(或者配置了限制)。通过分析,我们可以利用上述的文件操作漏洞,上传一个恶意的 web.xml 并覆盖掉 WEB-INF/web.xml,从而开启 JSP 支持。
通过源码审计确认漏洞后,我们使用以下脚本通过覆盖 web.xml 开启 JSP 支持,并上传 Webshell 获取 Flag。
- 构造一个包含
JspServlet配置的web.xml。 - 利用 Auth Bypass 将
resourceDir设置为.。 - 上传恶意的
web.xml(命名为web_pwn.xml)。 - 利用
/admin/rename将其重命名为WEB-INF/web.xml。 - Tomcat 检测到
web.xml变化后会自动重载应用。 - 上传 JSP Webshell 并执行命令。
1 | |

Re
题目名称 moremoreflower
1 | |

flag{Fl0weRTeAVM15E3s9!}
题目名称 medddgo
1 | |

flag{12d8b17b8ae52636a1211299451f9f6c}
Misc
题目名称 pcb5-BLUE

蓝色通道全选发现压缩包格式,但是得隔着提取,先保存为extracted.bin
然后脚本提取
1 | |

明文攻击

得到压缩包,解压获得两张图片

这蓝底条纹一看就是双图盲水印xor后的结果
再次xor获得图片xor.png

双图盲水印提取


题目名称 pcb5-zipcracker
zip伪加密,解出来
foremost解图片,拿到flag1.txt和flag2.txt,根据do u know it写还原脚本
1 | |
还原wav后,是个摩斯密码,手搓一下

解开flag.zip,flag.txt里面只有部分flag,明文攻击
1 | |
改密码
1 | |
拿到flag,解压拿到flag

题目名称 pcb5-SMB
先解密NTLM


密码12megankirwin12
在wireshark解密

导出


exe+store又是明文攻击

得到一个letter.exe,每次运行就给一个字符串

应该是要逆向一下
直接运行到give you a letter 中,rust的,直接alt+b搜索内存flag

题目名称 pcb5-whiteout
这是一个 OCI (Open Container Initiative) 镜像布局文件夹,是 Docker 镜像导出后的格式
先提取文件
1 | |
运行解密即可

题目名称 pcb5-The Rogue Beacon
要求找到速度最高值的包序号,我们首先要找到哪一个CAN ID对应速度
汽车里面速度变化是连续的,先提取各CAN ID及其data
1 | |
将data.txt放到excel筛选

最终找到CAN ID = 580的data是连续平滑变化的

稍加翻阅即可找到最大值所在包序号12149


flag为flag{9db878fd06dd7587a91c0fb600e0e9f7c3ea310e75f36253ef57ac2d92dd8c29}
题目名称 hide

lsb有不明所以的信息
尝试发现是steghide的密码


Crypto
题目名称 pcb5-weak_leak
题目分析
题目给出了一个基于 LCG (Linear Congruential Generator) 的加密系统。
- LCG 种子生成: 种子由 6 位数字密码 (
password) 和一个固定的SECRET_VALUE异或得到。 - 序列生成: 使用 LCG 生成一个序列,其中第 9 个元素
seq9被用于 RSA 的参数生成。 - RSA 参数:
n1 = p * (q + 1)n2 = (p + 1) * q + seq9cipher_rsa是 AES 密钥经过掩码处理后的 RSA 密文。
- AES 加密: Flag 被 AES 加密,密钥由
aes_key和seq9的哈希值异或得到。
解题思路
- 爆破密码: 由于密码只有 6 位数字,且题目给出了
salt和hash,我们可以直接爆破出密码。 - 恢复 LCG 序列: 有了密码,我们可以计算出 LCG 的种子,进而生成整个序列,得到
seq9。 - 分解 RSA:
- 已知
n1 = pq + p - 已知
n2 = pq + q + seq9 - 两式相减:
n1 - n2 = p - q - seq9=>p - q = n1 - n2 + seq9。 - 令
diff = p - q。我们知道n = pq,且n1 approx n。 - 实际上,我们可以利用
p = q + diff代入n1 = (q+diff)(q+1)来解二次方程求q。 - 或者更简单地,
n1 - p = pq,n2 - q - seq9 = pq。 n1 - p = n2 - q - seq9=>p - q = n1 - n2 + seq9。- 我们有
p - q的值,也有n1 approx pq。 p + q = sqrt((p-q)^2 + 4pq) approx sqrt(diff^2 + 4*n1)。- 有了
p-q和p+q,即可解出p和q。
- 已知
- 解密 AES 密钥:
- 计算
n = p * q,phi = (p-1)*(q-1),d = inverse(e, phi)。 - 解密 RSA 得到
masked_key_int。 - 计算
mask_bytes = sha256(str(seq9)).digest()[:16]。 - 异或恢复
aes_key。
- 计算
- 解密 Flag: 使用恢复的
aes_key解密 AES 密文。


1 | |
题目名称 pcb5-babyRSA
题目分析
题目给出了 RSA 的密文 c 和一个泄露值 leak。 leak 的计算公式为:leak = (3*P*P - 1) / (3*P*Q)。 其中 P 和 Q 是 decimal.Decimal 类型的高精度浮点数。 此外,题目虽然隐藏了 e,但在解题脚本中暗示了 d 是已知的(或者可以通过某种方式获得,实际上本题 d 是直接给出的)。
解题思路
- 利用 d 和 e 的关系: RSA 中满足
e * d = 1 + k * phi。 虽然e未知,但通常较小(如 3, 65537 等)。我们可以枚举e,进而枚举k(1 到 e)。 对于每一对(e, k),我们可以计算出候选的phi = (e * d - 1) // k。 - 推导 P 的方程: 已知
leak = (3P^2 - 1) / (3PQ),可得Q = (3P^2 - 1) / (3 * leak * P)。 已知phi = (P-1)(Q-1) = PQ - P - Q + 1。 将Q的表达式代入phi的公式中,消去Q,可以得到一个关于P的一元三次方程:3P^3 - (3*leak + 3)P^2 + (1 + 3*leak - 3*leak*phi)P + 1 = 0(注:具体系数取决于公式推导细节,核心是构建关于 P 的多项式)。 - 求解 P: 由于
P非常大(1024位),直接求根公式可能不适用精度问题。 利用牛顿迭代法(Newton’s Method),以sqrt(phi * leak)作为初始值(因为leak approx P/Q,phi approx P*Q,所以P approx sqrt(phi * leak)),快速逼近P的数值解。 - 验证与解密:
- 求出
P后,验证P-1是否整除phi。 - 计算
Q = phi // (P-1) + 1。 - 计算
N = P * Q。 - 使用私钥
d和模数N解密密文c:m = pow(c, d, N)。 - 检查解密结果是否包含 “flag” 字样,若包含则成功。
- 求出

1 | |
题目名称 pcb5-true_or_false
题目分析
这是一个 RSA 故障注入攻击 (Fault Attack) 结合 LCG 的题目。
- 数据混淆: 签名数据 (
sig_ok,sig_fault) 被一个 LCG 生成的序列异或混淆了。 - LCG: 参数
A, B, MOD已知,但种子seed未知。题目给出了seed_hint。 - 故障攻击: 提供了正确的签名
sig_ok和错误的签名sig_fault。这是典型的 RSA-CRT 故障攻击场景(Bellcore Attack)。
解题思路
- 恢复种子:
- 利用
seed_hint确定种子的搜索范围。 - 爆破种子,对
sig_ok_mixed进行去混淆(异或解密)。 - 验证种子:解密后的
sig_ok应该满足pow(sig_ok, e, n) < 2^256(因为它是 hash 的签名,原始消息是 hash 值)。
- 利用
- Bellcore Attack:
- 一旦恢复了正确的
sig_ok(s) 和错误的sig_fault(s’)。 - 利用公式
p = gcd(s - s', n)或q = gcd(s - s', n)。 - 其中一个因子可以通过 GCD 直接求出。
- 一旦恢复了正确的
- 分解 N:
- 求出
p后,q = n // p。
- 求出
- 解密 Flag:
- 计算私钥
d,解密flag_enc。
- 计算私钥


1 | |
题目名称 pcb5-PECO
题目分析
这是一道综合性的 RSA 题目,包含多个步骤:
- Pell 方程: 题目给出了
A * (x^2 - 1) = B * y^2的关系,这是一个变形的 Pell 方程。 - Hensel Lifting (部分私钥泄露): 题目给出了
gift2 = p^7 + q^13 mod 2^777。这是一个模幂方程,且模数是 2 的幂。 - 线性关系****恢复 P: 恢复了
p的低 777 位 (p_low) 后,需要恢复完整的p。 - Knapsack (背包问题): Flag 被分割成两部分
f0, f1,满足x*f0 + y*f1 = r mod m。
解题思路
- 求解 Pell 方程:
- 将方程变形为
x^2 - D*w^2 = 1的标准形式。 - 使用连分数法求解 Pell 方程,得到
x和y。
- 将方程变形为
- Hensel Lifting 恢复 p_low:
- 利用
gift2和n,在模2^k下逐位提升,求解p的低 777 位。 - 由于方程
p^20 - gift2*p^13 + n^13 = 0 mod 2^k比较复杂,使用 BFS 搜索合法的p_low。
- 利用
- Lattice / CVP 恢复完整 p:
- 已知
p = k * 2^777 + p_low,q = r * 2^777 + q_low。 - 代入
N = p*q,推导出k, r满足的线性方程:k*q_low + r*p_low = LHS mod 2^777。 - 构造格(Lattice),将问题转化为 CVP (Closest Vector Problem) 或 SVP。
- 使用 LLL 算法求解出较小的
k和r,从而恢复完整的p和q。
- 已知
- 解密 m:
- 有了
p, q,计算d,解密 RSA 密文得到m。
- 有了
- 求解 Knapsack:
- 已知
x*f0 + y*f1 = r mod m,其中x, y, m已知,f0, f1是 Flag 的两部分(较小),r也很小。 - 构造格:
- [ 1, 0, x ] [ 0, 1, y ] [ 0, 0, m ]
- 使用 LLL 算法寻找格中的短向量。目标向量为
(f0, f1, r)。 - 还原出
f0和f1,拼接得到 Flag。
- 已知

1 | |
题目名称 budo的pem
pem可以恢复出n,e
e=14180624331525991413806961940205749159059672195526010812302727853797689314317592739705685551298732523630959991899621053483135891357764554237827830483836439016974587279272031674430927658131895070464916701588233589386349049620755733138785652009983671996549157331713576664774799256183477206330524171028474266411634935294668960034971282728570749735946140241122767282799298230610201636191394577538375846828013584508852185295950919801912280565423819423712437302673912737370268540642137115217185193479116171916803844236143555349715053108779636638218404547424967160100212508958775263973108754654389190280868923617834114867493
n=27282116371983762041912669226171934834213267111869663414643046433946308990099670619902779534028098258662491783696548704814110569031913533951522948899897952050753641129753560031453499125038644663810374945611628785371618348480443687057347952494765550645132106424275386344675708722795562530893084586263715603616605019932670052317546124250273398628671233505778162949122797472901844999122236752056581074033257933303752665270582493695571812447018768673719950432810902857287900402430788862530621394430578906291537999146794893832511289918245846963416265417641139236739819022441678736012415250371091507897123724260254368398851
再使用经典boneh and durfee attack的wp就可解出
注意参数是8
1 | |

Pwn
题目名称 Heartbeat_Out_of_Bounds
Mqtt 国决原题
漏洞点

sleep(2)这里条件竞争
先输入合法 vin,再进行命令注入
使用 mqttx 订阅 diag,得到 VIN XDGV56EK1R8B3W42B

参考https://rocketma.dev/2025/07/19/final.mqtt/

1 | |