نواة لينكس CVE-2017-11176 تحليل هشاشة الأوضاع واستنساخ

خلفية الضعف

POSIX رسالة طابور في تطبيقات نواة لينكس يقدم الضعف اتحاد العمل النسائي CVE-2017-11176. يمكن للمهاجم استغلال هذه الثغرة الأمنية أن يتسبب في الحرمان من الخدمة أو تنفيذ تعليمات برمجية عشوائية. هذه المادة من أسباب الضعف، والتصحيح وتحليل هشاشة تتكاثر وجهة النظر الأخرى وتحليل هشاشة الأوضاع بالتفصيل.

الثاني، تحليل هشاشة الأوضاع

POSIX رسالة طابور يسمح إعلامات أحداث متزامنة عند قائمة انتظار فارغة لوضع الرسالة، قائمة انتظار الرسائل يسمح POSIX تولد إشارة بداية أو موضوع. هذا استدعاء دالة إعلام حدث غير متزامن mq_notify تحقيق، mq_notify إنشاء أو حذف الإعلام غير متزامن إلى قائمة الانتظار المحدد. منذ ظيفة mq_notify عند دخول يتم تعيين عملية إعادة المحاولة لم جورب المؤشر إلى NULL، يمكن أن يؤدي إلى ضعف اتحاد العمل النسائي.

من وجد رمز التصحيح، يمكن تعيين جورب إلى NULL.

ثم نلقي نظرة على أسباب الضعف، حيث إلى الإصدار 4.1.0 سبيل المثال شفرة المصدر.

في وظيفة mq_notify، u_notification من طبقة المستخدم الذي صدر في، 1193 خطوط هي u_notification العزم فارغ، إن لم يكن فارغ، من خلال u_notification نسخ البيانات copy_from_user في الإعلام من حيث يتم نسخ البيانات من طبقة المستخدم إلى الطبقة الأساسية. إذا فشلت نسخة والخروج.

بعد ذلك، نورث كارولاينا وفارغة جورب، على التوالي. 1203 خط، إذا u_notification يست فارغة، أولا وقبل كل شيء في أجل تحديد notification.sigev_notify SIGEV_NONE بد منه أو SIGEV_SIGNAL أو SIGEV_THREAD. إذا notification.sigev_notify هو SIGEV_SIGNAL، لتحديد ما إذا كانت الإشارة المشروعة.

خط 1212، إذا notification.sigev_notify هو SIGEV_THREAD، دخول كتلة الرئيسيين. خط 1216، عن طريق إنشاء notify_skb alloc_skb، لاستقبال البيانات. خط 1221، عن طريق نسخ البيانات notification.sigev_value.sival_ptr copy_from_user أشار إلى nc- > البيانات في. هنا يجب أن تكون ناجحة، وإلا الخروج، 1229 خطوط، رئيس بيانات الرسالة الإعداد دعوة skb_put. خط 1231 إلى خط 1248 هو حلقة إعادة المحاولة. 1232 خطوط، والدعوة وظيفة fdget للحصول على واصف الملف. 1237 خطوط، وظيفة مكالمة netlink_getsockbyfilp للحصول على netlink_sock التي كتبها واصف الملف، نظرة على وظيفة محددة netlink_getsockbyfilp.

File_inode يدعو عقدة للعثور على فيلب inode المقابلة، ثم يعامل من قبل وظيفة inode SOCK_I.

هنا لمعرفة بنية socket_alloc عضوا مأخذ التي كتبها container_of الماكرو. هنا لشرح، SOCKET_I قيمة الإرجاع هي بنية مأخذ. في الواقع، هيكل جورب هو أيضا أول عضو من نوع المقبس sock_common، هو نسخة مصغرة من المقبس.

وفيما يلي sock_common هيكل نظرة.

خط 1609، بعد الحصول على جورب لدينا، ويحدد ثم sock- > ومن sk_family يساوي AF_NETLINK. 1613 الصفوف، ثم يدعو إلى زيادة عدد sock_hold المرجعية. وظيفة sock_hold على النحو التالي:

atomic_inc يكون sk_refcnt زائد 1 هنا. وظيفة netlink_getsockbyfilp ترجع جورب، جورب في هذا الوقت هو عدد مرجع. بعد ذلك، خط 1246، داعيا netlink_attachskb. هذه هي وظيفة أساسية، والذي تتمثل مهمته في ربط SKB مأخذ netlink، رمز مفتاح محددة كما يلي:

