
تجاوز ASLR بدون تسريب معلومات
في هذا المقال، سأناقش تطبيق التقنية التي وصفها Samuel Groß في Remote iPhone Exploitation Part 2: Bringing Light into the Darkness -- a Remote ASLR Bypass، لتجاوز ASLR على Linux x86_64.
لإظهار ذلك، سأحل تحديًا من نوع pwnable من Buckeye CTF، اسمه guess_god.
سأحاول إبقاء المحتوى مناسبًا للمبتدئين قدر الإمكان، لذا لا تتردد في تخطي أي قسم إذا كنت تشعر بالثقة الكافية وتريد فقط رؤية الاستغلال.

لم ألعب CTF، لكنني أصبحت مهتمًا بالتحدي قبل حوالي ساعتين من نهاية الـ CTF بفضل Guray00، الذي كان يطلب المساعدة في ديسكورد fibonhack بشأن بعض الأمور المتعلقة بالتشفير.
لم أستطع مساعدته، لكنني ألقيت نظرة على تحديات pwnable، ورأيت أنه سيكون من الجيد فهم منشور P0 على المدونة، وربما الحصول على تلك المكافأة.
التوزيع العشوائي لمساحة العناوين (ASLR) هي تقنية أمن حاسوبي تتضمن الوضع العشوائي للعنوان الأساسي للملف التنفيذي ومواقع المكتبات، والـ heap، والـ stack في مساحة عناوين العملية.
على Linux، يمكنك فحص خرائط (mappings) عملية ما بمعرفة الـ pid الخاص بها من خلال procfs، عن طريق قراءة الملف /proc/<pid>/maps.
إذا كنت عملية وتريد معرفة خرائط الذاكرة الخاصة بك، يمكنك قراءة /proc/self/maps.
على سبيل المثال، يمكنك محاولة قراءة /proc/self/maps باستخدام cat:```
root@088ec31b2ce9:/home/ctf/challenge# cat /proc/self/maps
55faeb01c000-55faeb01e000 r--p 00000000 fe:01 2497233 /usr/bin/cat
55faeb01e000-55faeb023000 r-xp 00002000 fe:01 2497233 /usr/bin/cat
55faeb023000-55faeb026000 r--p 00007000 fe:01 2497233 /usr/bin/cat
55faeb026000-55faeb027000 r--p 00009000 fe:01 2497233 /usr/bin/cat
55faeb027000-55faeb028000 rw-p 0000a000 fe:01 2497233 /usr/bin/cat
55faeb115000-55faeb136000 rw-p 00000000 00:00 0 [heap]
7fe15dfb1000-7fe15dfd5000 rw-p 00000000 00:00 0
7fe15dfd5000-7fe15dffb000 r--p 00000000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15dffb000-7fe15e166000 r-xp 00026000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15e166000-7fe15e1b2000 r--p 00191000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15e1b2000-7fe15e1b5000 r--p 001dc000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15e1b5000-7fe15e1b8000 rw-p 001df000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15e1b8000-7fe15e1c3000 rw-p 00000000 00:00 0
7fe15e1c7000-7fe15e1c8000 r--p 00000000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fe15e1c8000-7fe15e1ef000 r-xp 00001000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fe15e1ef000-7fe15e1f9000 r--p 00028000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fe15e1f9000-7fe15e1fb000 r--p 00031000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fe15e1fb000-7fe15e1fd000 rw-p 00033000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fff4388f000-7fff438b0000 rw-p 00000000 00:00 0 [stack]
7fff43989000-7fff4398d000 r--p 00000000 00:00 0 [vvar]
7fff4398d000-7fff4398f000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
root@088ec31b2ce9:/home/ctf/challenge# cat /proc/self/maps 55ffc0b1b000-55ffc0b1d000 r--p 00000000 fe:01 2497233 /usr/bin/cat 55ffc0b1d000-55ffc0b22000 r-xp 00002000 fe:01 2497233 /usr/bin/cat 55ffc0b22000-55ffc0b25000 r--p 00007000 fe:01 2497233 /usr/bin/cat 55ffc0b25000-55ffc0b26000 r--p 00009000 fe:01 2497233 /usr/bin/cat 55ffc0b26000-55ffc0b27000 rw-p 0000a000 fe:01 2497233 /usr/bin/cat 55ffc2108000-55ffc2129000 rw-p 00000000 00:00 0 [heap] 7f1ec6e0f000-7f1ec6e33000 rw-p 00000000 00:00 0 7f1ec6e33000-7f1ec6e59000 r--p 00000000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec6e59000-7f1ec6fc4000 r-xp 00026000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec6fc4000-7f1ec7010000 r--p 00191000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec7010000-7f1ec7013000 r--p 001dc000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec7013000-7f1ec7016000 rw-p 001df000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec7016000-7f1ec7021000 rw-p 00000000 00:00 0 7f1ec7025000-7f1ec7026000 r--p 00000000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7f1ec7026000-7f1ec704d000 r-xp 00001000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7f1ec704d000-7f1ec7057000 r--p 00028000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7f1ec7057000-7f1ec7059000 r--p 00031000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7f1ec7059000-7f1ec705b000 rw-p 00033000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7ffc72fa4000-7ffc72fc5000 rw-p 00000000 00:00 0 [stack] 7ffc72fe7000-7ffc72feb000 r--p 00000000 00:00 0 [vvar] 7ffc72feb000-7ffc72fed000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
### أنماط خرائط الذاكرة
إذا قمت بذلك عدة مرات، يمكنك أن تستنتج ما يلي:
* يجب أن يكون عنوان القاعدة PIE للثنائي في النطاق 0x00005500_00000000-0x00005700_00000000، مما يعني 2 تيرابايت من العناوين الممكنة.
* الكومة قريبة من الثنائي.
* تقع المكتبات في النطاق 0x00007f00_00000000 - 0x00007fff_ffffffff، أي 1 تيرابايت من العناوين الممكنة.
* تذهب المكدس (في معظم الأحيان) إلى النطاق 0x00007ffc_00000000 - 0x00007fff_ffffffff، أي 16 غيغابايت من العناوين الممكنة.
* النطاق 0xffffffffff600000 - 0xffffffffff601000 يكون دائمًا مُخططًا، يمكنك قراءة [هذه المقالة](http://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/02/13/vsyscall-and-vdso) إذا كنت فضوليًا بشأن ما هو.
## 1.3 كيفية تجاوز ASLR بدون تسريب معلومات
لنناقش ما يمكنك فعله لتجاوز ASLR عندما لا يكون تسريب المعلومات ممكنًا.
هذه محاولتي لتلخيص ما استخلصته من قراءة تدوينة Saelo.
لتجاوز ASLR تحتاج إلى:
* تقنية رش الذاكرة، والتي تتيح لك تعيين ذاكرة متجاورة بحجم معين، على نطاق معين من العناوين.
كما يقول هناك طريقتان للقيام بذلك:
1. عن طريق إساءة استخدام تسريب ذاكرة (وليس تسريب معلومات!)، وهو خطأ يُنسى فيه جزء من الذاكرة ولا يتم تحريره أبدًا، وتشغيله عدة مرات حتى يتم تسريب المقدار المطلوب من الذاكرة.
2. عن طريق إيجاد وإساءة استخدام "أداة تضخيم": قطعة من الكود تأخذ جزءًا موجودًا من البيانات وتنسخه، ربما عدة مرات، مما يسمح للمهاجم برش كمية كبيرة من الذاكرة بإرسال عدد صغير نسبيًا من البايتات فقط.
* أوراكل `isAddressMapped`، الذي يخبرك عند إعطائه عنوانًا ما سواء كان ذلك العنوان مُخططًا أم لا.
### إثبات المفهوم لتجاوز ASLR على لينكس
لنجرب إعادة إنتاج إثبات المفهوم الخاص بـ saelo لكسر ASLR بالكامل على لينكس.
<p align="center"> <img src="https://assets.kitploit.com/production/public/readmes/48660/93fcc6aff8ffd2e8395f34b35bc2f5d244e74a53b2fac39c3dae35c802227339.png" > <i> إثبات المفهوم الخاص بـ saelo</i> <p/> <br/>
على لينكس، الأمر ليس بهذه السهولة، فمن الممكن كسر ASLR بالكامل فقط إذا كنت قادرًا على تخصيص 16 تيرابايت من الذاكرة.```C
#include <stdio.h>
#include <stdlib.h>
int main()
{
// 64gb
size_t size = 0x1000000000;