飞牛系统(fnOS)绕过认证远程代码执行漏洞链的复现
本文摘自Github用户bron1e,如有需要请前往原文查看。
经过分析与验证,目前已成功复现飞牛系统(fnOS)中的一个严重远程代码执行(RCE)漏洞链。该漏洞链允许攻击者在无需任何身份验证的情况下,远程获取设备的最高管理员(root)权限,从而完全控制设备。
成功复现的攻击链由以下四个关键漏洞构成:
漏洞一:路径穿越(任意文件读取)
描述:系统的一个Web接口(/app-center-static/serviceicon/myapp/…)未能正确过滤用户输入的路径,允许攻击者读取服务器文件系统上的任意文件。
在此攻击链中的作用:用于下载一个伪装成RSA私钥、但实际内嵌了硬编码AES密钥的文件 (/usr/trim/etc/rsa_private_key.pem)。这是整个攻击的起点。
漏洞二:硬编码的加密密钥
描述:上述下载的文件中,在固定偏移量(100字节处)硬编码了一个32字节的AES主密钥(Root Key)。
在此攻击链中的作用:为攻击者提供了“万能钥匙”。这是后续伪造合法用户凭证的核心要素。
漏洞三:认证绕过(通过伪造Token)
描述:系统的WebSocket网关在验证用户身份时存在致命逻辑缺陷。它允许攻击者使用上述获取的AES主密钥,在本地凭空“创造”出一个服务器会认为是合法的临时token。
在此攻击链中的作用:攻击者利用此漏洞,无需任何用户名和密码,即可伪造出一个“已登录”的管理员身份,从而有权调用需要高权限的API接口。
漏洞四:命令注入
描述:在通过认证后,一个用于添加Docker镜像的API接口(appcgi.dockermgr.systemMirrorAdd)未能正确处理其url参数。
在此攻击链中的作用:这是最终的执行环节。攻击者将恶意系统命令(如反弹Shell或下载执行脚本)注入到url参数中,服务器在处理该请求时会无条件执行这些命令
其中任意文件读取和授权命令执行已被披露。本文主要对飞牛OS的认证绕过进行分析,并提出另一潜在命令执行路径。
一、认证绕过
1. 原理分析
1.1 登录逻辑
飞牛OS的登录逻辑如下:
1 | 用户请求 (Login/ChangePassword) |
授权命令执行需要拿到 secret 或者 token。但读取堆内存略微困难,因此要么读取到 longtoken 转化为 token,要么想办法利用业务漏洞。
1.2 交互逻辑
前端使用 Websocket 协议交互,登录流程如下:

1.3 Token生成逻辑
在 /usr/trim/bin/handlers/users.hdl 中的 do_login 函数中包含了 secret, token, longtoken的生成逻辑:
Secret (16字节):随机生成的 16 字节数据,强制将第 16 字节设置为
o。Token (32字节):
前 16 字节 (IV):由时间戳、计时器和随机数拼接而成。
后 16 字节 (Cipher):使用 RSA 密钥对 Secret 进行 AES 加密后的数据。


因此 secret 和 token 可以相互转化,这点很重要。
在 /usr/trim/bin/trim 中的 handle_websocket_packet 函数中包含了鉴权逻辑。
后端能够解析两种类型的包:
- 加密包:不需要 secret 签名
- 明文包:除非req白名单或者设置了no_sign,否则需要secret对请求体签名
看上去可以构造一个加密包,然后使用 longtoken 进行登录,从而绕过签名:
1 | { |
遗憾的是,加密包会触发token长度的判断。

不过这里存在另一个漏洞:
验签时如果存在 token 字段,则直接对 token 解密得到 secret,然后对请求体计算签名。

因此,可以自己生成 secret 和 token 绕过认证。


2. PoC
需获取系统中的 rsa_private_key.pem(通过任意文件读取漏洞获取)。
1 | # 1. 命令执行 |
二、拓展
1. CGI路径穿越
/usr/trim/bin/trim_http_cgi 存在一个稍弱的路径穿越、命令执行。

filepath.Join并不防御路径穿越,因此能从 /var/apps_ui 穿越到 /var,并执行任意文件。但存在有一些限制:
- 需要合法token
- 由于nginx的解析问题,只能穿越一层到 /var
利用思路:需要结合认证绕过和后文提到的postgresql数据库中的longtoken,生成一个合法token,调用文件上传的API,上传一个bash到/var目录。
1 | import requests |
2. 读取postgresql数据库
PostgreSQL数据库位于 /var/lib/postgresql/*/main/base
该目录下有若干个数据库目录,通常为40000+,需要读取每个数据库下的pg_class表(固定OID为1259),然后从中获取 longtoken 表的 OID。


三、参考
- 标题: 飞牛系统(fnOS)绕过认证远程代码执行漏洞链的复现
- 作者: MoGuQAQ
- 创建于 : 2026-02-02 13:20:48
- 更新于 : 2026-02-02 13:39:31
- 链接: https://blog.moguq.top/posts/26020201/
- 版权声明: 本文摘自bron1e与LoopDNS频道,版权归原作者所有