1683 خطوط، دعوة sock_put تقليل عدد مرجع مرة واحدة، وأخيرا العودة 1، ترجع الدالة مباشرة لإعادة محاولة مكان التسمية غوتو.

هنا خط 1237 والخط 1246، الذي يدعو إلى عدد مرجع جيدا أكثر من الإزاحة. 1247 في خط إذا كانت العبارة ليست فارغة جورب، نظرة على خط 1233، إذا f.file فارغ، ثم اذهب اليه بشكل مباشر إلى التسمية. الكلمات من التعليمات البرمجية كما يلي:

خط 1306، لتحديد ما إذا كان جورب فارغ، إن لم يكن فارغ، وظيفة مكالمة netlink_detachskb.

يتم تحريرها SKB، ويقلل كورونا عدد مرجع، أن يطلق سراحه. حتى لا يكون هناك مشكلة، وإذا أنشأنا يبقى موضوع عودة netlink_attachskb 1، والمنطق إعادة المحاولة تكرار، وهذه المرة إلى جورب عدد مرجع هو الحفاظ على التوازن، وناقص واحد زائد واحد، ولكن ليس جورب فارغ. في نفس الوقت ثم قم بإنشاء موضوع لإغلاق netlink مأخذ B المقابلة لواصف الملف. منذ موضوع B إغلاق مأخذ netlink ملف واصف، ثم والمنطق موضوع إعادة المحاولة، خط 1232، ستفشل عندما دعا fdget، وبعد ذلك مباشرة إلى غوتو التسمية، التي ستصدر، كان الإصدار الثاني، مما أدى إلى الضعف. هذا الضعف هو جزء من شروط تنافسية للإفراج عن ضعف الثاني، مؤشر واحد فقط لا يمكن أن تؤدي إلى الضعف.

هذا الضعف هو مبدأ بسيط نسبيا، ولكن كيف لتحريك معقدة هذا الضعف تماما. أولا وقبل كل شيء، وكيفية تحقيق عوائد netlink_attachskb 1، وبالتالي إدخال بنجاح منطق إعادة المحاولة. انظر مرة أخرى إلى الوراء تحقيق netlink_attachskb.

خط 1657، من خلال الاستحواذ كورونا netlink_sock حسب الوظيفة nlk_sk. nlk_sk هنا أدناه.

ماكرو netlink_sock الحصول container_of بالدعوة. هيكل netlink_sock على النحو التالي:

الهيكل الأول هو netlink_sock عضوا نوع جورب، وأول عضو في الهيكل هو مأخذ جورب. خط 1660، إذا كان الإصرار على إدخال أولا.

! Netlink_skb_is_mmaped (SKB) عودة بالتأكيد الحقيقية، والمفتاح هو sk- > sk_rmem_alloc > sk- > sk_rcvbuf || test_bit (NETLINK_CONGESTED، وnlk- > يجب أن تكون الدولة) نتيجة صحيح.

هنا sk- الإعداد > sk_rmem_alloc الاختيار حجم الالتفافية أسهل، كما يلي.

إذا كان تقرير إذا لم يجتز، ثم استدعاء وظيفة netlink_skb_set_owner_r على النحو التالي.

خط 878، ويسمى الماكرو atomic_add، ينفذ الكلية إضافة ذرات العملية. معنى هذا الخط هو: sk- > بالإضافة إلى skb- على أساس sk_rmem_alloc > truesize. أي ما يعادل sk- > sk_rmem_alloc + = skb- > truesize. منذ هذه الوظيفة في هذا الخط من التعليمات البرمجية يمكن أن يكون زيادة مباشرة sk- > حجم sk_rmem_alloc، ثم مكالمات متعددة netlink_skb_set_owner_r وظيفة يمكن أن تزيد sk- > قيمة Rmem_alloc من؟ نظريا يمكن أن نرى كيفية الوصول إلى هذه الدالة من طبقة المستخدم.

يمكنك العثور بسرعة على سلسلة دعوة netlink_skb_set_owner_r فهم من خلال الأداة:

netlink_sendmsg- > netlink_unicast- > netlink_attachskb- > netlink_skb_set_owner_r

كيفية تمهيد الطريق من خلال استدعاء دالة؟ يجب أن نقوم بتحليل كيفية الوصول netlink_skb_set_owner_r من netlink_sendmsg.

netlink_sendmsg تحقيق المهام التالية.

