بسم الله الرحمن الرحيم الحمد لله رب العالمين والصلاة والسلام على أشرف المرسلين سيدنا محمد وعلى آله وصحبه ومن تبعهم بإحسان إلى يوم الدين.
حسابي في التويتر هنا
المتطلبات:
معرفة بأساسيات الHeap و التعامل مع malloc
معرفة ببعض هجمات الHeap
قرأءة مقالاتي السابقة بخصوص الHeap Attacks
البداية
ماهو Unsafe Unlink ؟
هو تكنيك فكرته أنشاء 2 chunks بحجم يناسب الsmallbins أول chunk نضع لها FD & BK ولازم يأشرون على نفس الchunk أو مكان فيه العنوان حق الchunk عشان تكون الfake chunk حقتنا وعشان نتخطى unlink check ثم نحاول إضافة prev_size الى chunk رقم أثنين وجعل prev_inuse flag الخاص بالchunk رقم 2 يساوي 0 ثم نسوي free لchunk رقم أثنين كي نستدعي unlink() macro وتندمج Chunk 1 و Chunk 2 ثم يعطينا هذا arbitrary write.
راح أشرح بعد التفاصيل لاحقاً
ماهو smallbins ؟
هي bin تشبه fastbin لكن فيه كذا أختلاف بسيط نوعها doubly linked, circular list فيها 62 bin تحتوي على الchunks الي صار لها free وحجمها أكبر من fastbin أو أقل, تتعامل مع FD & BK عكس fastbin الي تتعامل فقط مع FD
مثال:
Chunk A الFD حقها يأشر على Chunk B FD و Chunk B ال BK حقها يأشر على Chunk A FD و الBK حق Chunk A يأشر على Chunk B
أول Chunk موجودة في الbin الBK حقها يأشر على على أخر chunk موجودة في الBin
أخر Chunk موجودة في الbin الFD حقها يأشر على على أول chunk موجودة في الBin
عندما تطلب من malloc أن تحجز لك chunk حجمها 0xa00 سوف تذهب للبحث عن الchunk في unsortedbin و smallbin تبدأ البحث من الخلف (Tail).
الunsortedbin و الsmallbin عملية فك أرتبط الChunks فيهم هي Partial Unlink.
ماهو Partial Unlink ؟
هو عملية فك أرتباط الchunk جزئياً من smallbins و unsortedbins حيث يتم تتبع BK الخاص با victim chunk و نسخ العنوان الموجود في أعلى (Head) الbin سواً كانت smallbins او unsortedbins الى العنوان الموجود في الFD الخاص با victim chunk وبعد ذالك يتم نسخ BK الخاص با victim chunk الى BK الخاص با الHead الموجود في الBin.
أدري حوسه صح ؟ لكن في الشرح راح تفهمون الفكره
ماهي unlink() macro ؟
عندما نريد حذف chunk من bin نستدعي ()unlink كي تحذفها من الbin وترجعها للمستخدم.
هنا تتأكد الunlink من الFD و الBK اذا كانت ال FD تأشر على BK و الBK تأشر على الFD
هنا الsource code حق ()unlink حق اذا بغينا ندمج 2 smallbins chunks وتصير chunk وحدة زي مانشوف أول شرط تتأكد اذا كان الprev_inuse حق الchunk يساوي 0, ثم تتأكد اذا كان فيه prev_size للchunk ثم تتأكد اذا كان الprev_size صحيح او لا واذا كان صحيح راح تدمجه مع حجم الchunk و اذا كان حجم الchunk مايساوي prev_size الي مكتوب يعني اذا كان فيه Chunk A و Chunk B وكان حجم Chunk A 0x90 وحطينا في prev_size حق Chunk B 0x60 راح يصير abort ويطلع لنا error من glibc اذا كان لا الprev_size صحيح راح تستدعي ()unlink
عشان نوصل لل()unlink لازم نحط prev_size حق Chunk B ويكون صحيح عشان تندمج من الchunk الي قبلها, ونخلي prev_inuse حق Chunk B = 0
في إصدارت الglibc الجديدة unlink تتأكد من FD و BK حق الchunk اذا كان
FD = BK و BK = FD راح نتخطى الcheck
اذا ماكان الFD و الBK يأشرون على نفس الChunk راح يطلع Error
خطوات الهجوم
ننشئ 2 chunks
نحط لا أول Chunk الFD و الBK يأشرون على المتغير table الي راح يكون فيه العنوان حق Chunk A وكذا نتخطى الcheck حق unlink
نحط 0 كا الprev_size حق Chunk A و حجم أقل بقليل من حجم Chunk A في Chunk A عشان نقنع chunk_B ان ذا الprev_size و الsize حق Chunk A
نحط الحجم حق chunk A - 0x10 في prev_size حق Chunk B عشان نوصل للمكان الي حطينا فيه الprev_size و الsize حق Chunk A ونحط الحجم حق Chunk B في size field حق Chunk B نفسه بالزبط لكن prev_inuse = 0
نحرر Chunk B وراح تندمج Chunk A و Chunk B وأي شيء نكتبه في Chunk A راح ينكتب في المتغير table بحكم أنها الFake Chunk حقتنا وراح نغير الpointer الموجود في المتغير حق Chunk A الى free GOT وبكذا أي بعدها نكتبه في Chunk A راح ينكتب في free GOT ونغيره الى ()system ونحصل على Arbitrary Code Execution
في التطبيق راح أشرح الي ماهو مفهوم
رابط البرنامج المستخدم في الشرح هنا
الخطوة رقم 1
الخطوة رقم 2
ليش في الFD والBK نقصنا من العنوان ؟
عشان لو حطينا العنوان زي ماهو راح يزيد عليه 0x18 byte والBK كذالك راح يزيد عليه 0x10 byte وهذا الي مانبيه عشان كذا نقصنا منها عشان لو زاد راح يجي على العنوان حق المتغير table بالزبط ونتخطى unlink check>
الخطوة رقم 3
الخطوة رقم 4
نشوف قدرنا نحط new prev_size و new size لا Chunk A و Chunk B فا لو رجعنا نقصنا من العنوان حق Chunk B - 0x80 byte راح نرجع للfake prev_size و fake size حق chunk A ولو سوينا free لChunk B الحين راح تعتقد أن Chunk A محررة بعد فا راح تندمج وأي شيء نكتبه راح يروح للمتغير table بحكم أن حنا حطيناه في الFD و الBK حق Chunk A بسبب أنه يحتوي على العنوان حق Chunk A الي راح يخلي Chunk A تأشر على نفسها و نتخطى unlink check وعشان وراح يكون المتغير table هو الFake Chunk حقتنا وراح نقدر نسوي overwrite للبيانات الي فيه
الخطوة رقم 5 و الأخيره
نشوف الحين الchunk الوحيدة الموجودة هي Chunk A الحين نحاول نكتب فيها أي شيء ونشوف هل راح ينكتب في المتغير Table ولالا ؟
نشوف الحمدلله قدرنا نسوي overwrite للمتغير table بنجاح وراح نحط العنوان حق الGOT الخاص با ()free بدال العنوان حق Chunk A الموجود في المتغير table وأي شيء من بعدها نكتبه في Chunk A راح ينكتب في الGOT الخاص با ()free
قدرنا نسوي overwrite بنجاح للfree GOT والحين نسوي chunk فيها “bin/sh/“ ونسوي لها free ويوم نستدعي free راح نستدعي system(“/bin/sh“)
النهاية
وفي النهاية أتمنى عجبكم الموضوع وباذن الله أكون شرحت كل شيء والله يوفقكم جميعا وأسال الله أن يوفقني ويوفقكم جميعا.
Resources:
https://ir0nstone.gitbook.io/notes/types/heap/unlink-exploit
https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit
https://www.youtube.com/watch?v=HWhzH--89UQ
https://github.com/shellphish/how2heap/blob/master/glibc_2.35/unsafe_unlink.c