إيجاد الـ Bad Characters في الـ Shellcode

مقدمة

في مرحلة من مراحل كتابتنا لثغرة BufferOverflow فإننا قد نعاني من مشكلة مملة و نجد أن الـPayload يعطّل الـ Exploit بكامله مع أننا قد تأكدنا أن كل شئ يمشى بأفضل حال قبل وضع الـ Shellcode الحقيقي. السبب في ذلك هو وجود الـ Bad Characters أو الـ Restricted Characters.

ستكتشف تلك المشكلة عندما تضع نقطة وقوف Break Point في الـ Debugger ولكن عند تنفيذ الثغرة لن تصل إلى ذلك العنوان. أو أنك ستصل ولكن الـ Shellcode لن يعمل (بشرط تأكدك أن جميع الأجزاء الأخرى سليمة).

ما هي الـ Bad/Restricted Characters؟

هي Characters عادية من ضمن الـ Shellcode يتم عمل Decoding لها بشكل طبيعي ولكن لها معنى لا يقبله البرنامج المصاب كأن يكون هذا الـ Characters سيدخل في تسمية ملف مثلا و فلو فرضنا أن في الشل كود قيمة ستدخل في تسمية ملف ما و كانت القيمة “\x7D” و التي تعني “}” و من المعروف أننا لا نستطيع وضع هذا الحرف في إسم ملف فوقتها سيوقف هذا الحرف مجرى عملية الـ Decoding للـ Shellcode.

قد يبدر إلى أذهاننا بعض الأسئلة, منها..

س/ هل جميع البرامج المصابة سيكون بها Bad Characters Restriction ؟

ج/ لا

س/ هل يوجد Bad Characters أساسية يجيب أزيلها من أي Shellcode أقوم بعمله؟

ج/ نعم, هما: x00 و x0d

س/ هل كل البرامج لها نفس الـ Bad Characters أي أنني أستطيع أن أحذف كل ما تم اكتشافه سابقا في البرامج اللاحقة؟

ج/ لا, لكل برنامج Bad Characters مختلفة تختلف بطبيعة البرنامج و طريقة تنفيذه

س/ هل يمكن أن يحتوي البرنامج على أكثر من Bad Character واحد ؟

ج/ للأسف نعم

إيجاد الـ Bad Characters – الطريقة الأولى

في البداية, هذه الطريقة هي طريقة مملة و مرهقة جدا و إن كنت سأعطيها إسما فلا أجد أفضل من طريقة السكتة الدماغية حيث يتوقف العقل عن التفكير تماما مع الحاجة إلى الكثير من العمل الممل إلا إذا كنت محظوظ و وجدت الحرف في أول سطر أو سطرين, وأمر الحظ بالذات غير متوفر بالنسبة لي شخصيا.

تعتمد هذه الطريقة على إنشاء جميع احتمالات الحروف من 0-255 عن طريق سكريبت يسمى generatecodes.pl.

في البداية تقوم بتنفيذ السكريبت مع إزالة الـBad Characters الشائعة x00 و x0d .

./generatecodes.pl 00,0d
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e"
"\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d"
"\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c"
"\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b"
"\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a"
"\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79"
"\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88"
"\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97"
"\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6"
"\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5"
"\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4"
"\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
"\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2"
"\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1"
"\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

مثال: shellcode = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0e\x0f\x10") الأن نضيف السطر الثاني من المخرجات إلى السطر الأول و نضع الـ Break Point خاصتنا و من ثم ننفذ البرنامج. إذا وصلنا للعوان الصحيح فهذا يعني أن Bad Characters ليست من ضمن الحروف التي في السطر الثاني, و هكذا.

مثال: shellcode = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0e\x0f\x10" "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f") عندما لا نصل للعنوان الصحيح, نقوم بقسم السطر الذي وصلنا عنده و حصل عنده خطأ في النتائج و نستبدل النصف الأول منه بـ “\x41” مثلا . ثم نجرب فإن حصل خطأ, فهذا يعني أن الـ Bad Character في النصف الأخر, وقتها نبدأ نغير حروف النصف الثاني من السطر الأخير إلى “\x41” و نجرب في كل مره حتى نصل أنه لا يوجد خطأ في النتائج و عندها سنعرف ال Bad Character

مثال: "\x41\x41\x41\x41\x41\x41\x41\x41\x28\x29\x2a\x2b\x2c\x2d\x2e" سنفترض أننا وجدنا و أنه “x0a” إذا سنقول بعمل الأتي

./generatecodes.pl 00,0d,0a
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11"
"\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
"\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e"
"\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d"
"\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c"
"\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b"
"\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a"
"\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89"
"\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98"
"\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
"\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6"
"\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
"\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4"
"\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3"
"\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2"
"\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

و نتأكد مرة أخرى, لو لظهر أي خطأ في مجرى سير البرنامج في الـ Debugger إذن كل شئ على ما يرام. و إن لم!!, فهذا يعني -ولا حول ولا قوه إلا بالله- أنه يوجد Bad Character أخر و يجب أن تكمل المسيرة حتى تجده.

إيجاد الـ Bad Characters – الطريقة الثانية – تحديث 19/2/2013

قام فريق Corelan بإيقاف تطوير الإضافة pvefindaddr واستبدلها بالإضافة الجديدة والأفضل mona.py مع استخدام الدالة compare

حمل الإضافة من هنا mona.py

كل ما عليك فعله هو وضع الإضافة في مجلد الـمنقح Immunity debugger في المسار التالي

C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands

ثم ضع ملف الـ Shellcode في الـ C حيث يكون مساره

c:\shellcode.bin

ملاحظة: إذا كان الـShellcode بصيغة الـ Hex فيجب تحويله إلى Binary , الرجاء زيارة هذا الرابط

الأن ضع الـ Break point خاصتك ثم نفذ الـ exploit الذي يحتوي على الـ shellcode الحقيقي

بمجرد توقف البرنامج, نفذ الأمر التالي في Command bar في الـ Immunity Debugger

!mona compare c:\shellcode.bin

ستخرج لك نافذة تحتوي على العناوين التي تتواجد بها الـ Bad Characters مثل هذه

الأن اذهب إلى نافذة الـسجلات من

View >> Log أو اضغط ALT + L

ستجد التالي: (يرجى تكبير الصورة)

كما ترى في حالتي كانت الـ Bad Characters هي 5c و 2f

أيضا تستطيع أن تجد النتائج في ملف compare.txt على هذا المسار

C:\Program Files\Immunity Inc\Immunity Debugger

(هذا المسار يحتوي على معظم نتائج استخدام mona.py).

إيجاد الـ Bad Characters – الطريقة الثانية

في البداية أحب أن أرفع القبعة إلى Peter Van رئيس فريق Corelan و هو من أشهر و أقوى الأشخاص في شرح الـ Buffer Overflow ومبرمج للعديد من السكربتات المفيدة جدا في هذا المجال.

الطريقة الثانية هي عن طريق إضافة رائعة إسمها pvefindaddr مع استخدام الدالة compare

ملاحظة: لا تنسى إضافة pvefindaddr فلها استخدامات كثيرة و رائعة في الـ Buffer Overflow

كل ما عليك فعله هو وضع الإضافة في مجلد الـمنقح Immunity debugger في المسار التالي

C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands

ثم ضع ملف الـ Shellcode في الـ C حيث يكون مساره

c:\shellcode.bin

ملاحظة: إذا كان الـShellcode بصيغة الـ Hex فيجب تحويله إلى Binary , الرجاء زيارة هذا الرابط

الأن ضع الـ Break point خاصتك ثم نفذ الـ exploit الذي يحتوي على الـ shellcode الحقيقي

بمجرد توقف البرنامج, نفذ الأمر التالي في Command bar في الـ Immunity Debugger

!pvefindaddr compare c:\shellcode.bin

ستخرج لك نافذة تحتوي على العناوين التي تتواجد بها الـ Bad Characters مثل هذه

الأن اذهب إلى نافذة الـسجلات من

View >> Log أو اضغط ALT + L

ستجد التالي: (يرجى تكبير الصورة

كما ترى في حالتي كانت الـ Bad Characters هي 5c و 2f

أيضا تستطيع أن تجد النتائج في ملف compare.txt على هذا المسار

C:\Program Files\Immunity Inc\Immunity Debugger (هذا المسار يحتوي على معظم نتائج استخدام pvefindaddr).

تحياتي واحترامي

Last updated