بعد إجراء دراسة متعمقة على Aptos Moveevm، اكتشفنا ثغرة جديدة في تجاوز الأعداد الصحيحة. عملية تفعيل هذه الثغرة أكثر إثارة للاهتمام، أدناه سنقوم بتحليل هذه الثغرة بعمق، وسنقدم بعض المعلومات الأساسية عن لغة Move. من خلال شرح هذا المقال، نعتقد أنك ستفهم لغة Move بشكل أعمق.
تتحقق لغة Move من وحدات الكود قبل تنفيذ البايت كود. تتكون عملية التحقق من 4 خطوات، وتظهر هذه الثغرة في خطوة reference_safety.
أمان الاقتباس في Move
تدعم لغة Move نوعين من الإشارات: إشارة غير قابلة للتغيير ( & ) وإشارة قابلة للتغيير ( & mut ). تُستخدم الإشارة غير القابلة للتغيير لقراءة البيانات من الهيكل، بينما تُستخدم الإشارة القابلة للتغيير لتعديل البيانات. يساعد استخدام نوع الإشارة المناسب في الحفاظ على الأمان وتحديد وحدات القراءة.
في وحدة أمان الإشارة في Move، يتم مسح تعليمات بايت الكتل الأساسية في الوظائف للتحقق من صحة جميع عمليات الإشارة. تشمل العملية الرئيسية للتحقق من أمان الإشارة تنفيذ الكتل الأساسية، وتوليد الحالة اللاحقة، ودمج الحالات السابقة واللاحقة.
تحليل الثغرات
تظهر الثغرة في دالة join_ التي تستدعي وحدة الأمان. عندما يكون مجموع طول معلمات الدالة وطول المتغيرات المحلية أكبر من 256، فإن استخدام نوع u8 لتمثيل المتغيرات المحلية يؤدي إلى تجاوز سعة الأعداد.
على الرغم من أن Move لديه عملية للتحقق من عدد locals، إلا أن وحدة check bounds تتحقق فقط من locals، ولم تشمل طول المعلمات. يبدو أن المطورين أدركوا ضرورة التحقق من مجموع المعلمات والقيم المحلية، لكن الكود تحقق فقط من عدد المتغيرات المحلية.
من تجاوز السعة إلى هجمات DoS
باستخدام ثغرة تجاوز السعة هذه، يمكن للمهاجم إنشاء كتلة كود حلقية، وتغيير حالة الكتلة. عند تنفيذ دالة execute_block مرة أخرى، إذا كان المؤشر الذي تحتاج التعليمات للوصول إليه غير موجود في خريطة AbstractState locals الجديدة، فسوف يؤدي ذلك إلى هجوم DoS.
في وحدة مرجع الأمان، يمكن أن تؤدي أوامر مثل MoveLoc/CopyLoc/FreeRef إلى حدوث هذه الحالة. على سبيل المثال، في دالة copy_loc، إذا لم يكن LocalIndex موجودًا، فسوف يؤدي ذلك إلى حدوث panic، مما يؤدي بدوره إلى انهيار العقدة بأكملها.
إعادة إنتاج الثغرات
يمكن إعادة إنتاج هذا الثغرة في git من خلال كود PoC التالي:
نقل
test(a المرح العام: U64 ، B: U64 ، C: U64 ، D: u64) {
دع x = 0 ؛
حلقة {
إذا كان (x == 1) {
انقطاع
};
س = س + 1 ؛
}
}
خطوات تفعيل هجوم DoS كالتالي:
عند تنفيذ دالة execute_block للمرة الأولى، تم تعيين parameters و locals كلاً منهما إلى SignatureIndex(0)، مما أدى إلى أن num_locals أصبح 264. بعد تنفيذ دالة join_، أصبح طول خريطة locals الجديدة 8.
عند تنفيذ دالة execute_block للمرة الثانية، يتم تنفيذ السطر الأول من كود move copyloc(57). نظرًا لأن locals في هذه المرحلة لها طول 8 فقط، فإن offset 57 غير موجود، مما يؤدي إلى عودة دالة get(57).unwrap() بقيمة None، مما يؤدي في النهاية إلى حدوث panic.
تظهر هذه الثغرة أنه لا يوجد كود آمن بشكل مطلق. على الرغم من أن لغة Move تقوم بإجراء تحقق ثابت قبل تنفيذ الكود، إلا أنه لا يزال من الممكن تجاوزها بواسطة ثغرات الفيض. وهذا يبرز مرة أخرى أهمية تدقيق الكود.
بالنسبة للغة Move، نوصي بإضافة المزيد من رموز التحقق أثناء وقت التشغيل، لمنع حدوث حالات غير متوقعة. حاليًا، تتم عمليات التحقق الأمني بشكل رئيسي في مرحلة التحقق، ولكن بمجرد تجاوز التحقق، قد يؤدي نقص تعزيز الأمان الكافي في مرحلة التشغيل إلى مشاكل أكثر خطورة.
كقادة في بحث أمان لغة Move، سنواصل التعمق في قضايا الأمان المتعلقة بـ Move، وسنشارك المزيد من الاكتشافات في المستقبل.
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
تحليل ثغرات تجاوز سعة الأعداد في لغة Move: من أمان الإشارة إلى هجمات DoS
تحليل ثغرة تجاوز السعة في لغة Move
المقدمة
بعد إجراء دراسة متعمقة على Aptos Moveevm، اكتشفنا ثغرة جديدة في تجاوز الأعداد الصحيحة. عملية تفعيل هذه الثغرة أكثر إثارة للاهتمام، أدناه سنقوم بتحليل هذه الثغرة بعمق، وسنقدم بعض المعلومات الأساسية عن لغة Move. من خلال شرح هذا المقال، نعتقد أنك ستفهم لغة Move بشكل أعمق.
تتحقق لغة Move من وحدات الكود قبل تنفيذ البايت كود. تتكون عملية التحقق من 4 خطوات، وتظهر هذه الثغرة في خطوة reference_safety.
أمان الاقتباس في Move
تدعم لغة Move نوعين من الإشارات: إشارة غير قابلة للتغيير ( & ) وإشارة قابلة للتغيير ( & mut ). تُستخدم الإشارة غير القابلة للتغيير لقراءة البيانات من الهيكل، بينما تُستخدم الإشارة القابلة للتغيير لتعديل البيانات. يساعد استخدام نوع الإشارة المناسب في الحفاظ على الأمان وتحديد وحدات القراءة.
في وحدة أمان الإشارة في Move، يتم مسح تعليمات بايت الكتل الأساسية في الوظائف للتحقق من صحة جميع عمليات الإشارة. تشمل العملية الرئيسية للتحقق من أمان الإشارة تنفيذ الكتل الأساسية، وتوليد الحالة اللاحقة، ودمج الحالات السابقة واللاحقة.
تحليل الثغرات
تظهر الثغرة في دالة join_ التي تستدعي وحدة الأمان. عندما يكون مجموع طول معلمات الدالة وطول المتغيرات المحلية أكبر من 256، فإن استخدام نوع u8 لتمثيل المتغيرات المحلية يؤدي إلى تجاوز سعة الأعداد.
على الرغم من أن Move لديه عملية للتحقق من عدد locals، إلا أن وحدة check bounds تتحقق فقط من locals، ولم تشمل طول المعلمات. يبدو أن المطورين أدركوا ضرورة التحقق من مجموع المعلمات والقيم المحلية، لكن الكود تحقق فقط من عدد المتغيرات المحلية.
من تجاوز السعة إلى هجمات DoS
باستخدام ثغرة تجاوز السعة هذه، يمكن للمهاجم إنشاء كتلة كود حلقية، وتغيير حالة الكتلة. عند تنفيذ دالة execute_block مرة أخرى، إذا كان المؤشر الذي تحتاج التعليمات للوصول إليه غير موجود في خريطة AbstractState locals الجديدة، فسوف يؤدي ذلك إلى هجوم DoS.
في وحدة مرجع الأمان، يمكن أن تؤدي أوامر مثل MoveLoc/CopyLoc/FreeRef إلى حدوث هذه الحالة. على سبيل المثال، في دالة copy_loc، إذا لم يكن LocalIndex موجودًا، فسوف يؤدي ذلك إلى حدوث panic، مما يؤدي بدوره إلى انهيار العقدة بأكملها.
إعادة إنتاج الثغرات
يمكن إعادة إنتاج هذا الثغرة في git من خلال كود PoC التالي:
نقل test(a المرح العام: U64 ، B: U64 ، C: U64 ، D: u64) { دع x = 0 ؛ حلقة { إذا كان (x == 1) { انقطاع }; س = س + 1 ؛ } }
خطوات تفعيل هجوم DoS كالتالي:
عند تنفيذ دالة execute_block للمرة الأولى، تم تعيين parameters و locals كلاً منهما إلى SignatureIndex(0)، مما أدى إلى أن num_locals أصبح 264. بعد تنفيذ دالة join_، أصبح طول خريطة locals الجديدة 8.
عند تنفيذ دالة execute_block للمرة الثانية، يتم تنفيذ السطر الأول من كود move copyloc(57). نظرًا لأن locals في هذه المرحلة لها طول 8 فقط، فإن offset 57 غير موجود، مما يؤدي إلى عودة دالة get(57).unwrap() بقيمة None، مما يؤدي في النهاية إلى حدوث panic.
! اكتشفت Numen Cyber حصريا ثغرة أمنية أخرى عالية الخطورة في لغة الحركة
! اكتشف Numen Cyber حصريا ثغرة أمنية أخرى عالية الخطورة في لغة الحركة
! اكتشفت Numen Cyber حصريا ثغرة أمنية أخرى عالية الخطورة في لغة الحركة
ملخص
تظهر هذه الثغرة أنه لا يوجد كود آمن بشكل مطلق. على الرغم من أن لغة Move تقوم بإجراء تحقق ثابت قبل تنفيذ الكود، إلا أنه لا يزال من الممكن تجاوزها بواسطة ثغرات الفيض. وهذا يبرز مرة أخرى أهمية تدقيق الكود.
بالنسبة للغة Move، نوصي بإضافة المزيد من رموز التحقق أثناء وقت التشغيل، لمنع حدوث حالات غير متوقعة. حاليًا، تتم عمليات التحقق الأمني بشكل رئيسي في مرحلة التحقق، ولكن بمجرد تجاوز التحقق، قد يؤدي نقص تعزيز الأمان الكافي في مرحلة التشغيل إلى مشاكل أكثر خطورة.
كقادة في بحث أمان لغة Move، سنواصل التعمق في قضايا الأمان المتعلقة بـ Move، وسنشارك المزيد من الاكتشافات في المستقبل.