CISCN2025 半决赛 AWDP rng-assistant
字数 1552 2025-08-29 08:29:59
CISCN2025 半决赛 AWDP rng-assistant 题目分析与教学文档
题目概述
这是一个基于Flask框架的Web应用,结合了Redis缓存和"大模型"通信功能,存在多个安全漏洞点,主要涉及Redis未授权访问和格式化字符串漏洞。
系统架构分析
组件结构
- start.sh: 启动脚本,通过
redis-cli config set save ""禁用Redis的RDB持久化 - default.py 和 math-v1.py: 分别监听两个端口,处理来自Flask的请求(随机返回字符串)
- Flask: 监听8000端口,提供Web服务
- Nginx: 监听80端口作为反向代理
请求处理流程
- Nginx接收外部请求
- 反向代理到Flask应用
- Flask处理请求,可能涉及Redis交互或与"大模型"通信
安全机制分析
身份验证机制
- 默认给非本地连接的HTTP请求添加
X-User-Role: guest请求头 - 可通过自行传递
X-User-Role头绕过此限制
功能模块
- 用户注册
- 用户登录
- 用户提问
- Redis未授权访问
漏洞点分析
1. Redis未授权访问漏洞
漏洞原理:
- 系统通过socket连接与"大模型"通信,并设置了回答的缓存机制
- 提示词和对应模型作为key,将"大模型"的回答缓存到Redis中
- 管理员可以修改模型通信端口
- 攻击者可将通信端口修改为Redis默认端口6379,实现Redis未授权访问
利用步骤:
- 获取管理员权限
- 修改模型通信端口为6379
- 通过该端口直接与Redis交互
2. 格式化字符串漏洞
漏洞位置:
PromptTemplate#get_template方法- 首先从Redis寻找模板,找到则直接返回
- 否则在
static/prompts目录下查找
- 关键代码:
PromptTemplate.get_template(template_id).format(t=self)- 将类对象
self传入格式化字符串的上下文
- 将类对象
触发路径:
/ask路由调用generate_prompt但未传prompt_id- 通过往Redis增加键
prompt:math-v1,获取模板时可设置格式化字符串
利用方法:
- 通过Redis未授权访问或其它方式设置
prompt:math-v1键值 - 设置包含恶意格式化字符串的模板
- 触发
/ask路由执行格式化字符串攻击
3. Flag获取
- Flag存储在
from flag import FLAG引入的变量中 - 通过格式化字符串漏洞可能直接读取或间接获取FLAG值
修复建议
-
Redis端口修改限制:
- 禁止将模型通信端口修改为Redis默认端口6379
- 实施端口范围检查或黑名单机制
-
格式化字符串安全修复:
- 修改
PromptTemplate.get_template(template_id).format(t=self)代码 - 不将
self对象传入格式化字符串上下文 - 使用安全的模板渲染方式,如Jinja2的沙箱环境
- 修改
-
其他安全加固:
- 实施Redis认证
- 限制Redis绑定IP
- 对用户输入进行严格过滤
攻击利用链示例
- 利用身份验证缺陷获取管理员权限
- 修改模型通信端口为6379
- 通过Redis未授权访问设置恶意模板
- 触发格式化字符串漏洞读取FLAG
教学总结
本题展示了Web应用中常见的两类高危漏洞的组合利用:
- 配置不当导致的未授权访问(Redis)
- 代码实现缺陷导致的格式化字符串漏洞
通过本题可以学习到:
- Redis安全配置的重要性
- 格式化字符串漏洞的原理与利用
- 系统组件间信任边界的安全考量
- 权限提升与横向移动的技巧
- 多漏洞组合利用的攻击链构建