خط 2285، لأول مرة يحدد msg- > msg_flag لا يمكن MSG_OOB، على قراءة.

خط 2292، msg- العزم > طول Msg_namelen، هناك يجب ألا تكون فارغة، وبطبيعة الحال، وليس تفريغ. بعد دخول إذا، انطلاقا addr- > ومن nl_family يساوي AF_NETLINK. خط 2299، هو dst_group العزم أو dst_portid لا يفرغ، والتي تبين dst_group وضع الإرسال المتعدد، dst_portid من addr- > nl_pid، وبالتالي ضمان dst_portid لا إفراغ أسهل. التالي:

خط 2320، وتقرير msg- > msg_iter.iov- > iov_base لا يكون فارغا. وليس أكبر من sk- ليون > sk_sndbuf-32.

في الواقع، فإن وظيفة كاملة، وطبقة المستخدم تسيطر فقط من ذلك بكثير. تنظر مباشرة في netlink_unicast المكالمة.

netlink_unicast تحقيق المهام التالية:

في جميع أنحاء وظيفة، يمكن للمستخدم التحكم بكثير. 1783 خط، وإعداد timeo، وهنا لضمان msg- nonblock > msg_flags وMSG_DONTWAIT، حتى أن موضوع لن تكون كتلة. خط عام 1790، يتم تحديد ما إذا كان أو لم يكن إصدار النواة كورونا كورونا، عندما يقوم المستخدم باستخدام طبقة المقابس NETLINK_USERSOCK. خط 1793، لتحديد ما إذا كان هناك sk_filter، لضمان أن لا يدخل بيان إذا هنا، لا تقم بتعيين مرشح. خط عام 1800، مباشرة netlink_attachskb الدعوة، وصلت بنجاح وظيفة netlink_skb_set_owner_r. التي يمكن اعتبارها لزيادة sk- بالدعوة netlink_sendmsg > عملية sk_rmem_alloc. في الواقع، ونحن لا يمكن أن يؤدي إلا إلى زيادة sk- > sk_rmem_alloc، قد يقلل أيضا من sk- > sk_rcvbuf.

فكيف للحد من sk- > sk_rcvbuf؟ في الدالة setsockopt، والعثور على وظيفة sock_setsockopt من sk- > Sk_rcvbuf من العملية.

خط 773، sk- > sk_rcvbuf بين القيمة القصوى وفال * 2 SOCK_MIN_RCVBUF. خط 755، فال فال بين قيمة الحد الأدنى وsysctl_rmem_max. خط 749، وهذه الحالة هي SO_RCVBUF. مواصلة البحث حتى.

خط 693، لضمان optlen لا تقل عن sizeof (دولي). خط 696، سيتم تعيين لoptval فال، وoptval هنا هو السيطرة عليها المستخدم. خط 703، optname توزيع التبديل، وذلك لضمان optname SO_RCVBUF. وهذا يضمن وصول سلس تعديل sk- > التعليمات البرمجية حيث rcvbuf.

هنا، ونحن تجاوز أول وظيفة الشيك netlink_attachskb بطريقتين.

1) بنسبة netlink_sendmsg sk- > وsk_rmem_alloc القيمة.

2) انخفاض أكبر قدر ممكن من sock_setsockopt sk- > وrcvbuf القيمة.

بعد دخول إذا البيان، نظرة على التعليمات البرمجية التالية:

وهذا الرمز جعل الترابط الحالي في حالة انتظار، مباشرة كتلة. إذا كنت لا تريد أن تدخل في حالة انتظار، إلا أن مجموعة sock_flag SOCK_DEAD. ولكن إذا مجموعة sock_flag SOCK_DEAD، ليست هناك حاجة لإعادته، لذلك هناك لا بد أن يدخل حالة الانتظار. وتسمى طريقة بارعة wake_up_interruptible مباشرة القسري موضوع أيقظ. أن wake_up_interruptible كيفية يطلق عليه؟ سلسلة استدعاء دالة قصيرة جدا: netlink_setsockopt- > wake_up_interruptible.

في وظيفة Netlink_setsockopt:

2182 خط، يستيقظ دعوة موضوع wake_up_interruptible. خط 2178، حالة لNETLINK_NO_ENOBUFS.

