المجموعة 4
هذه آخر مجموعة من تحديات تشفير شيفرات الكتل، وهي أيضًا تغطيتنا لمصادقة الرسائل.
هذه المجموعة أسهل بكثير من المجموعة السابقة. نقدّم بعض المفاهيم الجديدة، لكن الهجمات نفسها تتضمن شيفرة أقل من، لنقل، أوراكل حشو CBC.
تزداد الأمور صعوبة بشكل ملحوظ في المجموعتين التاليتين. كثيرون يتوقفون بعد المجموعة 4.
25. كسر AES CTR «الوصول العشوائي للقراءة/الكتابة»
عودة إلى CTR. شفّر النص الصريح المستعاد من هذا الملف (تمرين ECB) بـ CTR تحت مفتاح عشوائي (في هذا التمرين ينبغي أن يكون المفتاح مجهولًا لك، لكن احتفظ به).
الآن، اكتب الشيفرة التي تتيح لك «التنقل» داخل النص المشفَّر، وفك التشفير، وإعادة التشفير بنص صريح مختلف. اعرض هذا كدالة، مثل، "edit(ciphertext, key, offset, newtext)".
تخيّل أن دالة «edit» عُرِّضت للمهاجمين عبر نداء API لا يكشف المفتاح ولا النص الصريح الأصلي؛ المهاجم يملك النص المشفَّر ويتحكم في الإزاحة و«النص الجديد».
استعد النص الصريح الأصلي.
طعام للفكر.
من الفوائد الشعبية المفترضة لوضع CTR القدرة على «التنقل للأمام» بسهولة داخل النص المشفَّر؛ للوصول إلى البايت رقم N من النص المشفَّر، كل ما تحتاج إليه هو توليد البايت رقم N من تيار المفاتيح (keystream). تخيّل لو اعتمدت على تلك النصيحة لتشفير قرص، مثلًا.
26. قلب البتّات في CTR
هناك أناس في العالم يعتقدون أن CTR يقاوم هجمات قلب البتّات من النوع الذي يتأثر به وضع CBC.
أعِد تنفيذ تمرين قلب البتّات في CBC السابق باستخدام وضع CTR بدلًا من وضع CBC. احقن رمزًا "admin=true".
27. استعادة المفتاح من CBC مع IV=Key
خذ شيفرتك من تمرين CBC وعدّلها بحيث تعيد استخدام مفتاح تشفير CBC كمتجه تهيئة (IV).
تستخدم التطبيقات أحيانًا المفتاح كمتجه تهيئة بحجة أن المرسل والمستقبل يعرفان المفتاح أصلًا، ويمكن توفير بعض المساحة باستخدامه مفتاحًا ومتجه تهيئة في آن واحد.
استخدام المفتاح كمتجه تهيئة غير آمن؛ فمهاجم قادر على تعديل النص المشفَّر أثناء النقل يمكنه جعل المستقبل يفك تشفير قيمة تكشف المفتاح.
شيفرة CBC من التمرين 16 تشفّر سلسلة URL. تحقق من توافق كل بايت من النص الصريح مع ASCII (أي ابحث عن قيم ASCII العليا). ينبغي أن تثير الرسائل غير المتوافقة استثناءً أو تعيد خطأً يتضمن النص الصريح المفكوك (يحدث هذا طوال الوقت في الأنظمة الحقيقية، لمن يهمه الأمر).
استخدم شيفرتك لتشفير رسالة بطول ثلاث كتل على الأقل:
AES-CBC(P_1, P_2, P_3) -> C_1, C_2, C_3
عدّل الرسالة (أنت الآن المهاجم):
C_1, C_2, C_3 -> C_1, 0, C_1
فك تشفير الرسالة (أنت الآن المستقبل) وأثر الخطأ المناسب عند العثور على ASCII عالٍ.
بوصفك المهاجم، وباستعادة النص الصريح من الخطأ، استخرج المفتاح:
P'_1 XOR P'_3
28. تنفيذ رمز مصادقة SHA-1 بمفتاح
اعثر على تنفيذ SHA-1 باللغة التي تكتب بها.
لا تغش. لن ينجح الأمر.
لا تستخدم تنفيذ SHA-1 الذي توفره لغتك أصلًا (على سبيل المثال، لا تستخدم مكتبة "Digest" في Ruby، ولا تستدعِ OpenSSL؛ في Ruby ستحتاج إلى SHA-1 نقي بـ Ruby).
اكتب دالة لمصادقة رسالة تحت مفتاح سري باستخدام رمز مصادقة بادئته سرية (secret-prefix MAC)، وهو ببساطة:
SHA1(key || message)
تحقق من أنك لا تستطيع العبث بالرسالة دون كسر رمز المصادقة الذي أنتجته، وأنك لا تستطيع إنتاج رمز مصادقة جديد دون معرفة المفتاح السري.
29. كسر رمز مصادقة SHA-1 بمفتاح باستخدام تمديد الطول
رموز مصادقة SHA-1 ذات البادئة السرية قابلة للكسر بسهولة.
يعتمد الهجوم على SHA-1 ذات البادئة السرية على حقيقة أنك تستطيع أخذ مخرج SHA-1 واستخدامه كنقطة انطلاق جديدة لـ SHA-1، وبذلك تأخذ تجزئة SHA-1 اعتباطية و«تغذّيها بيانات إضافية».
ولأن المفتاح يسبق البيانات في البادئة السرية، فإن أي بيانات إضافية تغذّي بها تجزئة SHA-1 بهذه الطريقة ستبدو وكأنها جُزّئت بالمفتاح السري.
لتنفيذ الهجوم، ستحتاج إلى مراعاة أن SHA-1 «محشو» بطول الرسالة بالبتّات؛ وستحتاج رسالتك المزوّرة إلى تضمين ذلك الحشو. نسمي هذا «حشو الغراء» (glue padding). الرسالة النهائية التي تزوّرها فعليًا ستكون:
SHA1(key || original-message || glue-padding || new-message)
(حيث يُفهم الحشو النهائي على الرسالة المبنية كاملة).
لاحظ أنك ستحتاج، لتوليد حشو الغراء، إلى معرفة الطول الأصلي للرسالة بالبتّات؛ والرسالة نفسها معروفة للمهاجم، أما المفتاح السري فلا، لذا ستحتاج إلى تخمينه.
يبدو هذا أعقد مما هو عليه في الواقع.
لتنفيذ الهجوم، اكتب أولًا دالة تحسب حشو MD لرسالة اعتباطية وتحقق من أنك تولّد الحشو نفسه الذي يستخدمه تنفيذ SHA-1 لديك. ينبغي أن يستغرق هذا منك 5-10 دقائق.
الآن، خذ رمز مصادقة SHA-1 ذا البادئة السرية للرسالة التي تريد تزويرها --- وهذا مجرد تجزئة SHA-1 --- وقسّمه إلى سجلات SHA-1 بطول 32 بتًا (تسميها SHA-1 "a" و"b" و"c" وما إلى ذلك).
عدّل تنفيذ SHA-1 لديك بحيث يمكن للمستدعين تمرير قيم جديدة لـ "a" و"b" و"c" وما إلى ذلك (تبدأ عادة بأعداد سحرية). وبعد «تثبيت» السجلات، جزّئ البيانات الإضافية التي تريد تزويرها.
باستخدام هذا الهجوم، ولّد رمز مصادقة ببادئة سرية تحت مفتاح سري (اختر كلمة عشوائية من /usr/share/dict/words أو ما شابه) للسلسلة:
"comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon"
زوّر نسخة معدّلة من هذه الرسالة تنتهي بـ ";admin=true".
هذا هجوم مفيد جدًا.
على سبيل المثال: استخدمه Thai Duong وJuliano Rizzo، اللذان سبقانا إلى هذا الهجوم، لكسر واجهة Flickr API.
30. كسر رمز مصادقة MD4 بمفتاح باستخدام تمديد الطول
البيت الثاني، كالأول، لكن استخدم MD4 بدلًا من SHA-1. وبعد أن أنجزت هذا الهجوم مرة على SHA-1، ينبغي أن يستغرق البديل بـ MD4 وقتًا أقل بكثير؛ معظمه سيكون وقت بحثك في Google عن تنفيذ لـ MD4.
أنت تفكّر: لماذا تكبدنا عناء هذا؟
اللوم على Stripe. في لعبتهم الثانية من CTF، تضمن التحدي قبل الأخير كسر رمز مصادقة H(k, m) بـ SHA1. ما يعني أن شيفرة SHA1 كانت تطفو في كل أنحاء الإنترنت. أما شيفرة MD4 فليس بالقدر نفسه.
31. تنفيذ وكسر HMAC-SHA1 مع تسرّب زمني اصطناعي
ينبغي أن تكفي الشيفرة الزائفة على ويكيبيديا. HMAC سهل جدًا.
باستخدام إطار الويب الذي تختاره (Sinatra أو web.py أو أيًا كان)، اكتب تطبيقًا صغيرًا فيه URL يأخذ وسيط "file" ووسيط "signature"، هكذا:
http://localhost:9000/test?file=foo&signature=46b4ec586117154dacd49d664e5d63fdc88efb51
اجعل الخادم يولّد مفتاح HMAC، ثم تحقق من أن "signature" في الطلبات الواردة صالح لـ "file"، باستخدام عامل "==" لمقارنة رمز المصادقة الصالح لملف ما بوسيط "signature" (بعبارة أخرى، تحقق من HMAC بالطريقة التي يتحقق بها أي مبرمج عادي).
اكتب دالة، سمّها "insecure_compare"، تنفّذ عملية == بإجراء مقارنات بايتًا بايتًا مع خروج مبكر (أي أعِد false عند أول بايت غير مطابق).
في حلقة "insecure_compare"، أضف نومًا مدته 50 مللي ثانية (نَم 50 مللي ثانية بعد كل بايت).
استخدم دالة "insecure_compare" للتحقق من رموز HMAC في الطلبات الواردة، واختبر أن الجهاز كله يعمل. أعِد 500 إذا كان رمز المصادقة غير صالح، و200 إذا كان سليمًا.
باستخدام التسرّب الزمني في هذا التطبيق، اكتب برنامجًا يكتشف رمز المصادقة الصالح لأي ملف.
لماذا التأخيرات الاصطناعية؟
مقارنات السلاسل ذات الخروج المبكر هي على الأرجح أكثر مصادر التسريبات الزمنية التشفيرية شيوعًا، لكنها ليست سهلة الاستغلال بوجه خاص. في الواقع، كثير من التسريبات الزمنية (مثلًا، أي منها في C أو C++ أو Ruby أو Python) على الأرجح غير قابلة للاستغلال عبر شبكة واسعة النطاق إطلاقًا. للعب بهجوم على تسريبات زمنية واقعية، عليك البدء بكتابة شيفرة توقيت منخفضة المستوى. نحن نُبقي الأمور تشفيرية في هذه التحديات.
32. كسر HMAC-SHA1 بتسرّب زمني أقل اصطناعية بقليل
قلّل مدة النوم في "insecure_compare" حتى ينكسر حلك السابق. (جرّب 5 مللي ثانية للبداية.)
الآن اكسره مرة أخرى.