Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-53360-POC — PoC لـ CVE-2026-53360: قراءة/كتابة خارج الحدود في الذاكرة الديناميكية (heap) مشغلة بواسطة الضيف في معالجة تغيير حالة الصفحة (PSC) في KVM SEV-SNP. | Kitploit
أدوات/GitHubGitHub/0xcyberstan/cve-2026-53360-poc
تحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالاستغلالأمن الأجهزةاستغلال الملفات الثنائية
GitHub0xcyberstan/cve-2026-53360-poc

CVE-2026-53360-POC

PoC لـ CVE-2026-53360: قراءة/كتابة خارج الحدود في الذاكرة الديناميكية (heap) مشغلة بواسطة الضيف في معالجة تغيير حالة الصفحة (PSC) في KVM SEV-SNP.

عرض المستودع
127منذ 3 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2026-53360: تجاوز حدود الكومة في PSC لـ KVM SEV-SNP

إثبات مفهوم لقراءة وكتابة خارج حدود الكومة في معالجة تغيير حالة الصفحة (PSC) لـ SEV-SNP في KVM. يقوم ضيف SEV-SNP ضار بجعل نواة المضيف تجتاز مصفوفة إدخالات PSC إلى ما بعد نهاية تخصيص البلاطة (slab) الخاصة بها. يؤدي ذلك إلى تسريب تخطيط كائنات kmalloc-cg-32 المجاورة وكتابة قيمة صغيرة مسيطر عليها فيها، ويمكن للضيف تكرار ذلك بقدر ما يشاء.

الشرح الكامل: https://cyberstan.co.uk/sev-snp-oob/

CVECVE-2026-53360
المكوندعم مضيف KVM SNP، arch/x86/kvm/svm/sev.c
قُدِّم9b54e248d264 (أول معالجة PSC لـ KVM SNP، مايو 2024، ~v6.10)
أُصْلِحdb3f219 (الرئيسي، مايو 2026، Cc: stable)، معنون بـ Fixes: 4af663c
أُبْلِغ[email protected]، 8 أبريل 2026
المتأثرمسار مضيف SEV-SNP فقط. لا يمكّن KVM PSC لضيوف SEV-ES العاديين.

التأثير

يمكن لأي ضيف SEV-SNP إفساد كومة نواة المضيف وقراءة معلومات حول تخطيطها عن طريق إرسال طلب PSC مشوه. هذا هو الاتجاه من الضيف إلى المضيف: تم بناء SEV-SNP لحماية الضيف من مضيف غير موثوق، ولكن لا يزال على المضيف الدفاع عن نفسه ضد ضيف ضار، وهذا المعالج لا يفعل ذلك.

المتطلبات

هذا يتطلب أجهزة SEV-SNP حقيقية. لا يمكن إعادة إنتاجه على Intel، ولن يعطيك المحاكاة الافتراضية المتداخلة ضيف SNP.

الأجهزة:

  • شريحة خادم AMD EPYC تدعم SEV-SNP: Milan (7003) أو أحدث، أي Genoa (9004)، Bergamo، Siena، أو Turin. SEV-SNP هو سيليكون حصري لـ EPYC. غير متوفر على Ryzen أو Threadripper، ولا يوجد مكافئ Intel هنا (تستخدم Intel TDX).
  • جهاز فعلي. تعمل مثيلات السحابة الفعلية أيضًا (Vultr، AWS *.metal، Hetzner AX، وما شابه).
  • في BIOS، قم بتمكين SEV، SEV-ES، SEV-SNP، SME، IOMMU، و SVM. عادةً ما تقوم السحب الفعلية المدارة بشحنها مفعلة.

نواة المضيف:

  • قم ببنائها مع KASAN حتى يتم الإبلاغ عن الوصولات خارج الحدود. بدون KASAN لا يزال الخلل يفسد ذاكرة المضيف، لكنه لا يُطبع. تم اختباره على 6.11.11.
    CONFIG_KASAN=y
    CONFIG_KASAN_GENERIC=y
    CONFIG_KVM=y
    CONFIG_KVM_AMD=y
    CONFIG_KVM_AMD_SEV=y
    CONFIG_CRYPTO_DEV_SP_PSP=y
    
  • الإقلاع مع تمكين SNP و KASAN في وضع متعدد اللقطات بحيث يتم تسجيل كل ضربة:
    kvm_amd.sev=1 kvm_amd.sev_es=1 kvm_amd.sev_snp=1 kasan_multi_shot
    
  • تأكد من أن المضيف جاهز:
    cat /sys/module/kvm_amd/parameters/sev_snp     # Y
    ls /dev/sev                                     # /dev/sev
    

