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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
extra_recipe — إكسبلويت إيان بير لثغرة CVE-2017-2370 (قراءة/كتابة ذاكرة النواة على iOS 10.2) | Kitploit
أدوات/GitHubGitHub/ldebug/extra_recipe
أمان iOSتحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالاستغلالأمن الجوالاستغلال الملفات الثنائية
GitHubldebug/extra_recipe

extra_recipe

إكسبلويت إيان بير لثغرة CVE-2017-2370 (قراءة/كتابة ذاكرة النواة على iOS 10.2)

عرض المستودع
4منذ 9 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

// ianbeer

استغلال قراءة/كتابة عشوائية للنواة لـ CVE-2017-2370 على iOS 10.2

تم الاختبار فقط على iPod Touch 6G 14C92 - الأجهزة/البرامج الثابتة الأخرى لن تعمل دون تعديل!

*** الثغرة ***

mach_voucher_extract_attr_recipe_trap هو مصيدة mach (mach trap) يمكن استدعاؤها من أي سياق. إنه كود جديد تمامًا، أُضيف في iOS 10.

kern_return_t mach_voucher_extract_attr_recipe_trap(struct mach_voucher_extract_attr_recipe_args *args) { ipc_voucher_t voucher = IV_NULL; kern_return_t kr = KERN_SUCCESS; mach_msg_type_number_t sz = 0;

root@kitploit:~
if (copyin(args->recipe_size, (void *)&sz, sizeof(sz)))              <---------- (a)
  return KERN_MEMORY_ERROR;

if (sz > MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE)
  return MIG_ARRAY_TOO_LARGE;

voucher = convert_port_name_to_voucher(args->voucher_name);
if (voucher == IV_NULL)
  return MACH_SEND_INVALID_DEST;

mach_msg_type_number_t __assert_only max_sz = sz;

if (sz < MACH_VOUCHER_TRAP_STACK_LIMIT) {
  /* keep small recipes on the stack for speed */
  uint8_t krecipe[sz];
  if (copyin(args->recipe, (void *)krecipe, sz)) {
    kr = KERN_MEMORY_ERROR;
    goto done;
  }
  kr = mach_voucher_extract_attr_recipe(voucher, args->key,
      (mach_voucher_attr_raw_recipe_t)krecipe, &sz);
  assert(sz <= max_sz);

  if (kr == KERN_SUCCESS && sz > 0)
    kr = copyout(krecipe, (void *)args->recipe, sz);
} else {
  uint8_t *krecipe = kalloc((vm_size_t)sz);                          <---------- (b)
  if (!krecipe) {
    kr = KERN_RESOURCE_SHORTAGE;
    goto done;
  }

  if (copyin(args->recipe, (void *)krecipe, args->recipe_size)) {    <----------- (c)
    kfree(krecipe, (vm_size_t)sz);
    kr = KERN_MEMORY_ERROR;
    goto done;
  }

  kr = mach_voucher_extract_attr_recipe(voucher, args->key,
        (mach_voucher_attr_raw_recipe_t)krecipe, &sz);
  assert(sz <= max_sz);

  if (kr == KERN_SUCCESS && sz > 0)
    kr = copyout(krecipe, (void *)args->recipe, sz);
  kfree(krecipe, (vm_size_t)sz);
}

kr = copyout(&sz, args->recipe_size, sizeof(sz));

done:
ipc_voucher_release(voucher);
return kr;

}

إليك بنية الوسائط (التي يتم التحكم فيها من مساحة المستخدم)

struct mach_voucher_extract_attr_recipe_args { PAD_ARG_(mach_port_name_t, voucher_name); PAD_ARG_(mach_voucher_attr_key_t, key); PAD_ARG_(mach_voucher_attr_raw_recipe_t, recipe); PAD_ARG_(user_addr_t, recipe_size); };

recipe وrecipe_size مؤشرات إلى مساحة المستخدم.

عند النقطة (a)، تُقرأ أربعة بايتات من الذاكرة التي يشير إليها مؤشر مساحة المستخدم recipe_size إلى sz.

عند النقطة (b)، إذا كانت sz أصغر من MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE (5120) وأكبر من MACH_VOUCHER_TRAP_STACK_LIMIT (256)، يُستخدم sz لتخصيص مخزن مؤقت في كومة النواة (kernel heap).

عند النقطة (c)، يُستدعى copyin مرة أخرى لنسخ ذاكرة مساحة المستخدم إلى ذلك المخزن المؤقت الذي تم تخصيصه للتو، ولكن بدلاً من تمرير sz (الحجم المُتحقق منه الذي تم تخصيصه) يتم تمرير args->recipe_size كحجم. هذا هو مؤشر مساحة المستخدم إلى الحجم، وليس الحجم نفسه!

يؤدي هذا إلى تجاوز سعة في كومة النواة يمكن التحكم فيه بالكامل. لاحظ أن الكود في الواقع لا يمكن أن يعمل بشكل صحيح :)

*** الاستغلال ***

أستهدف المخازن المؤقتة لرسائل mach المخصصة مسبقًا والتي يتم تخصيصها عبر kalloc. أول 4 بايتات هي حقل حجم يُستخدم لتحديد مكان قراءة وكتابة رسالة داخل المخزن المؤقت. بإفساد هذا الحقل يمكننا جعل رسائل mach تُقرأ وتُكتب خارج حدود تخصيص kalloc الذي يدعم kmsg.

هناك تعقيد بسيط يتمثل في أن kmsg المخصص مسبقًا لأي منفذ (port) سيُستخدم فقط لإرسالات mach_msg الفعلية من قبل النواة (وليس للردود على طرق MIG على سبيل المثال). وهذا يجعل الحصول على محتوى مُتحكم فيه بدرجة كافية داخلها أكثر صعوبة.

أحد أنواع رسائل mach التي ترسلها النواة مع الكثير من البيانات التي يتحكم فيها المستخدم هي رسالة الاستثناء (exception message)، والتي تُرسل عندما يتعطل خيط (thread).

يحتوي الملف load_regs_and_crash.s على تجميع ARM64 يحمّل مسجلات ARM64 العامة بمحتويات مخزن مؤقت بحيث عندما يتعطل، تحتوي رسالة الاستثناء على مخزن البيانات هذا (يتم التحكم في حوالي 0x70 بايت).

بإعادة كتابة حقل ikm_size الخاص بالمنفذ ليشير إلى ترويسة منفذ آخر، يمكننا قراءة وكتابة ترويسة منفذ آخر ومعرفة مكانها في الذاكرة. يمكننا بعد ذلك تحرير ذلك المنفذ الثاني وإعادة تخصيص user client مكانه يمكننا أيضًا قراءته وكتابته.

أقرأ مؤشر vtable الخاص بـ userclients ثم أستخدم تقنية gadget الخاصة بـ OSSerializer::serialize كما هو موضح في [https://info.lookout.com/rs/051-ESQ-475/images/pegasus-exploits-technical-details.pdf] لاستدعاء دالة عشوائية بوسيطين مُتحكم فيهما.

أستدعي uuid_copy والذي يستدعي memmove(arg0, arg1, 0x10). من خلال توجيه أيٍّ من arg0 أو arg1 إلى داخل userclient نفسه (والذي يمكننا قراءته عن طريق استلام رسالة الاستثناء) يمكننا قراءة وكتابة ذاكرة عشوائية للنواة على دفعات من 16 بايت.

تنزيل الأداة