
استغلال لإثبات المفهوم يتحايل على آلية ASLR في معالجات Intel عبر إساءة استخدام مخزن أهداف الفروع (Branch Target Buffer) والتنفيذ التخميني لتسريب العناوين العشوائية عبر قناة جانبية.
توزيع عشوائي لمساحة العنوان (ASLR) هو إجراء تخفيفي يُستخدم لزيادة صعوبة استغلال هجمات تلف الذاكرة. في سيناريو وجود ثغرة تجاوز سعة المخزن المؤقت، على سبيل المثال، يحتاج المهاجم الذي يحاول بناء استغلال باستخدام البرمجة الموجهة بالإرجاع (Return Oriented Programming) إلى معرفة عناوين القطع (gadgets) في السلسلة. إذا كان جزء الكود من البرنامج المستهدف يتم توزيعه عشوائيًا، يصبح من الأصعب بكثير على المهاجم اختيار العنوان الصحيح للاستغلال، مما يجعل الاستغلال غير ممكن.
يوضح المثال التالي كيف يتم توزيع عنوان عشوائيًا:
#include <stdio.h>
void DoNothing();
void (*codePtr)() = DoNothing;
void DoNothing(){}
int main(int argc,char **argv){
printf("Destination %p\n",codePtr);
DoNothing();
}
في كل تنفيذ يتم توزيع القيمة عشوائيًا:
Destination 0x563714256149
Destination 0x556d8e2f1149
Destination 0x5618c8bdd149
Destination 0x55ee623b0149
البتات الاثنتا عشرة الأخيرة 149 تكون نفسها دائمًا، لكن موقع الدالة يمكن أن يكون تقريبًا في أي مكان بين 0x550000000000 و0x570000000000، مما يعني أن 29 بتًا يتم توزيعها عشوائيًا، لتشغل مساحة عنوان محتملة تبلغ 0x200 0000 0000 أو 2.2 تيرابايت تقريبًا.
إن معالجة كل تعليمة هي مهمة صعبة. بعض مراحل معالجة تعليمة واحدة هي:
من أجل زيادة إنتاجية التعليمات في المعالج، يتم تنفيذ كل مهمة من مهام التعليمة بواسطة وحدة محددة من معالج. مع عمل جميع الوحدات بالتوازي، يسمح ذلك للمعالج بالعمل بسرعات ساعة أعلى بكثير، وهذه هي فكرة خط الأنابيب.
| العملية \ دورة الساعة | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| الجلب | A | B | C | ||
| فك الترميز | A | B | C | ||
| التنفيذ | A | B | C |
تنفيذ التعليمات A وB وC عبر الدورات 1-5. في الدورة 3، على سبيل المثال، تكون وحدات القراءة وفك الترميز والتنفيذ نشطة في الوقت نفسه
ومع ذلك، فإن التعليمات ليست مستقلة تمامًا عن بعضها البعض. على سبيل المثال، التسلسل التالي:
A. add ax,[bx]
B. jz $+1
C. mov dl,[rsi]
D. nop
في هذه الحالة، ستنتهي التعليمة A في أفضل الأحوال فقط في الدورة 3 عند مرحلة التنفيذ. ومع ذلك، تحتاج وحدة الجلب إلى تحديد ما هي التعليمة التالية التي يجب جلبها من الذاكرة، وما إذا كان يجب تخطي التعليمة C (mov dl,[rsi]).
في هذا السيناريو، أمام المعالج خيار الانتظار حتى تنتهي التعليمة A، وهو ما لن يحدث إلا في الدورة الثالثة، ليقوم بعدها بجلب التعليمة الصحيحة من الذاكرة، إذا كانت عملية الجمع تُرجع 0، على سبيل المثال:
| العملية \ دورة الساعة | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| الجلب | A | B | D | |||
| فك الترميز | A | B | D | |||
| التنفيذ | A | B | D |
وهذا يعني حدوث تأخير في خط الأنابيب لأن المعالج يجب أن ينتظر تنفيذ التعليمة. في هذا المثال، التأخير هو دورة ساعة واحدة فقط، لكن التعليمة add ax,[bx] تتطلب عملية ذاكرة، والتي كما رأينا سابقًا يمكن أن تستغرق مئات الدورات حتى تكتمل، مما يفرض تكلفة أداء كبيرة على المعالج.
سيكون الخيار الأسرع هو محاولة «تخمين» مسار التنفيذ الصحيح. يمكن للمعالج أن يخمن (speculate) ما إذا كان الفرع سيُتخذ أم لا. بعد تلك النقطة، يستمر التنفيذ من المسار المُخمَّن، ولا يتم اعتماد القيم إلا إذا ثبت صحة المسار بعد انتهاء التعليمة A. إذا ثبت أن المسار خاطئ، يتم تجاهل النتائج وإعادة الحالة إلى ما قبل نقطة التخمين.
| العملية \ دورة الساعة | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| الجلب | A | B | (S) C | |||
| فك الترميز | A | B | (S) C | |||
| التنفيذ | A | B | (S) C |
المشكلة الوحيدة في التراجع عن المسار المُتخذ هي أن الحالة المعمارية الدقيقة للمعالج لا يمكن التراجع عنها. لذا إذا خمّن المعالج تنفيذ التعليمة C (mov dl,[rsi])، فسيتم نقل البيانات المشار إليها بواسطة rsi إلى الكاش. ويمكن قياس هذا التأثير لاحقًا باستخدام هجوم قناة جانبية.