مساحة مستخدم المضيف:

  • QEMU قادر على SNP. QEMU العادي لا يدعم SNP، لذا قم ببناء فرع AMD:
    git clone https://github.com/AMDESE/qemu.git
    cd qemu && git checkout snp-latest
    mkdir build && cd build
    ../configure --target-list=x86_64-softmmu && make -j$(nproc)
    
  • برنامج OVMF الثابت لـ SNP من https://github.com/AMDESE/AMDSEV/releases.

الضيف:

  • أي ضيف Linux يُقلع تحت SNP، مع تثبيت build-essential و linux-headers-$(uname -r) حتى تتمكن من بناء الوحدة فيه.

الخلل

يتواصل ضيوف SEV-SNP مع المضيف من خلال GHCB، وهي صفحة مشتركة بحجم 4 كيلوبايت. يحدد طلب PSC SW_EXITCODE إلى SVM_VMGEXIT_PSC (0x80000010)، ويوجه SW_SCRATCH إلى واصف، ويضع طول الواصف في SW_EXITINFO2.

الواصف هو struct psc_buffer: رأس بحجم 8 بايت متبوع بمصفوفة من إدخالات بحجم 8 بايت. لا يوجد حقل عدد صريح. يعالج المضيف الإدخالات من hdr->cur_entry إلى hdr->end_entry، وكلاهما مسيطر عليه من قبل الضيف.

struct psc_hdr {
        u16 cur_entry;
        u16 end_entry;
        u32 reserved;
} __packed;                     /* 8 bytes */

struct psc_entry {
        u64 cur_page    : 12;
        u64 gfn         : 40;
        u64 operation   :  4;
        u64 pagesize    :  1;
        u64 reserved    :  7;
} __packed;                     /* 8 bytes */

من المفترض أن يحتفظ ضيف GHCB v2+ بمنطقة الخدش الخاصة به داخل المخزن المؤقت المشترك لـ GHCB بحجم 2032 بايت، حتى يتمكن المضيف من إعادة استخدام تعيينه الحالي. يتسع لـ (2032 - 8) / 8 = 253 إدخالًا، وهو مصدر الحد الأقصى للبروتوكول VMGEXIT_PSC_MAX_COUNT (253). هذا الرقم منطقي فقط عندما يكون المخزن المؤقت هو بالفعل المخزن المؤقت المشترك.

إذا وجه الضيف منطقة الخدش خارج GHCB، لا يمكن للمضيف استخدام تعيينه، لذا يقوم setup_vmgexit_scratch() بتخصيص مخزن مؤقت منفصل بالحجم الذي طلبه الضيف. لا ينبغي لـ SNP أن يسلك هذا المسار أبدًا، لكن لا شيء يمنعه:

scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);   /* len == exit_info_2, يتحكم به الضيف */

يأتي len مباشرة من الضيف، ويضع GFP_KERNEL_ACCOUNT التخصيص في ذاكرات التخزين المؤقت kmalloc-cg-N المحسوبة على مستوى المجموعة. اطلب exit_info_2 = 24 وستحصل على تخصيص بحجم 24 بايت في فتحة 32 بايت kmalloc-cg-32: مساحة للرأس بالإضافة إلى إدخالين. كل شيء بعد entries[1] هو ذاكرة كائن آخر.

ثم يتحقق snp_begin_psc() من عدد الإدخالات مقابل ثابت البروتوكول، وليس مقابل المخزن المؤقت الذي خصصه بالفعل:

idx_end = hdr->end_entry;

if (idx_end >= VMGEXIT_PSC_MAX_COUNT) {   /* يتحقق من 253، وليس حجم المخزن المؤقت */
        snp_complete_psc(svm, ...);
        return 1;
}

for (idx = idx_start; idx <= idx_end; idx++) {
        entry_start = entries[idx];       /* خارج الحدود بمجرد idx >= 2 */
        ...
}

مع مخزن مؤقت بحجم 24 بايت، يوجد إدخالان فقط، لكن التحقق يسمح بـ end_entry حتى 252. اضبطها على 252 وستجتاز الحلقة حوالي 2 كيلوبايت بعد التخصيص، عبر كائنات البلاطة المجاورة.

الأدوات الأولية