خط 2131، عازمة على أن تكون SOL_NETLINK مستوى خط 2134، فإنه يتم تحديد عدم NETLINK_RX_RING optname وNETLINK_TX_RING، مع ضمان أكبر optlen من أو sizeof المساواة (الباحث). خط 2139، optname توزيع التبديل، وهنا لضمان NETLINK_NO_ENOBUFS optname. هنا، يمكنك أن تضمن أساسا netlink_attachskb العودة.

بعد دخول دورة إعادة المحاولة لضمان أن هذه المرة الخف لم فارغة. لخطأ دورة إعادة المحاولة المقبل، والقفز إلى OUT، رمز كما يلي:

1232 خط، والحصول على notification.sigev_signo من فد التي كتبها fdget. Notification.sigev_signo أنها مرت في وضع المستخدم، وبالتالي يمكن أن يغلق مباشرة مأخذ على مستوى المستخدم. بعد طبقة المستخدم إغلاق مأخذ، خط 1233، إذا أدخل المنطق، ثم القفز من تسميات.

لا فارغة، يتم تحديد هذا جورب الوقت أن ينطبق IF إلى netlink_destachskb، تليها انهيار مجانا.

الثالث، والاستنساخ الضعف

اتحاد العمل النسائي لأنواع من نقاط الضعف، طريقة عامة لاستخدام عنصر نائب كومة طائرة. ضعف الكائن عدة مرات الإصدار هو كائن netlink_sock. netlink_sock حجم الكائن 0x3f0 بايت، وهذا هو 1008byte.

نواة الذاكرة الكائن حكم تخصيص، ينبغي تخصيص الكائن netlink_sock من ذاكرة التخزين المؤقت kmalloc 1024.

مخصص بلاطة في توزيع الأشياء، واتباع قواعد LIFO.

هنا هو عملية الإفراج عن الكائن لوح مخصص.

إطلاق سراح كائن objp وضع املهام > إنهاء دخول أ. ما يلي هو عملية مهمة لوح مخصص:

تعيين مباشرة من املهام > دخول نهاية كائن المنبثقة.

حتى صدر لتوه كائن في المرتبة في الفقرة الأخيرة من القائمة، إذا كان هذا الوقت يحدث أن تكون تخصيص نفس الكائن في ذاكرة التخزين المؤقت، وأنها مجرد كائنات صدر سيتم تخصيصها بها، والتي ظهرت اثنين من المؤشرات إلى نفس عنوان الذاكرة. لضمان تطبيق موقع الذاكرة من حق الذاكرة على ضعف الكائن، ونحن بحاجة لفهم النقاط:

كومة رش الأشياء التي تستخدمها الكائنات الذاكرة المؤقتة نواة والثغرات يجب أن يكون في نفس ذاكرة التخزين المؤقت. هذا الحجم يجب أن تقع ضمن نفس kmalloc-X؛

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

إذا كان الكائن كومة رذاذ تطبيق يقيمون لفترة وجيزة فقط، عندما ترجع الدالة صدر كائن من التطبيق، مما أدى إلى عدم الاحتلال بشكل صحيح. حتى تكون قادرة على ضمان التطبيق الهدف لا يتم إطلاق سراحهم، على الأقل ضمان عدم ستصدر في استخدام الثغرات الاعتراض هنا لاستخدام البصمة المقيم في الذاكرة، التي يمكن اتخاذها لجعل نظام معين يدعو عملية الحجب.

لوح مشكلة تجزئة ذاكرة التخزين المؤقت، هنا لحجم الكائن نائبا 1008، وحجم الجسم هو كبير نسبيا، وهو ما يمثل ربع صفحة، أكثر تنظيما، ينبغي أن يكون هناك أي مشكلة تجزئة.

إذا كيف يمكنك الحكم على نجاح كومة رذاذ ذلك؟

الحالة العامة، عندما كومة طائرة عندما بنية كومة عندما رش الهدف، فمن الضروري لضبط الذاكرة قيمة السحر تعويض المقابلة لبعض أعضاء محددة لضعف كائن المجال، ثم استدعاء نظام يمكن استخدامها لبيانات اكتساب نقاط الضعف المتعلقة كائن تحليل . العديد من الأعضاء الرئيسيين في هيكل netlink_sock على النحو التالي.

Getsockname باستخدام استدعاءات النظام للحصول على بيانات ومكالمات getsockname netlink_getname. النظر في وظيفة محددة netlink_getname:

