-
赛事:Bugku
-
题目:
game1 -
考点:前端加密逻辑分析 + 请求伪造 + Base64 编码识别
解题过程
1. 信息收集
- 访问题目链接,显示游戏页面,无直接功能入口
- 源码审计 (Ctrl+U):
- 发现内联 JavaScript 游戏逻辑代码
- 注意到特殊 IP 地址:
106.120.205.138 - 发现外部 JS 文件引入:
<script src="base.js"></script>
- 网络抓包 (Burp Suite):
-
游戏结束时提交分数,捕获请求:
httpPOST /score.php HTTP/1.1 Host: ctf.bugku.com ip=106.120.205.138&score=250&sign=MTIzNDU2 # 示例签名 -
响应固定返回:
"失败了"
-
2. 漏洞利用
▶ 签名机制分析
-
识别签名模式:
- 修改分数为
1000000重放请求,仍返回"失败了" - 发现
sign参数疑似 Base64 编码(特征:结尾无=,字符集为 A-Za-z0-9+/)
- 修改分数为
-
解码异常:
-
用 Burp Decoder 解码
MTIzNDU2→ 失败(非标准 Base64) -
回溯源码发现:
html<!-- 自定义 Base64 编码库 --> <script src="base.js"></script>
-
-
动态调用验证:
-
浏览器控制台执行:
javascript// 使用页面内置的 Base64 对象 Base64.encode("250") // 输出: MTIzNDU2 -
确认签名生成逻辑:
sign = Base64.encode(score.toString())
-
▶ 构造高分数请求
-
生成有效签名 :
-
控制台计算高分签名:
javascriptBase64.encode("1000000") // 输出: MTAwMDAwMA==
-
-
Burp 重放攻击 :
-
修改请求参数:
httpPOST /score.php ip=106.120.205.138&score=1000000&sign=MTAwMDAwMA== -
成功响应:
flag{bugku_g4m3_5c0r3_4m4z1ng}
-
原理总结
一、漏洞原理
1. 签名绕过本质
- 伪安全设计 :
开发者误认为 Base64 编码 = 加密,未使用 HMAC 等真实签名算法 - 客户端可控 :
签名逻辑完全暴露在前端,攻击者可任意调用Base64.encode()生成有效签名
2. 关键突破点
| 环节 | 错误实践 | 攻击方法 |
|---|---|---|
| 签名生成 | 使用自定义 Base64 编码 | 控制台动态调用函数 |
| 分数验证 | 仅校验签名格式,未校验分数合理性 | 构造超高分数触发逻辑漏洞 |
| 响应处理 | 固定返回"失败了" |
通过响应差异判断成功条件 |
3. 攻击链
源码发现 base.js
控制台调用 Base64.encode
生成高分签名
Burp 重放伪造请求
触发 flag 返回
二、防御方案
1. 签名安全规范
python
# 正确实现:HMAC-SHA256 签名(Python 示例)
import hmac
def generate_signature(score, secret_key):
message = f"score={score}&ip=106.120.205.138"
return hmac.new(secret_key.encode(), message.encode(), 'sha256').hexdigest()
# 服务端验证
if not hmac.compare_digest(signature, generate_signature(score, SECRET_KEY)):
return "Invalid signature", 403
2. 业务逻辑加固
-
分数合理性检查 :
pythonif int(score) > MAX_POSSIBLE_SCORE: # 根据游戏规则设定上限 return "Score manipulation detected", 400 -
服务端二次验证 :
- 记录玩家历史分数,检测异常跳跃
- 结合设备指纹/IP 频率限制
3. 前端安全建议
-
禁止暴露核心逻辑 :
- 游戏计分规则/签名算法移至服务端
- 使用 Webpack 混淆前端代码(非绝对安全,但增加逆向成本)
-
敏感操作防护 :
javascript// 服务端下发的临时签名(5秒过期) const tempSignature = await fetch("/api/get-temp-signature");
三、同类题目通用解法
| 步骤 | 操作要点 |
|---|---|
| 前端分析 | 1. 审计 JS 源码查找加密函数 2. 检查 Network 请求识别关键参数(sign/token) |
| 签名破解 | 1. 控制台复现加密逻辑 2. 使用 Burp Decoder 识别编码类型(Base64/Hex) |
| 请求伪造 | 1. 修改参数边界值(分数/ID) 2. 重放请求观察响应差异 |
| 自动化工具 | 1. Burp Macros 自动更新签名 2. Python 脚本批量生成有效请求 |
黄金技巧:
控制台即武器 :
window对象暴露的前端函数可直接调用编码三要素验证 :
javascript// 特征检测法 if (typeof Base64 !== 'undefined' && Base64.encode) { console.log("发现自定义编码库!"); }响应差分分析 :固定文字响应(如
"失败了")往往是突破口