كل خطوة تتجاوز النهاية تعيد تفسير الـ 8 بايت التالية من ذاكرة البلاطة كـ psc_entry وتشغيلها خلال كود PSC. يعطي ذلك ثلاثة أشياء:

  1. أوراكل القراءة. يقرأ المضيف الكلمة الرباعية المجاورة فقط لفك تشفيرها، مسحبًا entry.gfn و entry.operation من ذاكرة لم يمتلكها المخزن المؤقت أبدًا. هذا هو قراءة خارج حدود البلاطة التي يلتقطها KASAN.
  2. كتابة محدودة. إذا بدا الإدخال المفكوك صحيحًا وتم إرساله كـ KVM_HC_MAP_GPA_RANGE، يكتب كود الإكمال مرة أخرى في نفس الفتحة خارج الحدود: entries[idx].cur_page = entry.pagesize ? 512 : 1. واحدة من قيمتين صغيرتين في البتات الـ 12 المنخفضة لكلمة يختارها الضيف، قابلة للتكرار.
  3. أوراكل الفشل. إذا لم يتم التحقق من صحة الإدخال، يبلغ الرد في SW_EXITINFO2 عن الفهرس الذي توقف عنده. رفع end_entry واحدًا تلو الآخر يسرب، فتحة بعد فتحة، ما إذا كانت الذاكرة المجاورة قد فُككت إلى no-op أو إلى شيء فشل، وهو ما يكفي لإيجاد حدود الكائنات ومعرفة الصفر من غير الصفر.

كل VMGEXIT يعيد تخصيص المخزن المؤقت للخدش، لذا تهبط الطلبات المتكررة في فتحات قائمة حرة مختلفة وتسمح للضيف بالمسح عبر الجيران بدلاً من البقاء عالقًا مع واحد. مجتمعة، يعطي هذا كشف تخطيط الكومة، والكتابة المحدودة أعلاه، واستخدام بعد التحرير عبر الطلبات.

ما يفعله إثبات المفهوم

trigger.c هو وحدة نواة ضيف. قم بتحميلها داخل ضيف SEV-SNP وسيقود أربع مراحل ضد المضيف من insmod واحد:

  • المرحلة 1 تتحقق من 48 إدخالًا خارج الحدود واحدًا تلو الآخر وتبني خريطة لكومة المضيف (ذاكرة مجاورة صفرية مقابل غير صفرية).
  • المرحلة 2 تثبت أن الكتابة خارج الحدود تستمر عبر VMGEXITs عن طريق كتابة cur_page في جار صفري وتأكيد أن طلبًا لاحقًا يتجاوزه.
  • المرحلة 3 ترسل طلبًا واحدًا مع end_entry=200 وتقيس مدى وصول القراءة خارج الحدود قبل أن تصطدم ببيانات غير صفرية.
  • المرحلة 4 ترسل 200 طلب مع entries[3..10] خارج الحدود، كل منها يسبب تقرير KASAN على المضيف.

تخصص الوحدة صفحة، وتضع علامة عليها كمفكوكة التشفير باستخدام set_memory_decrypted()، وتستخدمها كمنطقة خدش، وتبني طلب GHCB PSC يدويًا. تخرج بـ -EAGAIN حتى لا تبقى محملة.

البناء والتشغيل

1. إطلاق ضيف SNP

اضبط مسارات OVMF والقرص حسب إعدادك:

qemu-system-x86_64 \
    -enable-kvm -cpu EPYC-v4 \
    -machine q35,confidential-guest-support=sev0,memory-backend=ram1 \
    -object memory-backend-memfd,id=ram1,size=4G \
    -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,policy=0x30000 \
    -smp 4 -m 4G \
    -bios OVMF_SNP.fd \
    -drive file=guest.qcow2,format=qcow2,if=virtio \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device virtio-net-pci,netdev=net0 \
    -nographic

2. البناء والتحميل في الضيف

انسخ trigger.c و Makefile إلى الضيف، ثم:

make
insmod trigger.ko

تتحقق الوحدة من SEV-SNP عبر CPUID أولاً وترفض التشغيل في أي مكان آخر. تشغل مراحلها الأربعة وتفرغ نفسها (يعيد init القيمة -EAGAIN، لذا لا تبقى أبدًا مقيمة).

3. مشاهدة المضيف

على المضيف:

dmesg | grep -E "KASAN|BUG|snp_begin_psc"

الإخراج المتوقع:

تنزيل الأداة