1576 خطوط للقانون، الكائن portid netlink_sock نسخها إلى nladdr- > nl_pid. 1577 خطوط للقانون، إذا nlk- > مجموعة 0، nladdr- > nl_groups المخصصة لNULL، dereference تجنب هنا nlk- > مجموعة المؤشر، قد تكون مجموعة مباشرة الصفر حقل مليء عند بناء الهدف كومة الرذاذ. يتم تحويل nladdr على من ADDR، يتم تمرير ADDR العازلة من طبقة المستخدم.

كومة رش النجاح على النحو التالي:

عادة مؤشر دالة إلى عضو بنية الجسم الهيكلي تغطي أو تحتوي على مؤشرات الدالة، كما هو الحال قد يكون. اختيار تغطي الانتظار الانتظار. هيكل netlink_sock على النحو التالي:

هيكل wait_queue_haed_t على النحو التالي:

عضو task_list هو في اتجاهين قائمة التداول الرأس، كل وصلة task_list عضوا ينتظرون لتتم معالجتها عناصر الروتينية. ثم كيفية استخدام هذا العضو؟ نظرة على التعليمات البرمجية التالية.

هذه هي وظيفة netlink_setsockopt كود جزء، واستعادة حللت القيامة موضوع السابقة هنا سوف ندعو الكائن الانتظار روتين netlink_sock مباشرة باستخدام nlk- المعلمة > الانتظار. يستمر في التحليل المتعمق:

استدعاء دالة __Wake_up_common:

70 خطوط للقانون، الماكرو list_for_each_entry_safe اجتياز Q- > task_list أعضاء للعودة إلى داء. 68 خطوط للقانون، يتم وصف داء wait_queue_t مؤشر Q- > يتم تخزين قائمة task_list العنصر نوع wait_queue_t، wait_queue_t البنية التالية:

هيكل wait_queue_t ديه مؤشر إلى ظائفها وظيفة. تبدو وظيفة __wake_up_common، وخطوط كود 73، داء التنفيذ المباشر > يمكن السيطرة عليها وظيفة ظائفها بواسطة تكوين المعلمة RIP ظائفها من __wait_queue. نعود وننظر في ماكرو list_for_each_entry_safe:

نقاط البيع هو __wait_queue سطر التعليمات البرمجية العنصر 62، لحاز أرفع > member.next لفهم الإشارات، حاز أرفع هنا > عضو هو __wait_queue في task_list. __wait_queue في task_list أيضا رئيس القائمة، لافتا إلى ضرورة list_head، لذلك فمن الضروري لبناء list_head كاذبة لdereference في الماكرو. الاختبارات هي كما يلي:

والخطوة التالية هي لأداء تجاوز SMEP ذكر رمز الصحيح عبر سلسلة شرطة عمان السلطانية. مباشرة بعد ذكر ناجحة على النحو التالي:

* المؤلف: ADLAB، يرجى تحديد مستنسخة من FreeBuf.COM

! الحصري 2013--2017 مجلات الاتجاهات خط الدولة (الماجستير | سيد خاص)

الاعتماد على المشي استهلاك الهجومية، واندلاع مطلق النار الحرس المحظية

على الخط في محاولة الخيال العلمي الجديد التصنيع المحلي إلى الساحة العالمية اليوم، إن "الشروق آخر"

و alipay APP شكك الصورة المستعمل جمع بصمت، بدا المسؤولون إلى الاستجابة

اللون ثلاثة أميال لا تنسى البصرية، نايك الجوية أكثر Uptempo أعمال جديدة مقنعة للبيع قريبا!

وقد انهار توظيف الأبحاث نظام صافي تبادل! هذه النصائح مبادلة يجب عليك استخدام للحصول على

السنة الصينية الجديدة لا تغلق على مجموعة كاملة من الحد X النوبي على التوالى بانخفاض 300 يوان!

SAIC تشيس G10 بواسطة نموذج أعلى الديزل للبيع 229800

مطيع انفجار يوم السينما | "الكابتن المعجزة" أعجوبة في أمريكا الشمالية الثلاثة الأولى، والثانية فقط إلى "ربط إعادة 3" "الفهود السود" بيع قبل

مقابلة المبتكر الغريب-CTO تشانغ اللعنة: سوف يولد العملاق القادم في مجال AI + B2B

لأنها تمثل أعلى مستوى من التصميم والعمل معا على المدفن بواسطة شاحنة مقفلة! هل لديك المفضلة لديك SK8-مرحبا

متر يانغ جينغ شيان خارج الأسرة المنزل الأرز طباخ الدخن دلو الأسرة من ذلك بكثير!