متنبئ شرطي ثنائي البت. https://en.wikipedia.org/wiki/Branch_predictor
لا يجب التنبؤ بالتعليمات الشرطية فقط، بل أيضًا بالفروع غير المباشرة. يجب أن يمتلك المعالج آلية لتخمين وجهات تعليمة مثل call [rdi].
تظهر ثغرة Spectre v2 أنه من الممكن استغلال المتنبئ غير المباشر لتحقيق تنفيذ عابر (transient execution) في عمليات أخرى:
مأخوذ من https://spectreattack.com/spectre.pdf
عند وضع تعليمة استدعاء في السياق A على نفس العنوان الافتراضي لتعليمة استدعاء أخرى في السياق B، يمكن للمهاجم تدريب المعالج على تنفيذ كود عند موضع يختاره المهاجم في السياق B، في هجوم إعادة استخدام الكود، على غرار البرمجة الموجهة بالإرجاع (ROP).
يجب أن يمتلك الضحية المستهدفة قطعة كود تُعرف باسم «spectre gadget» قادرة على تسريب سر باستخدام هجوم قناة جانبية. لنجاح هجوم Spectre، يجب على المهاجم أيضًا معرفة موقع الـ spectre gadget. لذلك، في هجمات المستخدم ضد المستخدم، كان حماية الضحية باستخدام ASLR تُستخدم كإجراء تخفيفي لهذا النوع من الهجمات. ومع ذلك، توجد أيضًا تقنيات لاستخراج ASLR باستخدام هجمات معمارية دقيقة مثل القفز فوق ASLR (Jump Over ASLR). لكن لهذه التقنية بعض القيود فيما يتعلق بكمية البتات المسربة، لأنها تعتمد على التصادم في المتنبئ المباشر لتجاوز ASLR.
الآليات الداخلية لهذا المتنبئ موضحة أدناه:

مأخوذ من https://spectreattack.com/spectre.pdf
بعض هذه المكونات هي:
التخطيط الكلاسيكي لهجوم Spectre v2 يبدو هكذا:

getenv + secret[0]*4096 تسريب قيمة السر في الموضع 0 باستخدام libc كذاكرة مشتركة.Exec ASLR (المعروف أيضًا باسم تسميم مخزن أهداف الفروع العكسي - Reverse Branch Target Buffer Poisoning) هو تقنية جديدة لتجاوز ASLR باستخدام ثغرة Spectre-BTI. تسيء هذه التقنية استخدام حقيقة أنه ليس فقط يمكن للمهاجم تلويث BTB في سيناريو Spectre-BTI الكلاسيكي، بل يمكن للضحايا أيضًا أن يتسببوا في تنبؤ خاطئ للفرع في عملية المهاجم، مما يقود المهاجم إلى قفزة تخمينية إلى عنوان محمي بواسطة ASLR. ثم باستخدام قناة جانبية تسرب العنوان الذي يتم تنفيذه، يمكن للمهاجم استرداد عنوان الوجهة الكامل، متجاوزًا ASLR للعملية المستهدفة.
يبدو تخطيط هجوم Exec ASLR هكذا:
