
لطلب سحب Metasploit
قد يؤدي هذا إلى حل المشكلة #8571، والتي تطلب وحدات Phoenix Talon.
على الجهاز المستهدف، يتم تشغيل double-free بسبب احتفاظ النواة بنسخة إضافية من mc_list في وقت accept().
جهاز يعمل بنواة 4.10.15 أو أقل يكون عرضة للخطر إذا كان يقوم بالروتين التالي:
sockfd = socket(AF_INET, xx, IPPROTO_TCP);
setsockopt(sockfd, SOL_IP, MCAST_JOIN_GROUP, xxxx, xxxx);
bind(sockfd, xxxx, xxxx);
listen(sockfd, xxxx);
newsockfd = accept(sockfd, xxxx, xxxx);
close(newsockfd); // trigger release calls, handoff to RCU
sleep(5); // wait for rcu to free()
close(sockfd); // second free()
يتم إنشاء الـ socket الأب، sockfd. يتم إضافته إلى مجموعة multicast باستخدام الخيار MCAST_JOIN_GROUP.
عند إضافة الـ socket إلى مجموعة multicast على الواجهة المحلية، تقوم النواة بتخصيص ذاكرة. في هذه المرحلة،
mc_list موجود في الـ socket الأب.
بعد تعيين عنوان للـ socket باستخدام bind()، ثم listen() للاتصال و accept().
يقوم accept() بإنشاء socket جديد، newsockfd، يتم نسخ جميع الحقول الضرورية من الأب إليه،
بما في ذلك قيمة مؤشر mc_list. في هذه المرحلة، هناك مؤشرات متعددة تشير
إلى نفس الكتلة الذاكرة، وبالتالي double-free.
عند تأسيس الاتصال، تقوم النواة بإنشاء socket فرعي يرث كائن mc_list الخاص بالـ socket الأب.
هذا الخلل في الوراثة موجود في inet_csk_clone_lock في السطر 648 من ملف net/ipv4/inet_connection_sock.c.
اطلع على الـ patch لرؤية الإصلاح المكون من سطر واحد لهذا الوراثة غير المقصودة.
بعد ذلك، أغلق الـ socket الفرعي. كما شرحنا أعلاه، هذا لا يحرر كائن mc_list.
يمر عبر بنية RCU (remote-copy-update) لتحرير الذاكرة.
sleep() لبضع ثوانٍ للتأكد من أن تسليم RCU لديه وقت كافٍ لاستدعاء kfree().
أخيرًا، أغلق الـ socket الأب، مما سيؤدي إلى تشغيل التحرير الثاني.
هجوم بسيط من نوع DoS. تشغيل double-free عن بعد على جهاز مستهدف معروف يقوم بالروتين الخادم المطلوب (مشروح أعلاه). هذا يسبب panic في النواة.